--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -115,17 +115,16 @@ const COMMENT_REGEXP = new RegExp(String
var scriptScope = this;
var ExtensionContext, GlobalManager;
// This object loads the ext-*.js scripts that define the extension API.
var Management = {
initialized: null,
scopes: [],
- apis: [],
schemaApis: [],
emitter: new EventEmitter(),
// Loads all the ext-*.js scripts currently registered.
lazyInit() {
if (this.initialized) {
return this.initialized;
}
@@ -157,37 +156,35 @@ var Management = {
// Save the scope to avoid it being garbage collected.
this.scopes.push(scope);
}
this.initialized = promise;
return this.initialized;
},
- // Called by an ext-*.js script to register an API. The |api|
- // parameter should be an object of the form:
- // {
- // tabs: {
- // create: ...,
- // onCreated: ...
- // }
- // }
- // This registers tabs.create and tabs.onCreated as part of the API.
- registerAPI(api) {
- this.apis.push({api});
- },
-
- // Same as above, but only register the API is the add-on has the
- // given permission.
- registerPrivilegedAPI(permission, api) {
- this.apis.push({api, permission});
- },
-
- registerSchemaAPI(namespace, api) {
- this.schemaApis.push({namespace, api});
+ /**
+ * Called by an ext-*.js script to register an API.
+ *
+ * @param {string} namespace The API namespace.
+ * Used to determine whether the API should be generated when the caller
+ * requests a subset of the available APIs (e.g. in content scripts).
+ * @param {function(BaseContext)} getAPI A function that returns an object
+ * that will be merged with |chrome| and |browser|. The next example adds
+ * the create, update and remove methods to the tabs API.
+ *
+ * registerSchemaAPI("tabs", (context) => ({
+ * tabs: { create, update },
+ * }));
+ * registerSchemaAPI("tabs", (context) => ({
+ * tabs: { remove },
+ * }));
+ */
+ registerSchemaAPI(namespace, getAPI) {
+ this.schemaApis.push({namespace, getAPI});
},
// Mash together into a single object all the APIs registered by the
// functions above. Return the merged object.
generateAPIs(context, apis, namespaces = null) {
let obj = {};
// Recursively copy properties from source to dest.
@@ -210,24 +207,19 @@ var Management = {
continue;
}
if (api.permission) {
if (!context.extension.hasPermission(api.permission)) {
continue;
}
}
- api = api.api(context);
+ api = api.getAPI(context);
copy(obj, api);
}
-
- for (let api of context.extension.apis) {
- copy(obj, api.getAPI(context));
- }
-
return obj;
},
// The ext-*.js scripts can ask to be notified for certain hooks.
on(hook, callback) {
this.emitter.on(hook, callback);
},
@@ -630,19 +622,16 @@ GlobalManager = {
}
},
getExtension(extensionId) {
return this.extensionMap.get(extensionId);
},
injectInObject(context, defaultCallback, dest, namespaces = null) {
- let api = Management.generateAPIs(context, Management.apis, namespaces);
- injectAPI(api, dest);
-
let schemaApi = Management.generateAPIs(context, Management.schemaApis, namespaces);
// Add in any extra API namespaces which do not have implementations
// outside of their schema file.
schemaApi.extensionTypes = {};
let schemaWrapper = {
get principal() {
@@ -704,16 +693,19 @@ GlobalManager = {
removeListener(path, name, listener) {
return findPathInObject(schemaApi, path)[name].removeListener.call(null, listener);
},
hasListener(path, name, listener) {
return findPathInObject(schemaApi, path)[name].hasListener.call(null, listener);
},
};
Schemas.inject(dest, schemaWrapper);
+
+ let experimentalApis = Management.generateAPIs(context, context.extension.apis, namespaces);
+ injectAPI(experimentalApis, dest);
},
observe(document, topic, data) {
let contentWindow = document.defaultView;
if (!contentWindow) {
return;
}
--- a/toolkit/components/extensions/ExtensionAPI.jsm
+++ b/toolkit/components/extensions/ExtensionAPI.jsm
@@ -43,17 +43,17 @@ var ExtensionAPIs = {
let api = this.apis.get(apiName);
if (api.loadPromise) {
return api.loadPromise;
}
let {script, schema} = api;
- let addonId = `${api}@experiments.addons.mozilla.org`;
+ let addonId = `${apiName}@experiments.addons.mozilla.org`;
api.sandbox = Cu.Sandbox(global, {
wantXrays: false,
sandboxName: script,
addonId,
metadata: {addonID: addonId},
});
api.sandbox.ExtensionAPI = ExtensionAPI;