diff --git a/common/content/events.js b/common/content/events.js index f67f0eb2..99843730 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -493,6 +493,29 @@ var Events = Module("events", { this._activeMenubar = false; this.listen(window, this, "events", true); + + this.popups = { + active: [], + + update: function update(elem) { + if (elem) { + if (elem instanceof Ci.nsIAutoCompletePopup + || elem.localName == "tooltip" + || !elem.popupBoxObject) + return; + + if (!~this.active.indexOf(elem)) + this.active.push(elem); + } + + this.active = this.active.filter(function (e) e.popupBoxObject.popupState != "closed"); + + if (!this.active.length && !events._activeMenubar) + modes.remove(modes.MENU, true); + else if (modes.main != modes.MENU) + modes.push(modes.MENU); + } + }; }, signals: { @@ -1118,13 +1141,13 @@ var Events = Module("events", { }, events: { - DOMMenuBarActive: function () { + DOMMenuBarActive: function onDOMMenuBarActive() { this._activeMenubar = true; if (modes.main != modes.MENU) modes.push(modes.MENU); }, - DOMMenuBarInactive: function () { + DOMMenuBarInactive: function onDOMMenuBarInactive() { this._activeMenubar = false; modes.remove(modes.MENU, true); }, @@ -1376,24 +1399,27 @@ var Events = Module("events", { } }, + popupshowing: function onPopupShowing(event) { + this.popups.update(event.originalTarget); + }, + popupshown: function onPopupShown(event) { let elem = event.originalTarget; + this.popups.update(elem); + if (elem instanceof Ci.nsIAutoCompletePopup) { if (modes.main != modes.AUTOCOMPLETE) modes.push(modes.AUTOCOMPLETE); } - else if (elem.localName !== "tooltip") - if (Events.isHidden(elem)) { + else if (elem.localName !== "tooltip") { + if (Events.isHidden(elem)) if (elem.hidePopup && Events.isHidden(elem.parentNode)) elem.hidePopup(); - } - else if (modes.main != modes.MENU) - modes.push(modes.MENU); + } }, popuphidden: function onPopupHidden(event) { - if (window.gContextMenu == null && !this._activeMenubar) - modes.remove(modes.MENU, true); + this.popups.update(); modes.remove(modes.AUTOCOMPLETE); }, diff --git a/common/content/modes.js b/common/content/modes.js index 3edabf2e..3fd8fa9f 100644 --- a/common/content/modes.js +++ b/common/content/modes.js @@ -608,7 +608,11 @@ var Modes = Module("modes", { mappings.add([modes.MENU], [""], "Close the current popup", - function () { return Events.PASS_THROUGH; }); + function () { + if (modes.popup.active.length) + return Events.PASS_THROUGH; + modes.pop(); + }); mappings.add([modes.MENU], [""], "Close the current popup", diff --git a/common/modules/dom.jsm b/common/modules/dom.jsm index 06864b77..70f0048e 100644 --- a/common/modules/dom.jsm +++ b/common/modules/dom.jsm @@ -821,8 +821,8 @@ var DOM = Class("DOM", { }; opts = opts || {}; - var t = this.constructor.types[type]; - var evt = doc.createEvent((t || "HTML") + "Events"); + var t = this.constructor.types[type] || ""; + var evt = doc.createEvent(t + "Events"); let defaults = DEFAULTS[t || "HTML"]; update(defaults, this.constructor.defaults[type]);