diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index fc7ac27fa705..02b2d53fca6b 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -459,6 +459,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm", ContextualIdentityService: "resource://gre/modules/ContextualIdentityService.jsm", Corroborate: "resource://gre/modules/Corroborate.jsm", + DateTimePickerParent: "resource://gre/modules/DateTimePickerParent.jsm", Discovery: "resource:///modules/Discovery.jsm", ExtensionsUI: "resource:///modules/ExtensionsUI.jsm", FxAccounts: "resource://gre/modules/FxAccounts.jsm", @@ -1396,6 +1397,7 @@ BrowserGlue.prototype = { this._checkForOldBuildUpdates(); AutoCompletePopup.init(); + DateTimePickerParent.init(); // Check if Sync is configured if (Services.prefs.prefHasUserValue("services.sync.username")) { WeaveService.init(); @@ -1567,6 +1569,7 @@ BrowserGlue.prototype = { AboutPrivateBrowsingHandler.uninit(); AboutProtectionsHandler.uninit(); AutoCompletePopup.uninit(); + DateTimePickerParent.uninit(); Normandy.uninit(); RFPHelper.uninit(); diff --git a/toolkit/actors/DateTimePickerChild.jsm b/toolkit/actors/DateTimePickerChild.jsm index a11c0ffdadf2..e1efea3bad00 100644 --- a/toolkit/actors/DateTimePickerChild.jsm +++ b/toolkit/actors/DateTimePickerChild.jsm @@ -8,11 +8,13 @@ ChromeUtils.defineModuleGetter(this, "BrowserUtils", var EXPORTED_SYMBOLS = ["DateTimePickerChild"]; +const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm"); + /** * DateTimePickerChild is the communication channel between the input box * (content) for date/time input types and its picker (chrome). */ -class DateTimePickerChild extends JSWindowActorChild { +class DateTimePickerChild extends ActorChild { /** * On init, just listen for the event to open the picker, once the picker is * opened, we'll listen for update and close events. @@ -27,7 +29,7 @@ class DateTimePickerChild extends JSWindowActorChild { * Cleanup function called when picker is closed. */ close() { - this.removeListeners(this._inputElement); + this.removeListeners(); let dateTimeBoxElement = this._inputElement.dateTimeBoxElement; if (!dateTimeBoxElement) { this._inputElement = null; @@ -49,15 +51,25 @@ class DateTimePickerChild extends JSWindowActorChild { * Called after picker is opened to start listening for input box update * events. */ - addListeners(aElement) { - aElement.ownerGlobal.addEventListener("pagehide", this); + addListeners() { + this.mm.addEventListener("MozUpdateDateTimePicker", this); + this.mm.addEventListener("MozCloseDateTimePicker", this); + this.mm.addEventListener("pagehide", this); + + this.mm.addMessageListener("FormDateTime:PickerValueChanged", this); + this.mm.addMessageListener("FormDateTime:PickerClosed", this); } /** * Stop listeneing for events when picker is closed. */ - removeListeners(aElement) { - aElement.ownerGlobal.removeEventListener("pagehide", this); + removeListeners() { + this.mm.removeEventListener("MozUpdateDateTimePicker", this); + this.mm.removeEventListener("MozCloseDateTimePicker", this); + this.mm.removeEventListener("pagehide", this); + + this.mm.removeMessageListener("FormDateTime:PickerValueChanged", this); + this.mm.removeMessageListener("FormDateTime:PickerClosed", this); } /** @@ -90,10 +102,6 @@ class DateTimePickerChild extends JSWindowActorChild { break; } case "FormDateTime:PickerValueChanged": { - if (!this._inputElement) { - return; - } - let dateTimeBoxElement = this._inputElement.dateTimeBoxElement; if (!dateTimeBoxElement) { return; @@ -151,10 +159,10 @@ class DateTimePickerChild extends JSWindowActorChild { new win.CustomEvent("MozSetDateTimePickerState", { detail: true })); } - this.addListeners(this._inputElement); + this.addListeners(); let value = this._inputElement.getDateTimeInputBoxValue(); - this.sendAsyncMessage("FormDateTime:OpenPicker", { + this.mm.sendAsyncMessage("FormDateTime:OpenPicker", { rect: this.getBoundingContentRect(this._inputElement), dir: this.getComputedDirection(this._inputElement), type: this._inputElement.type, @@ -174,18 +182,18 @@ class DateTimePickerChild extends JSWindowActorChild { case "MozUpdateDateTimePicker": { let value = this._inputElement.getDateTimeInputBoxValue(); value.type = this._inputElement.type; - this.sendAsyncMessage("FormDateTime:UpdatePicker", { value }); + this.mm.sendAsyncMessage("FormDateTime:UpdatePicker", { value }); break; } case "MozCloseDateTimePicker": { - this.sendAsyncMessage("FormDateTime:ClosePicker", {}); + this.mm.sendAsyncMessage("FormDateTime:ClosePicker"); this.close(); break; } case "pagehide": { if (this._inputElement && this._inputElement.ownerDocument == aEvent.target) { - this.sendAsyncMessage("FormDateTime:ClosePicker", {}); + this.mm.sendAsyncMessage("FormDateTime:ClosePicker"); this.close(); } break; diff --git a/toolkit/actors/UAWidgetsChild.jsm b/toolkit/actors/UAWidgetsChild.jsm index 87861114b211..d25353fee224 100644 --- a/toolkit/actors/UAWidgetsChild.jsm +++ b/toolkit/actors/UAWidgetsChild.jsm @@ -1,14 +1,15 @@ /* vim: set ts=2 sw=2 sts=2 et tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public -* License, v. 2.0. If a copy of the MPL was not distributed with this -* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; var EXPORTED_SYMBOLS = ["UAWidgetsChild"]; +const {ActorChild} = ChromeUtils.import("resource://gre/modules/ActorChild.jsm"); const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); -class UAWidgetsChild extends JSWindowActorChild { +class UAWidgetsChild extends ActorChild { constructor(dispatcher) { super(dispatcher); diff --git a/toolkit/actors/moz.build b/toolkit/actors/moz.build index e5c9713df30f..a7fcee64db53 100644 --- a/toolkit/actors/moz.build +++ b/toolkit/actors/moz.build @@ -26,7 +26,6 @@ FINAL_TARGET_FILES.actors += [ 'BrowserElementParent.jsm', 'ControllersChild.jsm', 'DateTimePickerChild.jsm', - 'DateTimePickerParent.jsm', 'ExtFindChild.jsm', 'FindBarChild.jsm', 'FinderChild.jsm', diff --git a/toolkit/components/pictureinpicture/tests/browser_showMessage.js b/toolkit/components/pictureinpicture/tests/browser_showMessage.js index ce0b8d2339db..63acf3a5cb23 100644 --- a/toolkit/components/pictureinpicture/tests/browser_showMessage.js +++ b/toolkit/components/pictureinpicture/tests/browser_showMessage.js @@ -23,8 +23,7 @@ add_task(async () => { try { await assertShowingMessage(browser, videoID, true); } finally { - let uaWidgetUpdate = BrowserTestUtils.waitForContentEvent(browser, "UAWidgetSetupOrChange", - true /* capture */); + let uaWidgetUpdate = BrowserTestUtils.waitForContentEvent(browser, "UAWidgetSetupOrChange"); await BrowserTestUtils.closeWindow(pipWin); await uaWidgetUpdate; } diff --git a/toolkit/modules/ActorManagerParent.jsm b/toolkit/modules/ActorManagerParent.jsm index 82b25d152771..0528ed3d2bf0 100644 --- a/toolkit/modules/ActorManagerParent.jsm +++ b/toolkit/modules/ActorManagerParent.jsm @@ -131,23 +131,6 @@ let ACTORS = { allFrames: true, }, - DateTimePicker: { - parent: { - moduleURI: "resource://gre/actors/DateTimePickerParent.jsm", - }, - - child: { - moduleURI: "resource://gre/actors/DateTimePickerChild.jsm", - events: { - "MozOpenDateTimePicker": {}, - "MozUpdateDateTimePicker": {}, - "MozCloseDateTimePicker": {}, - }, - }, - - allFrames: true, - }, - InlineSpellChecker: { parent: { moduleURI: "resource://gre/actors/InlineSpellCheckerParent.jsm", @@ -201,18 +184,6 @@ let ACTORS = { allFrames: true, }, - - UAWidgets: { - child: { - moduleURI: "resource://gre/actors/UAWidgetsChild.jsm", - events: { - "UAWidgetSetupOrChange": {}, - "UAWidgetTeardown": {}, - }, - }, - - allFrames: true, - }, }; let LEGACY_ACTORS = { @@ -238,6 +209,15 @@ let LEGACY_ACTORS = { }, }, + DateTimePicker: { + child: { + module: "resource://gre/actors/DateTimePickerChild.jsm", + events: { + "MozOpenDateTimePicker": {}, + }, + }, + }, + ExtFind: { child: { module: "resource://gre/actors/ExtFindChild.jsm", @@ -379,6 +359,16 @@ let LEGACY_ACTORS = { }, }, + UAWidgets: { + child: { + module: "resource://gre/actors/UAWidgetsChild.jsm", + events: { + "UAWidgetSetupOrChange": {}, + "UAWidgetTeardown": {}, + }, + }, + }, + UnselectedTabHover: { child: { module: "resource://gre/actors/UnselectedTabHoverChild.jsm", diff --git a/toolkit/actors/DateTimePickerParent.jsm b/toolkit/modules/DateTimePickerParent.jsm similarity index 60% rename from toolkit/actors/DateTimePickerParent.jsm rename to toolkit/modules/DateTimePickerParent.jsm index 3aaa0a0ed1b1..5dc3231a2360 100644 --- a/toolkit/actors/DateTimePickerParent.jsm +++ b/toolkit/modules/DateTimePickerParent.jsm @@ -11,7 +11,9 @@ function debug(aStr) { } } -var EXPORTED_SYMBOLS = ["DateTimePickerParent"]; +var EXPORTED_SYMBOLS = [ + "DateTimePickerParent", +]; const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); ChromeUtils.defineModuleGetter(this, "DateTimePickerPanel", "resource://gre/modules/DateTimePickerPanel.jsm"); @@ -22,53 +24,86 @@ ChromeUtils.defineModuleGetter(this, "DateTimePickerPanel", "resource://gre/modu * DateTimePickerParent listens for picker's events and notifies the content * side (input box) about them. */ -class DateTimePickerParent extends JSWindowActorParent { +var DateTimePickerParent = { + picker: null, + weakBrowser: null, + + MESSAGES: [ + "FormDateTime:OpenPicker", + "FormDateTime:ClosePicker", + "FormDateTime:UpdatePicker", + ], + + init() { + for (let msg of this.MESSAGES) { + Services.mm.addMessageListener(msg, this); + } + }, + + uninit() { + for (let msg of this.MESSAGES) { + Services.mm.removeMessageListener(msg, this); + } + }, + + // MessageListener receiveMessage(aMessage) { debug("receiveMessage: " + aMessage.name); switch (aMessage.name) { case "FormDateTime:OpenPicker": { - let topBrowsingContext = this.manager.browsingContext.top; - let browser = topBrowsingContext.embedderElement; - this.showPicker(browser, aMessage.data); + this.showPicker(aMessage.target, aMessage.data); break; } case "FormDateTime:ClosePicker": { - if (!this._picker) { + if (!this.picker) { return; } - this._picker.closePicker(); + this.picker.closePicker(); this.close(); break; } case "FormDateTime:UpdatePicker": { - if (!this._picker) { + if (!this.picker) { return; } - this._picker.setPopupValue(aMessage.data); + this.picker.setPopupValue(aMessage.data); break; } default: break; } - } + }, + // nsIDOMEventListener handleEvent(aEvent) { debug("handleEvent: " + aEvent.type); switch (aEvent.type) { case "DateTimePickerValueChanged": { - this.sendAsyncMessage("FormDateTime:PickerValueChanged", aEvent.detail); + this.updateInputBoxValue(aEvent); break; } case "popuphidden": { - this.sendAsyncMessage("FormDateTime:PickerClosed", {}); - this._picker.closePicker(); + let browser = this.weakBrowser ? this.weakBrowser.get() : null; + if (browser) { + browser.messageManager.sendAsyncMessage("FormDateTime:PickerClosed"); + } + this.picker.closePicker(); this.close(); break; } default: break; } - } + }, + + // Called when picker value has changed, notify input box about it. + updateInputBoxValue(aEvent) { + let browser = this.weakBrowser ? this.weakBrowser.get() : null; + if (browser) { + browser.messageManager.sendAsyncMessage( + "FormDateTime:PickerValueChanged", aEvent.detail); + } + }, // Get picker from browser and show it anchored to the input box. showPicker(aBrowser, aData) { @@ -94,40 +129,42 @@ class DateTimePickerParent extends JSWindowActorParent { return; } + this.weakBrowser = Cu.getWeakReference(aBrowser); if (!aBrowser.dateTimePicker) { debug("aBrowser.dateTimePicker not found, exiting now."); return; } - this._picker = new DateTimePickerPanel(aBrowser.dateTimePicker); + this.picker = new DateTimePickerPanel(aBrowser.dateTimePicker); // The arrow panel needs an anchor to work. The popupAnchor (this._anchor) // is a transparent div that the arrow can point to. - this._picker.openPicker(type, this._anchor, detail); + this.picker.openPicker(type, this._anchor, detail); this.addPickerListeners(); - } + }, // Picker is closed, do some cleanup. close() { this.removePickerListeners(); - this._picker = null; + this.picker = null; + this.weakBrowser = null; this._anchor.hidden = true; - } + }, // Listen to picker's event. addPickerListeners() { - if (!this._picker) { + if (!this.picker) { return; } - this._picker.element.addEventListener("popuphidden", this); - this._picker.element.addEventListener("DateTimePickerValueChanged", this); - } + this.picker.element.addEventListener("popuphidden", this); + this.picker.element.addEventListener("DateTimePickerValueChanged", this); + }, // Stop listening to picker's event. removePickerListeners() { - if (!this._picker) { + if (!this.picker) { return; } - this._picker.element.removeEventListener("popuphidden", this); - this._picker.element.removeEventListener("DateTimePickerValueChanged", this); - } -} + this.picker.element.removeEventListener("popuphidden", this); + this.picker.element.removeEventListener("DateTimePickerValueChanged", this); + }, +}; diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index 3e7739baaed5..53f1c2806c96 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -179,6 +179,7 @@ EXTRA_JS_MODULES += [ 'CreditCard.jsm', 'css-selector.js', 'DateTimePickerPanel.jsm', + 'DateTimePickerParent.jsm', 'DeferredTask.jsm', 'Deprecated.jsm', 'E10SUtils.jsm',