Bug 1388211: Fold ExtensionAPI.jsm into ExtensionCommon.jsm. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Mon, 07 Aug 2017 17:58:14 -0700
changeset 642288 17589c1c9fe1bb38184ed2ece06bbad1516e820f
parent 642286 bc1aa25102b490619d53d3b26638a1ec17ab4070
child 642300 985267de01ba579c9928213eb99867d366ee2170
push id72697
push usermaglione.k@gmail.com
push dateTue, 08 Aug 2017 00:59:16 +0000
reviewersmixedpuppy
bugs1388211
milestone57.0a1
Bug 1388211: Fold ExtensionAPI.jsm into ExtensionCommon.jsm. r?mixedpuppy We always load one when we load the other, so there's no need for the overhead of a separate JSM. MozReview-Commit-ID: 8u4OhJJEN3b
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/ExtensionAPI.jsm
toolkit/components/extensions/ExtensionCommon.jsm
toolkit/components/extensions/moz.build
toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js
toolkit/mozapps/extensions/internal/APIExtensionBootstrap.js
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -46,18 +46,16 @@ Cu.import("resource://gre/modules/Servic
 XPCOMUtils.defineLazyPreferenceGetter(this, "processCount", "dom.ipc.processCount.extension");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
                                   "resource://gre/modules/AddonManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
                                   "resource://gre/modules/AddonManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
                                   "resource://gre/modules/AsyncShutdown.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ExtensionAPIs",
-                                  "resource://gre/modules/ExtensionAPI.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionCommon",
                                   "resource://gre/modules/ExtensionCommon.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionPermissions",
                                   "resource://gre/modules/ExtensionPermissions.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionStorage",
                                   "resource://gre/modules/ExtensionStorage.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionTestCommon",
                                   "resource://testing-common/ExtensionTestCommon.jsm");
@@ -966,17 +964,17 @@ this.Extension = class extends Extension
   loadManifest() {
     return super.loadManifest().then(manifest => {
       if (this.errors.length) {
         return Promise.reject({errors: this.errors});
       }
 
       // Load Experiments APIs that this extension depends on.
       return Promise.all(
-        Array.from(this.apiNames, api => ExtensionAPIs.load(api))
+        Array.from(this.apiNames, api => ExtensionCommon.ExtensionAPIs.load(api))
       ).then(apis => {
         for (let API of apis) {
           this.apis.push(new API(this));
         }
 
         return manifest;
       });
     });
deleted file mode 100644
--- a/toolkit/components/extensions/ExtensionAPI.jsm
+++ /dev/null
@@ -1,115 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["ExtensionAPI", "ExtensionAPIs"];
-
-/* exported ExtensionAPIs */
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPI",
-                                  "resource://gre/modules/Console.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Schemas",
-                                  "resource://gre/modules/Schemas.jsm");
-
-Cu.import("resource://gre/modules/ExtensionUtils.jsm");
-
-const global = this;
-
-class ExtensionAPI extends ExtensionUtils.EventEmitter {
-  constructor(extension) {
-    super();
-
-    this.extension = extension;
-
-    extension.once("shutdown", () => {
-      if (this.onShutdown) {
-        this.onShutdown(extension.shutdownReason);
-      }
-      this.extension = null;
-    });
-  }
-
-  destroy() {
-  }
-
-  onManifestEntry(entry) {
-  }
-
-  getAPI(context) {
-    throw new Error("Not Implemented");
-  }
-}
-
-var ExtensionAPIs = {
-  apis: new Map(),
-
-  load(apiName) {
-    let api = this.apis.get(apiName);
-
-    if (api.loadPromise) {
-      return api.loadPromise;
-    }
-
-    let {script, schema} = api;
-
-    let addonId = `${apiName}@experiments.addons.mozilla.org`;
-    api.sandbox = Cu.Sandbox(global, {
-      wantXrays: false,
-      sandboxName: script,
-      addonId,
-      metadata: {addonID: addonId},
-    });
-
-    api.sandbox.ExtensionAPI = ExtensionAPI;
-
-    // Create a console getter which lazily provide a ConsoleAPI instance.
-    XPCOMUtils.defineLazyGetter(api.sandbox, "console", () => {
-      return new ConsoleAPI({prefix: addonId});
-    });
-
-    Services.scriptloader.loadSubScript(script, api.sandbox, "UTF-8");
-
-    api.loadPromise = Schemas.load(schema).then(() => {
-      let API = Cu.evalInSandbox("API", api.sandbox);
-      API.prototype.namespace = apiName;
-      return API;
-    });
-
-    return api.loadPromise;
-  },
-
-  unload(apiName) {
-    let api = this.apis.get(apiName);
-
-    let {schema} = api;
-
-    Schemas.unload(schema);
-    Cu.nukeSandbox(api.sandbox);
-
-    api.sandbox = null;
-    api.loadPromise = null;
-  },
-
-  register(namespace, schema, script) {
-    if (this.apis.has(namespace)) {
-      throw new Error(`API namespace already exists: ${namespace}`);
-    }
-
-    this.apis.set(namespace, {schema, script});
-  },
-
-  unregister(namespace) {
-    if (!this.apis.has(namespace)) {
-      throw new Error(`API namespace does not exist: ${namespace}`);
-    }
-
-    this.apis.delete(namespace);
-  },
-};
--- a/toolkit/components/extensions/ExtensionCommon.jsm
+++ b/toolkit/components/extensions/ExtensionCommon.jsm
@@ -15,29 +15,33 @@ const {classes: Cc, interfaces: Ci, util
 
 this.EXPORTED_SYMBOLS = ["ExtensionCommon"];
 
 Cu.importGlobalProperties(["fetch"]);
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "ConsoleAPI",
+                                  "resource://gre/modules/Console.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "MessageChannel",
                                   "resource://gre/modules/MessageChannel.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
                                   "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
                                   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Schemas",
                                   "resource://gre/modules/Schemas.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "styleSheetService",
                                    "@mozilla.org/content/style-sheet-service;1",
                                    "nsIStyleSheetService");
 
