Bug 1472491: Part 5a - Add BrowserTabChild actor. r?felipe draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 29 Jul 2018 19:42:46 -0700
changeset 828383 16bab45158cc84061e2469f0237c73ce14695145
parent 828382 44f9ef69bb930d5f4f28c12cf5636b0cfbb3186d
child 828384 a7b3689cc1f073db9aa6a49d0e0f9a73d611a2ed
push id118679
push usermaglione.k@gmail.com
push dateFri, 10 Aug 2018 21:19:41 +0000
reviewersfelipe
bugs1472491
milestone63.0a1
Bug 1472491: Part 5a - Add BrowserTabChild actor. r?felipe MozReview-Commit-ID: 38Y1xwkgxCx
browser/base/content/tab-content.js
browser/base/content/test/performance/browser_startup_content.js
browser/components/nsBrowserGlue.js
browser/modules/BrowserTabChild.jsm
browser/modules/moz.build
toolkit/content/browser-content.js
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -27,75 +27,26 @@ ChromeUtils.defineModuleGetter(this, "Pa
 
 ChromeUtils.import("resource://gre/modules/ActorManagerChild.jsm");
 
 ActorManagerChild.attach(this, "browsers");
 
 // TabChildGlobal
 var global = this;
 
-
-addEventListener("MozDOMPointerLock:Entered", function(aEvent) {
-  sendAsyncMessage("PointerLock:Entered", {
-    originNoSuffix: aEvent.target.nodePrincipal.originNoSuffix
-  });
-});
-
-addEventListener("MozDOMPointerLock:Exited", function(aEvent) {
-  sendAsyncMessage("PointerLock:Exited");
-});
-
-
 addMessageListener("Browser:HideSessionRestoreButton", function(message) {
   // Hide session restore button on about:home
   let doc = content.document;
   let container;
   if (doc.documentURI.toLowerCase() == "about:home" &&
       (container = doc.getElementById("sessionRestoreContainer"))) {
     container.hidden = true;
   }
 });
 
-if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
-  addMessageListener("Browser:HasSiblings", function(message) {
-    let tabChild = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
-                           .getInterface(Ci.nsITabChild);
-    let hasSiblings = message.data;
-    tabChild.hasSiblings = hasSiblings;
-  });
-}
-
-// XXX(nika): Should we try to call this in the parent process instead?
-addMessageListener("Browser:Reload", function(message) {
-  /* First, we'll try to use the session history object to reload so
-   * that framesets are handled properly. If we're in a special
-   * window (such as view-source) that has no session history, fall
-   * back on using the web navigation's reload method.
-   */
-
-  let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
-  try {
-    if (webNav.sessionHistory) {
-      webNav = webNav.sessionHistory;
-    }
-  } catch (e) {
-  }
-
-  let reloadFlags = message.data.flags;
-  try {
-    E10SUtils.wrapHandlingUserInput(content, message.data.handlingUserInput,
-                                    () => webNav.reload(reloadFlags));
-  } catch (e) {
-  }
-});
-
-addMessageListener("MixedContent:ReenableProtection", function() {
-  docShell.mixedContentChannel = null;
-});
-
 XPCOMUtils.defineLazyProxy(this, "LightweightThemeChildHelper",
   "resource:///modules/LightweightThemeChildHelper.jsm");
 
 XPCOMUtils.defineLazyProxy(this, "ManifestMessages", () => {
   let tmp = {};
   ChromeUtils.import("resource://gre/modules/ManifestMessages.jsm", tmp);
   return new tmp.ManifestMessages(global);
 });
@@ -352,22 +303,16 @@ function gKeywordURIFixup(fixupInfo) {
 
   sendAsyncMessage("Browser:URIFixup", data);
 }
 Services.obs.addObserver(gKeywordURIFixup, "keyword-uri-fixup");
 addEventListener("unload", () => {
   Services.obs.removeObserver(gKeywordURIFixup, "keyword-uri-fixup");
 }, false);
 
-addMessageListener("Browser:AppTab", function(message) {
-  if (docShell) {
-    docShell.isAppTab = message.data.isAppTab;
-  }
-});
-
 var WebBrowserChrome = {
   onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) {
     return BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
   },
 
   // Check whether this URI should load in the current process
   shouldLoadURI(aDocShell, aURI, aReferrer, aHasPostData, aTriggeringPrincipal) {
     if (!E10SUtils.shouldLoadURI(aDocShell, aURI, aReferrer, aHasPostData)) {
@@ -476,55 +421,18 @@ var DOMFullscreenHandler = {
         }
         break;
       }
     }
   }
 };
 DOMFullscreenHandler.init();
 
