Bug 1323845: Part 2b - Support separate schema roots for each API manager. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 16 Dec 2017 14:51:10 -0600
changeset 718298 3036170b873d6edbd4d270f5b2c75279688fb4b1
parent 718297 fb1aa3bbf66d6d6c4f0897977caf76cca2ce0c71
child 718299 545a27f5130be2e6b2fb1db470a169c2bf76cac5
push id94869
push usermaglione.k@gmail.com
push dateWed, 10 Jan 2018 01:49:31 +0000
reviewersaswan
bugs1323845
milestone59.0a1
Bug 1323845: Part 2b - Support separate schema roots for each API manager. r?aswan MozReview-Commit-ID: 61LhYiIKVTH
toolkit/components/extensions/ExtensionChild.jsm
toolkit/components/extensions/ExtensionCommon.jsm
toolkit/components/extensions/ExtensionContent.jsm
toolkit/components/extensions/ExtensionPageChild.jsm
toolkit/components/extensions/ExtensionParent.jsm
toolkit/components/extensions/ProxyScriptContext.jsm
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -773,16 +773,17 @@ class ChildAPIManager {
     this.messageManager = messageManager;
     this.url = contextData.url;
 
     // The root namespace of all locally implemented APIs. If an extension calls
     // an API that does not exist in this object, then the implementation is
     // delegated to the ParentAPIManager.
     this.localApis = localAPICan.root;
     this.apiCan = localAPICan;
+    this.schema = this.apiCan.apiManager.schema;
 
     this.id = `${context.extension.id}.${context.contextId}`;
 
     MessageChannel.addListener(messageManager, "API:RunListener", this);
     messageManager.addMessageListener("API:CallResult", this);
 
     this.messageFilterStrict = {childId: this.id};
 
@@ -816,16 +817,20 @@ class ChildAPIManager {
           }
         }
       };
       this.context.extension.on("add-permissions", this.updatePermissions);
       this.context.extension.on("remove-permissions", this.updatePermissions);
     }
   }
 
