Bug 1053434 - Listen for lightweight theme changes and call relevant listeners for devedition theme;r=Gijs
authorBrian Grinstead <bgrinstead@mozilla.com>
Mon, 03 Nov 2014 17:46:08 -0800
changeset 233720 60fa1d966ca040ea6781f52a064d33171a9f824c
parent 233719 7c0675ad8c5aba306fd504b650811e1f3647b56c
child 233721 f627be943750ee77da7ef2e298fb6596da625f06
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1053434
milestone35.0a2
Bug 1053434 - Listen for lightweight theme changes and call relevant listeners for devedition theme;r=Gijs
browser/base/content/browser-devedition.js
browser/base/content/test/general/browser_devedition.js
--- a/browser/base/content/browser-devedition.js
+++ b/browser/base/content/browser-devedition.js
@@ -9,77 +9,110 @@
 let DevEdition = {
   _prefName: "browser.devedition.theme.enabled",
   _themePrefName: "general.skins.selectedSkin",
   _lwThemePrefName: "lightweightThemes.isThemeSelected",
   _devtoolsThemePrefName: "devtools.theme",
 
   styleSheetLocation: "chrome://browser/skin/devedition.css",
   styleSheet: null,
+  defaultThemeID: "{972ce4c6-7e08-4474-a285-3208198ce6fd}",
 
   init: function () {
     this._updateDevtoolsThemeAttribute();
-    this._updateStyleSheet();
+    this._updateStyleSheetFromPrefs();
 
     // Listen for changes to all prefs except for complete themes.
     // No need for this since changing a complete theme requires a
     // restart.
     Services.prefs.addObserver(this._lwThemePrefName, this, false);
     Services.prefs.addObserver(this._prefName, this, false);
     Services.prefs.addObserver(this._devtoolsThemePrefName, this, false);
+    Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
   },
 
   observe: function (subject, topic, data) {
+    if (topic == "lightweight-theme-styling-update") {
+      let newTheme = JSON.parse(data);
+      if (!newTheme || newTheme.id === this.defaultThemeID) {
+        // A lightweight theme has been unapplied, so just re-read prefs.
+        this._updateStyleSheetFromPrefs();
+      } else {
+        // A lightweight theme has been applied, but the pref may not be
+        // set yet if this happened from customize menu or addons page.
+        this._toggleStyleSheet(false);
+      }
+    }
+
     if (topic == "nsPref:changed") {
       if (data == this._devtoolsThemePrefName) {
         this._updateDevtoolsThemeAttribute();
       } else {
-        this._updateStyleSheet();
+        this._updateStyleSheetFromPrefs();
       }
     }
   },
 
   _updateDevtoolsThemeAttribute: function() {
     // Set an attribute on root element to make it possible
     // to change colors based on the selected devtools theme.
     document.documentElement.setAttribute("devtoolstheme",
       Services.prefs.getCharPref(this._devtoolsThemePrefName));
+    this._updateStyleSheetFromPrefs();
   },
 
-  _updateStyleSheet: function() {
-    // Only try to apply the dev edition theme if it is preffered
-    // on and there are no other themes applied.
+  _updateStyleSheetFromPrefs: function() {
     let lightweightThemeSelected = false;
     try {
       lightweightThemeSelected = Services.prefs.getBoolPref(this._lwThemePrefName);
     } catch(e) {}
 
     let defaultThemeSelected = false;
     try {
        defaultThemeSelected = Services.prefs.getCharPref(this._themePrefName) == "classic/1.0";
     } catch(e) {}
 
+    let devtoolsIsDark = false;
+    try {
+       devtoolsIsDark = Services.prefs.getCharPref(this._devtoolsThemePrefName) == "dark";
+    } catch(e) {}
+
     let deveditionThemeEnabled = Services.prefs.getBoolPref(this._prefName) &&
-      !lightweightThemeSelected && defaultThemeSelected;
+      !lightweightThemeSelected && defaultThemeSelected && devtoolsIsDark;
+
+    this._toggleStyleSheet(deveditionThemeEnabled);
+  },
 
+  handleEvent: function(e) {
+    if (e.type === "load") {
+      this.styleSheet.removeEventListener("load", this);
+      gBrowser.tabContainer._positionPinnedTabs();
+      ToolbarIconColor.inferFromText();
+    }
+  },
+
+  _toggleStyleSheet: function(deveditionThemeEnabled) {
     if (deveditionThemeEnabled && !this.styleSheet) {
       let styleSheetAttr = `href="${this.styleSheetLocation}" type="text/css"`;
-      let styleSheet = this.styleSheet = document.createProcessingInstruction(
+      this.styleSheet = document.createProcessingInstruction(
         'xml-stylesheet', styleSheetAttr);
-      this.styleSheet.addEventListener("load", function onLoad() {
-        styleSheet.removeEventListener("load", onLoad);
-        ToolbarIconColor.inferFromText();
-      });
+      this.styleSheet.addEventListener("load", this);
       document.insertBefore(this.styleSheet, document.documentElement);
     } else if (!deveditionThemeEnabled && this.styleSheet) {
+      this.styleSheet.removeEventListener("load", this);
       this.styleSheet.remove();
       this.styleSheet = null;
+      gBrowser.tabContainer._positionPinnedTabs();
       ToolbarIconColor.inferFromText();
     }
   },
 
   uninit: function () {
     Services.prefs.removeObserver(this._lwThemePrefName, this);
     Services.prefs.removeObserver(this._prefName, this);
     Services.prefs.removeObserver(this._devtoolsThemePrefName, this);
+    Services.obs.removeObserver(this, "lightweight-theme-styling-update", false);
+    if (this.styleSheet) {
+      this.styleSheet.removeEventListener("load", this);
+    }
     this.styleSheet = null;
   }
 };
--- a/browser/base/content/test/general/browser_devedition.js
+++ b/browser/base/content/test/general/browser_devedition.js
@@ -1,69 +1,122 @@
 /*
  * Testing changes for Developer Edition theme.
  * A special stylesheet should be added to the browser.xul document
  * when browser.devedition.theme.enabled is set to true and no themes
  * are applied.
  */
 
 const PREF_DEVEDITION_THEME = "browser.devedition.theme.enabled";
-const PREF_THEME = "general.skins.selectedSkin";
 const PREF_LWTHEME = "lightweightThemes.isThemeSelected";
 const PREF_DEVTOOLS_THEME = "devtools.theme";
 
 registerCleanupFunction(() => {
   // Set preferences back to their original values
   Services.prefs.clearUserPref(PREF_DEVEDITION_THEME);
-  Services.prefs.clearUserPref(PREF_THEME);
   Services.prefs.clearUserPref(PREF_LWTHEME);
   Services.prefs.clearUserPref(PREF_DEVTOOLS_THEME);
 });
 
 function test() {
   waitForExplicitFinish();
   startTests();
 }
 
 function startTests() {
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
+
   info ("Setting browser.devedition.theme.enabled to false.");
   Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, false);
   ok (!DevEdition.styleSheet, "There is no devedition style sheet when the pref is false.");
 
   info ("Setting browser.devedition.theme.enabled to true.");
   Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, true);
   ok (DevEdition.styleSheet, "There is a devedition stylesheet when no themes are applied and pref is set.");
 
   info ("Adding a lightweight theme.");
   Services.prefs.setBoolPref(PREF_LWTHEME, true);
   ok (!DevEdition.styleSheet, "The devedition stylesheet has been removed when a lightweight theme is applied.");
 
   info ("Removing a lightweight theme.");
   Services.prefs.setBoolPref(PREF_LWTHEME, false);
   ok (DevEdition.styleSheet, "The devedition stylesheet has been added when a lightweight theme is removed.");
 
-  // There are no listeners for the complete theme pref since applying the theme
-  // requires a restart.
-  info ("Setting general.skins.selectedSkin to a custom string.");
-  Services.prefs.setCharPref(PREF_THEME, "custom-theme");
-  ok (DevEdition.styleSheet, "The devedition stylesheet is still here when a complete theme is added.");
-
-  info ("Resetting general.skins.selectedSkin to default value.");
-  Services.prefs.clearUserPref(PREF_THEME);
-  ok (DevEdition.styleSheet, "The devedition stylesheet is still here when a complete theme is removed.");
-
   info ("Setting browser.devedition.theme.enabled to false.");
   Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, false);
   ok (!DevEdition.styleSheet, "The devedition stylesheet has been removed.");
 
