Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 73383ab

Browse files
committed
Bug 1366818, r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D122785
1 parent 4487c2b commit 73383ab

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

browser/actors/FormValidationParent.jsm

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,59 @@
1010

1111
var EXPORTED_SYMBOLS = ["FormValidationParent"];
1212

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+
1347
class FormValidationParent extends JSWindowActorParent {
1448
constructor() {
1549
super();
1650

1751
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;
1866
}
1967

2068
/*
@@ -23,6 +71,7 @@ class FormValidationParent extends JSWindowActorParent {
2371

2472
uninit() {
2573
this._panel = null;
74+
this._obs = null;
2675
}
2776

2877
hidePopup() {
@@ -47,6 +96,10 @@ class FormValidationParent extends JSWindowActorParent {
4796
return;
4897
}
4998

99+
if (FormValidationParent.hasOpenPopups()) {
100+
return;
101+
}
102+
50103
this._showPopup(data);
51104
break;
52105
case "FormValidation:HidePopup":
@@ -55,10 +108,6 @@ class FormValidationParent extends JSWindowActorParent {
55108
}
56109
}
57110

58-
observe(aSubject, aTopic, aData) {
59-
this._hidePopup();
60-
}
61-
62111
handleEvent(aEvent) {
63112
switch (aEvent.type) {
64113
case "FullZoomChange":
@@ -78,11 +127,13 @@ class FormValidationParent extends JSWindowActorParent {
78127

79128
_onPopupHiding(aEvent) {
80129
aEvent.originalTarget.removeEventListener("popuphiding", this, true);
130+
Services.obs.removeObserver(this._obs, "popup-shown");
81131
let tabBrowser = aEvent.originalTarget.ownerGlobal.gBrowser;
82132
tabBrowser.selectedBrowser.removeEventListener("scroll", this, true);
83133
tabBrowser.selectedBrowser.removeEventListener("FullZoomChange", this);
84134
tabBrowser.selectedBrowser.removeEventListener("TextZoomChange", this);
85135

136+
this._obs = null;
86137
this._panel = null;
87138
}
88139

@@ -110,6 +161,9 @@ class FormValidationParent extends JSWindowActorParent {
110161
if (!previouslyShown) {
111162
// Cleanup after the popup is hidden
112163
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);
113167

114168
// Hide if the user scrolls the page
115169
tabBrowser.selectedBrowser.addEventListener("scroll", this, true);

layout/xul/nsMenuPopupFrame.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "mozilla/LookAndFeel.h"
5252
#include "mozilla/MouseEvents.h"
5353
#include "mozilla/PresShell.h"
54+
#include "mozilla/Services.h"
5455
#include "mozilla/StaticPrefs_xul.h"
5556
#include "mozilla/dom/BrowserParent.h"
5657
#include "mozilla/dom/Element.h"
@@ -399,6 +400,13 @@ NS_IMETHODIMP nsXULPopupShownEvent::Run() {
399400
popup->SetPopupState(ePopupShown);
400401
}
401402

403+
if (!mPopup->IsXULElement(nsGkAtoms::tooltip)) {
404+
nsCOMPtr<nsIObserverService> obsService =
405+
mozilla::services::GetObserverService();
406+
if (obsService) {
407+
obsService->NotifyObservers(mPopup, "popup-shown", nullptr);
408+
}
409+
}
402410
WidgetMouseEvent event(true, eXULPopupShown, nullptr,
403411
WidgetMouseEvent::eReal);
404412
return EventDispatcher::Dispatch(mPopup, mPresContext, &event);

0 commit comments

Comments
 (0)