+  inject(obj) {
+    this.schema.inject(obj, this);
+  }
+
   receiveMessage({name, messageName, data}) {
     if (data.childId != this.id) {
       return;
     }
 
     switch (name || messageName) {
       case "API:RunListener":
         let map = this.listeners.get(data.path);
--- a/toolkit/components/extensions/ExtensionCommon.jsm
+++ b/toolkit/components/extensions/ExtensionCommon.jsm
@@ -935,21 +935,23 @@ class CanOfAPIs {
 class SchemaAPIManager extends EventEmitter {
   /**
    * @param {string} processType
    *     "main" - The main, one and only chrome browser process.
    *     "addon" - An addon process.
    *     "content" - A content process.
    *     "devtools" - A devtools process.
    *     "proxy" - A proxy script process.
+   * @param {SchemaRoot} schema
    */
-  constructor(processType) {
+  constructor(processType, schema) {
     super();
     this.processType = processType;
     this.global = this._createExtGlobal();
+    this.schema = schema;
 
     this.modules = new Map();
     this.modulePaths = {children: new Map(), modules: new Set()};
     this.manifestKeys = new Map();
     this.eventModules = new DefaultMap(() => new Set());
 
     this._modulesJSONLoaded = false;
 
--- a/toolkit/components/extensions/ExtensionContent.jsm
+++ b/toolkit/components/extensions/ExtensionContent.jsm
@@ -68,17 +68,17 @@ XPCOMUtils.defineLazyGetter(this, "conso
 
 var DocumentManager;
 
 const CATEGORY_EXTENSION_SCRIPTS_CONTENT = "webextension-scripts-content";
 const CONTENT_SCRIPT_INJECTION_HISTOGRAM = "WEBEXT_CONTENT_SCRIPT_INJECTION_MS";
 
 var apiManager = new class extends SchemaAPIManager {
   constructor() {
-    super("content");
+    super("content", Schemas);
     this.initialized = false;
   }
 
   lazyInit() {
     if (!this.initialized) {
       this.initialized = true;
       for (let [/* name */, value] of XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_SCRIPTS_CONTENT)) {
         this.loadScript(value);
@@ -475,17 +475,17 @@ class ContentScriptContextChild extends 
       configurable: true,
     });
 
     this.url = contentWindow.location.href;
 
     defineLazyGetter(this, "chromeObj", () => {
       let chromeObj = Cu.createObjectIn(this.sandbox);
 
-      Schemas.inject(chromeObj, this.childManager);
+      this.childManager.inject(chromeObj);
       return chromeObj;
     });
 
     Schemas.exportLazyGetter(this.sandbox, "browser", () => this.chromeObj);
     Schemas.exportLazyGetter(this.sandbox, "chrome", () => this.chromeObj);
   }
 
   injectAPI() {
--- a/toolkit/components/extensions/ExtensionPageChild.jsm
+++ b/toolkit/components/extensions/ExtensionPageChild.jsm
@@ -61,33 +61,33 @@ const {
 var ExtensionPageChild;
 
 function getFrameData(global) {
   return processScript.getFrameData(global, true);
 }
 
 var apiManager = new class extends SchemaAPIManager {
   constructor() {
-    super("addon");
+    super("addon", Schemas);
     this.initialized = false;
   }
 
   lazyInit() {
     if (!this.initialized) {
       this.initialized = true;
       for (let [/* name */, value] of XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_SCRIPTS_ADDON)) {
         this.loadScript(value);
       }
     }
   }
 }();
 
 var devtoolsAPIManager = new class extends SchemaAPIManager {
   constructor() {
-    super("devtools");
+    super("devtools", Schemas);
     this.initialized = false;
   }
 
   lazyInit() {
     if (!this.initialized) {
       this.initialized = true;
       for (let [/* name */, value] of XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_SCRIPTS_DEVTOOLS)) {
         this.loadScript(value);
@@ -133,26 +133,26 @@ class ExtensionBaseContextChild extends 
     }
     if (uri) {
       sender.url = uri.spec;
     }
     this.sender = sender;
 
     Schemas.exportLazyGetter(contentWindow, "browser", () => {
       let browserObj = Cu.createObjectIn(contentWindow);
-      Schemas.inject(browserObj, this.childManager);
+      this.childManager.inject(browserObj);
       return browserObj;
     });
 
     Schemas.exportLazyGetter(contentWindow, "chrome", () => {
       let chromeApiWrapper = Object.create(this.childManager);
       chromeApiWrapper.isChromeCompat = true;
 
       let chromeObj = Cu.createObjectIn(contentWindow);
-      Schemas.inject(chromeObj, chromeApiWrapper);
+      chromeApiWrapper.inject(chromeObj);
       return chromeObj;
     });
   }
 
   get cloneScope() {
     return this.contentWindow;
   }
 
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -72,17 +72,17 @@ let ParentAPIManager;
 let ProxyMessenger;
 let StartupCache;
 
 const global = this;
 
 // This object loads the ext-*.js scripts that define the extension API.
 let apiManager = new class extends SchemaAPIManager {
   constructor() {
-    super("main");
+    super("main", Schemas);
     this.initialized = null;
 
     /* eslint-disable mozilla/balanced-listeners */
     this.on("startup", (e, extension) => {
       return extension.apiManager.onStartup(extension);
     });
 
     this.on("update", async (e, {id, resourceURI}) => {
--- a/toolkit/components/extensions/ProxyScriptContext.jsm
+++ b/toolkit/components/extensions/ProxyScriptContext.jsm
@@ -319,17 +319,17 @@ class ProxyScriptContext extends BaseCon
     ProxyService.unregisterFilter(this);
     Cu.nukeSandbox(this.sandbox);
     this.sandbox = null;
   }
 }
 
 class ProxyScriptAPIManager extends SchemaAPIManager {
   constructor() {
-    super("proxy");
+    super("proxy", Schemas);
     this.initialized = false;
   }
 
   lazyInit() {
     if (!this.initialized) {
       let entries = XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_SCRIPTS_CONTENT);
       for (let [/* name */, value] of entries) {
         this.loadScript(value);
@@ -383,11 +383,11 @@ let proxyScriptAPIManager = new ProxyScr
 
 defineLazyGetter(ProxyScriptContext.prototype, "browserObj", function() {
   let localAPIs = {};
   let can = new CanOfAPIs(this, proxyScriptAPIManager, localAPIs);
   proxyScriptAPIManager.lazyInit();
 
   let browserObj = Cu.createObjectIn(this.sandbox);
   let injectionContext = new ProxyScriptInjectionContext(this, can);
-  Schemas.inject(browserObj, injectionContext);
+  proxyScriptAPIManager.schema.inject(browserObj, injectionContext);
   return browserObj;
 });