10
10
11
11
var EXPORTED_SYMBOLS = [ "FormValidationParent" ] ;
12
12
13
+ ChromeUtils . defineModuleGetter (
14
+ this ,
15
+ "BrowserWindowTracker" ,
16
+ "resource:///modules/BrowserWindowTracker.jsm"
17
+ ) ;
18
+
19
+ const { Services } = ChromeUtils . import ( "resource://gre/modules/Services.jsm" ) ;
20
+
21
+ class PopupShownObserver {
22
+ _weakContext = null ;
23
+
24
+ constructor ( browsingContext ) {
25
+ this . _weakContext = Cu . getWeakReference ( browsingContext ) ;
26
+ }
27
+
28
+ observe ( subject , topic , data ) {
29
+ let ctxt = this . _weakContext . get ( ) ;
30
+ let actor = ctxt . currentWindowGlobal ?. getExistingActor ( "FormValidation" ) ;
31
+ if ( ! actor ) {
32
+ Services . obs . removeObserver ( this , "popup-shown" ) ;
33
+ return ;
34
+ }
35
+ // If any panel besides ourselves shows, hide ourselves again.
36
+ if ( topic == "popup-shown" && subject != actor . _panel ) {
37
+ actor . _hidePopup ( ) ;
38
+ }
39
+ }
40
+
41
+ QueryInterface = ChromeUtils . generateQI ( [
42
+ Ci . nsIObserver ,
43
+ Ci . nsISupportsWeakReference ,
44
+ ] ) ;
45
+ }
46
+
13
47
class FormValidationParent extends JSWindowActorParent {
14
48
constructor ( ) {
15
49
super ( ) ;
16
50
17
51
this . _panel = null ;
52
+ this . _obs = null ;
53
+ }
54
+
55
+ static hasOpenPopups ( ) {
56
+ for ( let win of BrowserWindowTracker . orderedWindows ) {
57
+ let popups = win . document . querySelectorAll ( "panel,menupopup" ) ;
58
+ for ( let popup of popups ) {
59
+ let { state } = popup ;
60
+ if ( state == "open" || state == "showing" ) {
61
+ return true ;
62
+ }
63
+ }
64
+ }
65
+ return false ;
18
66
}
19
67
20
68
/*
@@ -23,6 +71,7 @@ class FormValidationParent extends JSWindowActorParent {
23
71
24
72
uninit ( ) {
25
73
this . _panel = null ;
74
+ this . _obs = null ;
26
75
}
27
76
28
77
hidePopup ( ) {
@@ -47,6 +96,10 @@ class FormValidationParent extends JSWindowActorParent {
47
96
return ;
48
97
}
49
98
99
+ if ( FormValidationParent . hasOpenPopups ( ) ) {
100
+ return ;
101
+ }
102
+
50
103
this . _showPopup ( data ) ;
51
104
break ;
52
105
case "FormValidation:HidePopup" :
@@ -55,10 +108,6 @@ class FormValidationParent extends JSWindowActorParent {
55
108
}
56
109
}
57
110
58
- observe ( aSubject , aTopic , aData ) {
59
- this . _hidePopup ( ) ;
60
- }
61
-
62
111
handleEvent ( aEvent ) {
63
112
switch ( aEvent . type ) {
64
113
case "FullZoomChange" :
@@ -78,11 +127,13 @@ class FormValidationParent extends JSWindowActorParent {
78
127
79
128
_onPopupHiding ( aEvent ) {
80
129
aEvent . originalTarget . removeEventListener ( "popuphiding" , this , true ) ;
130
+ Services . obs . removeObserver ( this . _obs , "popup-shown" ) ;
81
131
let tabBrowser = aEvent . originalTarget . ownerGlobal . gBrowser ;
82
132
tabBrowser . selectedBrowser . removeEventListener ( "scroll" , this , true ) ;
83
133
tabBrowser . selectedBrowser . removeEventListener ( "FullZoomChange" , this ) ;
84
134
tabBrowser . selectedBrowser . removeEventListener ( "TextZoomChange" , this ) ;
85
135
136
+ this . _obs = null ;
86
137
this . _panel = null ;
87
138
}
88
139
@@ -110,6 +161,9 @@ class FormValidationParent extends JSWindowActorParent {
110
161
if ( ! previouslyShown ) {
111
162
// Cleanup after the popup is hidden
112
163
this . _panel . addEventListener ( "popuphiding" , this , true ) ;
164
+ // Hide ourselves if other popups shown
165
+ this . _obs = new PopupShownObserver ( this . browsingContext ) ;
166
+ Services . obs . addObserver ( this . _obs , "popup-shown" , true ) ;
113
167
114
168
// Hide if the user scrolls the page
115
169
tabBrowser . selectedBrowser . addEventListener ( "scroll" , this , true ) ;
0 commit comments