Bug 1314091 - Sync the applied devtools toolbox theme and compact themes;r=ochameau draft
authorBrian Grinstead <bgrinstead@mozilla.com>
Tue, 10 Jan 2017 16:21:11 -0800
changeset 458753 d31eb5be32bcf050a129d6dbf7de59778766f643
parent 458750 28f124784d81b384efe8292b90595c99d048d27f
child 541736 20e24ddfe7babc3e2bc18ff89184d430025ebcf8
push id41049
push userbgrinstead@mozilla.com
push dateWed, 11 Jan 2017 00:21:30 +0000
reviewersochameau
bugs1314091
milestone53.0a1
Bug 1314091 - Sync the applied devtools toolbox theme and compact themes;r=ochameau MozReview-Commit-ID: 38OLFmF3ALk
devtools/client/framework/devtools-browser.js
devtools/client/framework/test/browser.ini
devtools/client/framework/test/browser_toolbox_theme.js
--- a/devtools/client/framework/devtools-browser.js
+++ b/devtools/client/framework/devtools-browser.js
@@ -24,25 +24,29 @@ loader.lazyRequireGetter(this, "TargetFa
 loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
 loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
 loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
 loader.lazyRequireGetter(this, "BrowserMenus", "devtools/client/framework/browser-menus");
 loader.lazyRequireGetter(this, "findCssSelector", "devtools/shared/inspector/css-logic", true);
 
 loader.lazyImporter(this, "CustomizableUI", "resource:///modules/CustomizableUI.jsm");
 loader.lazyImporter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm");
+loader.lazyImporter(this, "LightweightThemeManager", "resource://gre/modules/LightweightThemeManager.jsm");
 
 const {LocalizationHelper} = require("devtools/shared/l10n");
 const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
 
 const TABS_OPEN_PEAK_HISTOGRAM = "DEVTOOLS_TABS_OPEN_PEAK_LINEAR";
 const TABS_OPEN_AVG_HISTOGRAM = "DEVTOOLS_TABS_OPEN_AVERAGE_LINEAR";
 const TABS_PINNED_PEAK_HISTOGRAM = "DEVTOOLS_TABS_PINNED_PEAK_LINEAR";
 const TABS_PINNED_AVG_HISTOGRAM = "DEVTOOLS_TABS_PINNED_AVERAGE_LINEAR";
 
+const COMPACT_LIGHT_ID = "firefox-compact-light@mozilla.org";
+const COMPACT_DARK_ID = "firefox-compact-dark@mozilla.org";
+
 /**
  * gDevToolsBrowser exposes functions to connect the gDevTools instance with a
  * Firefox instance.
  */
 var gDevToolsBrowser = exports.gDevToolsBrowser = {
   /**
    * A record of the windows whose menus we altered, so we can undo the changes
    * as the window is closed
@@ -138,16 +142,32 @@ var gDevToolsBrowser = exports.gDevTools
     // Set an attribute on root element of each window to make it possible
     // to change colors based on the selected devtools theme.
     let devtoolsTheme = Services.prefs.getCharPref("devtools.theme");
     if (devtoolsTheme != "dark") {
       devtoolsTheme = "light";
     }
 
     win.document.documentElement.setAttribute("devtoolstheme", devtoolsTheme);
+
+    // If the toolbox color changes and we have the opposite compact theme applied,
+    // change it to match.  For example:
+    // 1) toolbox changes to dark, and the light compact theme was applied.
+    //    Switch to the dark compact theme.
+    // 2) toolbox changes to light or firebug, and the dark compact theme was applied.
+    //    Switch to the light compact theme.
+    // 3) No compact theme was applied. Do nothing.
+    let currentLighweightTheme = LightweightThemeManager.currentTheme;
+    let currentLighweightThemeID = currentLighweightTheme && currentLighweightTheme.id;
+    if (currentLighweightThemeID == COMPACT_LIGHT_ID && devtoolsTheme == "dark") {
+      LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID);
+    }
+    if (currentLighweightThemeID == COMPACT_DARK_ID && devtoolsTheme == "light") {
+      LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID);
+    }
   },
 
   observe: function (subject, topic, prefName) {
     switch (topic) {
       case "browser-delayed-startup-finished":
         this._registerBrowserWindow(subject);
         break;
       case "nsPref:changed":
@@ -167,16 +187,30 @@ var gDevToolsBrowser = exports.gDevTools
         break;
       case "sdk:loader:destroy":
         // This event is fired when the devtools loader unloads, which happens
         // only when the add-on workflow ask devtools to be reloaded.
         if (subject.wrappedJSObject == require('@loader/unload')) {
           gDevToolsBrowser.destroy({ shuttingDown: false });
         }
         break;
+      case "lightweight-theme-changed":
+        let currentLighweightTheme = LightweightThemeManager.currentTheme;
+        let currentLighweightThemeID = currentLighweightTheme && currentLighweightTheme.id;
+        let devtoolsTheme = Services.prefs.getCharPref("devtools.theme");
+
+        // If the current lightweight theme changes to one of the compact themes, then
+        // keep the devtools color in sync.
+        if (currentLighweightThemeID == COMPACT_LIGHT_ID && devtoolsTheme == "dark") {
+          Services.prefs.setCharPref("devtools.theme", "light");
+        }
+        if (currentLighweightThemeID == COMPACT_DARK_ID && devtoolsTheme == "light") {
+            Services.prefs.setCharPref("devtools.theme", "dark");
+        }
+        break;
     }
   },
 
   _prefObserverRegistered: false,
 
   ensurePrefObserver: function () {
     if (!this._prefObserverRegistered) {
       this._prefObserverRegistered = true;
@@ -766,16 +800,17 @@ var gDevToolsBrowser = exports.gDevTools
 
    * @param {boolean} shuttingDown
    *        True if firefox is currently shutting down. We may prevent doing
    *        some cleanups to speed it up. Otherwise everything need to be
    *        cleaned up in order to be able to load devtools again.
    */
   destroy: function ({ shuttingDown }) {
     Services.prefs.removeObserver("devtools.", gDevToolsBrowser);
+    Services.obs.removeObserver(gDevToolsBrowser, "lightweight-theme-changed", false);
     Services.obs.removeObserver(gDevToolsBrowser, "browser-delayed-startup-finished");
     Services.obs.removeObserver(gDevToolsBrowser, "quit-application");
     Services.obs.removeObserver(gDevToolsBrowser, "sdk:loader:destroy");
 
     gDevToolsBrowser._pingTelemetry();
     gDevToolsBrowser._telemetry = null;
 
     for (let win of gDevToolsBrowser._trackedBrowserWindows) {
@@ -805,16 +840,17 @@ gDevTools.on("tool-unregistered", functi
 
 gDevTools.on("toolbox-ready", gDevToolsBrowser._updateMenuCheckbox);
 gDevTools.on("toolbox-destroyed", gDevToolsBrowser._updateMenuCheckbox);
 
 Services.obs.addObserver(gDevToolsBrowser, "quit-application", false);
 Services.obs.addObserver(gDevToolsBrowser, "browser-delayed-startup-finished", false);
 // Watch for module loader unload. Fires when the tools are reloaded.
 Services.obs.addObserver(gDevToolsBrowser, "sdk:loader:destroy", false);
+Services.obs.addObserver(gDevToolsBrowser, "lightweight-theme-changed", false);
 
 // Fake end of browser window load event for all already opened windows
 // that is already fully loaded.
 let enumerator = Services.wm.getEnumerator(gDevTools.chromeWindowType);
 while (enumerator.hasMoreElements()) {
   let win = enumerator.getNext();
   if (win.gBrowserInit && win.gBrowserInit.delayedStartupFinished) {
     gDevToolsBrowser._registerBrowserWindow(win);
--- a/devtools/client/framework/test/browser.ini
+++ b/devtools/client/framework/test/browser.ini
@@ -69,16 +69,17 @@ skip-if = e10s # Bug 1069044 - destroyIn
 [browser_toolbox_sidebar.js]
 [browser_toolbox_sidebar_events.js]
 [browser_toolbox_sidebar_existing_tabs.js]
 [browser_toolbox_sidebar_overflow_menu.js]
 [browser_toolbox_split_console.js]
 [browser_toolbox_target.js]
 [browser_toolbox_tabsswitch_shortcuts.js]
 [browser_toolbox_textbox_context_menu.js]
+[browser_toolbox_theme.js]
 [browser_toolbox_theme_registration.js]
 [browser_toolbox_toggle.js]
 [browser_toolbox_tool_ready.js]
 [browser_toolbox_tool_remote_reopen.js]
 [browser_toolbox_tools_per_toolbox_registration.js]
 [browser_toolbox_transport_events.js]
 [browser_toolbox_view_source_01.js]
 [browser_toolbox_view_source_02.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/framework/test/browser_toolbox_theme.js
@@ -0,0 +1,76 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const COMPACT_LIGHT_ID = "firefox-compact-light@mozilla.org";
+const COMPACT_DARK_ID = "firefox-compact-dark@mozilla.org";
+const PREF_DEVTOOLS_THEME = "devtools.theme";
+const {LightweightThemeManager} = Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", {});
+
+registerCleanupFunction(() => {
+  // Set preferences back to their original values
+  Services.prefs.clearUserPref(PREF_DEVTOOLS_THEME);
+  LightweightThemeManager.currentTheme = null;
+});
+
+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.");
+
+  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, "firebug");
+  is(document.documentElement.getAttribute("devtoolstheme"), "light",
+    "The documentElement has 'light' as a default for the devtoolstheme attribute");
+});
+
+add_task(function* testDevtoolsAndCompactThemeSyncing() {
+  if (!AppConstants.INSTALL_COMPACT_THEMES) {
+    ok(true, "No need to run this test since themes aren't installed");
+    return;
+  }
+
+  info("Devtools theme light -> dark when dark compact applied");
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID);
+  is(Services.prefs.getCharPref(PREF_DEVTOOLS_THEME), "dark");
+
+  info("Devtools theme dark -> light when light compact applied");
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID);
+  is(Services.prefs.getCharPref(PREF_DEVTOOLS_THEME), "light");
+
+  info("Devtools theme shouldn't change if it wasn't light or dark during lwt change");
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "firebug");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID);
+  is(Services.prefs.getCharPref(PREF_DEVTOOLS_THEME), "firebug");
+
+  info("Compact theme dark -> light when devtools changes dark -> light");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID);
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
+  is(LightweightThemeManager.currentTheme, LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID));
+
+  info("Compact theme dark -> light when devtools changes dark -> firebug");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID);
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "firebug");
+  is(LightweightThemeManager.currentTheme, LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID));
+
+  info("Compact theme light -> dark when devtools changes light -> dark");
+  LightweightThemeManager.currentTheme = LightweightThemeManager.getUsedTheme(COMPACT_LIGHT_ID);
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
+  is(LightweightThemeManager.currentTheme, LightweightThemeManager.getUsedTheme(COMPACT_DARK_ID));
+
+  info("Compact theme shouldn't change if it wasn't set during devtools change");
+  LightweightThemeManager.currentTheme = null;
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "light");
+  Services.prefs.setCharPref(PREF_DEVTOOLS_THEME, "dark");
+  is(LightweightThemeManager.currentTheme, null);
+});