-var UserContextIdNotifier = {
-  init() {
-    addEventListener("DOMWindowCreated", this);
-    this.init = null;
-  },
-
-  uninit() {
-    removeEventListener("DOMWindowCreated", this);
-  },
-
-  handleEvent(aEvent) {
-    // When the window is created, we want to inform the tabbrowser about
-    // the userContextId in use in order to update the UI correctly.
-    // Just because we cannot change the userContextId from an active docShell,
-    // we don't need to check DOMContentLoaded again.
-    this.uninit();
-
-    // We use the docShell because content.document can have been loaded before
-    // setting the originAttributes.
-    let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
-    let userContextId = loadContext.originAttributes.userContextId;
-
-    sendAsyncMessage("Browser:WindowCreated", { userContextId });
-  }
-};
-
-UserContextIdNotifier.init();
-
 Services.obs.notifyObservers(this, "tab-content-frameloader-created");
 
-addMessageListener("AllowScriptsToClose", () => {
-  content.windowUtils.allowScriptsToClose();
-});
-
-addEventListener("MozAfterPaint", function onFirstPaint() {
-  removeEventListener("MozAfterPaint", onFirstPaint);
-  sendAsyncMessage("Browser:FirstPaint");
-});
-
 // Remove this once bug 1397365 is fixed.
 addEventListener("MozAfterPaint", function onFirstNonBlankPaint() {
   if (content.document.documentURI == "about:blank" && !content.opener)
     return;
   removeEventListener("MozAfterPaint", onFirstNonBlankPaint);
   sendAsyncMessage("Browser:FirstNonBlankPaint");
 });
 
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -43,16 +43,17 @@ const whitelist = {
     "resource:///modules/sessionstore/ContentSessionStore.jsm",
     "resource://gre/modules/sessionstore/SessionHistory.jsm",
 
     // Forms and passwords
     "resource://formautofill/FormAutofill.jsm",
     "resource://formautofill/FormAutofillContent.jsm",
 
     // Browser front-end
+    "resource:///modules/BrowserTabChild.jsm",
     "resource:///modules/ContentLinkHandler.jsm",
     "resource:///modules/ContentMetaHandler.jsm",
     "resource:///modules/PageStyleHandler.jsm",
     "resource://gre/modules/ActorChild.jsm",
     "resource://gre/modules/ActorManagerChild.jsm",
     "resource://gre/modules/BrowserUtils.jsm",
     "resource://gre/modules/E10SUtils.jsm",
     "resource://gre/modules/PrivateBrowsingUtils.jsm",
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -7,16 +7,39 @@ const XULNS = "http://www.mozilla.org/ke
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 
 ChromeUtils.defineModuleGetter(this, "ActorManagerParent",
                                "resource://gre/modules/ActorManagerParent.jsm");
 
 let ACTORS = {
+  BrowserTab: {
+    module: "resource:///modules/BrowserTab",
+    child: {
+      group: "browsers",
+
+      events: {
+        "DOMWindowCreated": {once: true},
+        "MozAfterPaint": {once: true},
+        "MozDOMPointerLock:Entered": {},
+        "MozDOMPointerLock:Exited": {},
+      },
+
+      messages: [
+        "AllowScriptsToClose",
+        "Browser:AppTab",
+        "Browser:HasSiblings",
+        "Browser:Reload",
+        "MixedContent:ReenableProtection",
+        "SwitchDocumentDirection",
+        "UpdateCharacterSet",
+      ],
+    },
+  },
 };
 
 (function earlyBlankFirstPaint() {
   if (!Services.prefs.getBoolPref("browser.startup.blankWindow", false))
     return;
 
   let store = Services.xulStore;
   let getValue = attr =>
new file mode 100644
--- /dev/null
+++ b/browser/modules/BrowserTabChild.jsm
@@ -0,0 +1,113 @@
+/* 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/. */
+"use strict";
+
+var EXPORTED_SYMBOLS = ["BrowserTabChild"];
+
+ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
+ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
+
+ChromeUtils.defineModuleGetter(this, "E10SUtils",
+                               "resource://gre/modules/E10SUtils.jsm");
+
+class BrowserTabChild extends ActorChild {
+  handleEvent(event) {
+    switch (event.type) {
+    case "DOMWindowCreated":
+      let loadContext = this.mm.docShell.QueryInterface(Ci.nsILoadContext);
+      let userContextId = loadContext.originAttributes.userContextId;
+
+      this.mm.sendAsyncMessage("Browser:WindowCreated", { userContextId });
+      break;
+
+    case "MozAfterPaint":
+      this.mm.sendAsyncMessage("Browser:FirstPaint");
+      break;
+
+    case "MozDOMPointerLock:Entered":
+      this.mm.sendAsyncMessage("PointerLock:Entered", {
+        originNoSuffix: event.target.nodePrincipal.originNoSuffix
+      });
+      break;
+
+    case "MozDOMPointerLock:Exited":
+      this.mm.sendAsyncMessage("PointerLock:Exited");
+      break;
+    }
+  }
+
+  switchDocumentDirection(window = this.content) {
+   // document.dir can also be "auto", in which case it won't change
+    if (window.document.dir == "ltr" || window.document.dir == "") {
+      window.document.dir = "rtl";
+    } else if (window.document.dir == "rtl") {
+      window.document.dir = "ltr";
+    }
+    for (let i = 0; i < window.frames.length; i++) {
+      this.switchDocumentDirection(window.frames[i]);
+    }
+  }
+
+  receiveMessage(message) {
+    switch (message.name) {
+      case "AllowScriptsToClose":
+        this.content.windowUtils.allowScriptsToClose();
+        break;
+
+      case "Browser:AppTab":
+        if (this.docShell) {
+          this.docShell.isAppTab = message.data.isAppTab;
+        }
+        break;
+
+      case "Browser:HasSiblings":
+        try {
+          let tabChild = this.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+                             .getInterface(Ci.nsITabChild);
+          let hasSiblings = message.data;
+          tabChild.hasSiblings = hasSiblings;
+        } catch (e) {
+        }
+        break;
+
+      // XXX(nika): Should we try to call this in the parent process instead?
+      case "Browser:Reload":
+        /* First, we'll try to use the session history object to reload so
+         * that framesets are handled properly. If we're in a special
+         * window (such as view-source) that has no session history, fall
+         * back on using the web navigation's reload method.
+         */
+
+        let webNav = this.docShell.QueryInterface(Ci.nsIWebNavigation);
+        try {
+          if (webNav.sessionHistory) {
+            webNav = webNav.sessionHistory;
+          }
+        } catch (e) {
+        }
+
+        let reloadFlags = message.data.flags;
+        try {
+          E10SUtils.wrapHandlingUserInput(this.content, message.data.handlingUserInput,
+                                          () => webNav.reload(reloadFlags));
+        } catch (e) {
+        }
+        break;
+
+      case "MixedContent:ReenableProtection":
+        this.docShell.mixedContentChannel = null;
+        break;
+
+      case "SwitchDocumentDirection":
+        this.switchDocumentDirection();
+        break;
+
+      case "UpdateCharacterSet":
+        this.docShell.charset = message.data.value;
+        this.docShell.gatherCharsetMenuTelemetry();
+        break;
+    }
+  }
+}
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -131,16 +131,17 @@ BROWSER_CHROME_MANIFESTS += [
 ]
 XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
 
 EXTRA_JS_MODULES += [
     'AboutNewTab.jsm',
     'AsyncTabSwitcher.jsm',
     'BlockedSiteContent.jsm',
     'BrowserErrorReporter.jsm',
+    'BrowserTabChild.jsm',
     'BrowserUsageTelemetry.jsm',
     'BrowserWindowTracker.jsm',
     'ClickEventHandler.jsm',
     'ContentClick.jsm',
     'ContentCrashHandlers.jsm',
     'ContentLinkHandler.jsm',
     'ContentMetaHandler.jsm',
     'ContentObservers.js',
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -116,32 +116,16 @@ var Printing = {
   },
 
   receiveMessage(message) {
     return PrintingContent.receiveMessage(global, message);
   },
 };
 Printing.init();
 
-function SwitchDocumentDirection(aWindow) {
- // document.dir can also be "auto", in which case it won't change
-  if (aWindow.document.dir == "ltr" || aWindow.document.dir == "") {
-    aWindow.document.dir = "rtl";
-  } else if (aWindow.document.dir == "rtl") {
-    aWindow.document.dir = "ltr";
-  }
-  for (let run = 0; run < aWindow.frames.length; run++) {
-    SwitchDocumentDirection(aWindow.frames[run]);
-  }
-}
-
-addMessageListener("SwitchDocumentDirection", () => {
-  SwitchDocumentDirection(content.window);
-});
-
 var FindBar = {
   /**
    * _findKey and _findModifiers are used to determine whether a keypress
    * is a user attempting to use the find shortcut, after which we'll
    * route keypresses to the parent until we know the findbar has focus
    * there. To do this, we need shortcut data from the parent.
    */
   _findKey: null,