+const global = this;
+
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 
 var {
   DefaultMap,
   DefaultWeakMap,
   EventEmitter,
   ExtensionError,
   defineLazyGetter,
@@ -79,16 +83,108 @@ class NoCloneSpreadArgs {
     this.unwrappedValues = args;
   }
 
   [Symbol.iterator]() {
     return this.unwrappedValues[Symbol.iterator]();
   }
 }
 
+class ExtensionAPI extends ExtensionUtils.EventEmitter {
+  constructor(extension) {
+    super();
+
+    this.extension = extension;
+
+    extension.once("shutdown", () => {
+      if (this.onShutdown) {
+        this.onShutdown(extension.shutdownReason);
+      }
+      this.extension = null;
+    });
+  }
+
+  destroy() {
+  }
+
+  onManifestEntry(entry) {
+  }
+
+  getAPI(context) {
+    throw new Error("Not Implemented");
+  }
+}
+
+var ExtensionAPIs = {
+  apis: new Map(),
+
+  load(apiName) {
+    let api = this.apis.get(apiName);
+
+    if (api.loadPromise) {
+      return api.loadPromise;
+    }
+
+    let {script, schema} = api;
+
+    let addonId = `${apiName}@experiments.addons.mozilla.org`;
+    api.sandbox = Cu.Sandbox(global, {
+      wantXrays: false,
+      sandboxName: script,
+      addonId,
+      metadata: {addonID: addonId},
+    });
+
+    api.sandbox.ExtensionAPI = ExtensionAPI;
+
+    // Create a console getter which lazily provide a ConsoleAPI instance.
+    XPCOMUtils.defineLazyGetter(api.sandbox, "console", () => {
+      return new ConsoleAPI({prefix: addonId});
+    });
+
+    Services.scriptloader.loadSubScript(script, api.sandbox, "UTF-8");
+
+    api.loadPromise = Schemas.load(schema).then(() => {
+      let API = Cu.evalInSandbox("API", api.sandbox);
+      API.prototype.namespace = apiName;
+      return API;
+    });
+
+    return api.loadPromise;
+  },
+
+  unload(apiName) {
+    let api = this.apis.get(apiName);
+
+    let {schema} = api;
+
+    Schemas.unload(schema);
+    Cu.nukeSandbox(api.sandbox);
+
+    api.sandbox = null;
+    api.loadPromise = null;
+  },
+
+  register(namespace, schema, script) {
+    if (this.apis.has(namespace)) {
+      throw new Error(`API namespace already exists: ${namespace}`);
+    }
+
+    this.apis.set(namespace, {schema, script});
+  },
+
+  unregister(namespace) {
+    if (!this.apis.has(namespace)) {
+      throw new Error(`API namespace does not exist: ${namespace}`);
+    }
+
+    this.apis.delete(namespace);
+  },
+};
+
 class BaseContext {
   constructor(envType, extension) {
     this.envType = envType;
     this.onClose = new Set();
     this.checkedLastError = false;
     this._lastError = null;
     this.contextId = getUniqueId();
     this.unloaded = false;
@@ -1150,20 +1246,19 @@ class SchemaAPIManager extends EventEmit
    * @returns {object} A sandbox that is used as the global by `loadScript`.
    */
   _createExtGlobal() {
     let global = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), {
       wantXrays: false,
       sandboxName: `Namespace of ext-*.js scripts for ${this.processType}`,
     });
 
-    Object.assign(global, {global, Cc, Ci, Cu, Cr, XPCOMUtils, ChromeWorker, ExtensionCommon, MatchPattern, MatchPatternSet, StructuredCloneHolder, extensions: this});
+    Object.assign(global, {global, Cc, Ci, Cu, Cr, XPCOMUtils, ChromeWorker, ExtensionAPI, ExtensionCommon, MatchPattern, MatchPatternSet, StructuredCloneHolder, extensions: this});
 
     Cu.import("resource://gre/modules/AppConstants.jsm", global);
-    Cu.import("resource://gre/modules/ExtensionAPI.jsm", global);
 
     XPCOMUtils.defineLazyGetter(global, "console", getConsole);
 
     XPCOMUtils.defineLazyModuleGetter(global, "ExtensionUtils",
                                       "resource://gre/modules/ExtensionUtils.jsm");
     XPCOMUtils.defineLazyModuleGetter(global, "XPCOMUtils",
                                       "resource://gre/modules/XPCOMUtils.jsm");
     XPCOMUtils.defineLazyModuleGetter(global, "require",
@@ -1559,16 +1654,18 @@ const stylesheetMap = new DefaultMap(url
   return styleSheetService.preloadSheet(uri, styleSheetService.AGENT_SHEET);
 });
 
 
 ExtensionCommon = {
   BaseContext,
   CanOfAPIs,
   EventManager,
+  ExtensionAPI,
+  ExtensionAPIs,
   LocalAPIImplementation,
   LocaleData,
   NoCloneSpreadArgs,
   SchemaAPIInterface,
   SchemaAPIManager,
   SpreadArgs,
   ignoreEvent,
   stylesheetMap,
--- a/toolkit/components/extensions/moz.build
+++ b/toolkit/components/extensions/moz.build
@@ -4,17 +4,16 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 with Files('**'):
     BUG_COMPONENT = ('Toolkit', 'WebExtensions: General')
 
 EXTRA_JS_MODULES += [
     'Extension.jsm',
-    'ExtensionAPI.jsm',
     'ExtensionChild.jsm',
     'ExtensionChildDevToolsUtils.jsm',
     'ExtensionCommon.jsm',
     'ExtensionContent.jsm',
     'ExtensionPageChild.jsm',
     'ExtensionParent.jsm',
     'ExtensionPermissions.jsm',
     'ExtensionPreferencesManager.jsm',
--- a/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
@@ -124,17 +124,17 @@ add_task(async function test_experiments
     Services.obs.removeObserver(observer, "webext-api-loaded");
     Services.obs.removeObserver(observer, "webext-api-hello");
   });
 
 
   // Install API add-on.
   let apiAddon = await AddonManager.installTemporaryAddon(apiAddonFile);
 
-  let {ExtensionAPIs} = Cu.import("resource://gre/modules/ExtensionAPI.jsm", {});
+  let {ExtensionAPIs} = Cu.import("resource://gre/modules/ExtensionCommon.jsm", {}).ExtensionCommon;
   ok(ExtensionAPIs.apis.has("meh"), "Should have meh API.");
 
 
   // Install boring WebExtension add-on.
   let boringAddon = await AddonManager.installTemporaryAddon(boringAddonFile);
   await AddonTestUtils.promiseWebExtensionStartup();
 
   // Install interesting WebExtension add-on.
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js
@@ -1,12 +1,14 @@
 "use strict";
 
-/* global ExtensionAPIs */
-Components.utils.import("resource://gre/modules/ExtensionAPI.jsm");
+Components.utils.import("resource://gre/modules/ExtensionCommon.jsm");
+
+const {ExtensionAPIs} = ExtensionCommon;
+
 const {ExtensionManager} = Components.utils.import("resource://gre/modules/ExtensionChild.jsm", {});
 
 Components.utils.importGlobalProperties(["Blob", "URL"]);
 
 let schema = [
   {
     namespace: "userinputtest",
     functions: [
--- a/toolkit/mozapps/extensions/internal/APIExtensionBootstrap.js
+++ b/toolkit/mozapps/extensions/internal/APIExtensionBootstrap.js
@@ -1,19 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /* exported startup, shutdown, install, uninstall, ExtensionAPIs */
 
-Components.utils.import("resource://gre/modules/ExtensionAPI.jsm");
+Components.utils.import("resource://gre/modules/ExtensionCommon.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
+const {ExtensionAPIs} = ExtensionCommon;
+
 var namespace;
 var resource;
 var resProto;
 
 function install(data, reason) {
 }
 
 function startup(data, reason) {