Bug 1451402 - Display WebExtension static themes in the customize mode. r=Gijs draft
authorTim Nguyen <ntim.bugs@gmail.com>
Tue, 26 Jun 2018 13:22:25 +0100
changeset 810880 af3611bb9dcaa9936d05a59f5855d1d7e664d005
parent 810879 bc2cf45138bbf66411bb9513a4300136bb2024c8
push id114145
push userbmo:ntim.bugs@gmail.com
push dateTue, 26 Jun 2018 17:13:02 +0000
reviewersGijs
bugs1451402
milestone63.0a1
Bug 1451402 - Display WebExtension static themes in the customize mode. r=Gijs MozReview-Commit-ID: L6nTkTGDSr
browser/components/customizableui/CustomizeMode.jsm
browser/components/customizableui/test/browser_970511_undo_restore_default.js
toolkit/mozapps/extensions/LightweightThemeManager.jsm
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -158,22 +158,23 @@ CustomizeMode.prototype = {
     }
     if (this._customizing) {
       this.exit();
     } else {
       this.enter();
     }
   },
 
-  _updateLWThemeButtonIcon() {
+  async _updateLWThemeButtonIcon() {
     let lwthemeButton = this.$("customization-lwtheme-button");
     let lwthemeIcon = this.document.getAnonymousElementByAttribute(lwthemeButton,
                         "class", "button-icon");
-    lwthemeIcon.style.backgroundImage = LightweightThemeManager.currentTheme ?
-      "url(" + LightweightThemeManager.currentTheme.iconURL + ")" : "";
+    let selectedTheme = await this.getSelectedTheme();
+    lwthemeIcon.style.backgroundImage = selectedTheme ?
+      "url(" + selectedTheme.iconURL + ")" : "";
   },
 
   setTab(aTab) {
     if (gTab == aTab) {
       return;
     }
 
     if (gTab) {
@@ -1329,95 +1330,106 @@ CustomizeMode.prototype = {
   updateAutoTouchMode(checked) {
     Services.prefs.setBoolPref("browser.touchmode.auto", checked);
     // Re-render the menu items since the active mode might have
     // change because of this.
     this.onUIDensityMenuShowing();
     this._onUIChange();
   },
 
-  onLWThemesMenuShowing(aEvent) {
+  async getAllThemes() {
+    let themes = await AddonManager.getAddonsByTypes(["theme"]);
+    return themes.filter(a => !a.hidden);
+  },
+
+  async getSelectedTheme() {
+    let themes = await this.getAllThemes();
+    return themes.filter(a => a.isActive)[0];
+  },
+
+  async onLWThemesMenuShowing(aEvent) {
     const DEFAULT_THEME_ID = "default-theme@mozilla.org";
     const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
     const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
     const MAX_THEME_COUNT = 6;
 
     this._clearLWThemesMenu(aEvent.target);
 
     function previewTheme(aPreviewThemeEvent) {
-      LightweightThemeManager.previewTheme(
-        aPreviewThemeEvent.target.theme.id != DEFAULT_THEME_ID ?
-        aPreviewThemeEvent.target.theme : null);
+      let { lwtData } = aPreviewThemeEvent.target;
+      if (lwtData) {
+        LightweightThemeManager.previewTheme(lwtData.id != DEFAULT_THEME_ID ? lwtData : null);
+      } else {
+        resetPreview();
+      }
     }
 
     function resetPreview() {
       LightweightThemeManager.resetPreview();
     }
 
     let onThemeSelected = panel => {
       this._updateLWThemeButtonIcon();
       this._onUIChange();
       panel.hidePopup();
     };
 
     let doc = this.window.document;
 
-    function buildToolbarButton(aTheme) {
+    function buildToolbarButton(aTheme, lwtData) {
       let tbb = doc.createElement("toolbarbutton");
       tbb.theme = aTheme;
+      tbb.lwtData = lwtData;
       tbb.setAttribute("label", aTheme.name);
       tbb.setAttribute("image", aTheme.iconURL);
       if (aTheme.description)
         tbb.setAttribute("tooltiptext", aTheme.description);
       tbb.setAttribute("tabindex", "0");
       tbb.classList.add("customization-lwtheme-menu-theme");
       let isActive = activeThemeID == aTheme.id;
       tbb.setAttribute("aria-checked", isActive);
       tbb.setAttribute("role", "menuitemradio");
       if (isActive) {
         tbb.setAttribute("active", "true");
       }
       tbb.addEventListener("focus", previewTheme);
       tbb.addEventListener("mouseover", previewTheme);
       tbb.addEventListener("blur", resetPreview);
-
       return tbb;
     }
 
     let themes = [];
-    let lwts = LightweightThemeManager.usedThemes;
-    let currentLwt = LightweightThemeManager.currentTheme;
+    let unorderedThemes = await this.getAllThemes();
+    let currentLwt = await this.getSelectedTheme();
 
     let activeThemeID = currentLwt ? currentLwt.id : DEFAULT_THEME_ID;
 
     // Move the current theme (if any) and the light/dark themes to the start:
     let importantThemes = [DEFAULT_THEME_ID, LIGHT_THEME_ID, DARK_THEME_ID];
     if (currentLwt && !importantThemes.includes(currentLwt.id)) {
       importantThemes.push(currentLwt.id);
     }
     for (let importantTheme of importantThemes) {
-      let themeIndex = lwts.findIndex(theme => theme.id == importantTheme);
+      let themeIndex = unorderedThemes.findIndex(theme => theme.id == importantTheme);
       if (themeIndex > -1) {
-        themes.push(...lwts.splice(themeIndex, 1));
+        themes.push(...unorderedThemes.splice(themeIndex, 1));
       }
     }
-    themes = themes.concat(lwts);
+    themes = themes.concat(unorderedThemes);
     if (themes.length > MAX_THEME_COUNT)
       themes.length = MAX_THEME_COUNT;
 
     let footer = doc.getElementById("customization-lwtheme-menu-footer");
     let panel = footer.parentNode;
     let recommendedLabel = doc.getElementById("customization-lwtheme-menu-recommended");
+
     for (let theme of themes) {
-      let button = buildToolbarButton(theme);
+      let button = buildToolbarButton(theme, LightweightThemeManager.getThemeByAddonID(theme.id));
       button.addEventListener("command", () => {
-        if ("userDisabled" in button.theme)
-          button.theme.userDisabled = false;
-        else
-          LightweightThemeManager.currentTheme = button.theme;
+        button.theme.enable();
         onThemeSelected(panel);
       });
       panel.insertBefore(button, recommendedLabel);
     }
 
     function panelMouseOut(e) {
       // mouseout events bubble, so we get mouseout events for the buttons
       // in the panel. Here, we only care when the mouse actually leaves
@@ -1444,20 +1456,25 @@ CustomizeMode.prototype = {
         theme.name = sb.GetStringFromName("lightweightThemes." + theme.id + ".name");
         theme.description = sb.GetStringFromName("lightweightThemes." + theme.id + ".description");
       } catch (ex) {
         // If finding strings for this failed, just don't build it. This can
         // happen for users with 'older' recommended themes lists, some of which
         // have since been removed from Firefox.
         continue;
       }
-      let button = buildToolbarButton(theme);
+
+      let addonWrapper = {
+        ...theme,
+        id: theme.id + "@personas.mozilla.org",
+      };
+      let button = buildToolbarButton(addonWrapper, theme);
       button.addEventListener("command", () => {
-        LightweightThemeManager.setLocalTheme(button.theme);
-        recommendedThemes = recommendedThemes.filter((aTheme) => { return aTheme.id != button.theme.id; });
+        LightweightThemeManager.setLocalTheme(button.lwtData);
+        recommendedThemes = recommendedThemes.filter((aTheme) => { return aTheme.id != button.lwtData.id; });
         lwthemePrefs.setStringPref("recommendedThemes",
                                    JSON.stringify(recommendedThemes));
         onThemeSelected(panel);
       });
       panel.insertBefore(button, footer);
     }
     let hideRecommendedLabel = (footer.previousSibling == recommendedLabel);
     recommendedLabel.hidden = hideRecommendedLabel;
--- a/browser/components/customizableui/test/browser_970511_undo_restore_default.js
+++ b/browser/components/customizableui/test/browser_970511_undo_restore_default.js
@@ -20,17 +20,17 @@ add_task(async function() {
   let popup = document.getElementById("customization-lwtheme-menu");
   let popupShownPromise = popupShown(popup);
   EventUtils.synthesizeMouseAtCenter(themesButton, {});
   info("Clicked on themes button");
   await popupShownPromise;
 
   let recommendedHeader = document.getElementById("customization-lwtheme-menu-recommended");
   let firstLWTheme = recommendedHeader.nextSibling;
-  let firstLWThemeId = firstLWTheme.theme.id;
+  let firstLWThemeId = firstLWTheme.lwtData.id;
   let themeChangedPromise = promiseObserverNotified("lightweight-theme-changed");
   firstLWTheme.doCommand();
   info("Clicked on first theme");
   await themeChangedPromise;
 
   is(LightweightThemeManager.currentTheme.id, firstLWThemeId, "Theme changed to first option");
 
   await gCustomizeMode.reset();
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -442,16 +442,37 @@ var LightweightThemeManager = {
       AddonManagerPrivate.callAddonListeners("onEnabling", wrapper, false);
       this.themeChanged(theme);
       AddonManagerPrivate.callAddonListeners("onEnabled", wrapper);
 
       _themeIDBeingEnabled = null;
     }
   },
 
+
+  /**
+   * Called to get an theme with a particular addon ID.
+   *
+   * @param  aId
+   *         The external ID of the theme o retrieve
+   */
+  getThemeByAddonID(aId) {
+    let id = _getInternalID(aId);
+    if (!id) {
+      return null;
+     }
+
+    let theme = this.getUsedTheme(id);
+    if (!theme) {
+      return null;
+    }
+
+    return theme;
+  },
+
   /**
    * Called to get an Addon with a particular ID.
    *
    * @param  aId
    *         The ID of the add-on to retrieve
    */
   async getAddonByID(aId) {
     let id = _getInternalID(aId);