 |
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5 /**
6 * Listeners for the DevEdition theme. This adds an extra stylesheet
7 * to browser.xul if a pref is set and no other themes are applied.
8 */
9 let DevEdition = {
10 _prefName: "browser.devedition.theme.enabled",
11 _themePrefName: "general.skins.selectedSkin",
12 _lwThemePrefName: "lightweightThemes.selectedThemeID",
13 _devtoolsThemePrefName: "devtools.theme",
14
15 styleSheetLocation: "chrome://browser/skin/devedition.css",
16 styleSheet: null,
17
18 init: function () {
19 this._updateDevtoolsThemeAttribute();
20 this._updateStyleSheetFromPrefs();
21
22 // Listen for changes to all prefs except for complete themes.
23 // No need for this since changing a complete theme requires a
24 // restart.
25 Services.prefs.addObserver(this._lwThemePrefName, this, false);
26 Services.prefs.addObserver(this._prefName, this, false);
27 Services.prefs.addObserver(this._devtoolsThemePrefName, this, false);
28 Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
29 },
30
31 observe: function (subject, topic, data) {
32 if (topic == "lightweight-theme-styling-update") {
33 let newTheme = JSON.parse(data);
34 if (!newTheme) {
35 // A lightweight theme has been unapplied, so just re-read prefs.
36 this._updateStyleSheetFromPrefs();
37 } else {
38 // A lightweight theme has been applied, but the pref may not be
39 // set yet if this happened from customize menu or addons page.
40 this._toggleStyleSheet(false);
41 }
42 }
43
44 if (topic == "nsPref:changed") {
45 if (data == this._devtoolsThemePrefName) {
46 this._updateDevtoolsThemeAttribute();
47 } else {
48 this._updateStyleSheetFromPrefs();
49 }
50 }
51 },
52
53 _inferBrightness: function() {
54 ToolbarIconColor.inferFromText();
55 // Get an inverted full screen button if the dark theme is applied.
56 if (this.styleSheet &&
57 document.documentElement.getAttribute("devtoolstheme") == "dark") {
58 document.documentElement.setAttribute("brighttitlebarforeground", "true");
59 } else {
60 document.documentElement.removeAttribute("brighttitlebarforeground");
61 }
62 },
63
64 _updateDevtoolsThemeAttribute: function() {
65 // Set an attribute on root element to make it possible
66 // to change colors based on the selected devtools theme.
67 let devtoolsTheme = Services.prefs.getCharPref(this._devtoolsThemePrefName);
68 if (devtoolsTheme != "dark") {
69 devtoolsTheme = "light";
70 }
71 document.documentElement.setAttribute("devtoolstheme", devtoolsTheme);
72 this._inferBrightness();
73 this._updateStyleSheetFromPrefs();
74 },
75
76 _updateStyleSheetFromPrefs: function() {
77 let lightweightThemeSelected = false;
78 try {
79 lightweightThemeSelected = !!Services.prefs.getCharPref(this._lwThemePrefName);
80 } catch(e) {}
81
82 let defaultThemeSelected = false;
83 try {
84 defaultThemeSelected = Services.prefs.getCharPref(this._themePrefName) == "classic/1.0";
85 } catch(e) {}
86
87 let deveditionThemeEnabled = Services.prefs.getBoolPref(this._prefName) &&
88 !lightweightThemeSelected && defaultThemeSelected;
89
90 this._toggleStyleSheet(deveditionThemeEnabled);
91 },
92
93 handleEvent: function(e) {
94 if (e.type === "load") {
95 this.styleSheet.removeEventListener("load", this);
96 gBrowser.tabContainer._positionPinnedTabs();
97 this._inferBrightness();
98 Services.obs.notifyObservers(window, "devedition-theme-state-changed", true);
99 }
100 },
101
102 _toggleStyleSheet: function(deveditionThemeEnabled) {
103 if (deveditionThemeEnabled && !this.styleSheet) {
104 let styleSheetAttr = `href="${this.styleSheetLocation}" type="text/css"`;
105 this.styleSheet = document.createProcessingInstruction(
106 'xml-stylesheet', styleSheetAttr);
107 this.styleSheet.addEventListener("load", this);
108 document.insertBefore(this.styleSheet, document.documentElement);
109 // NB: we'll notify observers once the stylesheet has fully loaded, see
110 // handleEvent above.
111 } else if (!deveditionThemeEnabled && this.styleSheet) {
112 this.styleSheet.removeEventListener("load", this);
113 this.styleSheet.remove();
114 this.styleSheet = null;
115 gBrowser.tabContainer._positionPinnedTabs();
116 this._inferBrightness();
117 Services.obs.notifyObservers(window, "devedition-theme-state-changed", false);
118 }
119 },
120
121 uninit: function () {
122 Services.prefs.removeObserver(this._lwThemePrefName, this);
123 Services.prefs.removeObserver(this._prefName, this);
124 Services.prefs.removeObserver(this._devtoolsThemePrefName, this);
125 Services.obs.removeObserver(this, "lightweight-theme-styling-update", false);
126 if (this.styleSheet) {
127 this.styleSheet.removeEventListener("load", this);
128 }
129 this.styleSheet = null;
130 }
131 };
132