mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1287010 - Make environment of Context explicit. r=billm
- Add `envType` to BaseContext. - Pass an explicit envType to all `registerSchemaAPI` invocations. - The factories passed to `registerSchemaAPI` will be split up later, so that content scripts (`content_child`) and addon pages can share common implementations. - The factories that implement the addon API will also be split up, to separate code running in the main process (`addon_parent`) from code running in a child process (`addon_child`). - Remove the use of a hardcoded list of `namespaces` from ProxyContext. Now `envType` is used to specify whether an API should be activated. MozReview-Commit-ID: Jiff8HIwG92 --HG-- extra : rebase_source : 946a3c0009a4e3223c2d10044b3099a94c845394
This commit is contained in:
parent
1067b066d5
commit
be3652cd57
@ -77,7 +77,7 @@ function convert(result) {
|
||||
return node;
|
||||
}
|
||||
|
||||
extensions.registerSchemaAPI("bookmarks", context => {
|
||||
extensions.registerSchemaAPI("bookmarks", "addon_parent", context => {
|
||||
return {
|
||||
bookmarks: {
|
||||
get: function(idOrIdList) {
|
||||
|
@ -365,7 +365,7 @@ extensions.on("shutdown", (type, extension) => {
|
||||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
||||
extensions.registerSchemaAPI("browserAction", context => {
|
||||
extensions.registerSchemaAPI("browserAction", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
browserAction: {
|
||||
|
@ -228,7 +228,7 @@ extensions.on("shutdown", (type, extension) => {
|
||||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
||||
extensions.registerSchemaAPI("commands", context => {
|
||||
extensions.registerSchemaAPI("commands", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
commands: {
|
||||
|
@ -485,7 +485,7 @@ extensions.on("shutdown", (type, extension) => {
|
||||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
||||
extensions.registerSchemaAPI("contextMenus", context => {
|
||||
extensions.registerSchemaAPI("contextMenus", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
contextMenus: {
|
||||
|
@ -130,7 +130,7 @@ function getObserver() {
|
||||
return _observer;
|
||||
}
|
||||
|
||||
extensions.registerSchemaAPI("history", context => {
|
||||
extensions.registerSchemaAPI("history", "addon_parent", context => {
|
||||
return {
|
||||
history: {
|
||||
addUrl: function(details) {
|
||||
|
@ -217,7 +217,7 @@ PageAction.for = extension => {
|
||||
|
||||
global.pageActionFor = PageAction.for;
|
||||
|
||||
extensions.registerSchemaAPI("pageAction", context => {
|
||||
extensions.registerSchemaAPI("pageAction", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
pageAction: {
|
||||
|
@ -264,7 +264,7 @@ let tabListener = {
|
||||
},
|
||||
};
|
||||
|
||||
extensions.registerSchemaAPI("tabs", context => {
|
||||
extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
let self = {
|
||||
tabs: {
|
||||
|
@ -15,7 +15,7 @@ var {
|
||||
EventManager,
|
||||
} = ExtensionUtils;
|
||||
|
||||
extensions.registerSchemaAPI("windows", context => {
|
||||
extensions.registerSchemaAPI("windows", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
windows: {
|
||||
|
@ -117,7 +117,7 @@ extensions.on("shutdown", (type, extension) => {
|
||||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
||||
extensions.registerSchemaAPI("pageAction", context => {
|
||||
extensions.registerSchemaAPI("pageAction", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
pageAction: {
|
||||
|
@ -118,7 +118,12 @@ var ExtensionContext, GlobalManager;
|
||||
var Management = {
|
||||
initialized: null,
|
||||
scopes: [],
|
||||
schemaApis: [],
|
||||
schemaApis: {
|
||||
addon_parent: [],
|
||||
addon_child: [],
|
||||
content_parent: [],
|
||||
content_child: [],
|
||||
},
|
||||
emitter: new EventEmitter(),
|
||||
|
||||
// Loads all the ext-*.js scripts currently registered.
|
||||
@ -152,25 +157,38 @@ var Management = {
|
||||
* 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).
|
||||
* Intended to match the namespace of the generated API, but not used at
|
||||
* the moment - see bugzil.la/1295774.
|
||||
* @param {string} envType Restricts the API to contexts that run in the
|
||||
* given environment. Must be one of the following:
|
||||
* - "addon_parent" - addon APIs that runs in the main process.
|
||||
* - "addon_child" - addon APIs that runs in an addon process.
|
||||
* - "content_parent" - content script APIs that runs in the main process.
|
||||
* - "content_child" - content script APIs that runs in a content process.
|
||||
* @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) => ({
|
||||
* registerSchemaAPI("tabs", "addon_parent", (context) => ({
|
||||
* tabs: { create, update },
|
||||
* }));
|
||||
* registerSchemaAPI("tabs", (context) => ({
|
||||
* registerSchemaAPI("tabs", "addon_parent", (context) => ({
|
||||
* tabs: { remove },
|
||||
* }));
|
||||
*/
|
||||
registerSchemaAPI(namespace, getAPI) {
|
||||
this.schemaApis.push({namespace, getAPI});
|
||||
registerSchemaAPI(namespace, envType, getAPI) {
|
||||
this.schemaApis[envType].push({namespace, getAPI});
|
||||
if (envType === "addon_child") {
|
||||
// TODO(robwu): Remove this. It is a temporary hack to ease the transition
|
||||
// from ext-*.js running in the parent to APIs running in a child process.
|
||||
// This can be removed once there is a dedicated ExtensionContext with type
|
||||
// "addon_child".
|
||||
this.schemaApis.addon_parent.push({namespace, getAPI});
|
||||
}
|
||||
},
|
||||
|
||||
// Mash together all the APIs from apis into obj.
|
||||
generateAPIs(context, apis, obj, namespaces = null) {
|
||||
generateAPIs(context, apis, obj) {
|
||||
// Recursively copy properties from source to dest.
|
||||
function copy(dest, source) {
|
||||
for (let prop in source) {
|
||||
@ -187,9 +205,6 @@ var Management = {
|
||||
}
|
||||
|
||||
for (let api of apis) {
|
||||
if (namespaces && !namespaces.includes(api.namespace)) {
|
||||
continue;
|
||||
}
|
||||
if (api.permission) {
|
||||
if (!context.extension.hasPermission(api.permission)) {
|
||||
continue;
|
||||
@ -229,7 +244,9 @@ var Management = {
|
||||
// |incognito| is the content running in a private context (default: false).
|
||||
ExtensionContext = class extends BaseContext {
|
||||
constructor(extension, params) {
|
||||
super(extension);
|
||||
// TODO(robwu): This should be addon_child once all ext- files are split.
|
||||
// There should be a new ProxyContext instance with the "addon_parent" type.
|
||||
super("addon_parent", extension);
|
||||
|
||||
let {type, uri} = params;
|
||||
this.type = type;
|
||||
@ -305,11 +322,14 @@ class ProxyContext extends ExtensionContext {
|
||||
params.uri = NetUtil.newURI(params.url);
|
||||
|
||||
super(extension, params);
|
||||
// TODO(robwu): Get ProxyContext to inherit from BaseContext instead of
|
||||
// ExtensionContext and let callers specify the environment type.
|
||||
this.envType = "content_parent";
|
||||
this.messageManager = messageManager;
|
||||
this.principal_ = principal;
|
||||
|
||||
this.apiObj = {};
|
||||
GlobalManager.injectInObject(this, null, this.apiObj, ["storage", "test"]);
|
||||
GlobalManager.injectInObject(this, null, this.apiObj);
|
||||
|
||||
this.listenerProxies = new Map();
|
||||
|
||||
@ -609,12 +629,12 @@ GlobalManager = {
|
||||
return this.extensionMap.get(extensionId);
|
||||
},
|
||||
|
||||
injectInObject(context, defaultCallback, dest, namespaces = null) {
|
||||
injectInObject(context, defaultCallback, dest) {
|
||||
let apis = {
|
||||
extensionTypes: {},
|
||||
};
|
||||
Management.generateAPIs(context, Management.schemaApis, apis, namespaces);
|
||||
Management.generateAPIs(context, context.extension.apis, apis, namespaces);
|
||||
Management.generateAPIs(context, Management.schemaApis[context.envType], apis);
|
||||
Management.generateAPIs(context, context.extension.apis, apis);
|
||||
|
||||
let schemaWrapper = {
|
||||
get principal() {
|
||||
@ -656,9 +676,6 @@ GlobalManager = {
|
||||
},
|
||||
|
||||
shouldInject(namespace, name) {
|
||||
if (namespaces && !namespaces.includes(namespace)) {
|
||||
return false;
|
||||
}
|
||||
return findPathInObject(apis, [namespace]) != null;
|
||||
},
|
||||
|
||||
|
@ -315,7 +315,7 @@ var ExtensionManager;
|
||||
// frame.
|
||||
class ExtensionContext extends BaseContext {
|
||||
constructor(extension, contentWindow, contextOptions = {}) {
|
||||
super(extension);
|
||||
super("content_child", extension);
|
||||
|
||||
let {isExtensionPage} = contextOptions;
|
||||
|
||||
|
@ -162,7 +162,8 @@ class SpreadArgs extends Array {
|
||||
let gContextId = 0;
|
||||
|
||||
class BaseContext {
|
||||
constructor(extension) {
|
||||
constructor(envType, extension) {
|
||||
this.envType = envType;
|
||||
this.onClose = new Set();
|
||||
this.checkedLastError = false;
|
||||
this._lastError = null;
|
||||
|
@ -93,7 +93,7 @@ extensions.on("shutdown", (type, extension) => {
|
||||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
||||
extensions.registerSchemaAPI("alarms", context => {
|
||||
extensions.registerSchemaAPI("alarms", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
alarms: {
|
||||
|
@ -144,7 +144,7 @@ extensions.on("shutdown", (type, extension) => {
|
||||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
||||
extensions.registerSchemaAPI("extension", context => {
|
||||
extensions.registerSchemaAPI("extension", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
extension: {
|
||||
|
@ -238,7 +238,7 @@ function* query(detailsIn, props, extension) {
|
||||
}
|
||||
}
|
||||
|
||||
extensions.registerSchemaAPI("cookies", context => {
|
||||
extensions.registerSchemaAPI("cookies", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
let self = {
|
||||
cookies: {
|
||||
|
@ -386,7 +386,7 @@ function queryHelper(query) {
|
||||
});
|
||||
}
|
||||
|
||||
extensions.registerSchemaAPI("downloads", context => {
|
||||
extensions.registerSchemaAPI("downloads", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
downloads: {
|
||||
|
@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
extensions.registerSchemaAPI("extension", context => {
|
||||
extensions.registerSchemaAPI("extension", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
extension: {
|
||||
|
@ -7,7 +7,7 @@ var {
|
||||
detectLanguage,
|
||||
} = ExtensionUtils;
|
||||
|
||||
extensions.registerSchemaAPI("i18n", context => {
|
||||
extensions.registerSchemaAPI("i18n", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
i18n: {
|
||||
|
@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
extensions.registerSchemaAPI("idle", context => {
|
||||
extensions.registerSchemaAPI("idle", "addon_parent", context => {
|
||||
return {
|
||||
idle: {
|
||||
queryState: function(detectionIntervalInSeconds) {
|
||||
|
@ -16,7 +16,7 @@ function installType(addon) {
|
||||
return "normal";
|
||||
}
|
||||
|
||||
extensions.registerSchemaAPI("management", context => {
|
||||
extensions.registerSchemaAPI("management", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
management: {
|
||||
|
@ -92,7 +92,7 @@ extensions.on("shutdown", (type, extension) => {
|
||||
|
||||
var nextId = 0;
|
||||
|
||||
extensions.registerSchemaAPI("notifications", context => {
|
||||
extensions.registerSchemaAPI("notifications", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
notifications: {
|
||||
|
@ -20,7 +20,7 @@ var {
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NativeApp",
|
||||
"resource://gre/modules/NativeMessaging.jsm");
|
||||
|
||||
extensions.registerSchemaAPI("runtime", context => {
|
||||
extensions.registerSchemaAPI("runtime", "addon_parent", context => {
|
||||
let {extension} = context;
|
||||
return {
|
||||
runtime: {
|
||||
|
@ -10,7 +10,7 @@ var {
|
||||
EventManager,
|
||||
} = ExtensionUtils;
|
||||
|
||||
extensions.registerSchemaAPI("storage", context => {
|
||||
function storageApiFactory(context) {
|
||||
let {extension} = context;
|
||||
return {
|
||||
storage: {
|
||||
@ -41,4 +41,6 @@ extensions.registerSchemaAPI("storage", context => {
|
||||
}).api(),
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
extensions.registerSchemaAPI("storage", "addon_parent", storageApiFactory);
|
||||
extensions.registerSchemaAPI("storage", "content_parent", storageApiFactory);
|
||||
|
@ -25,7 +25,7 @@ extensions.on("test-message", (type, extension, ...args) => {
|
||||
});
|
||||
/* eslint-enable mozilla/balanced-listeners */
|
||||
|
||||
extensions.registerSchemaAPI("test", context => {
|
||||
function testApiFactory(context) {
|
||||
let {extension} = context;
|
||||
return {
|
||||
test: {
|
||||
@ -75,4 +75,6 @@ extensions.registerSchemaAPI("test", context => {
|
||||
}).api(),
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
extensions.registerSchemaAPI("test", "addon_parent", testApiFactory);
|
||||
extensions.registerSchemaAPI("test", "content_parent", testApiFactory);
|
||||
|
@ -158,7 +158,7 @@ function convertGetFrameResult(tabId, data) {
|
||||
};
|
||||
}
|
||||
|
||||
extensions.registerSchemaAPI("webNavigation", context => {
|
||||
extensions.registerSchemaAPI("webNavigation", "addon_parent", context => {
|
||||
return {
|
||||
webNavigation: {
|
||||
onBeforeNavigate: new WebNavigationEventManager(context, "onBeforeNavigate").api(),
|
||||
|
@ -100,7 +100,7 @@ function WebRequestEventManager(context, eventName) {
|
||||
|
||||
WebRequestEventManager.prototype = Object.create(SingletonEventManager.prototype);
|
||||
|
||||
extensions.registerSchemaAPI("webRequest", context => {
|
||||
extensions.registerSchemaAPI("webRequest", "addon_parent", context => {
|
||||
return {
|
||||
webRequest: {
|
||||
onBeforeRequest: new WebRequestEventManager(context, "onBeforeRequest").api(),
|
||||
|
@ -14,7 +14,7 @@ var {
|
||||
class StubContext extends BaseContext {
|
||||
constructor() {
|
||||
let fakeExtension = {id: "test@web.extension"};
|
||||
super(fakeExtension);
|
||||
super("testEnv", fakeExtension);
|
||||
this.sandbox = Cu.Sandbox(global);
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ add_task(function* test_post_unload_listeners() {
|
||||
class Context extends BaseContext {
|
||||
constructor(principal) {
|
||||
let fakeExtension = {id: "test@web.extension"};
|
||||
super(fakeExtension);
|
||||
super("testEnv", fakeExtension);
|
||||
Object.defineProperty(this, "principal", {
|
||||
value: principal,
|
||||
configurable: true,
|
||||
|
@ -49,7 +49,7 @@ add_task(function* testSchemaAPIInjection() {
|
||||
yield Schemas.load(url);
|
||||
|
||||
// Register an API that will skip the background page.
|
||||
Management.registerSchemaAPI("noBackgroundAPI.testnamespace", context => {
|
||||
Management.registerSchemaAPI("noBackgroundAPI.testnamespace", "addon_child", context => {
|
||||
if (context.type !== "background") {
|
||||
return {
|
||||
noBackgroundAPI: {
|
||||
@ -66,7 +66,7 @@ add_task(function* testSchemaAPIInjection() {
|
||||
});
|
||||
|
||||
// Register an API that will skip any but the background page.
|
||||
Management.registerSchemaAPI("backgroundAPI.testnamespace", context => {
|
||||
Management.registerSchemaAPI("backgroundAPI.testnamespace", "addon_child", context => {
|
||||
if (context.type === "background") {
|
||||
return {
|
||||
backgroundAPI: {
|
||||
|
Loading…
Reference in New Issue
Block a user