Bug 1350152 - Don't rely on gBrowser in nsLoginManagerPrompter.js. r=mkaply a=jorgk THUNDERBIRD560b1_2017081901_RELBRANCH
authorJohann Hofmann <jhofmann@mozilla.com>
Thu, 01 Jun 2017 21:41:11 +0200
branchTHUNDERBIRD560b1_2017081901_RELBRANCH
changeset 421253 adccebcd50ec6b552c0d004fd26a55a4d5d98ed6
parent 421252 933fbae1415a6385e51b60d5ee40b3183a5b2d7f
child 421254 7455f5305055bf1d2a30ad17459a0d6aed385523
push id7638
push usermozilla@jorgk.com
push dateSat, 19 Aug 2017 16:59:40 +0000
treeherdermozilla-beta@db099741d3da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkaply, jorgk
bugs1350152, 1266836
milestone56.0
Bug 1350152 - Don't rely on gBrowser in nsLoginManagerPrompter.js. r=mkaply a=jorgk In bug 1266836 we fixed this code to properly work in e10s, but made the mistake of using gBrowser in toolkit code, breaking XUL apps that don't have a gBrowser. This solution implements a different code-path for non-e10s and returns a chrome window for consumers that don't offer a browser. MozReview-Commit-ID: 929ahDenzu5
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -803,16 +803,19 @@ LoginManagerPrompter.prototype = {
    *        Login to save or change. For changes, this login should contain the
    *        new password.
    * @param {string} type
    *        This is "password-save" or "password-change" depending on the
    *        original notification type. This is used for telemetry and tests.
    */
   _showLoginCaptureDoorhanger(login, type) {
     let { browser } = this._getNotifyWindow();
+    if (!browser) {
+      return;
+    }
 
     let saveMsgNames = {
       prompt: login.username === "" ? "saveLoginMsgNoUser"
                                     : "saveLoginMsg",
       buttonLabel: "saveLoginButtonAllow.label",
       buttonAccessKey: "saveLoginButtonAllow.accesskey",
       secondaryButtonLabel: "saveLoginButtonDeny.label",
       secondaryButtonAccessKey: "saveLoginButtonDeny.accesskey",
@@ -1415,20 +1418,43 @@ LoginManagerPrompter.prototype = {
     propBag.setProperty("timesUsedIncrement", 1);
     this._pwmgr.modifyLogin(login, propBag);
   },
 
   /**
    * Given a content DOM window, returns the chrome window and browser it's in.
    */
   _getChromeWindow(aWindow) {
+    // Handle non-e10s toolkit consumers.
+    if (!Cu.isCrossProcessWrapper(aWindow)) {
+      let chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                             .getInterface(Ci.nsIWebNavigation)
+                             .QueryInterface(Ci.nsIDocShell)
+                             .chromeEventHandler.ownerGlobal;
+      if (!chromeWin) {
+        return null;
+      }
+
+      // gBrowser only exists on some apps, like Firefox.
+      let tabbrowser = chromeWin.gBrowser || chromeWin.getBrowser();
+      // At least serve the chrome window if getBrowser()
+      // or getBrowserForContentWindow() are not supported.
+      if (!tabbrowser || typeof tabbrowser.getBrowserForContentWindow != "function") {
+        return { win: chromeWin };
+      }
+
+      let browser = tabbrowser.getBrowserForContentWindow(aWindow);
+      return { win: chromeWin, browser };
+    }
+
     let windows = Services.wm.getEnumerator(null);
     while (windows.hasMoreElements()) {
       let win = windows.getNext();
-      let browser = win.gBrowser.getBrowserForContentWindow(aWindow);
+      let tabbrowser = win.gBrowser || win.getBrowser();
+      let browser = tabbrowser.getBrowserForContentWindow(aWindow);
       if (browser) {
         return { win, browser };
       }
     }
     return null;
   },
 
   _getNotifyWindow() {