Bug 1344926 - make sure that WebExtension theme data is persisted across windows when they open and image data is persisted to disk as well. r?Mossop
MozReview-Commit-ID: 5UUjajCa8nK
--- a/toolkit/components/extensions/ext-theme.js
+++ b/toolkit/components/extensions/ext-theme.js
@@ -1,14 +1,16 @@
"use strict";
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
+ "resource://gre/modules/LightweightThemeManager.jsm");
// WeakMap[Extension -> Theme]
let themeMap = new WeakMap();
const ICONS = Preferences.get("extensions.webextensions.themes.icons.buttons", "").split(",");
/** Class representing a theme. */
class Theme {
@@ -45,16 +47,17 @@ class Theme {
if (details.icons) {
this.loadIcons(details.icons);
}
// Lightweight themes require all properties to be defined.
if (this.lwtStyles.headerURL &&
this.lwtStyles.accentcolor &&
this.lwtStyles.textcolor) {
+ LightweightThemeManager.fallbackThemeData = this.lwtStyles;
Services.obs.notifyObservers(null,
"lightweight-theme-styling-update",
JSON.stringify(this.lwtStyles));
}
}
/**
* Helper method for loading colors found in the extension's manifest.
@@ -137,16 +140,17 @@ class Theme {
accentcolor: "",
textcolor: "",
icons: {},
};
for (let icon of ICONS) {
lwtStyles.icons[`--${icon}--icon`] = "";
}
+ LightweightThemeManager.fallbackThemeData = null;
Services.obs.notifyObservers(null,
"lightweight-theme-styling-update",
JSON.stringify(lwtStyles));
}
}
/* eslint-disable mozilla/balanced-listeners */
extensions.on("manifest_theme", (type, directive, extension, manifest) => {
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -66,16 +66,20 @@ Object.defineProperty(this, "_maxUsedThe
});
// Holds the ID of the theme being enabled or disabled while sending out the
// events so cached AddonWrapper instances can return correct values for
// permissions and pendingOperations
var _themeIDBeingEnabled = null;
var _themeIDBeingDisabled = null;
+// Holds optional fallback theme data that will be returned when no data for an
+// active theme can be found. This the case for WebExtension Themes, for example.
+var _fallbackThemeData = null;
+
// Convert from the old storage format (in which the order of usedThemes
// was combined with isThemeSelected to determine which theme was selected)
// to the new one (where a selectedThemeID determines which theme is selected).
(function() {
let wasThemeSelected = _prefs.getBoolPref("isThemeSelected", false);
if (wasThemeSelected) {
_prefs.clearUserPref("isThemeSelected");
@@ -91,16 +95,29 @@ var _themeIDBeingDisabled = null;
}
})();
this.LightweightThemeManager = {
get name() {
return "LightweightThemeManager";
},
+ set fallbackThemeData(data) {
+ if (data && Object.getOwnPropertyNames(data).length) {
+ _fallbackThemeData = Object.assign({}, data);
+ if (PERSIST_ENABLED) {
+ LightweightThemeImageOptimizer.purge();
+ _persistImages(_fallbackThemeData, () => {});
+ }
+ } else {
+ _fallbackThemeData = null;
+ }
+ return _fallbackThemeData;
+ },
+
// Themes that can be added for an application. They can't be removed, and
// will always show up at the top of the list.
_builtInThemes: new Map(),
get usedThemes() {
let themes = [];
try {
themes = JSON.parse(_prefs.getComplexValue("usedThemes",
@@ -118,16 +135,18 @@ this.LightweightThemeManager = {
if (selectedThemeID) {
data = this.getUsedTheme(selectedThemeID);
}
return data;
},
get currentThemeForDisplay() {
var data = this.currentTheme;
+ if (!data && _fallbackThemeData)
+ data = _fallbackThemeData;
if (data && PERSIST_ENABLED) {
for (let key in PERSIST_FILES) {
try {
if (data[key] && _prefs.getBoolPref("persisted." + key))
data[key] = _getLocalImageURI(PERSIST_FILES[key]).spec
+ "?" + data.id + ";" + _version(data);
} catch (e) {}
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -7525,17 +7525,17 @@ AddonWrapper.prototype = {
},
set userDisabled(val) {
let addon = addonFor(this);
if (val == this.userDisabled) {
return val;
}
if (addon.inDatabase) {
- let theme = isTheme(addon.type)
+ let theme = isTheme(addon.type);
if (theme && val) {
if (addon.internalName == XPIProvider.defaultSkin)
throw new Error("Cannot disable the default theme");
XPIProvider.enableDefaultTheme();
}
if (!(theme && val) || isWebExtension(addon.type)) {
// hidden and system add-ons should not be user disasbled,
// as there is no UI to re-enable them.