-  info ("Checking :root attributes based on devtools theme.");
+  testDevtoolsTheme();
+  testLightweightThemePreview();
+  finish();
+}
+
+function testDevtoolsTheme() {
+  info ("Checking that Australis is shown when the light devtools theme is applied.");
+
+  Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, true);
+  ok (DevEdition.styleSheet, "The devedition stylesheet exists.");
+
+  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 (!DevEdition.styleSheet, "The devedition stylesheet has been removed because of light devtools theme.");
+
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
+  is (document.documentElement.getAttribute("devtoolstheme"), "dark",
+    "The documentElement has an attribute based on devtools theme.");
+  ok (DevEdition.styleSheet, "The devedition stylesheet has been readded because of dark 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 (!DevEdition.styleSheet, "The devedition stylesheet has been removed because of light devtools theme.");
+
   Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
   is (document.documentElement.getAttribute("devtoolstheme"), "dark",
     "The documentElement has an attribute 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 (DevEdition.styleSheet, "The devedition stylesheet has been readded because of dark devtools theme.");
+}
+
+function dummyLightweightTheme(id) {
+  return {
+    id: id,
+    name: id,
+    headerURL: "http://lwttest.invalid/a.png",
+    footerURL: "http://lwttest.invalid/b.png",
+    textcolor: "red",
+    accentcolor: "blue"
+  };
+}
+
+function testLightweightThemePreview() {
+  let {LightweightThemeManager} = Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", {});
 
-  finish();
+  info ("Turning the pref on, then previewing lightweight themes");
+  Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, true);
+  ok (DevEdition.styleSheet, "The devedition stylesheet is enabled.");
+  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview0"));
+  ok (!DevEdition.styleSheet, "The devedition stylesheet is not enabled after a lightweight theme preview.");
+  LightweightThemeManager.resetPreview();
+  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview1"));
+  ok (!DevEdition.styleSheet, "The devedition stylesheet is not enabled after a second lightweight theme preview.");
+  LightweightThemeManager.resetPreview();
+  ok (DevEdition.styleSheet, "The devedition stylesheet is enabled again after resetting the preview.");
+
+  info ("Turning the pref on, then previewing a theme, turning it off and resetting the preview");
+  Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, true);
+  ok (DevEdition.styleSheet, "The devedition stylesheet is enabled.");
+  LightweightThemeManager.previewTheme(dummyLightweightTheme("preview2"));
+  ok (!DevEdition.styleSheet, "The devedition stylesheet is not enabled after a lightweight theme preview.");
+  Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, false);
+  ok (!DevEdition.styleSheet, "The devedition stylesheet is not enabled after pref is turned off.");
+  LightweightThemeManager.resetPreview();
+  ok (!DevEdition.styleSheet, "The devedition stylesheet is still disabled after resetting the preview.");
+
+  info ("Turning the pref on, then previewing the default theme, turning it off and resetting the preview");
+  Services.prefs.setBoolPref(PREF_DEVEDITION_THEME, true);
+  ok (DevEdition.styleSheet, "The devedition stylesheet is enabled.");
+  LightweightThemeManager.previewTheme(dummyLightweightTheme("{972ce4c6-7e08-4474-a285-3208198ce6fd}"));
+  ok (DevEdition.styleSheet, "The devedition stylesheet is still enabled after the default theme is applied.");
+  LightweightThemeManager.resetPreview();
+  ok (DevEdition.styleSheet, "The devedition stylesheet is still enabled after resetting the preview.");
 }