Bug 1357242 - Make initial browser tab remote by default instead of flipping it in DOMContentLoaded. r?felipe draft
authorMike Conley <mconley@mozilla.com>
Tue, 23 May 2017 13:55:58 -0400
changeset 585268 11d61e90f10a2ed44fa3d85d26bf29bc9ec96143
parent 582257 9851fcb0bf4d855c36729d7de19f0fa5c9f69776
child 630704 fe86da255781b79ca214dcb10c8b07e63ffcd4f0
push id61090
push userbmo:mconley@mozilla.com
push dateFri, 26 May 2017 20:02:51 +0000
reviewersfelipe
bugs1357242
milestone55.0a1
Bug 1357242 - Make initial browser tab remote by default instead of flipping it in DOMContentLoaded. r?felipe MozReview-Commit-ID: 1nEKB6hAiTG
browser/base/content/browser.js
browser/base/content/tabbrowser.xml
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1176,35 +1176,226 @@ function RedirectLoad({ target: browser,
         LoadInOtherProcess(browser, data.loadOptions, data.historyIndex);
       }
     };
     Services.obs.addObserver(delayedStartupFinished,
                              "browser-delayed-startup-finished");
   }
 }
 
+function nsBrowserAccess() { }
+
+nsBrowserAccess.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]),
+
+  _openURIInNewTab(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
+                             aIsExternal, aForceNotRemote = false,
+                             aUserContextId = Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID,
+                             aOpener = null, aTriggeringPrincipal = null,
+                             aNextTabParentId = 0) {
+    let win, needToFocusWin;
+
+    // try the current window.  if we're in a popup, fall back on the most recent browser window
+    if (window.toolbar.visible)
+      win = window;
+    else {
+      win = RecentWindow.getMostRecentBrowserWindow({private: aIsPrivate});
+      needToFocusWin = true;
+    }
+
+    if (!win) {
+      // we couldn't find a suitable window, a new one needs to be opened.
+      return null;
+    }
+
+    if (aIsExternal && (!aURI || aURI.spec == "about:blank")) {
+      win.BrowserOpenTab(); // this also focuses the location bar
+      win.focus();
+      return win.gBrowser.selectedBrowser;
+    }
+
+    let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
+
+    let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
+                                      triggeringPrincipal: aTriggeringPrincipal,
+                                      referrerURI: aReferrer,
+                                      referrerPolicy: aReferrerPolicy,
+                                      userContextId: aUserContextId,
+                                      fromExternal: aIsExternal,
+                                      inBackground: loadInBackground,
+                                      forceNotRemote: aForceNotRemote,
+                                      opener: aOpener,
+                                      nextTabParentId: aNextTabParentId,
+                                      });
+    let browser = win.gBrowser.getBrowserForTab(tab);
+
+    if (needToFocusWin || (!loadInBackground && aIsExternal))
+      win.focus();
+
+    return browser;
+  },
+
+  openURI(aURI, aOpener, aWhere, aFlags) {
+    // This function should only ever be called if we're opening a URI
+    // from a non-remote browser window (via nsContentTreeOwner).
+    if (aOpener && Cu.isCrossProcessWrapper(aOpener)) {
+      Cu.reportError("nsBrowserAccess.openURI was passed a CPOW for aOpener. " +
+                     "openURI should only ever be called from non-remote browsers.");
+      throw Cr.NS_ERROR_FAILURE;
+    }
+
+    var newWindow = null;
+    var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
+
+    if (aOpener && isExternal) {
+      Cu.reportError("nsBrowserAccess.openURI did not expect an opener to be " +
+                     "passed if the context is OPEN_EXTERNAL.");
+      throw Cr.NS_ERROR_FAILURE;
+    }
+
+    if (isExternal && aURI && aURI.schemeIs("chrome")) {
+      dump("use --chrome command-line option to load external chrome urls\n");
+      return null;
+    }
+
+    if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
+      if (isExternal &&
+          gPrefService.prefHasUserValue("browser.link.open_newwindow.override.external"))
+        aWhere = gPrefService.getIntPref("browser.link.open_newwindow.override.external");
+      else
+        aWhere = gPrefService.getIntPref("browser.link.open_newwindow");
+    }
+
+    let referrer = aOpener ? makeURI(aOpener.location.href) : null;
+    let triggeringPrincipal = null;
+    let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_UNSET;
+    if (aOpener && aOpener.document) {
+      referrerPolicy = aOpener.document.referrerPolicy;
+      triggeringPrincipal = aOpener.document.nodePrincipal;
+    }
+    let isPrivate = aOpener
+                  ? PrivateBrowsingUtils.isContentWindowPrivate(aOpener)
+                  : PrivateBrowsingUtils.isWindowPrivate(window);
+
+    switch (aWhere) {
+      case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW :
+        // FIXME: Bug 408379. So how come this doesn't send the
+        // referrer like the other loads do?
+        var url = aURI ? aURI.spec : "about:blank";
+        let features = "all,dialog=no";
+        if (isPrivate) {
+          features += ",private";
+        }
+        // Pass all params to openDialog to ensure that "url" isn't passed through
+        // loadOneOrMoreURIs, which splits based on "|"
+        newWindow = openDialog(getBrowserURL(), "_blank", features, url, null, null, null);
+        break;
+      case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB :
+        // If we have an opener, that means that the caller is expecting access
+        // to the nsIDOMWindow of the opened tab right away. For e10s windows,
+        // this means forcing the newly opened browser to be non-remote so that
+        // we can hand back the nsIDOMWindow. The XULBrowserWindow.shouldLoadURI
+        // will do the job of shuttling off the newly opened browser to run in
+        // the right process once it starts loading a URI.
+        let forceNotRemote = !!aOpener;
+        let userContextId = aOpener && aOpener.document
+                              ? aOpener.document.nodePrincipal.originAttributes.userContextId
+                              : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
+        let openerWindow = (aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_OPENER) ? null : aOpener;
+        let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
+                                            isPrivate, isExternal,
+                                            forceNotRemote, userContextId,
+                                            openerWindow, triggeringPrincipal);
+        if (browser)
+          newWindow = browser.contentWindow;
+        break;
+      default : // OPEN_CURRENTWINDOW or an illegal value
+        newWindow = window.content;
+        if (aURI) {
+          let loadflags = isExternal ?
+                            Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
+                            Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
+          gBrowser.loadURIWithFlags(aURI.spec, {
+                                    triggeringPrincipal,
+                                    flags: loadflags,
+                                    referrerURI: referrer,
+                                    referrerPolicy,
+                                    });
+        }
+        if (!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
+          window.focus();
+    }
+    return newWindow;
+  },
+
+  openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aFlags,
+                                                  aNextTabParentId) {
+    dump("openURIInFrame, fool!\n");
+    if (aWhere != Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
+      dump("Error: openURIInFrame can only open in new tabs");
+      return null;
+    }
+
+    var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
+
+    var userContextId = aParams.openerOriginAttributes &&
+                        ("userContextId" in aParams.openerOriginAttributes)
+                          ? aParams.openerOriginAttributes.userContextId
+                          : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID
+
+    let referrer = aParams.referrer ? makeURI(aParams.referrer) : null;
+    let browser = this._openURIInNewTab(aURI, referrer,
+                                        aParams.referrerPolicy,
+                                        aParams.isPrivate,
+                                        isExternal, false,
+                                        userContextId, null,
+                                        aParams.triggeringPrincipal,
+                                        aNextTabParentId);
+    if (browser)
+      return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
+
+    return null;
+  },
+
+  isTabContentWindow(aWindow) {
+    return gBrowser.browsers.some(browser => browser.contentWindow == aWindow);
+  },
+
+  canClose() {
+    return CanCloseWindow();
+  },
+}
+
+
+dump("browser.js is loaded now\n");
+window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
+  new nsBrowserAccess();
+
+
+
 addEventListener("DOMContentLoaded", function onDCL() {
   removeEventListener("DOMContentLoaded", onDCL);
 
+window.QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(nsIWebNavigation)
+      .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
+      .QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsIXULWindow)
+      .XULBrowserWindow = window.XULBrowserWindow;
+
+
+  dump("Setting browserDOMWindow in a window now\n");
+
   // There are some windows, like macBrowserOverlay.xul, that
   // load browser.js, but never load tabbrowser.xml. We can ignore
   // those cases.
   if (!gBrowser || !gBrowser.updateBrowserRemoteness) {
     return;
   }
 
-  window.QueryInterface(Ci.nsIInterfaceRequestor)
-        .getInterface(nsIWebNavigation)
-        .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
-        .QueryInterface(Ci.nsIInterfaceRequestor)
-        .getInterface(Ci.nsIXULWindow)
-        .XULBrowserWindow = window.XULBrowserWindow;
-  window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
-    new nsBrowserAccess();
-
   let initBrowser =
     document.getAnonymousElementByAttribute(gBrowser, "anonid", "initialBrowser");
 
   // remoteType and sameProcessAsFrameLoader are passed through to
   // updateBrowserRemoteness as part of an options object, which itself defaults
   // to an empty object. So defaulting them to undefined here will cause the
   // default behavior in updateBrowserRemoteness if they don't get set.
   let isRemote = gMultiProcessBrowser;
@@ -1250,16 +1441,17 @@ let _resolveDelayedStartup;
 var delayedStartupPromise = new Promise(resolve => {
   _resolveDelayedStartup = resolve;
 });
 
 var gBrowserInit = {
   delayedStartupFinished: false,
 
   onLoad() {
+    dump("browser.js's onLoad is fired now\n");
     gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver);
 
     Services.obs.addObserver(gPluginHandler.NPAPIPluginCrashed, "plugin-crashed");
 
     window.addEventListener("AppCommand", HandleAppCommandEvent, true);
 
     // These routines add message listeners. They must run before
     // loading the frame script to ensure that we don't miss any
@@ -5247,197 +5439,16 @@ var TabsProgressListener = {
     webrtcUI.forgetStreamsFromBrowser(aBrowser);
 
     gBrowser.getNotificationBox(aBrowser).removeTransientNotifications();
 
     FullZoom.onLocationChange(aLocationURI, false, aBrowser);
   },
 }
 
-function nsBrowserAccess() { }
-
-nsBrowserAccess.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]),
-
-  _openURIInNewTab(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
-                             aIsExternal, aForceNotRemote = false,
-                             aUserContextId = Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID,
-                             aOpener = null, aTriggeringPrincipal = null,
-                             aNextTabParentId = 0) {
-    let win, needToFocusWin;
-
-    // try the current window.  if we're in a popup, fall back on the most recent browser window
-    if (window.toolbar.visible)
-      win = window;
-    else {
-      win = RecentWindow.getMostRecentBrowserWindow({private: aIsPrivate});
-      needToFocusWin = true;
-    }
-
-    if (!win) {
-      // we couldn't find a suitable window, a new one needs to be opened.
-      return null;
-    }
-
-    if (aIsExternal && (!aURI || aURI.spec == "about:blank")) {
-      win.BrowserOpenTab(); // this also focuses the location bar
-      win.focus();
-      return win.gBrowser.selectedBrowser;
-    }
-
-    let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
-
-    let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
-                                      triggeringPrincipal: aTriggeringPrincipal,
-                                      referrerURI: aReferrer,
-                                      referrerPolicy: aReferrerPolicy,
-                                      userContextId: aUserContextId,
-                                      fromExternal: aIsExternal,
-                                      inBackground: loadInBackground,
-                                      forceNotRemote: aForceNotRemote,
-                                      opener: aOpener,
-                                      nextTabParentId: aNextTabParentId,
-                                      });
-    let browser = win.gBrowser.getBrowserForTab(tab);
-
-    if (needToFocusWin || (!loadInBackground && aIsExternal))
-      win.focus();
-
-    return browser;
-  },
-
-  openURI(aURI, aOpener, aWhere, aFlags) {
-    // This function should only ever be called if we're opening a URI
-    // from a non-remote browser window (via nsContentTreeOwner).
-    if (aOpener && Cu.isCrossProcessWrapper(aOpener)) {
-      Cu.reportError("nsBrowserAccess.openURI was passed a CPOW for aOpener. " +
-                     "openURI should only ever be called from non-remote browsers.");
-      throw Cr.NS_ERROR_FAILURE;
-    }
-
-    var newWindow = null;
-    var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
-
-    if (aOpener && isExternal) {
-      Cu.reportError("nsBrowserAccess.openURI did not expect an opener to be " +
-                     "passed if the context is OPEN_EXTERNAL.");
-      throw Cr.NS_ERROR_FAILURE;
-    }
-
-    if (isExternal && aURI && aURI.schemeIs("chrome")) {
-      dump("use --chrome command-line option to load external chrome urls\n");
-      return null;
-    }
-
-    if (aWhere == Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
-      if (isExternal &&
-          gPrefService.prefHasUserValue("browser.link.open_newwindow.override.external"))
-        aWhere = gPrefService.getIntPref("browser.link.open_newwindow.override.external");
-      else
-        aWhere = gPrefService.getIntPref("browser.link.open_newwindow");
-    }
-
-    let referrer = aOpener ? makeURI(aOpener.location.href) : null;
-    let triggeringPrincipal = null;
-    let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_UNSET;
-    if (aOpener && aOpener.document) {
-      referrerPolicy = aOpener.document.referrerPolicy;
-      triggeringPrincipal = aOpener.document.nodePrincipal;
-    }
-    let isPrivate = aOpener
-                  ? PrivateBrowsingUtils.isContentWindowPrivate(aOpener)
-                  : PrivateBrowsingUtils.isWindowPrivate(window);
-
-    switch (aWhere) {
-      case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW :
-        // FIXME: Bug 408379. So how come this doesn't send the
-        // referrer like the other loads do?
-        var url = aURI ? aURI.spec : "about:blank";
-        let features = "all,dialog=no";
-        if (isPrivate) {
-          features += ",private";
-        }
-        // Pass all params to openDialog to ensure that "url" isn't passed through
-        // loadOneOrMoreURIs, which splits based on "|"
-        newWindow = openDialog(getBrowserURL(), "_blank", features, url, null, null, null);
-        break;
-      case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB :
-        // If we have an opener, that means that the caller is expecting access
-        // to the nsIDOMWindow of the opened tab right away. For e10s windows,
-        // this means forcing the newly opened browser to be non-remote so that
-        // we can hand back the nsIDOMWindow. The XULBrowserWindow.shouldLoadURI
-        // will do the job of shuttling off the newly opened browser to run in
-        // the right process once it starts loading a URI.
-        let forceNotRemote = !!aOpener;
-        let userContextId = aOpener && aOpener.document
-                              ? aOpener.document.nodePrincipal.originAttributes.userContextId
-                              : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
-        let openerWindow = (aFlags & Ci.nsIBrowserDOMWindow.OPEN_NO_OPENER) ? null : aOpener;
-        let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
-                                            isPrivate, isExternal,
-                                            forceNotRemote, userContextId,
-                                            openerWindow, triggeringPrincipal);
-        if (browser)
-          newWindow = browser.contentWindow;
-        break;
-      default : // OPEN_CURRENTWINDOW or an illegal value
-        newWindow = window.content;
-        if (aURI) {
-          let loadflags = isExternal ?
-                            Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
-                            Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
-          gBrowser.loadURIWithFlags(aURI.spec, {
-                                    triggeringPrincipal,
-                                    flags: loadflags,
-                                    referrerURI: referrer,
-                                    referrerPolicy,
-                                    });
-        }
-        if (!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
-          window.focus();
-    }
-    return newWindow;
-  },
-
-  openURIInFrame: function browser_openURIInFrame(aURI, aParams, aWhere, aFlags,
-                                                  aNextTabParentId) {
-    if (aWhere != Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
-      dump("Error: openURIInFrame can only open in new tabs");
-      return null;
-    }
-
-    var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
-
-    var userContextId = aParams.openerOriginAttributes &&
-                        ("userContextId" in aParams.openerOriginAttributes)
-                          ? aParams.openerOriginAttributes.userContextId
-                          : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID
-
-    let referrer = aParams.referrer ? makeURI(aParams.referrer) : null;
-    let browser = this._openURIInNewTab(aURI, referrer,
-                                        aParams.referrerPolicy,
-                                        aParams.isPrivate,
-                                        isExternal, false,
-                                        userContextId, null,
-                                        aParams.triggeringPrincipal,
-                                        aNextTabParentId);
-    if (browser)
-      return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
-
-    return null;
-  },
-
-  isTabContentWindow(aWindow) {
-    return gBrowser.browsers.some(browser => browser.contentWindow == aWindow);
-  },
-
-  canClose() {
-    return CanCloseWindow();
-  },
-}
 
 function getTogglableToolbars() {
   let toolbarNodes = Array.slice(gNavToolbox.childNodes);
   toolbarNodes = toolbarNodes.concat(gNavToolbox.externalToolbars);
   toolbarNodes = toolbarNodes.filter(node => node.getAttribute("toolbarname"));
   return toolbarNodes;
 }
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -23,16 +23,18 @@
                   onselect="if (event.target.localName == 'tabpanels') this.parentNode.updateCurrentBrowser();">
         <xul:tabpanels flex="1" class="plain" selectedIndex="0" anonid="panelcontainer">
           <xul:notificationbox flex="1" notificationside="top">
             <xul:hbox flex="1" class="browserSidebarContainer">
               <xul:vbox flex="1" class="browserContainer">
                 <xul:stack flex="1" class="browserStack" anonid="browserStack">
                   <xul:browser anonid="initialBrowser" type="content" message="true" messagemanagergroup="browsers"
                                primary="true"
+                               remote="true"
+                               remoteType="web"
                                xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,selectmenulist,datetimepicker"/>
                 </xul:stack>
               </xul:vbox>
             </xul:hbox>
           </xul:notificationbox>
         </xul:tabpanels>
       </xul:tabbox>
       <children/>