Bug 1595143 - Port LightweightThemeChild to JSWindowActors r=mconley,Gijs
authorJames Jahns <jahnsjam@msu.edu>
Mon, 18 Nov 2019 22:51:18 +0000
changeset 502504 c1d83dcf63762028c6601f34d3e83466fe2ceca9
parent 502503 ee044234e17fe1b28a3aaaf1dd04ddbe0a975251
child 502505 25cfc79bf77c58372a6233bc15b5b93161b30cef
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley, Gijs
bugs1595143
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1595143 - Port LightweightThemeChild to JSWindowActors r=mconley,Gijs Differential Revision: https://phabricator.services.mozilla.com/D52555
browser/actors/LightweightThemeChild.jsm
browser/components/BrowserGlue.jsm
browser/components/places/content/bookmarksSidebar.js
browser/components/places/content/historySidebar.js
browser/components/syncedtabs/sidebar.js
--- a/browser/actors/LightweightThemeChild.jsm
+++ b/browser/actors/LightweightThemeChild.jsm
@@ -1,91 +1,75 @@
 /* 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 = ["LightweightThemeChild"];
 
-const { ActorChild } = ChromeUtils.import(
-  "resource://gre/modules/ActorChild.jsm"
-);
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 /**
  * LightweightThemeChild forwards theme data to in-content pages.
  * It is both instantiated by the traditional Actor mechanism,
- * and also manually within the sidebar JS global (which has no message manager)
+ * and also manually within the sidebar JS global (which has no message manager).
+ * The manual instantiation is necessary due to Bug 1596852.
  */
