Bug 1342712 - Allow scoping a theme per-window. f=mikedeboer draft
authorTim Nguyen
Sun, 23 Jul 2017 17:35:10 +0000
changeset 614011 93de9e0b94348f4ac8feb102fbfa9af2f39ddc9b
parent 603793 acbd9a64c0fa4e1980c7732735d4f4c2761ca4c9
child 638751 cdac738e9f459214fbc6b816109601ed3c70da48
push id69887
push userbmo:ntim.bugs@gmail.com
push dateSun, 23 Jul 2017 17:35:23 +0000
bugs1342712
milestone56.0a1
Bug 1342712 - Allow scoping a theme per-window. f=mikedeboer MozReview-Commit-ID: 7Lx1xJAaSOq
toolkit/components/extensions/ext-theme.js
toolkit/components/extensions/schemas/theme.json
toolkit/modules/LightweightThemeConsumer.jsm
--- a/toolkit/components/extensions/ext-theme.js
+++ b/toolkit/components/extensions/ext-theme.js
@@ -33,18 +33,26 @@ class Theme {
   }
 
   /**
    * Loads a theme by reading the properties from the extension's manifest.
    * This method will override any currently applied theme.
    *
    * @param {Object} details Theme part of the manifest. Supported
    *   properties can be found in the schema under ThemeType.
+   * @param {Object} targetWindow The window to apply the theme to. Ommiting
+   *   this parameter will apply the theme globally.
    */
-  load(details) {
+  load(details, targetWindow) {
+    if (targetWindow) {
+      this.lwtStyles.window = targetWindow
+        .QueryInterface(Ci.nsIInterfaceRequestor)
+        .getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
+    }
+
     if (details.colors) {
       this.loadColors(details.colors);
     }
 
     if (details.images) {
       this.loadImages(details.images);
     }
 
@@ -264,30 +272,34 @@ this.theme = class extends ExtensionAPI 
     }
   }
 
   getAPI(context) {
     let {extension} = context;
 
     return {
       theme: {
-        update: (details) => {
+        update: (windowId, details) => {
           if (!gThemesEnabled) {
             // Return early if themes are disabled.
             return;
           }
 
           if (!this.theme) {
             // WebExtensions using the Theme API will not have a theme defined
             // in the manifest. Therefore, we need to initialize the theme the
             // first time browser.theme.update is called.
             this.theme = new Theme(extension.baseURI, extension.logger);
           }
-
-          this.theme.load(details);
+          
+          let browserWindow;
+          if (windowId !== null) {
+            browserWindow = windowTracker.getWindow(windowId, context);
+          }
+          this.theme.load(details, browserWindow);
         },
         reset: () => {
           if (!gThemesEnabled) {
             // Return early if themes are disabled.
             return;
           }
 
           if (!this.theme) {
--- a/toolkit/components/extensions/schemas/theme.json
+++ b/toolkit/components/extensions/schemas/theme.json
@@ -448,16 +448,22 @@
     "functions": [
       {
         "name": "update",
         "type": "function",
         "async": true,
         "description": "Make complete or partial updates to the theme. Resolves when the update has completed.",
         "parameters": [
           {
+            "type": "integer",
+            "name": "windowId",
+            "optional": true,
+            "description": "The id of the window to update. No id updates all windows."
+          },
+          {
             "name": "details",
             "$ref": "manifest.ThemeType",
             "description": "The properties of the theme to update."
           }
         ]
       },
       {
         "name": "reset",
--- a/toolkit/modules/LightweightThemeConsumer.jsm
+++ b/toolkit/modules/LightweightThemeConsumer.jsm
@@ -55,16 +55,25 @@ LightweightThemeConsumer.prototype = {
   getData() {
     return this._enabled ? Cu.cloneInto(this._lastData, this._win) : null;
   },
 
   observe(aSubject, aTopic, aData) {
     if (aTopic != "lightweight-theme-styling-update")
       return;
 
+    const { outerWindowID } = this._win
+      .QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsIDOMWindowUtils);
+
+    console.log(aData.window, outerWindowID);
+    if (aData.window && aData.window !== outerWindowID) {
+      return;
+    }
+
     this._update(JSON.parse(aData));
   },
 
   handleEvent(aEvent) {
     let {width, height} = this._win.screen;
 
     if (this._lastScreenWidth != width || this._lastScreenHeight != height) {
       this._lastScreenWidth = width;