Bug 1314091 - WIP Expose 'compact' themes instead of the Dev Edition theme draft
authorBrian Grinstead <bgrinstead@mozilla.com>
Thu, 05 Jan 2017 14:27:40 -0600
changeset 456494 0d629c45bfbf54676cdb971043e64886605bd76e
parent 456493 2e2dfbcd19dc5ca29c7b2da0f3d51c1f7d43071c
child 456495 a73b36a68e2cc4ad4b03efc7a3ed96687fd6416a
push id40521
push userbgrinstead@mozilla.com
push dateThu, 05 Jan 2017 20:28:43 +0000
bugs1314091
milestone53.0a1
Bug 1314091 - WIP Expose 'compact' themes instead of the Dev Edition theme * Rename 'devtoolstheme' attribute to 'compacttheme' for the lightweight themes (keep 'devtoolstheme' for devtools usage) * Install two lightweight themes instead of one * Introduce a build config to install the themes instead of relying on channel: INSTALL_COMPACT_THEMES * Change browser-devedition to use the new themes instead of the old one What this doesn't do: 1) Handle migration for users currently on firefox-devedition@mozilla.org 2) Add new strings and icons for the themes MozReview-Commit-ID: 8lHzWUU9Vyk
browser/app/profile/firefox.js
browser/base/content/browser-compacttheme.js
browser/base/content/test/general/browser_compacttheme.js
browser/components/nsBrowserGlue.js
toolkit/modules/AppConstants.jsm
toolkit/modules/moz.build
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1125,17 +1125,17 @@ pref("services.sync.prefs.sync.xpinstall
 // fetching these icons to show remote tabs may leak information about that
 // user's tabs and bookmarks. Note this pref is also synced.
 pref("services.sync.syncedTabs.showRemoteIcons", true);
 
 pref("services.sync.sendTabToDevice.enabled", true);
 
 // Developer edition preferences
 #ifdef MOZ_DEV_EDITION
-sticky_pref("lightweightThemes.selectedThemeID", "firefox-devedition@mozilla.org");
+sticky_pref("lightweightThemes.selectedThemeID", "firefox-compact-dark@mozilla.org");
 #else
 sticky_pref("lightweightThemes.selectedThemeID", "");
 #endif
 
 // Whether the character encoding menu is under the main Firefox button. This
 // preference is a string so that localizers can alter it.
 pref("browser.menu.showCharacterEncoding", "chrome://browser/locale/browser.properties");
 
--- a/browser/base/content/browser-compacttheme.js
+++ b/browser/base/content/browser-compacttheme.js
@@ -6,69 +6,84 @@
  * Listeners for the compact theme.  This adds an extra stylesheet
  * to browser.xul if a pref is set and no other themes are applied.
  */
 var CompactTheme = {
   _devtoolsThemePrefName: "devtools.theme",
   styleSheetLocation: "chrome://browser/skin/compacttheme.css",
   styleSheet: null,
   initialized: false,
+  currentThemeId: null,
 
   get isStyleSheetEnabled() {
     return this.styleSheet && !this.styleSheet.sheet.disabled;
   },
 
   get isThemeCurrentlyApplied() {
     let theme = LightweightThemeManager.currentTheme;
-    return theme && theme.id == "firefox-devedition@mozilla.org";
+    return theme && (
+           theme.id == "firefox-compact-dark@mozilla.org" ||
+           theme.id == "firefox-compact-light@mozilla.org");
+  },
+
+  // This is not checking the LightweightThemeManager.currentTheme since
+  // we want the value to be correct even during previewing (Bug 1321911).
+  get isCurrentThemeIdDark() {
+    return this.currentThemeId == "firefox-compact-dark@mozilla.org";
   },
 
   init() {
     this.initialized = true;
     Services.prefs.addObserver(this._devtoolsThemePrefName, this, false);
     Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
     this._updateDevtoolsThemeAttribute();
 
     if (this.isThemeCurrentlyApplied) {
-      this._toggleStyleSheet(true);
+      this._toggleStyleSheet(LightweightThemeManager.currentTheme.id);
     }
   },
 
   createStyleSheet() {
     let styleSheetAttr = `href="${this.styleSheetLocation}" type="text/css"`;
     this.styleSheet = document.createProcessingInstruction(
       "xml-stylesheet", styleSheetAttr);
     this.styleSheet.addEventListener("load", this);
     document.insertBefore(this.styleSheet, document.documentElement);
     this.styleSheet.sheet.disabled = true;
   },
 
   observe(subject, topic, data) {
     if (topic == "lightweight-theme-styling-update") {
       let newTheme = JSON.parse(data);
-      if (newTheme && newTheme.id == "firefox-devedition@mozilla.org") {
-        this._toggleStyleSheet(true);
+      if (newTheme && (
+          newTheme.id == "firefox-compact-light@mozilla.org" ||
+          newTheme.id == "firefox-compact-dark@mozilla.org")) {
+        // We are using the theme ID on this object instead of always referencing
+        // LightweightThemeManager.currentTheme in case this is a preview
+        this._toggleStyleSheet(newTheme.id);
       } else {
-        this._toggleStyleSheet(false);
+        this._toggleStyleSheet(null);
       }
+
     }
 
     if (topic == "nsPref:changed" && data == this._devtoolsThemePrefName) {
       this._updateDevtoolsThemeAttribute();
     }
   },
 
   _inferBrightness() {
     ToolbarIconColor.inferFromText();
-    // Get an inverted full screen button if the dark theme is applied.
-    if (this.isStyleSheetEnabled &&
-        document.documentElement.getAttribute("devtoolstheme") == "dark") {
-      document.documentElement.setAttribute("brighttitlebarforeground", "true");
-    } else {
-      document.documentElement.removeAttribute("brighttitlebarforeground");
+
+    if (this.isStyleSheetEnabled) {
+      if (this.isCurrentThemeIdDark) {
+        document.documentElement.setAttribute("brighttitlebarforeground", "true");
+      } else {
+        document.documentElement.removeAttribute("brighttitlebarforeground");
+      }
     }
   },
 
   _updateDevtoolsThemeAttribute() {
     // Set an attribute on root element to make it possible
     // to change colors based on the selected devtools theme.
     let devtoolsTheme = Services.prefs.getCharPref(this._devtoolsThemePrefName);
     if (devtoolsTheme != "dark") {
@@ -89,27 +104,36 @@ var CompactTheme = {
     // Don't touch things on the browser if gBrowserInit.onLoad hasn't
     // yet fired.
     if (this.initialized) {
       gBrowser.tabContainer._positionPinnedTabs();
       this._inferBrightness();
     }
   },
 
-  _toggleStyleSheet(deveditionThemeEnabled) {
+  _toggleStyleSheet(currentThemeId) {
     let wasEnabled = this.isStyleSheetEnabled;
-    if (deveditionThemeEnabled && !wasEnabled) {
+    if (currentThemeId) {
+      // If this is called at startup, we haven't had a chance to set currentThemeId.
+      // We only get here in this case if LightweightThemeManager.currentTheme is already
+      // light or dark.
+      this.currentThemeId = currentThemeId;
+
       // The stylesheet may not have been created yet if it wasn't
       // needed on initial load.  Make it now.
       if (!this.styleSheet) {
         this.createStyleSheet();
       }
       this.styleSheet.sheet.disabled = false;
+
+      let compactTheme = this.isCurrentThemeIdDark ? "dark" : "light";
+      document.documentElement.setAttribute("compacttheme", compactTheme);
+
       this.refreshBrowserDisplay();
-    } else if (!deveditionThemeEnabled && wasEnabled) {
+    } else if (!currentThemeId && wasEnabled) {
       this.styleSheet.sheet.disabled = true;
       this.refreshBrowserDisplay();
     }
   },
 
   uninit() {
     Services.prefs.removeObserver(this._devtoolsThemePrefName, this);
     Services.obs.removeObserver(this, "lightweight-theme-styling-update", false);
@@ -118,12 +142,12 @@ var CompactTheme = {
     }
     this.styleSheet = null;
   }
 };
 
 // If the compact theme is going to be applied in gBrowserInit.onLoad,
 // then preload it now.  This prevents a flash of unstyled content where the
 // normal theme is applied while the compact theme stylesheet is loading.
-if (!AppConstants.RELEASE_OR_BETA &&
+if (AppConstants.INSTALL_COMPACT_THEMES &&
     this != Services.appShell.hiddenDOMWindow && CompactTheme.isThemeCurrentlyApplied) {
   CompactTheme.createStyleSheet();
 }
--- a/browser/base/content/test/general/browser_compacttheme.js
+++ b/browser/base/content/test/general/browser_compacttheme.js
@@ -1,121 +1,101 @@
 /*
  * Testing changes for Developer Edition theme.
  * A special stylesheet should be added to the browser.xul document
  * when the firefox-devedition@mozilla.org lightweight theme
  * is applied.
  */
 
 const PREF_LWTHEME_USED_THEMES = "lightweightThemes.usedThemes";
-const PREF_DEVTOOLS_THEME = "devtools.theme";
+const COMPACT_LIGHT_ID = "firefox-compact-light@mozilla.org";
+const COMPACT_DARK_ID = "firefox-compact-dark@mozilla.org";
+const SKIP_TEST = !AppConstants.INSTALL_COMPACT_THEMES;
 const {LightweightThemeManager} = Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", {});
 
-LightweightThemeManager.clearBuiltInThemes();
-LightweightThemeManager.addBuiltInTheme(dummyLightweightTheme("firefox-devedition@mozilla.org"));
-
 registerCleanupFunction(() => {
   // Set preferences back to their original values
   LightweightThemeManager.currentTheme = null;
-  Services.prefs.clearUserPref(PREF_DEVTOOLS_THEME);
   Services.prefs.clearUserPref(PREF_LWTHEME_USED_THEMES);
-
-  LightweightThemeManager.currentTheme = null;
-  LightweightThemeManager.clearBuiltInThemes();
 });
 
 add_task(function* startTests() {
-  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
+  if (SKIP_TEST) {
+    ok(true, "No need to run this test since themes aren't installed");
+    return;
+  }
 
   info("Setting the current theme to null");
   LightweightThemeManager.currentTheme = null;
-  ok(!CompactTheme.isStyleSheetEnabled, "There is no devedition style sheet when no lw theme is applied.");
+  ok(!CompactTheme.isStyleSheetEnabled, "There is no compact style sheet when no lw theme is applied.");
 
   info("Adding a lightweight theme.");
   LightweightThemeManager.currentTheme = dummyLightweightTheme("preview0");
-  ok(!CompactTheme.isStyleSheetEnabled, "The devedition stylesheet has been removed when a lightweight theme is applied.");
+  ok(!CompactTheme.isStyleSheetEnabled, "The compact stylesheet has been removed when a lightweight theme is applied.");
 
-  info("Applying the devedition lightweight theme.");
+  info("Applying the dark compact theme.");
   let onAttributeAdded = waitForBrightTitlebarAttribute();
-  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme("firefox-devedition@mozilla.org");
-  ok(CompactTheme.isStyleSheetEnabled, "The devedition stylesheet has been added when the devedition lightweight theme is applied");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID);
+  ok(CompactTheme.isStyleSheetEnabled, "The compact stylesheet has been added when the compact lightweight theme is applied");
   yield onAttributeAdded;
-  is(document.documentElement.getAttribute("brighttitlebarforeground"), "true",
-     "The brighttitlebarforeground attribute is set on the window.");
+  ok(document.documentElement.hasAttribute("brighttitlebarforeground"),
+     "The brighttitlebarforeground attribute is set on the window with dark theme.");
+
+  info("Applying the light compact theme.");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID);
+  ok(CompactTheme.isStyleSheetEnabled, "The compact stylesheet has been added when the compact lightweight theme is applied");
+  ok(!document.documentElement.hasAttribute("brighttitlebarforeground"),
+     "The brighttitlebarforeground attribute is not on the window with light theme.");
+
+  info("Adding a different lightweight theme.");
+  LightweightThemeManager.currentTheme = dummyLightweightTheme("preview1");
+  ok(!CompactTheme.isStyleSheetEnabled, "The compact stylesheet has been removed when a lightweight theme is applied.");
 
   info("Unapplying all themes.");
   LightweightThemeManager.currentTheme = null;
-  ok(!CompactTheme.isStyleSheetEnabled, "There is no devedition style sheet when no lw theme is applied.");
-
-  info("Applying the devedition lightweight theme.");
-  onAttributeAdded = waitForBrightTitlebarAttribute();
-  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme("firefox-devedition@mozilla.org");
-  ok(CompactTheme.isStyleSheetEnabled, "The devedition stylesheet has been added when the devedition lightweight theme is applied");
-  yield onAttributeAdded;
-  ok(document.documentElement.hasAttribute("brighttitlebarforeground"),
-     "The brighttitlebarforeground attribute is set on the window with dark devtools theme.");
+  ok(!CompactTheme.isStyleSheetEnabled, "There is no compact style sheet when no lw theme is applied.");
 });
 
-add_task(function* testDevtoolsTheme() {
-  info("Checking stylesheet and :root attributes based on devtools theme.");
-  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
-  is(document.documentElement.getAttribute("devtoolstheme"), "light",
-    "The documentElement has an attribute based on devtools theme.");
-  ok(CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is still there with the light devtools theme.");
-  ok(!document.documentElement.hasAttribute("brighttitlebarforeground"),
-     "The brighttitlebarforeground attribute is not set on the window with light devtools theme.");
+add_task(function* testLightweightThemePreview() {
+  if (SKIP_TEST) {
+    ok(true, "No need to run this test since themes aren't installed");
+    return;
+  }
+  info("Setting compact to current and the previewing others");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID);
+  ok(CompactTheme.isStyleSheetEnabled, "The compact stylesheet is enabled.");
+  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview0"));
+  ok(!CompactTheme.isStyleSheetEnabled, "The compact stylesheet is not enabled after a lightweight theme preview.");
+  LightweightThemeManager.resetPreview();
+  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview1"));
+  ok(!CompactTheme.isStyleSheetEnabled, "The compact stylesheet is not enabled after a second lightweight theme preview.");
+  LightweightThemeManager.resetPreview();
+  ok(CompactTheme.isStyleSheetEnabled, "The compact stylesheet is enabled again after resetting the preview.");
+  LightweightThemeManager.currentTheme = null;
+  ok(!CompactTheme.isStyleSheetEnabled, "The compact stylesheet is gone after removing the current theme.");
 
-  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
-  is(document.documentElement.getAttribute("devtoolstheme"), "dark",
-    "The documentElement has an attribute based on devtools theme.");
-  ok(CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is still there with the dark devtools theme.");
-  is(document.documentElement.getAttribute("brighttitlebarforeground"), "true",
-     "The brighttitlebarforeground attribute is set on the window with dark devtools theme.");
-
-  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "foobar");
-  is(document.documentElement.getAttribute("devtoolstheme"), "light",
-    "The documentElement has 'light' as a default for the devtoolstheme attribute");
-  ok(CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is still there with the foobar devtools theme.");
-  ok(!document.documentElement.hasAttribute("brighttitlebarforeground"),
-     "The brighttitlebarforeground attribute is not set on the window with light devtools theme.");
+  info("Previewing the compact theme");
+  LightweightThemeManager.previewTheme(COMPACT_LIGHT_ID);
+  ok(CompactTheme.isStyleSheetEnabled, "The compact stylesheet is enabled.");
+  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview2"));
+  LightweightThemeManager.resetPreview();
+  ok(!CompactTheme.isStyleSheetEnabled, "The compact stylesheet is now disabled after resetting the preview.");
 });
 
 function dummyLightweightTheme(id) {
   return {
-    id,
+    id: id,
     name: id,
     headerURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.header.png",
     iconURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.icon.png",
     textcolor: "red",
     accentcolor: "blue"
   };
 }
 
-add_task(function* testLightweightThemePreview() {
-  info("Setting devedition to current and the previewing others");
-  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme("firefox-devedition@mozilla.org");
-  ok(CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is enabled.");
-  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview0"));
-  ok(!CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is not enabled after a lightweight theme preview.");
-  LightweightThemeManager.resetPreview();
-  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview1"));
-  ok(!CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is not enabled after a second lightweight theme preview.");
-  LightweightThemeManager.resetPreview();
-  ok(CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is enabled again after resetting the preview.");
-  LightweightThemeManager.currentTheme = null;
-  ok(!CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is gone after removing the current theme.");
-
-  info("Previewing the devedition theme");
-  LightweightThemeManager.previewTheme(LightweightThemeManager.getUsedTheme("firefox-devedition@mozilla.org"));
-  ok(CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is enabled.");
-  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview2"));
-  LightweightThemeManager.resetPreview();
-  ok(!CompactTheme.isStyleSheetEnabled, "The devedition stylesheet is now disabled after resetting the preview.");
-});
-
 // Use a mutation observer to wait for the brighttitlebarforeground
 // attribute to change.  Using this instead of waiting for the load
 // event on the DevEdition styleSheet.
 function waitForBrightTitlebarAttribute() {
   return new Promise((resolve, reject) => {
     let mutationObserver = new MutationObserver(function(mutations) {
       for (let mutation of mutations) {
         if (mutation.attributeName == "brighttitlebarforeground") {
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -642,25 +642,37 @@ BrowserGlue.prototype = {
     ReaderParent.init();
     URLBarZoom.init();
 
     SelfSupportBackend.init();
 
     // Ensure we keep track of places/pw-mananager undo by init'ing this early.
     Cu.import("resource:///modules/AutoMigrate.jsm");
 
-    if (!AppConstants.RELEASE_OR_BETA) {
-      let themeName = gBrowserBundle.GetStringFromName("deveditionTheme.name");
+    if (AppConstants.INSTALL_COMPACT_THEMES) {
       let vendorShortName = gBrandBundle.GetStringFromName("vendorShortName");
 
+      // XXX: Localize + Add custom icons
       LightweightThemeManager.addBuiltInTheme({
-        id: "firefox-devedition@mozilla.org",
-        name: themeName,
+        id: "firefox-compact-light@mozilla.org",
+        name: "Compact Light",
         headerURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.header.png",
         iconURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.icon.png",
+        textcolor: "black",
+        accentcolor: "white",
+        author: vendorShortName,
+      });
+      // XXX: Localize + Add custom icons
+      LightweightThemeManager.addBuiltInTheme({
+        id: "firefox-compact-dark@mozilla.org",
+        name: "Compact Dark",
+        headerURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.header.png",
+        iconURL: "resource:///chrome/browser/content/browser/defaultthemes/devedition.icon.png",
+        textcolor: "white",
+        accentcolor: "black",
         author: vendorShortName,
       });
     }
 
     TabCrashHandler.init();
     if (AppConstants.MOZ_CRASHREPORTER) {
       PluginCrashReporter.init();
       UnsubmittedCrashHandler.init();
--- a/toolkit/modules/AppConstants.jsm
+++ b/toolkit/modules/AppConstants.jsm
@@ -255,16 +255,23 @@ this.AppConstants = Object.freeze({
 
   MOZ_REQUIRE_SIGNING:
 #ifdef MOZ_REQUIRE_SIGNING
   true,
 #else
   false,
 #endif
 
+  INSTALL_COMPACT_THEMES:
+#ifdef INSTALL_COMPACT_THEMES
+  true,
+#else
+  false,
+#endif
+
   MENUBAR_CAN_AUTOHIDE:
 #ifdef MENUBAR_CAN_AUTOHIDE
   true,
 #else
   false,
 #endif
 
   CAN_DRAW_IN_TITLEBAR:
--- a/toolkit/modules/moz.build
+++ b/toolkit/modules/moz.build
@@ -98,16 +98,17 @@ EXTRA_JS_MODULES += [
     'UpdateUtils.jsm',
     'WebChannel.jsm',
     'WindowDraggingUtils.jsm',
     'ZipUtils.jsm',
 ]
 EXTRA_JS_MODULES.third_party.jsesc += ['third_party/jsesc/jsesc.js']
 EXTRA_JS_MODULES.sessionstore += ['sessionstore/Utils.jsm']
 
+DEFINES['INSTALL_COMPACT_THEMES'] = 1
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
     DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
     DEFINES['MENUBAR_CAN_AUTOHIDE'] = 1
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
     DEFINES['HAVE_SHELL_SERVICE'] = 1