-class LightweightThemeChild extends ActorChild {
-  constructor(dispatcher) {
-    if (dispatcher.mm) {
-      // This is being instantiated by the Actor mechanism.
-      super(dispatcher);
-    } else {
-      // Manually instantiated by the sidebar.
-      let fakeDispatcher = {
-        mm: dispatcher,
-        window: dispatcher.content,
-        addEventListener: dispatcher.content.addEventListener,
-      };
-      super(fakeDispatcher);
-    }
-
-    this.init();
+class LightweightThemeChild extends JSWindowActorChild {
+  constructor() {
+    super();
+    Services.cpmm.sharedData.addEventListener("change", this);
   }
 
-  /**
-   * Initializes the actor for the current page, sending it any existing
-   * theme data, and adding shared data change listeners so it can
-   * notify the page of future updates.
-   *
-   * This is called when the actor is constructed, and any time
-   * ActorManagerChild receives a pageshow event for the page we're
-   * attached to.
-   */
-  init() {
-    Services.cpmm.sharedData.addEventListener("change", this);
-    this.update(this.mm.chromeOuterWindowID, this.content);
+  didDestroy() {
+    Services.cpmm.sharedData.removeEventListener("change", this);
   }
 
-  /**
-   * Cleans up any global listeners registered by the actor.
-   *
-   * This is called by ActorManagerChild any time it receives a pagehide
-   * event for the page we're attached to.
-   */
-  cleanup() {
-    Services.cpmm.sharedData.removeEventListener("change", this);
+  _getChromeOuterWindowID() {
+    if (this.docShell.messageManager) {
+      return this.docShell.messageManager.chromeOuterWindowID;
+    }
+    // We don't have a message manager, so presumable we're running in a sidebar
+    // in the parent process.
+    return this.contentWindow.top.windowUtils.outerWindowID;
   }
 
   /**
    * Handles "change" events on the child sharedData map, and notifies
    * our content page if its theme data was among the changed keys.
    */
   handleEvent(event) {
-    if (event.type === "change") {
-      if (event.changedKeys.includes(`theme/${this.mm.chromeOuterWindowID}`)) {
-        this.update(this.mm.chromeOuterWindowID, this.content);
-      }
+    switch (event.type) {
+      // Make sure to update the theme data on first page show.
+      case "pageshow":
+        this.update();
+        break;
+
+      case "change":
+        if (
+          event.changedKeys.includes(`theme/${this._getChromeOuterWindowID()}`)
+        ) {
+          this.update();
+        }
+        break;
     }
   }
 
   /**
    * Forward the theme data to the page.
-   * @param {Object} outerWindowID The outerWindowID the parent process window has.
-   * @param {Object} content The receiving global
    */
-  update(outerWindowID, content) {
+  update() {
     const event = Cu.cloneInto(
       {
         detail: {
-          data: Services.cpmm.sharedData.get(`theme/${outerWindowID}`),
+          data: Services.cpmm.sharedData.get(
+            `theme/${this._getChromeOuterWindowID()}`
+          ),
         },
       },
-      content
+      this.contentWindow
     );
-    content.dispatchEvent(
-      new content.CustomEvent("LightweightTheme:Set", event)
+    this.contentWindow.dispatchEvent(
+      new this.contentWindow.CustomEvent("LightweightTheme:Set", event)
     );
   }
 }
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -131,16 +131,35 @@ let ACTORS = {
       events: {
         MozInvalidForm: {},
       },
     },
 
     allFrames: true,
   },
 
+  LightweightTheme: {
+    child: {
+      moduleURI: "resource:///actors/LightweightThemeChild.jsm",
+      events: {
+        pageshow: { mozSystemGroup: true },
+      },
+    },
+    includeChrome: true,
+    allFrames: true,
+    matches: [
+      "about:home",
+      "about:newtab",
+      "about:welcome",
+      "chrome://browser/content/syncedtabs/sidebar.xhtml",
+      "chrome://browser/content/places/historySidebar.xul",
+      "chrome://browser/content/places/bookmarksSidebar.xul",
+    ],
+  },
+
   LinkHandler: {
     parent: {
       moduleURI: "resource:///actors/LinkHandlerParent.jsm",
     },
     child: {
       moduleURI: "resource:///actors/LinkHandlerChild.jsm",
       events: {
         DOMHeadElementParsed: {},
@@ -338,26 +357,16 @@ let LEGACY_ACTORS = {
       ],
       events: {
         ContentSearchClient: { capture: true, wantUntrusted: true },
       },
       messages: ["ContentSearch"],
     },
   },
 
-  LightweightTheme: {
-    child: {
-      module: "resource:///actors/LightweightThemeChild.jsm",
-      matches: ["about:home", "about:newtab", "about:welcome"],
-      events: {
-        pageshow: { mozSystemGroup: true },
-      },
-    },
-  },
-
   OfflineApps: {
     child: {
       module: "resource:///actors/OfflineAppsChild.jsm",
       events: {
         MozApplicationManifest: {},
       },
       messages: ["OfflineApps:StartFetching"],
     },
--- a/browser/components/places/content/bookmarksSidebar.js
+++ b/browser/components/places/content/bookmarksSidebar.js
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Shared Places Import - change other consumers if you change this: */
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 XPCOMUtils.defineLazyModuleGetters(this, {
-  LightweightThemeChild: "resource:///actors/LightweightThemeChild.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   PlacesUIUtils: "resource:///modules/PlacesUIUtils.jsm",
   PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
 });
 XPCOMUtils.defineLazyScriptGetter(
   this,
   "PlacesTreeView",
@@ -28,29 +27,31 @@ XPCOMUtils.defineLazyScriptGetter(
 /* End Shared Places Import */
 
 function init() {
   let uidensity = window.top.document.documentElement.getAttribute("uidensity");
   if (uidensity) {
     document.documentElement.setAttribute("uidensity", uidensity);
   }
 
-  /* Listen for sidebar theme changes */
-  let themeListener = new LightweightThemeChild({
-    content: window,
-    chromeOuterWindowID: window.top.windowUtils.outerWindowID,
-    docShell: window.docShell,
-  });
-
-  window.addEventListener("unload", () => {
-    themeListener.cleanup();
-  });
-
   document.getElementById("bookmarks-view").place =
     "place:type=" + Ci.nsINavHistoryQueryOptions.RESULTS_AS_ROOTS_QUERY;
+
+  // Needed due to Bug 1596852.
+  // Should be removed once this bug is resolved.
+  window.addEventListener(
+    "pageshow",
+    e => {
+      window
+        .getWindowGlobalChild()
+        .getActor("LightweightTheme")
+        .handleEvent(e);
+    },
+    { once: true }
+  );
 }
 
 function searchBookmarks(aSearchString) {
   var tree = document.getElementById("bookmarks-view");
   if (!aSearchString) {
     // eslint-disable-next-line no-self-assign
     tree.place = tree.place;
   } else {
--- a/browser/components/places/content/historySidebar.js
+++ b/browser/components/places/content/historySidebar.js
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Shared Places Import - change other consumers if you change this: */
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 XPCOMUtils.defineLazyModuleGetters(this, {
-  LightweightThemeChild: "resource:///actors/LightweightThemeChild.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   PlacesUIUtils: "resource:///modules/PlacesUIUtils.jsm",
   PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
 });
 XPCOMUtils.defineLazyScriptGetter(
   this,
   "PlacesTreeView",
@@ -33,27 +32,16 @@ var gHistoryGrouping = "";
 var gSearching = false;
 
 function HistorySidebarInit() {
   let uidensity = window.top.document.documentElement.getAttribute("uidensity");
   if (uidensity) {
     document.documentElement.setAttribute("uidensity", uidensity);
   }
 
-  /* Listen for sidebar theme changes */
-  let themeListener = new LightweightThemeChild({
-    content: window,
-    chromeOuterWindowID: window.top.windowUtils.outerWindowID,
-    docShell: window.docShell,
-  });
-
-  window.addEventListener("unload", () => {
-    themeListener.cleanup();
-  });
-
   gHistoryTree = document.getElementById("historyTree");
   gSearchBox = document.getElementById("search-box");
 
   gHistoryGrouping = document
     .getElementById("viewButton")
     .getAttribute("selectedsort");
 
   if (gHistoryGrouping == "site") {
@@ -64,16 +52,29 @@ function HistorySidebarInit() {
     document.getElementById("bylastvisited").setAttribute("checked", "true");
   } else if (gHistoryGrouping == "dayandsite") {
     document.getElementById("bydayandsite").setAttribute("checked", "true");
   } else {
     document.getElementById("byday").setAttribute("checked", "true");
   }
 
   searchHistory("");
+
+  // Needed due to Bug 1596852.
+  // Should be removed once this bug is resolved.
+  window.addEventListener(
+    "pageshow",
+    e => {
+      window
+        .getWindowGlobalChild()
+        .getActor("LightweightTheme")
+        .handleEvent(e);
+    },
+    { once: true }
+  );
 }
 
 function GroupBy(groupingType) {
   gHistoryGrouping = groupingType;
   searchHistory(gSearchBox.value);
 }
 
 function searchHistory(aInput) {
--- a/browser/components/syncedtabs/sidebar.js
+++ b/browser/components/syncedtabs/sidebar.js
@@ -5,50 +5,50 @@
 "use strict";
 
 const { SyncedTabs } = ChromeUtils.import(
   "resource://services-sync/SyncedTabs.jsm"
 );
 const { SyncedTabsDeckComponent } = ChromeUtils.import(
   "resource:///modules/syncedtabs/SyncedTabsDeckComponent.js"
 );
-const { LightweightThemeChild } = ChromeUtils.import(
-  "resource:///actors/LightweightThemeChild.jsm"
-);
 
 var syncedTabsDeckComponent = new SyncedTabsDeckComponent({
   window,
   SyncedTabs,
 });
 
-let themeListener;
-
 let onLoaded = () => {
   window.top.MozXULElement.insertFTLIfNeeded("browser/syncedTabs.ftl");
   window.top.document
     .getElementById("SyncedTabsSidebarContext")
     .querySelectorAll("[data-lazy-l10n-id]")
     .forEach(el => {
       el.setAttribute("data-l10n-id", el.getAttribute("data-lazy-l10n-id"));
       el.removeAttribute("data-lazy-l10n-id");
     });
-  themeListener = new LightweightThemeChild({
-    content: window,
-    chromeOuterWindowID: window.top.windowUtils.outerWindowID,
-    docShell: window.docShell,
-  });
   syncedTabsDeckComponent.init();
   document
     .getElementById("template-container")
     .appendChild(syncedTabsDeckComponent.container);
+
+  // Needed due to Bug 1596852.
+  // Should be removed once this bug is resolved.
+  window.addEventListener(
+    "pageshow",
+    e => {
+      window
+        .getWindowGlobalChild()
+        .getActor("LightweightTheme")
+        .handleEvent(e);
+    },
+    { once: true }
+  );
 };
 
 let onUnloaded = () => {
-  if (themeListener) {
-    themeListener.cleanup();
-  }
   removeEventListener("DOMContentLoaded", onLoaded);
   removeEventListener("unload", onUnloaded);
   syncedTabsDeckComponent.uninit();
 };
 
 addEventListener("DOMContentLoaded", onLoaded);
 addEventListener("unload", onUnloaded);