Bug 1295082 - Put Extension in BaseContext r=kmag

ExtensionContext in Extension.jsm has |extension| as an instance member,
so use it instead of passing |extension| to registerSchemaAPI's
callback.

And to make sure that this pattern also works in content processes, move
the |extension| member to BaseContext.

MozReview-Commit-ID: BgsGGCPQxJR

--HG--
extra : rebase_source : 7aa9fb7a53e057e8d3d8c477bd6821f8344c571a
This commit is contained in:
Rob Wu 2016-08-15 01:04:58 -07:00
Родитель 35c04e9513
Коммит bacc209644
29 изменённых файлов: 85 добавлений и 71 удалений

Просмотреть файл

@ -77,7 +77,7 @@ function convert(result) {
return node;
}
extensions.registerSchemaAPI("bookmarks", (extension, context) => {
extensions.registerSchemaAPI("bookmarks", context => {
return {
bookmarks: {
get: function(idOrIdList) {

Просмотреть файл

@ -259,7 +259,8 @@ extensions.on("shutdown", (type, extension) => {
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("browserAction", (extension, context) => {
extensions.registerSchemaAPI("browserAction", context => {
let {extension} = context;
return {
browserAction: {
onClicked: new EventManager(context, "browserAction.onClicked", fire => {

Просмотреть файл

@ -228,7 +228,8 @@ extensions.on("shutdown", (type, extension) => {
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("commands", (extension, context) => {
extensions.registerSchemaAPI("commands", context => {
let {extension} = context;
return {
commands: {
getAll() {

Просмотреть файл

@ -485,7 +485,8 @@ extensions.on("shutdown", (type, extension) => {
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("contextMenus", (extension, context) => {
extensions.registerSchemaAPI("contextMenus", context => {
let {extension} = context;
return {
contextMenus: {
create: function(createProperties, callback) {

Просмотреть файл

@ -130,7 +130,7 @@ function getObserver() {
return _observer;
}
extensions.registerSchemaAPI("history", (extension, context) => {
extensions.registerSchemaAPI("history", context => {
return {
history: {
addUrl: function(details) {

Просмотреть файл

@ -217,7 +217,8 @@ PageAction.for = extension => {
global.pageActionFor = PageAction.for;
extensions.registerSchemaAPI("pageAction", (extension, context) => {
extensions.registerSchemaAPI("pageAction", context => {
let {extension} = context;
return {
pageAction: {
onClicked: new EventManager(context, "pageAction.onClicked", fire => {

Просмотреть файл

@ -264,7 +264,8 @@ let tabListener = {
},
};
extensions.registerSchemaAPI("tabs", (extension, context) => {
extensions.registerSchemaAPI("tabs", context => {
let {extension} = context;
let self = {
tabs: {
onActivated: new WindowEventManager(context, "tabs.onActivated", "TabSelect", (fire, event) => {

Просмотреть файл

@ -15,7 +15,8 @@ var {
EventManager,
} = ExtensionUtils;
extensions.registerSchemaAPI("windows", (extension, context) => {
extensions.registerSchemaAPI("windows", context => {
let {extension} = context;
return {
windows: {
onCreated:

Просмотреть файл

@ -117,7 +117,8 @@ extensions.on("shutdown", (type, extension) => {
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("pageAction", (extension, context) => {
extensions.registerSchemaAPI("pageAction", context => {
let {extension} = context;
return {
pageAction: {
onClicked: new SingletonEventManager(context, "pageAction.onClicked", fire => {

Просмотреть файл

@ -187,7 +187,7 @@ var Management = {
// Mash together into a single object all the APIs registered by the
// functions above. Return the merged object.
generateAPIs(extension, context, apis, namespaces = null) {
generateAPIs(context, apis, namespaces = null) {
let obj = {};
// Recursively copy properties from source to dest.
@ -210,16 +210,16 @@ var Management = {
continue;
}
if (api.permission) {
if (!extension.hasPermission(api.permission)) {
if (!context.extension.hasPermission(api.permission)) {
continue;
}
}
api = api.api(extension, context);
api = api.api(context);
copy(obj, api);
}
for (let api of extension.apis) {
for (let api of context.extension.apis) {
copy(obj, api.getAPI(context));
}
@ -254,10 +254,9 @@ var Management = {
// |incognito| is the content running in a private context (default: false).
ExtensionContext = class extends BaseContext {
constructor(extension, params) {
super(extension.id);
super(extension);
let {type, uri} = params;
this.extension = extension;
this.type = type;
this.uri = uri || extension.baseURI;
this.incognito = params.incognito || false;
@ -335,7 +334,7 @@ class ProxyContext extends ExtensionContext {
this.principal_ = principal;
this.apiObj = {};
GlobalManager.injectInObject(extension, this, null, this.apiObj, ["storage", "test"]);
GlobalManager.injectInObject(this, null, this.apiObj, ["storage", "test"]);
this.listenerProxies = new Map();
@ -635,11 +634,11 @@ GlobalManager = {
return this.extensionMap.get(extensionId);
},
injectInObject(extension, context, defaultCallback, dest, namespaces = null) {
let api = Management.generateAPIs(extension, context, Management.apis, namespaces);
injectInObject(context, defaultCallback, dest, namespaces = null) {
let api = Management.generateAPIs(context, Management.apis, namespaces);
injectAPI(api, dest);
let schemaApi = Management.generateAPIs(extension, context, Management.schemaApis, namespaces);
let schemaApi = Management.generateAPIs(context, Management.schemaApis, namespaces);
// Add in any extra API namespaces which do not have implementations
// outside of their schema file.
@ -655,7 +654,7 @@ GlobalManager = {
},
hasPermission(permission) {
return extension.hasPermission(permission);
return context.extension.hasPermission(permission);
},
callFunction(path, name, args) {
@ -718,14 +717,14 @@ GlobalManager = {
return;
}
let inject = (extension, context) => {
let inject = context => {
// We create two separate sets of bindings, one for the `chrome`
// global, and one for the `browser` global. The latter returns
// Promise objects if a callback is not passed, while the former
// does not.
let injectObject = (name, defaultCallback) => {
let browserObj = Cu.createObjectIn(contentWindow, {defineAs: name});
this.injectInObject(extension, context, defaultCallback, browserObj);
this.injectInObject(context, defaultCallback, browserObj);
};
injectObject("browser", null);
@ -774,7 +773,7 @@ GlobalManager = {
let incognito = PrivateBrowsingUtils.isContentWindowPrivate(contentWindow);
let context = new ExtensionContext(extension, {type, contentWindow, uri, docShell, incognito});
inject(extension, context);
inject(context);
if (type == "background") {
this._initializeBackgroundPage(contentWindow);
}

Просмотреть файл

@ -312,14 +312,12 @@ var ExtensionManager;
// Cu.Sandbox to run the code. There is a separate scope for each
// frame.
class ExtensionContext extends BaseContext {
constructor(extensionId, contentWindow, contextOptions = {}) {
super(extensionId);
constructor(extension, contentWindow, contextOptions = {}) {
super(extension);
let {isExtensionPage} = contextOptions;
this.isExtensionPage = isExtensionPage;
this.extension = ExtensionManager.get(extensionId);
this.extensionId = extensionId;
this.setContentWindow(contentWindow);
@ -338,7 +336,7 @@ class ExtensionContext extends BaseContext {
// copy origin attributes from the content window origin attributes to
// preserve the user context id. overwrite the addonId.
let attrs = contentPrincipal.originAttributes;
attrs.addonId = extensionId;
attrs.addonId = this.extensionId;
let extensionPrincipal = ssm.createCodebasePrincipal(this.extension.baseURI, attrs);
Object.defineProperty(this, "principal",
{value: extensionPrincipal, enumerable: true, configurable: true});
@ -352,7 +350,7 @@ class ExtensionContext extends BaseContext {
}
if (isExtensionPage) {
if (ExtensionManagement.getAddonIdForWindow(this.contentWindow) != extensionId) {
if (ExtensionManagement.getAddonIdForWindow(this.contentWindow) != this.extensionId) {
throw new Error("Invalid target window for this extension context");
}
// This is an iframe with content script API enabled and its principal should be the
@ -400,7 +398,7 @@ class ExtensionContext extends BaseContext {
let sender = {id: this.extension.uuid, frameId, url};
// Properties in |filter| must match those in the |recipient|
// parameter of sendMessage.
let filter = {extensionId, frameId};
let filter = {extensionId: this.extensionId, frameId};
this.messenger = new Messenger(this, [mm], sender, filter, delegate);
this.chromeObj = Cu.createObjectIn(this.sandbox, {defineAs: "browser"});
@ -532,9 +530,11 @@ DocumentManager = {
const {CONTENTSCRIPT_PRIVILEGES} = ExtensionManagement.API_LEVELS;
let extensionId = ExtensionManagement.getAddonIdForWindow(window);
if (ExtensionManagement.getAPILevelForWindow(window, extensionId) == CONTENTSCRIPT_PRIVILEGES &&
ExtensionManager.get(extensionId)) {
DocumentManager.getExtensionPageContext(extensionId, window);
if (ExtensionManagement.getAPILevelForWindow(window, extensionId) == CONTENTSCRIPT_PRIVILEGES) {
let extension = ExtensionManager.get(extensionId);
if (extension) {
DocumentManager.getExtensionPageContext(extension, window);
}
}
this.trigger("document_start", window);
@ -594,7 +594,7 @@ DocumentManager = {
let script = new Script(extension, options, deferred);
if (script.matches(window)) {
let context = this.getContentScriptContext(extensionId, window);
let context = this.getContentScriptContext(extension, window);
context.addScript(script);
return deferred.promise;
}
@ -642,27 +642,27 @@ DocumentManager = {
return [];
},
getContentScriptContext(extensionId, window) {
getContentScriptContext(extension, window) {
let winId = getInnerWindowID(window);
if (!this.contentScriptWindows.has(winId)) {
this.contentScriptWindows.set(winId, new Map());
}
let extensions = this.contentScriptWindows.get(winId);
if (!extensions.has(extensionId)) {
let context = new ExtensionContext(extensionId, window);
extensions.set(extensionId, context);
if (!extensions.has(extension.id)) {
let context = new ExtensionContext(extension, window);
extensions.set(extension.id, context);
}
return extensions.get(extensionId);
return extensions.get(extension.id);
},
getExtensionPageContext(extensionId, window) {
getExtensionPageContext(extension, window) {
let winId = getInnerWindowID(window);
let context = this.extensionPageWindows.get(winId);
if (!context) {
let context = new ExtensionContext(extensionId, window, {isExtensionPage: true});
let context = new ExtensionContext(extension, window, {isExtensionPage: true});
this.extensionPageWindows.set(winId, context);
}
@ -683,7 +683,7 @@ DocumentManager = {
for (let window of this.enumerateWindows(global.docShell)) {
for (let script of extension.scripts) {
if (script.matches(window)) {
let context = this.getContentScriptContext(extensionId, window);
let context = this.getContentScriptContext(extension, window);
context.addScript(script);
}
}
@ -721,10 +721,10 @@ DocumentManager = {
let state = this.getWindowState(window);
if (state == "document_start") {
for (let [extensionId, extension] of ExtensionManager.extensions) {
for (let extension of ExtensionManager.extensions.values()) {
for (let script of extension.scripts) {
if (script.matches(window)) {
let context = this.getContentScriptContext(extensionId, window);
let context = this.getContentScriptContext(extension, window);
context.addScript(script);
}
}

Просмотреть файл

@ -162,13 +162,14 @@ class SpreadArgs extends Array {
let gContextId = 0;
class BaseContext {
constructor(extensionId) {
constructor(extension) {
this.onClose = new Set();
this.checkedLastError = false;
this._lastError = null;
this.contextId = `${++gContextId}-${Services.appinfo.uniqueProcessID}`;
this.unloaded = false;
this.extensionId = extensionId;
this.extension = extension;
this.extensionId = extension.id;
this.jsonSandbox = null;
this.active = true;

Просмотреть файл

@ -93,7 +93,8 @@ extensions.on("shutdown", (type, extension) => {
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("alarms", (extension, context) => {
extensions.registerSchemaAPI("alarms", context => {
let {extension} = context;
return {
alarms: {
create: function(name, alarmInfo) {

Просмотреть файл

@ -143,7 +143,8 @@ extensions.on("shutdown", (type, extension) => {
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("extension", (extension, context) => {
extensions.registerSchemaAPI("extension", context => {
let {extension} = context;
return {
extension: {
getBackgroundPage: function() {

Просмотреть файл

@ -238,7 +238,8 @@ function* query(detailsIn, props, extension) {
}
}
extensions.registerSchemaAPI("cookies", (extension, context) => {
extensions.registerSchemaAPI("cookies", context => {
let {extension} = context;
let self = {
cookies: {
get: function(details) {

Просмотреть файл

@ -386,7 +386,8 @@ function queryHelper(query) {
});
}
extensions.registerSchemaAPI("downloads", (extension, context) => {
extensions.registerSchemaAPI("downloads", context => {
let {extension} = context;
return {
downloads: {
download(options) {

Просмотреть файл

@ -1,6 +1,7 @@
"use strict";
extensions.registerSchemaAPI("extension", (extension, context) => {
extensions.registerSchemaAPI("extension", context => {
let {extension} = context;
return {
extension: {
getURL: function(url) {

Просмотреть файл

@ -7,7 +7,8 @@ var {
detectLanguage,
} = ExtensionUtils;
extensions.registerSchemaAPI("i18n", (extension, context) => {
extensions.registerSchemaAPI("i18n", context => {
let {extension} = context;
return {
i18n: {
getMessage: function(messageName, substitutions) {

Просмотреть файл

@ -1,6 +1,6 @@
"use strict";
extensions.registerSchemaAPI("idle", (extension, context) => {
extensions.registerSchemaAPI("idle", context => {
return {
idle: {
queryState: function(detectionIntervalInSeconds) {

Просмотреть файл

@ -2,7 +2,7 @@
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
extensions.registerSchemaAPI("management", (extension, context) => {
extensions.registerSchemaAPI("management", context => {
return {
management: {},
};

Просмотреть файл

@ -92,7 +92,8 @@ extensions.on("shutdown", (type, extension) => {
var nextId = 0;
extensions.registerSchemaAPI("notifications", (extension, context) => {
extensions.registerSchemaAPI("notifications", context => {
let {extension} = context;
return {
notifications: {
create: function(notificationId, options) {

Просмотреть файл

@ -20,7 +20,8 @@ var {
XPCOMUtils.defineLazyModuleGetter(this, "NativeApp",
"resource://gre/modules/NativeMessaging.jsm");
extensions.registerSchemaAPI("runtime", (extension, context) => {
extensions.registerSchemaAPI("runtime", context => {
let {extension} = context;
return {
runtime: {
onStartup: new EventManager(context, "runtime.onStartup", fire => {

Просмотреть файл

@ -10,7 +10,8 @@ var {
EventManager,
} = ExtensionUtils;
extensions.registerSchemaAPI("storage", (extension, context) => {
extensions.registerSchemaAPI("storage", context => {
let {extension} = context;
return {
storage: {
local: {

Просмотреть файл

@ -25,7 +25,8 @@ extensions.on("test-message", (type, extension, ...args) => {
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("test", (extension, context) => {
extensions.registerSchemaAPI("test", context => {
let {extension} = context;
return {
test: {
sendMessage: function(...args) {

Просмотреть файл

@ -158,7 +158,7 @@ function convertGetFrameResult(tabId, data) {
};
}
extensions.registerSchemaAPI("webNavigation", (extension, context) => {
extensions.registerSchemaAPI("webNavigation", context => {
return {
webNavigation: {
onBeforeNavigate: new WebNavigationEventManager(context, "onBeforeNavigate").api(),

Просмотреть файл

@ -99,7 +99,7 @@ function WebRequestEventManager(context, eventName) {
WebRequestEventManager.prototype = Object.create(SingletonEventManager.prototype);
extensions.registerSchemaAPI("webRequest", (extension, context) => {
extensions.registerSchemaAPI("webRequest", context => {
return {
webRequest: {
onBeforeRequest: new WebRequestEventManager(context, "onBeforeRequest").api(),

Просмотреть файл

@ -49,7 +49,7 @@ add_task(function* test_contentscript_context() {
// Get the content script context and check that it points to the correct window.
let {DocumentManager} = SpecialPowers.Cu.import("resource://gre/modules/ExtensionContent.jsm", {});
let context = DocumentManager.getContentScriptContext(extension.id, win);
let context = DocumentManager.getContentScriptContext(extension, win);
ok(context != null, "Got content script context");
is(SpecialPowers.unwrap(context.contentWindow), win, "Context's contentWindow property is correct");

Просмотреть файл

@ -13,16 +13,13 @@ var {
class StubContext extends BaseContext {
constructor() {
super();
let fakeExtension = {id: "test@web.extension"};
super(fakeExtension);
this.sandbox = Cu.Sandbox(global);
}
get cloneScope() {
return this. sandbox;
}
get extension() {
return {id: "test@web.extension"};
return this.sandbox;
}
}
@ -130,13 +127,13 @@ add_task(function* test_post_unload_listeners() {
class Context extends BaseContext {
constructor(principal) {
super();
let fakeExtension = {id: "test@web.extension"};
super(fakeExtension);
Object.defineProperty(this, "principal", {
value: principal,
configurable: true,
});
this.sandbox = Cu.Sandbox(principal, {wantXrays: false});
this.extension = {id: "test@web.extension"};
}
get cloneScope() {

Просмотреть файл

@ -46,7 +46,7 @@ add_task(function* testSchemaAPIInjection() {
yield Schemas.load(url);
// Register an API that will skip the background page.
Management.registerSchemaAPI("noBackgroundAPI.testnamespace", (extension, context) => {
Management.registerSchemaAPI("noBackgroundAPI.testnamespace", context => {
if (context.type !== "background") {
return {
noBackgroundAPI: {
@ -63,7 +63,7 @@ add_task(function* testSchemaAPIInjection() {
});
// Register an API that will skip any but the background page.
Management.registerSchemaAPI("backgroundAPI.testnamespace", (extension, context) => {
Management.registerSchemaAPI("backgroundAPI.testnamespace", context => {
if (context.type === "background") {
return {
backgroundAPI: {