Bug 1387899: Part 1 - Cache browserAction icon data for startup. r?mixedpuppy
MozReview-Commit-ID: 57ANCciibCn
--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -26,16 +26,17 @@ XPCOMUtils.defineLazyServiceGetter(this,
var {
DefaultWeakMap,
} = ExtensionUtils;
Cu.import("resource://gre/modules/ExtensionParent.jsm");
var {
IconDetails,
+ StartupCache,
} = ExtensionParent;
const POPUP_PRELOAD_TIMEOUT_MS = 200;
const POPUP_OPEN_MS_HISTOGRAM = "WEBEXT_BROWSERACTION_POPUP_OPEN_MS";
const POPUP_RESULT_HISTOGRAM = "WEBEXT_BROWSERACTION_POPUP_PRELOAD_RESULT_COUNT";
var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@@ -60,17 +61,17 @@ XPCOMUtils.defineLazyGetter(this, "brows
};
});
this.browserAction = class extends ExtensionAPI {
static for(extension) {
return browserActionMap.get(extension);
}
- onManifestEntry(entryName) {
+ async onManifestEntry(entryName) {
let {extension} = this;
let options = extension.manifest.browser_action;
this.iconData = new DefaultWeakMap(icons => this.getIconData(icons));
let widgetId = makeWidgetId(extension.id);
this.id = `${widgetId}-browser-action`;
@@ -83,35 +84,45 @@ this.browserAction = class extends Exten
this.tabManager = extension.tabManager;
this.defaults = {
enabled: true,
title: options.default_title || extension.name,
badgeText: "",
badgeBackgroundColor: null,
- icon: IconDetails.normalize({
- path: options.default_icon,
- themeIcons: options.theme_icons,
- }, extension),
popup: options.default_popup || "",
area: browserAreas[options.default_area || "navbar"],
};
this.browserStyle = options.browser_style || false;
if (options.browser_style === null) {
this.extension.logger.warn("Please specify whether you want browser_style " +
"or not in your browser_action options.");
}
+ browserActionMap.set(extension, this);
+
+ this.defaults.icon = await StartupCache.get(
+ extension, ["browserAction", "default_icon"],
+ () => IconDetails.normalize({
+ path: options.default_icon,
+ themeIcons: options.theme_icons,
+ }, extension));
+
+ this.iconData.set(
+ this.defaults.icon,
+ await StartupCache.get(
+ extension, ["browserAction", "default_icon_data"],
+ () => this.getIconData(this.defaults.icon)));
+
this.tabContext = new TabContext(tab => Object.create(this.defaults),
extension);
this.build();
- browserActionMap.set(extension, this);
}
onShutdown(reason) {
browserActionMap.delete(this.extension);
this.tabContext.shutdown();
CustomizableUI.destroyWidget(this.id);
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -1359,17 +1359,17 @@ let IconDetails = {
escapeUrl(url) {
return url.replace(/[\\\s"]/g, encodeURIComponent);
},
};
let StartupCache = {
DB_NAME: "ExtensionStartupCache",
- STORE_NAMES: Object.freeze(["locales", "manifests", "permissions", "schemas"]),
+ STORE_NAMES: Object.freeze(["general", "locales", "manifests", "permissions", "schemas"]),
get file() {
return FileUtils.getFile("ProfLD", ["startupCache", "webext.sc.lz4"]);
},
get saver() {
if (!this._saver) {
this._saver = new DeferredSave(this.file.path,
@@ -1408,31 +1408,41 @@ let StartupCache = {
if (!this._dataPromise) {
this._dataPromise = this._readData();
}
return this._dataPromise;
},
clearAddonData(id) {
return Promise.all([
+ this.general.delete(id),
this.locales.delete(id),
this.manifests.delete(id),
this.permissions.delete(id),
]).catch(e => {
// Ignore the error. It happens when we try to flush the add-on
// data after the AddonManager has flushed the entire startup cache.
});
},
observe(subject, topic, data) {
if (topic === "startupcache-invalidate") {
this._data = new Map();
this._dataPromise = Promise.resolve(this._data);
}
},
+
+ get(extension, path, createFunc) {
+ return this.general.get([extension.id, extension.version, ...path],
+ createFunc);
+ },
+
+ delete(extension, path) {
+ return this.general.delete([extension.id, extension.version, ...path]);
+ },
};
// void StartupCache.dataPromise;
Services.obs.addObserver(StartupCache, "startupcache-invalidate");
class CacheStore {
constructor(storeName) {