Bug 1572827 - Ensure global pop-up notifications uses the outer-most window when needed. r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Wed, 14 Aug 2019 12:09:00 +1200
changeset 27320 5fcdaaf9a166114e58db8a55d7b6f083907fa1df
parent 27319 6c065f72218ce826ec61371a65dc944903d204ed
child 27321 089cade441b7a363121ac2b4f2ac1dab2c21dad7
push id16281
push usermozilla@jorgk.com
push dateWed, 14 Aug 2019 08:25:43 +0000
treeherdercomm-central@089cade441b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1572827
Bug 1572827 - Ensure global pop-up notifications uses the outer-most window when needed. r=mkmelin
mail/base/modules/ExtensionsUI.jsm
--- a/mail/base/modules/ExtensionsUI.jsm
+++ b/mail/base/modules/ExtensionsUI.jsm
@@ -24,22 +24,26 @@ XPCOMUtils.defineLazyModuleGetters(this,
 
 XPCOMUtils.defineLazyGetter(this, "addonsBundle", function() {
   return new StringBundle(ADDONS_PROPERTIES);
 });
 XPCOMUtils.defineLazyGetter(this, "brandBundle", function() {
   return new StringBundle(BRAND_PROPERTIES);
 });
 
+function getTopWindow() {
+  return Services.wm.getMostRecentWindow("mail:3pane");
+}
+
 function getNotification(id, browser) {
-  return browser.ownerGlobal.PopupNotifications.getNotification(id, browser);
+  return getTopWindow().PopupNotifications.getNotification(id, browser);
 }
 
 function showNotification(browser, id, message, anchorID, mainAction, secondaryActions, options) {
-  let notifications = browser.ownerGlobal.PopupNotifications;
+  let notifications = getTopWindow().PopupNotifications;
   if (options.popupIconURL == "chrome://browser/content/extension.svg") {
     options.popupIconURL = DEFAULT_EXTENSION_ICON;
   }
   return notifications.show(browser, id, message, anchorID, mainAction, secondaryActions, options);
 }
 
 // Removes a doorhanger notification if all of the installs it was notifying
 // about have ended in some way.
@@ -68,17 +72,17 @@ function removeNotificationOnEnd(notific
   }
 }
 
 var gXPInstallObserver = {
   pendingInstalls: new WeakMap(),
   pendingNotifications: new WeakMap(),
 
   showInstallConfirmation(browser, installInfo, height = undefined) {
-    let document = browser.ownerDocument;
+    let document = getTopWindow().document;
     // If the confirmation notification is already open cache the installInfo
     // and the new confirmation will be shown later
     if (getNotification("addon-install-confirmation", browser)) {
       let pending = this.pendingInstalls.get(browser);
       if (pending) {
         pending.push(installInfo);
       } else {
         this.pendingInstalls.set(browser, [installInfo]);
@@ -187,28 +191,28 @@ var gXPInstallObserver = {
     }
 
     let popup = showNotification(browser, "addon-install-confirmation", messageString, anchorID,
                                  action, [secondaryAction], options);
     removeNotificationOnEnd(popup, installInfo.installs);
   },
 
   async showPermissionsPrompt(browser, strings, icon) {
-    let window = browser.ownerGlobal;
+    let window = getTopWindow();
 
     // Wait for any pending prompts in this window to complete before
     // showing the next one.
     let pending;
     while ((pending = this.pendingNotifications.get(window))) {
       await pending;
     }
 
     let promise = new Promise(resolve => {
       function eventCallback(topic) {
-        let doc = this.browser.ownerDocument;
+        let doc = window.document;
         if (topic == "showing") {
           let textEl = doc.getElementById("addon-webext-perm-text");
           textEl.textContent = strings.text;
           textEl.hidden = !strings.text;
 
           let listIntroEl = doc.getElementById("addon-webext-perm-intro");
           listIntroEl.textContent = strings.listIntro;
           listIntroEl.hidden = (strings.msgs.length == 0);
@@ -265,18 +269,18 @@ var gXPInstallObserver = {
     });
 
     this.pendingNotifications.set(window, promise);
     promise.finally(() => this.pendingNotifications.delete(window));
     return promise;
   },
 
   async showInstallNotification(browser, addon) {
-    let document = browser.ownerDocument;
-    let window = browser.ownerGlobal;
+    let window = getTopWindow();
+    let document = window.document;
 
     let brandBundle = document.getElementById("bundle_brand");
     let appName = brandBundle.getString("brandShortName");
 
     let message = addonsBundle.getFormattedString("addonPostInstall.message1",
                                                   ["<>", appName]);
 
     let restartRequired = await this._installRequiresRestart(addon);
@@ -294,17 +298,17 @@ var gXPInstallObserver = {
 
     let list = document.getElementById("addon-installed-list");
     list.hidden = true;
 
     this._showInstallNotification(browser, restartRequired, message, options);
   },
 
   _showInstallNotification(browser, restartRequired, message, options) {
-    let document = browser.ownerDocument;
+    let document = getTopWindow().document;
 
     let brandBundle = document.getElementById("bundle_brand");
     let appName = brandBundle.getString("brandShortName");
 
     let action;
     let secondaryActions = null;
     let textEl = document.getElementById("addon-installed-restart-text");
     if (restartRequired) {
@@ -336,17 +340,17 @@ var gXPInstallObserver = {
     showNotification(browser, "addon-installed", message, "addons-notification-icon",
                      action, secondaryActions, options);
   },
 
   /* eslint-disable complexity */
   observe(subject, topic, data) {
     let installInfo = subject.wrappedJSObject;
     let browser = installInfo.browser || installInfo.target;
-    let window = browser.ownerGlobal;
+    let window = getTopWindow();
 
     const anchorID = "addons-notification-icon";
     var messageString, action;
     var brandShortName = brandBundle.getString("brandShortName");
 
     var notificationID = topic;
     // Make notifications persistent
     var options = {
@@ -521,18 +525,18 @@ var gXPInstallObserver = {
         }
         this._removeProgressNotification(browser);
         break;
       }
       case "addon-install-confirmation": {
         let showNotification = () => {
           let height;
           if (window.PopupNotifications.isPanelOpen) {
-            let rect = browser.ownerDocument.getElementById("addon-progress-notification")
-                                            .getBoundingClientRect();
+            let rect = window.document.getElementById("addon-progress-notification")
+                                      .getBoundingClientRect();
             height = rect.height;
           }
 
           this._removeProgressNotification(browser);
           this.showInstallConfirmation(browser, installInfo, height);
         };
 
         let progressNotification = getNotification("addon-progress", browser);
@@ -703,17 +707,17 @@ var gXPInstallObserver = {
 
     // Confirm sideloaded add-ons were installed and ask to restart if necessary.
 
     if (enabled.length == 1) {
       this.showInstallNotification(browser, enabled[0]);
       return;
     }
 
-    let document = browser.ownerDocument;
+    let document = getTopWindow().document;
 
     let brandBundle = document.getElementById("bundle_brand");
     let appName = brandBundle.getString("brandShortName");
 
     let message = addonsBundle.getFormattedString(
       "addonPostInstall.multiple.message", [appName]
     );