--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -1188,17 +1188,16 @@ class Extension extends ExtensionData {
this.onStartup = null;
this.hasShutdown = false;
this.onShutdown = new Set();
this.uninstallURL = null;
- this.apis = [];
this.whiteListedHosts = null;
this._optionalOrigins = null;
this.webAccessibleResources = null;
this.emitter = new EventEmitter();
/* eslint-disable mozilla/balanced-listeners */
this.on("add-permissions", (ignoreEvent, permissions) => {
@@ -1387,28 +1386,16 @@ class Extension extends ExtensionData {
async loadManifest() {
let manifest = await super.loadManifest();
if (this.errors.length) {
return Promise.reject({errors: this.errors});
}
- if (this.apiNames.size) {
- // Load Experiments APIs that this extension depends on.
- let apis = await Promise.all(
- Array.from(this.apiNames, api => ExtensionCommon.ExtensionAPIs.load(api)));
-
- for (let API of apis) {
- if (API) {
- this.apis.push(new API(this));
- }
- }
- }
-
return manifest;
}
// Representation of the extension to send to content
// processes. This should include anything the content process might
// need.
serialize() {
return {
@@ -1644,27 +1631,29 @@ class Extension extends ExtensionData {
this.emit("startup", this);
Management.emit("startup", this);
await this.runManifest(this.manifest);
Management.emit("ready", this);
this.emit("ready");
TelemetryStopwatch.finish("WEBEXT_EXTENSION_STARTUP_MS", this);
- } catch (e) {
- dump(`Extension error: ${e.message || e} ${e.filename || e.fileName}:${e.lineNumber} :: ${e.stack || new Error().stack}\n`);
- Cu.reportError(e);
+ } catch (errors) {
+ for (let e of [].concat(errors)) {
+ dump(`Extension error: ${e.message || e} ${e.filename || e.fileName}:${e.lineNumber} :: ${e.stack || new Error().stack}\n`);
+ Cu.reportError(e);
+ }
if (this.policy) {
this.policy.active = false;
}
this.cleanupGeneratedFile();
- throw e;
+ throw errors;
}
this.startupPromise = null;
}
cleanupGeneratedFile() {
if (!this.cleanupFile) {
return;
@@ -1755,20 +1744,16 @@ class Extension extends ExtensionData {
}
GlobalManager.uninit(this);
for (let obj of this.onShutdown) {
obj.close();
}
- for (let api of this.apis) {
- api.destroy();
- }
-
ParentAPIManager.shutdownExtension(this.id);
Management.emit("shutdown", this);
this.emit("shutdown");
await this.broadcast("Extension:Shutdown", {id: this.id});
MessageChannel.abortResponses({extensionId: this.id});
--- a/toolkit/components/extensions/ExtensionCommon.jsm
+++ b/toolkit/components/extensions/ExtensionCommon.jsm
@@ -27,18 +27,16 @@ XPCOMUtils.defineLazyModuleGetters(this,
Schemas: "resource://gre/modules/Schemas.jsm",
SchemaRoot: "resource://gre/modules/Schemas.jsm",
});
XPCOMUtils.defineLazyServiceGetter(this, "styleSheetService",
"@mozilla.org/content/style-sheet-service;1",
"nsIStyleSheetService");
-const global = Cu.getGlobalForObject(this);
-
ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
var {
DefaultMap,
DefaultWeakMap,
EventEmitter,
ExtensionError,
defineLazyGetter,
@@ -109,87 +107,16 @@ class ExtensionAPI extends ExtensionUtil
onManifestEntry(entry) {
}
getAPI(context) {
throw new Error("Not Implemented");
}
}
-var ExtensionAPIs = {
- apis: new Map(),
-
- load(apiName) {
- let api = this.apis.get(apiName);
- if (!api) {
- return null;
- }
-
- 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,
- wantGlobalProperties: ["ChromeUtils"],
- 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);
- },
-};
-
/**
* This class contains the information we have about an individual
* extension. It is never instantiated directly, instead subclasses
* for each type of process extend this class and add members that are
* relevant for that process.
* @abstract
*/
class BaseContext {
@@ -1417,36 +1344,16 @@ class SchemaAPIManager extends EventEmit
// in the sandbox's context instead of here.
let scope = Cu.createObjectIn(this.global);
Services.scriptloader.loadSubScript(scriptUrl, scope, "UTF-8");
// Save the scope to avoid it being garbage collected.
this._scriptScopes.push(scope);
}
-
- /**
- * Mash together all the APIs from `apis` into `obj`.
- *
- * @param {BaseContext} context The context for which the API bindings are
- * generated.
- * @param {Array} apis A list of objects, see `registerSchemaAPI`.
- * @param {object} obj The destination of the API.
- */
- static generateAPIs(context, apis, obj) {
- function hasPermission(perm) {
- return context.extension.hasPermission(perm, true);
- }
- for (let api of apis) {
- if (Schemas.checkPermissions(api.namespace, {hasPermission})) {
- api = api.getAPI(context);
- deepCopy(obj, api);
- }
- }
- }
}
class LazyAPIManager extends SchemaAPIManager {
constructor(processType, moduleData, schemaURLs) {
super(processType);
this.initialized = false;
@@ -1893,17 +1800,16 @@ const stylesheetMap = new DefaultMap(url
});
ExtensionCommon = {
BaseContext,
CanOfAPIs,
EventManager,
ExtensionAPI,
- ExtensionAPIs,
LocalAPIImplementation,
LocaleData,
NoCloneSpreadArgs,
SchemaAPIInterface,
SchemaAPIManager,
SpreadArgs,
ignoreEvent,
stylesheetMap,
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -424,20 +424,16 @@ GlobalManager = {
browser.messageManager.sendAsyncMessage("Extension:SetFrameData",
data);
}
},
getExtension(extensionId) {
return this.extensionMap.get(extensionId);
},
-
- injectInObject(context, isChromeCompat, dest) {
- SchemaAPIManager.generateAPIs(context, context.extension.apis, dest);
- },
};
/**
* The proxied parent side of a context in ExtensionChild.jsm, for the
* parent side of a proxied API.
*/
class ProxyContextParent extends BaseContext {
constructor(envType, extension, params, xulBrowser, principal) {
@@ -507,17 +503,16 @@ class ProxyContextParent extends BaseCon
super.unload();
apiManager.emit("proxy-context-unload", this);
}
}
defineLazyGetter(ProxyContextParent.prototype, "apiCan", function() {
let obj = {};
let can = new CanOfAPIs(this, this.extension.apiManager, obj);
- GlobalManager.injectInObject(this, false, obj);
return can;
});
defineLazyGetter(ProxyContextParent.prototype, "apiObj", function() {
return this.apiCan.root;
});
defineLazyGetter(ProxyContextParent.prototype, "sandbox", function() {
--- a/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_experiments.js
@@ -7,192 +7,16 @@ ChromeUtils.defineModuleGetter(this, "Ad
AddonTestUtils.init(this);
add_task(async function setup() {
AddonTestUtils.overrideCertDB();
await ExtensionTestUtils.startAddonManager();
});
-add_task(async function test_experiments_api() {
- let apiAddonFile = Extension.generateZipFile({
- "install.rdf": `<?xml version="1.0" encoding="UTF-8"?>
- <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
- <Description about="urn:mozilla:install-manifest"
- em:id="fooBar@experiments.addons.mozilla.org"
- em:name="FooBar Experiment"
- em:type="256"
- em:version="0.1"
- em:description="FooBar experiment"
- em:creator="Mozilla">
-
- <em:targetApplication>
- <Description
- em:id="xpcshell@tests.mozilla.org"
- em:minVersion="48"
- em:maxVersion="*"/>
- </em:targetApplication>
- </Description>
- </RDF>
- `,
-
- "api.js": String.raw`
- Components.utils.import("resource://gre/modules/Services.jsm");
-
- Services.obs.notifyObservers(null, "webext-api-loaded", "");
-
- class API extends ExtensionAPI {
- getAPI(context) {
- return {
- fooBar: {
- hello(text) {
- console.log('fooBar.hello API called', text);
- Services.obs.notifyObservers(null, "webext-api-hello", text);
- }
- }
- }
- }
- }
- `,
-
- "schema.json": [
- {
- "namespace": "fooBar",
- "description": "All full of fooBar.",
- "permissions": ["experiments.fooBar"],
- "functions": [
- {
- "name": "hello",
- "type": "function",
- "description": "Hates you. This is all.",
- "parameters": [
- {"type": "string", "name": "text"},
- ],
- },
- ],
- },
- ],
- });
-
- let addonFile = Extension.generateXPI({
- manifest: {
- applications: {gecko: {id: "fooBar@web.extension"}},
- permissions: ["experiments.fooBar"],
- },
-
- background() {
- // The test code below checks that hello() is called at the right
- // time with the string "Here I am". Verify that the api schema is
- // being correctly interpreted by calling hello() with bad arguments
- // and only calling hello() with the magic string if the call with
- // bad arguments throws.
- try {
- browser.fooBar.hello("I should not see this", "since two arguments are bad");
- } catch (err) {
- browser.fooBar.hello("Here I am");
- }
- },
- });
-
- let boringAddonFile = Extension.generateXPI({
- manifest: {
- applications: {gecko: {id: "boring@web.extension"}},
- },
- background() {
- if (browser.fooBar) {
- browser.fooBar.hello("Here I should not be");
- }
- },
- });
-
- registerCleanupFunction(() => {
- for (let file of [apiAddonFile, addonFile, boringAddonFile]) {
- Services.obs.notifyObservers(file, "flush-cache-entry");
- file.remove(false);
- }
- });
-
-
- let resolveHello;
- let observer = (subject, topic, data) => {
- if (topic == "webext-api-loaded") {
- ok(!!resolveHello, "Should not see API loaded until dependent extension loads");
- } else if (topic == "webext-api-hello") {
- resolveHello(data);
- }
- };
-
- Services.obs.addObserver(observer, "webext-api-loaded");
- Services.obs.addObserver(observer, "webext-api-hello");
- registerCleanupFunction(() => {
- 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} = ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm", {}).ExtensionCommon;
- ok(ExtensionAPIs.apis.has("fooBar"), "Should have fooBar API.");
-
-
- // Install boring WebExtension add-on.
- let boringAddon = await AddonManager.installTemporaryAddon(boringAddonFile);
- await AddonTestUtils.promiseWebExtensionStartup();
-
- // Install interesting WebExtension add-on.
- let promise = new Promise(resolve => {
- resolveHello = resolve;
- });
-
- let addon = await AddonManager.installTemporaryAddon(addonFile);
- await AddonTestUtils.promiseWebExtensionStartup();
-
- let hello = await promise;
- equal(hello, "Here I am", "Should get hello from add-on");
-
- // Install management test add-on.
- let managementAddon = ExtensionTestUtils.loadExtension({
- manifest: {
- applications: {gecko: {id: "management@web.extension"}},
- permissions: ["management"],
- },
- async background() {
- // Should find the simple extension.
- let normalAddon = await browser.management.get("boring@web.extension");
- browser.test.assertEq(normalAddon.id, "boring@web.extension", "Found boring addon");
-
- try {
- // Not allowed to get the API experiment.
- await browser.management.get("fooBar@experiments.addons.mozilla.org");
- } catch (e) {
- browser.test.sendMessage("done");
- }
- },
- useAddonManager: "temporary",
- });
-
- await managementAddon.startup();
- await managementAddon.awaitMessage("done");
- await managementAddon.unload();
-
- // Cleanup.
- apiAddon.uninstall();
-
- boringAddon.userDisabled = true;
- await new Promise(executeSoon);
-
- equal(addon.appDisabled, true, "Add-on should be app-disabled after its dependency is removed.");
-
- addon.uninstall();
- boringAddon.uninstall();
-});
-
let fooExperimentAPIs = {
foo: {
schema: "schema.json",
parent: {
scopes: ["addon_parent"],
script: "parent.js",
paths: [["experiments", "foo", "parent"]],
},
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_interactive.js
@@ -1,44 +1,79 @@
"use strict";
-ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
-
-const {ExtensionAPI, ExtensionAPIs} = ExtensionCommon;
-
const {ExtensionManager} = ChromeUtils.import("resource://gre/modules/ExtensionChild.jsm", {});
Cu.importGlobalProperties(["Blob", "URL"]);
-let schema = [
- {
- namespace: "userinputtest",
- functions: [
- {
- name: "test",
- type: "function",
- async: true,
- requireUserInput: true,
- parameters: [],
- },
- ],
+let experimentAPIs = {
+ userinputtest: {
+ schema: "schema.json",
+ parent: {
+ scopes: ["addon_parent"],
+ script: "parent.js",
+ paths: [["userinputtest"]],
+ },
+ child: {
+ scopes: ["addon_child"],
+ script: "child.js",
+ paths: [["userinputtest", "child"]],
+ },
},
-];
+};
+
+let experimentFiles = {
+ "schema.json": JSON.stringify([
+ {
+ namespace: "userinputtest",
+ functions: [
+ {
+ name: "test",
+ type: "function",
+ async: true,
+ requireUserInput: true,
+ parameters: [],
+ },
+ {
+ name: "child",
+ type: "function",
+ async: true,
+ requireUserInput: true,
+ parameters: [],
+ },
+ ],
+ },
+ ]),
-class API extends ExtensionAPI {
- getAPI(context) {
- return {
- userinputtest: {
- test() {},
- },
+ /* globals ExtensionAPI */
+ "parent.js": () => {
+ this.userinputtest = class extends ExtensionAPI {
+ getAPI(context) {
+ return {
+ userinputtest: {
+ test() {},
+ },
+ };
+ }
};
- }
-}
+ },
-let schemaUrl = `data:,${JSON.stringify(schema)}`;
+ /* globals ExtensionAPI */
+ "child.js": () => {
+ this.userinputtest = class extends ExtensionAPI {
+ getAPI(context) {
+ return {
+ userinputtest: {
+ child() {},
+ },
+ };
+ }
+ };
+ },
+};
// Set the "handlingUserInput" flag for the given extension's background page.
// Returns an RAIIHelper that should be destruct()ed eventually.
function setHandlingUserInput(extension) {
let extensionChild = ExtensionManager.extensions.get(extension.extension.id);
let bgwin = null;
for (let view of extensionChild.views) {
if (view.viewType == "background") {
@@ -50,88 +85,77 @@ function setHandlingUserInput(extension)
let winutils = bgwin.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
return winutils.setHandlingUserInput(true);
}
// Test that the schema requireUserInput flag works correctly for
// proxied api implementations.
add_task(async function test_proxy() {
- let apiUrl = URL.createObjectURL(new Blob([API.toString()]));
- ExtensionAPIs.register("userinputtest", schemaUrl, apiUrl);
-
let extension = ExtensionTestUtils.loadExtension({
background() {
browser.test.onMessage.addListener(async () => {
try {
await browser.userinputtest.test();
browser.test.sendMessage("result", null);
} catch (err) {
browser.test.sendMessage("result", err.message);
}
});
},
manifest: {
permissions: ["experiments.userinputtest"],
+ experiment_apis: experimentAPIs,
},
+ files: experimentFiles,
});
await extension.startup();
extension.sendMessage("test");
let result = await extension.awaitMessage("result");
ok(/test may only be called from a user input handler/.test(result),
- "function failed when not called from a user input handler");
-
- let handle = setHandlingUserInput(extension);
- extension.sendMessage("test");
- result = await extension.awaitMessage("result");
- equal(result, null, "function succeeded when called from a user input handler");
- handle.destruct();
-
- await extension.unload();
- ExtensionAPIs.unregister("userinputtest");
-});
-
-// Test that the schema requireUserInput flag works correctly for
-// non-proxied api implementations.
-add_task(async function test_local() {
- let apiString = `this.userinputtest = ${API.toString()};`;
- let apiUrl = URL.createObjectURL(new Blob([apiString]));
- await Schemas.load(schemaUrl);
- const {apiManager} = ChromeUtils.import("resource://gre/modules/ExtensionPageChild.jsm", {});
- apiManager.registerModules({
- userinputtest: {
- url: apiUrl,
- scopes: ["addon_child"],
- paths: [["userinputtest"]],
- },
- });
-
- let extension = ExtensionTestUtils.loadExtension({
- background() {
- browser.test.onMessage.addListener(async () => {
- try {
- await browser.userinputtest.test();
- browser.test.sendMessage("result", null);
- } catch (err) {
- browser.test.sendMessage("result", err.message);
- }
- });
- },
- manifest: {},
- });
-
- await extension.startup();
-
- extension.sendMessage("test");
- let result = await extension.awaitMessage("result");
- ok(/test may only be called from a user input handler/.test(result),
- "function failed when not called from a user input handler");
+ `function failed when not called from a user input handler: ${result}`);
let handle = setHandlingUserInput(extension);
extension.sendMessage("test");
result = await extension.awaitMessage("result");
equal(result, null, "function succeeded when called from a user input handler");
handle.destruct();
await extension.unload();
});
+
+// Test that the schema requireUserInput flag works correctly for
+// non-proxied api implementations.
+add_task(async function test_local() {
+ let extension = ExtensionTestUtils.loadExtension({
+ background() {
+ browser.test.onMessage.addListener(async () => {
+ try {
+ await browser.userinputtest.child();
+ browser.test.sendMessage("result", null);
+ } catch (err) {
+ browser.test.sendMessage("result", err.message);
+ }
+ });
+ },
+ manifest: {
+ experiment_apis: experimentAPIs,
+ },
+ files: experimentFiles,
+ });
+
+ await extension.startup();
+
+ extension.sendMessage("test");
+ let result = await extension.awaitMessage("result");
+ ok(/child may only be called from a user input handler/.test(result),
+ `function failed when not called from a user input handler: ${result}`);
+
+ let handle = setHandlingUserInput(extension);
+ extension.sendMessage("test");
+ result = await extension.awaitMessage("result");
+ equal(result, null, "function succeeded when called from a user input handler");
+ handle.destruct();
+
+ await extension.unload();
+});
deleted file mode 100644
--- a/toolkit/mozapps/extensions/internal/APIExtensionBootstrap.js
+++ /dev/null
@@ -1,43 +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";
-
-/* exported startup, shutdown, install, uninstall, ExtensionAPIs */
-
-ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-const {ExtensionAPIs} = ExtensionCommon;
-
-var namespace;
-var resource;
-var resProto;
-
-function install(data, reason) {
-}
-
-function startup(data, reason) {
- namespace = data.id.replace(/@.*/, "");
- resource = `extension-${namespace.toLowerCase()}-api`;
-
- resProto = Services.io.getProtocolHandler("resource")
- .QueryInterface(Ci.nsIResProtocolHandler);
-
- resProto.setSubstitution(resource, data.resourceURI);
-
- ExtensionAPIs.register(
- namespace,
- `resource://${resource}/schema.json`,
- `resource://${resource}/api.js`);
-}
-
-function shutdown(data, reason) {
- resProto.setSubstitution(resource, null);
-
- ExtensionAPIs.unregister(namespace);
-}
-
-function uninstall(data, reason) {
-}
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -135,31 +135,30 @@ const PROP_METADATA = ["id", "versi
const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"];
const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
// Map new string type identifiers to old style nsIUpdateItem types.
// Retired values:
// 32 = multipackage xpi file
// 8 = locale
+// 256 = apiextension
const TYPES = {
extension: 2,
theme: 4,
dictionary: 64,
experiment: 128,
- apiextension: 256,
};
const COMPATIBLE_BY_DEFAULT_TYPES = {
extension: true,
dictionary: true,
};
const RESTARTLESS_TYPES = new Set([
- "apiextension",
"dictionary",
"experiment",
"webextension",
"webextension-theme",
]);
// This is a random number array that can be used as "salt" when generating
// an automatic ID based on the directory path of an add-on. It will prevent
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -188,38 +188,35 @@ const BOOTSTRAP_REASONS = {
ADDON_UNINSTALL: 6,
ADDON_UPGRADE: 7,
ADDON_DOWNGRADE: 8
};
// Some add-on types that we track internally are presented as other types
// externally
const TYPE_ALIASES = {
- "apiextension": "extension",
"webextension": "extension",
"webextension-theme": "theme",
"webextension-langpack": "locale",
};
const CHROME_TYPES = new Set([
"extension",
"experiment",
]);
const SIGNED_TYPES = new Set([
- "apiextension",
"extension",
"experiment",
"webextension",
"webextension-langpack",
"webextension-theme",
]);
const LEGACY_TYPES = new Set([
- "apiextension",
"extension",
"theme",
]);
const ALL_EXTERNAL_TYPES = new Set([
"dictionary",
"extension",
"experiment",
@@ -3796,18 +3793,16 @@ var XPIProvider = {
if (isWebExtension(aType)) {
activeAddon.bootstrapScope = Extension.getBootstrapScope(aId, aFile);
} else if (aType === "webextension-langpack") {
activeAddon.bootstrapScope = Langpack.getBootstrapScope(aId, aFile);
} else {
let uri = getURIForResourceInFile(aFile, "bootstrap.js").spec;
if (aType == "dictionary")
uri = "resource://gre/modules/addons/SpellCheckDictionaryBootstrap.js";
- else if (aType == "apiextension")
- uri = "resource://gre/modules/addons/APIExtensionBootstrap.js";
activeAddon.bootstrapScope =
new Cu.Sandbox(principal, { sandboxName: uri,
addonId: aId,
wantGlobalProperties: ["ChromeUtils"],
metadata: { addonID: aId, URI: uri } });
try {
@@ -4767,20 +4762,16 @@ AddonWrapper.prototype = {
get type() {
return getExternalType(addonFor(this).type);
},
get isWebExtension() {
return isWebExtension(addonFor(this).type);
},
- get isAPIExtension() {
- return addonFor(this).type == "apiextension";
- },
-
get temporarilyInstalled() {
return addonFor(this)._installLocation == TemporaryInstallLocation;
},
get aboutURL() {
return this.isActive ? addonFor(this).aboutURL : null;
},
--- a/toolkit/mozapps/extensions/internal/moz.build
+++ b/toolkit/mozapps/extensions/internal/moz.build
@@ -3,17 +3,16 @@
# 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/.
EXTRA_JS_MODULES.addons += [
'AddonRepository.jsm',
'AddonSettings.jsm',
'AddonUpdateChecker.jsm',
- 'APIExtensionBootstrap.js',
'Content.js',
'GMPProvider.jsm',
'LightweightThemeImageOptimizer.jsm',
'ProductAddonChecker.jsm',
'SpellCheckDictionaryBootstrap.js',
'UpdateRDFConverter.jsm',
'XPIInstall.jsm',
'XPIProvider.jsm',
--- a/toolkit/mozapps/extensions/test/xpcshell/test_legacy.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_legacy.js
@@ -7,22 +7,16 @@ startupManager();
add_task(async function test_disable() {
let legacy = [
{
id: "bootstrap@tests.mozilla.org",
name: "Bootstrap add-on",
version: "1.0",
bootstrap: true,
},
- {
- id: "apiexperiment@tests.mozilla.org",
- name: "WebExtension Experiment",
- version: "1.0",
- type: 256,
- },
];
let nonLegacy = [
{
id: "webextension@tests.mozilla.org",
manifest: {
applications: {gecko: {id: "webextension@tests.mozilla.org"}},
},
--- a/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js
@@ -753,42 +753,8 @@ add_task(async function() {
await promiseInstallAllFiles([do_get_addon("test_bootstrap1_1")], true);
const addon = await promiseAddonByID(ID);
notEqual(addon, null);
equal(addon.temporarilyInstalled, false);
await promiseRestartManager();
});
-
-// Check that WebExtensions experiments can only be installed temporarily
-// in builds that allow legacy extensions.
-add_task(async function() {
- AddonTestUtils.usePrivilegedSignatures = false;
-
- const API_ID = "apiexperiment@tests.mozilla.org";
- let xpi = createTempXPIFile({
- id: API_ID,
- name: "WebExtension Experiment",
- version: "1.0",
- type: 256,
- targetApplications: [{
- id: "xpcshell@tests.mozilla.org",
- minVersion: "1",
- maxVersion: "1"
- }],
- });
-
- let addon = null;
- try {
- await AddonManager.installTemporaryAddon(xpi);
- addon = await promiseAddonByID(API_ID);
- } catch (err) {
- // fall through, level addon null
- }
-
- if (AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS) {
- notEqual(addon, null, "Temporary install of WebExtension experiment succeeded");
- addon.uninstall();
- } else {
- equal(addon, null, "Temporary install of WebExtension experiment was not allowed");
- }
-});
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js
@@ -295,39 +295,16 @@ add_task(async function test_experiments
deepEqual(addon.dependencies, ["meh@experiments.addons.mozilla.org"],
"Addon should have the expected dependencies");
equal(addon.appDisabled, true, "Add-on should be app disabled due to missing dependencies");
addon.uninstall();
});
-// Test that experiments API extensions install correctly.
-add_task(async function test_experiments_api() {
- const extensionId = "meh@experiments.addons.mozilla.org";
-
- let addonFile = createTempXPIFile({
- id: extensionId,
- type: 256,
- version: "0.1",
- name: "Meh API",
- });
-
- await promiseInstallAllFiles([addonFile]);
-
- let addons = await AddonManager.getAddonsByTypes(["extension"]);
- let addon = addons.pop();
- equal(addon.id, extensionId, "Add-on should be installed as an API extension");
-
- addons = await AddonManager.getAddonsByTypes(["extension"]);
- equal(addons.pop().id, extensionId, "Add-on type should be aliased to extension");
-
- addon.uninstall();
-});
-
add_task(async function developerShouldOverride() {
let addon = await promiseInstallWebExtension({
manifest: {
default_locale: "en",
developer: {
name: "__MSG_name__",
url: "__MSG_url__"
},