Bug 1385880: Part 1 - Remove WebExtensionBootstrap.js. r?aswan
MozReview-Commit-ID: X4JoEC61TF
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -42,16 +42,18 @@ Cu.import("resource://gre/modules/XPCOMU
Cu.import("resource://gre/modules/Services.jsm");
/* globals processCount */
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");
@@ -745,16 +747,46 @@ this.ExtensionData = class {
return results[0];
}
};
const PROXIED_EVENTS = new Set(["test-harness-message", "add-permissions", "remove-permissions"]);
const shutdownPromises = new Map();
+class BootstrapScope {
+ install(data, reason) {}
+ uninstall(data, reason) {}
+
+ startup(data, reason) {
+ this.extension = new Extension(data, this.BOOTSTRAP_REASON_TO_STRING_MAP[reason]);
+ this.extension.startup();
+ }
+
+ shutdown(data, reason) {
+ this.extension.shutdown(this.BOOTSTRAP_REASON_TO_STRING_MAP[reason]);
+ this.extension = null;
+ }
+}
+
+XPCOMUtils.defineLazyGetter(BootstrapScope.prototype, "BOOTSTRAP_REASON_TO_STRING_MAP", () => {
+ const {BOOTSTRAP_REASONS} = AddonManagerPrivate;
+
+ return Object.freeze({
+ [BOOTSTRAP_REASONS.APP_STARTUP]: "APP_STARTUP",
+ [BOOTSTRAP_REASONS.APP_SHUTDOWN]: "APP_SHUTDOWN",
+ [BOOTSTRAP_REASONS.ADDON_ENABLE]: "ADDON_ENABLE",
+ [BOOTSTRAP_REASONS.ADDON_DISABLE]: "ADDON_DISABLE",
+ [BOOTSTRAP_REASONS.ADDON_INSTALL]: "ADDON_INSTALL",
+ [BOOTSTRAP_REASONS.ADDON_UNINSTALL]: "ADDON_UNINSTALL",
+ [BOOTSTRAP_REASONS.ADDON_UPGRADE]: "ADDON_UPGRADE",
+ [BOOTSTRAP_REASONS.ADDON_DOWNGRADE]: "ADDON_DOWNGRADE",
+ });
+});
+
// We create one instance of this class per extension. |addonData|
// comes directly from bootstrap.js when initializing.
this.Extension = class extends ExtensionData {
constructor(addonData, startupReason) {
super(addonData.resourceURI);
this.uuid = UUIDMap.get(addonData.id);
this.instanceId = getUniqueId();
@@ -835,16 +867,20 @@ this.Extension = class extends Extension
.filter(host => !origins.includes(host.pattern)));
this.policy.permissions = Array.from(this.permissions);
this.policy.allowedOrigins = this.whiteListedHosts;
});
/* eslint-enable mozilla/balanced-listeners */
}
+ static getBootstrapScope(id, file) {
+ return new BootstrapScope();
+ }
+
get groupFrameLoader() {
let frameLoader = this._backgroundPageFrameLoader;
for (let view of this.views) {
if (view.viewType === "background" && view.xulBrowser) {
return view.xulBrowser.frameLoader;
}
if (!frameLoader && view.xulBrowser) {
frameLoader = view.xulBrowser.frameLoader;
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -3170,16 +3170,21 @@ this.AddonManagerPrivate = {
AddonAuthor,
AddonScreenshot,
AddonCompatibilityOverride,
AddonType,
+ get BOOTSTRAP_REASONS() {
+ return AddonManagerInternal._getProviderByName("XPIProvider")
+ .BOOTSTRAP_REASONS;
+ },
+
recordTimestamp(name, value) {
AddonManagerInternal.recordTimestamp(name, value);
},
_simpleMeasures: {},
recordSimpleMeasure(name, value) {
this._simpleMeasures[name] = value;
},
deleted file mode 100644
--- a/toolkit/mozapps/extensions/internal/WebExtensionBootstrap.js
+++ /dev/null
@@ -1,38 +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 */
-
-Components.utils.import("resource://gre/modules/Extension.jsm");
-
-var extension;
-
-const BOOTSTRAP_REASON_TO_STRING_MAP = {
- [this.APP_STARTUP]: "APP_STARTUP",
- [this.APP_SHUTDOWN]: "APP_SHUTDOWN",
- [this.ADDON_ENABLE]: "ADDON_ENABLE",
- [this.ADDON_DISABLE]: "ADDON_DISABLE",
- [this.ADDON_INSTALL]: "ADDON_INSTALL",
- [this.ADDON_UNINSTALL]: "ADDON_UNINSTALL",
- [this.ADDON_UPGRADE]: "ADDON_UPGRADE",
- [this.ADDON_DOWNGRADE]: "ADDON_DOWNGRADE",
-};
-
-function install(data, reason) {
-}
-
-function startup(data, reason) {
- extension = new Extension(data, BOOTSTRAP_REASON_TO_STRING_MAP[reason]);
- extension.startup();
-}
-
-function shutdown(data, reason) {
- extension.shutdown(BOOTSTRAP_REASON_TO_STRING_MAP[reason]);
- extension = null;
-}
-
-function uninstall(data, reason) {
-}
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -20,16 +20,18 @@ Cu.import("resource://gre/modules/AddonM
XPCOMUtils.defineLazyModuleGetter(this, "AddonRepository",
"resource://gre/modules/addons/AddonRepository.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonSettings",
"resource://gre/modules/addons/AddonSettings.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ChromeManifestParser",
"resource://gre/modules/ChromeManifestParser.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Extension",
+ "resource://gre/modules/Extension.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
"resource://gre/modules/LightweightThemeManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Locale",
"resource://gre/modules/Locale.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ZipUtils",
"resource://gre/modules/ZipUtils.jsm");
@@ -1794,16 +1796,18 @@ this.XPIStates = {
},
};
this.XPIProvider = {
get name() {
return "XPIProvider";
},
+ BOOTSTRAP_REASONS: Object.freeze(BOOTSTRAP_REASONS),
+
// An array of known install locations
installLocations: null,
// A dictionary of known install locations by name
installLocationsByName: null,
// An array of currently active AddonInstalls
installs: null,
// The default skin for the application
defaultSkin: "classic/1.0",
@@ -4222,47 +4226,49 @@ this.XPIProvider = {
new Cu.Sandbox(principal, { sandboxName: aFile.path,
wantGlobalProperties: ["indexedDB"],
addonId: aId,
metadata: { addonID: aId } });
logger.error("Attempted to load bootstrap scope from missing directory " + aFile.path);
return;
}
- let uri = getURIForResourceInFile(aFile, "bootstrap.js").spec;
- if (aType == "dictionary")
- uri = "resource://gre/modules/addons/SpellCheckDictionaryBootstrap.js"
- else if (isWebExtension(aType))
- uri = "resource://gre/modules/addons/WebExtensionBootstrap.js"
- else if (aType == "apiextension")
- uri = "resource://gre/modules/addons/APIExtensionBootstrap.js"
-
- activeAddon.bootstrapScope =
- new Cu.Sandbox(principal, { sandboxName: uri,
- wantGlobalProperties: ["indexedDB"],
- addonId: aId,
- metadata: { addonID: aId, URI: uri } });
-
- try {
- // Copy the reason values from the global object into the bootstrap scope.
- for (let name in BOOTSTRAP_REASONS)
- activeAddon.bootstrapScope[name] = BOOTSTRAP_REASONS[name];
-
- // Add other stuff that extensions want.
- Object.assign(activeAddon.bootstrapScope, {Worker, ChromeWorker});
-
- // Define a console for the add-on
- XPCOMUtils.defineLazyGetter(
- activeAddon.bootstrapScope, "console",
- () => new ConsoleAPI({ consoleID: "addon/" + aId }));
-
- activeAddon.bootstrapScope.__SCRIPT_URI_SPEC__ = uri;
- Services.scriptloader.loadSubScript(uri, activeAddon.bootstrapScope);
- } catch (e) {
- logger.warn("Error loading bootstrap.js for " + aId, e);
+ if (isWebExtension(aType)) {
+ activeAddon.bootstrapScope = Extension.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,
+ wantGlobalProperties: ["indexedDB"],
+ addonId: aId,
+ metadata: { addonID: aId, URI: uri } });
+
+ try {
+ // Copy the reason values from the global object into the bootstrap scope.
+ for (let name in BOOTSTRAP_REASONS)
+ activeAddon.bootstrapScope[name] = BOOTSTRAP_REASONS[name];
+
+ // Add other stuff that extensions want.
+ Object.assign(activeAddon.bootstrapScope, {Worker, ChromeWorker});
+
+ // Define a console for the add-on
+ XPCOMUtils.defineLazyGetter(
+ activeAddon.bootstrapScope, "console",
+ () => new ConsoleAPI({ consoleID: "addon/" + aId }));
+
+ activeAddon.bootstrapScope.__SCRIPT_URI_SPEC__ = uri;
+ Services.scriptloader.loadSubScript(uri, activeAddon.bootstrapScope);
+ } catch (e) {
+ logger.warn("Error loading bootstrap.js for " + aId, e);
+ }
}
// Notify the BrowserToolboxProcess that a new addon has been loaded.
let wrappedJSObject = { id: aId, options: { global: activeAddon.bootstrapScope }};
Services.obs.notifyObservers({ wrappedJSObject }, "toolbox-update-addon-options");
},
/**
@@ -4335,18 +4341,18 @@ this.XPIProvider = {
aExtraParams.instanceID = this.activeAddons.get(aAddon.id).instanceID;
}
// Nothing to call for locales
if (aAddon.type == "locale")
return;
let method = undefined;
+ let scope = activeAddon.bootstrapScope;
try {
- let scope = activeAddon.bootstrapScope;
method = scope[aMethod] || Cu.evalInSandbox(`${aMethod};`, scope);
} catch (e) {
// An exception will be caught if the expected method is not defined.
// That will be logged below.
}
// Extensions are automatically deinitialized in the correct order at shutdown.
if (aMethod == "shutdown" && aReason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {
@@ -4382,17 +4388,17 @@ this.XPIProvider = {
}
if (!method) {
logger.warn("Add-on " + aAddon.id + " is missing bootstrap method " + aMethod);
} else {
logger.debug("Calling bootstrap method " + aMethod + " on " + aAddon.id + " version " +
aAddon.version);
try {
- method(params, aReason);
+ method.call(scope, params, aReason);
} catch (e) {
logger.warn("Exception running bootstrap method " + aMethod + " on " + aAddon.id, e);
}
}
} finally {
// Extensions are automatically initialized in the correct order at startup.
if (aMethod == "startup" && aReason != BOOTSTRAP_REASONS.APP_STARTUP) {
for (let addon of this.getDependentAddons(aAddon))
--- a/toolkit/mozapps/extensions/internal/moz.build
+++ b/toolkit/mozapps/extensions/internal/moz.build
@@ -11,17 +11,16 @@ EXTRA_JS_MODULES.addons += [
'AddonUpdateChecker.jsm',
'APIExtensionBootstrap.js',
'Content.js',
'E10SAddonsRollout.jsm',
'GMPProvider.jsm',
'LightweightThemeImageOptimizer.jsm',
'ProductAddonChecker.jsm',
'SpellCheckDictionaryBootstrap.js',
- 'WebExtensionBootstrap.js',
'XPIInstall.jsm',
'XPIProvider.jsm',
'XPIProviderUtils.js',
]
TESTING_JS_MODULES += [
'AddonTestUtils.jsm',
]