Bug 1387899: Part 1 - Cache browserAction icon data for startup. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 06 Aug 2017 16:12:14 -0700
changeset 641401 094d227a2f6ea2aa357b2c29925a5737a398c0c8
parent 641399 502eab2879b44db9cbfe7c67b25638fbd54dadc4
child 641402 78851ac803c7a1924c96a2b9764f1fbbe7e01a70
push id72507
push usermaglione.k@gmail.com
push dateSun, 06 Aug 2017 23:17:53 +0000
reviewersmixedpuppy
bugs1387899
milestone57.0a1
Bug 1387899: Part 1 - Cache browserAction icon data for startup. r?mixedpuppy MozReview-Commit-ID: 57ANCciibCn
browser/components/extensions/ext-browserAction.js
toolkit/components/extensions/ExtensionParent.jsm
--- 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) {