Bug 1287007 - Use child's Extension instead of the process'
MozReview-Commit-ID: 9o8tOuUbchn
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -1159,18 +1159,16 @@ this.Extension = class extends Extension
delete addonData.cleanupFile;
}
this.addonData = addonData;
this.id = addonData.id;
this.baseURI = NetUtil.newURI(this.getURL("")).QueryInterface(Ci.nsIURL);
this.principal = this.createPrincipal();
- this.views = new Set();
-
this.onStartup = null;
this.hasShutdown = false;
this.onShutdown = new Set();
this.uninstallURL = null;
this.apis = [];
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -39,18 +39,16 @@ var {
SchemaAPIManager,
} = ExtensionUtils;
// There is a circular dependency between Extension.jsm and us.
// Long-term this file should not reference Extension.jsm (because they would
// live in different processes), but for now use lazy getters.
XPCOMUtils.defineLazyGetter(this, "findPathInObject",
() => Cu.import("resource://gre/modules/Extension.jsm", {}).findPathInObject);
-XPCOMUtils.defineLazyGetter(this, "GlobalManager",
- () => Cu.import("resource://gre/modules/Extension.jsm", {}).GlobalManager);
XPCOMUtils.defineLazyGetter(this, "ParentAPIManager",
() => Cu.import("resource://gre/modules/Extension.jsm", {}).ParentAPIManager);
var apiManager = new class extends SchemaAPIManager {
constructor() {
super("addon");
this.initialized = false;
}
@@ -120,27 +118,31 @@ class WannabeChildAPIManager extends Chi
// will be available, but no actual implementation is given.
// You should either provide an implementation or rewrite the JSON schema.
}
return super.getFallbackImplementation(namespace, name);
}
}
-// An extension page is an execution context for any extension content
-// that runs in the chrome process. It's used for background pages
-// (viewType="background"), popups (viewType="popup"), and any extension
-// content loaded into browser tabs (viewType="tab").
-//
-// |params| is an object with the following properties:
-// |viewType| is one of "background", "popup", or "tab".
-// |contentWindow| is the DOM window the content runs in.
-// |uri| is the URI of the content (optional).
-// |tabId| is the tab's ID, used if viewType is "tab".
class ExtensionContext extends BaseContext {
+ /**
+ * This ExtensionContext represents a privileged addon execution environment
+ * that has full access to the WebExtensions APIs (provided that the correct
+ * permissions have been requested).
+ *
+ * @param {BrowserExtensionContent} extension This context's owner.
+ * @param {object} params
+ * @param {nsIDOMWindow} params.contentWindow The window where the addon runs.
+ * @param {string} params.viewType One of "background", "popup" or "tab".
+ * "background" and "tab" are used by `browser.extension.getViews`.
+ * "popup" is only used internally to identify page action and browser
+ * action popups and options_ui pages.
+ * @param {number} [params.tabId] This tab's ID, used if viewType is "tab".
+ */
constructor(extension, params) {
super("addon_child", extension);
if (Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT) {
// This check is temporary. It should be removed once the proxy creation
// is asynchronous.
throw new Error("ExtensionContext cannot be created in child processes");
}
@@ -357,25 +359,21 @@ this.ExtensionChild = {
uninit(global) {
this.contentGlobals.get(global).uninit();
this.contentGlobals.delete(global);
},
/**
* Create a privileged context at document-element-inserted.
*
- * @param {Extension|BrowserExtensionContent} extension
+ * @param {BrowserExtensionContent} extension
* The extension for which the context should be created.
* @param {nsIDOMWindow} contentWindow The global of the page.
*/
createExtensionContext(extension, contentWindow) {
- // TODO(robwu): Remove dependencies on the bloated Extension from
- // Extension.jsm and use the thin BrowserExtensionContent from
- // ExtensionContent.jsm instead.
- extension = GlobalManager.extensionMap.get(extension.id);
let windowId = getInnerWindowID(contentWindow);
let context = this.extensionContexts.get(windowId);
if (context) {
if (context.extension !== extension) {
// Oops. This should never happen.
Cu.reportError("A different extension context already exists in this frame!");
} else {
// This should not happen either.
--- a/toolkit/components/extensions/ExtensionContent.jsm
+++ b/toolkit/components/extensions/ExtensionContent.jsm
@@ -697,16 +697,19 @@ function BrowserExtensionContent(data) {
this.whiteListedHosts = new MatchPattern(data.whiteListedHosts);
this.permissions = data.permissions;
this.localeData = new LocaleData(data.localeData);
this.manifest = data.manifest;
this.baseURI = Services.io.newURI(data.baseURL, null, null);
+ // Only used in addon processes.
+ this.views = new Set();
+
let uri = Services.io.newURI(data.resourceURL, null, null);
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
// Extension.jsm takes care of this in the parent.
ExtensionManagement.startupExtension(this.uuid, uri, this);
}
}
@@ -721,16 +724,20 @@ BrowserExtensionContent.prototype = {
return this.localeData.localizeMessage(...args);
},
localize(...args) {
return this.localeData.localize(...args);
},
hasPermission(perm) {
+ let match = /^manifest:(.*)/.exec(perm);
+ if (match) {
+ return this.manifest[match[1]] != null;
+ }
return this.permissions.has(perm);
},
};
ExtensionManager = {
// Map[extensionId, BrowserExtensionContent]
extensions: new Map(),