Bug 1287007 - Move ExtensionContext to separate file draft
authorRob Wu <rob@robwu.nl>
Mon, 05 Sep 2016 00:15:18 -0700
changeset 411551 bb36a764a97dec24b28ca6cbec11e817e797bda8
parent 411550 6690c74b4cab7067d24e0b29797c988285375150
child 411552 c8204bd45b6f9e48bfe27ba6f0464ba3c2e8fb65
push id28922
push userbmo:rob@robwu.nl
push dateThu, 08 Sep 2016 08:44:00 +0000
bugs1287007
milestone51.0a1
Bug 1287007 - Move ExtensionContext to separate file This is just a mechanical change, literally nothing more than cutting ExtensionContext from Extension.jsm, pasting it in ExtensionChild.jsm and adding the minimal imoort boilerplate. MozReview-Commit-ID: 5uVt1IOdEFU
toolkit/components/extensions/Extension.jsm
toolkit/components/extensions/ExtensionChild.jsm
toolkit/components/extensions/moz.build
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -27,16 +27,18 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
                                   "resource://gre/modules/AddonManager.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
                                   "resource://gre/modules/AppConstants.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionAPIs",
                                   "resource://gre/modules/ExtensionAPI.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ExtensionContext",
+                                  "resource://gre/modules/ExtensionChild.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionStorage",
                                   "resource://gre/modules/ExtensionStorage.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
                                   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Locale",
                                   "resource://gre/modules/Locale.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Log",
                                   "resource://gre/modules/Log.jsm");
@@ -84,17 +86,16 @@ if (!AppConstants.RELEASE_BUILD) {
 }
 
 Cu.import("resource://gre/modules/ExtensionUtils.jsm");
 var {
   BaseContext,
   EventEmitter,
   SchemaAPIManager,
   LocaleData,
-  Messenger,
   instanceOf,
   LocalAPIImplementation,
   flushJarCache,
 } = ExtensionUtils;
 
 const LOGGER_ID_BASE = "addons.webextension.";
 const UUID_MAP_PREF = "extensions.webextensions.uuids";
 const LEAVE_STORAGE_PREF = "extensions.webextensions.keepStorageOnUninstall";
@@ -107,17 +108,17 @@ const COMMENT_REGEXP = new RegExp(String
         [^"\n] |
         " (?:[^"\\\n] | \\.)* "
       )*?
     )
 
     //.*
   `.replace(/\s+/g, ""), "gm");
 
-var ExtensionContext, GlobalManager;
+var GlobalManager;
 
 // This object loads the ext-*.js scripts that define the extension API.
 var Management = new class extends SchemaAPIManager {
   constructor() {
     super("main");
     this.initialized = null;
   }
 
@@ -164,98 +165,16 @@ var Management = new class extends Schem
       // 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".
       super.registerSchemaAPI(namespace, "addon_parent", getAPI);
     }
   }
 };
 
-// An extension page is an execution context for any extension content
-// that runs in the chrome process. It's used for background pages
-// (type="background"), popups (type="popup"), and any extension
-// content loaded into browser tabs (type="tab").
-//
-// |params| is an object with the following properties:
-// |type| is one of "background", "popup", or "tab".
-// |contentWindow| is the DOM window the content runs in.
-// |uri| is the URI of the content (optional).
-// |docShell| is the docshell the content runs in (optional).
-ExtensionContext = class extends BaseContext {
-  constructor(extension, params) {
-    // 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;
-    this.uri = uri || extension.baseURI;
-
-    this.setContentWindow(params.contentWindow);
-
-    // This is the MessageSender property passed to extension.
-    // It can be augmented by the "page-open" hook.
-    let sender = {id: extension.uuid};
-    if (uri) {
-      sender.url = uri.spec;
-    }
-    Management.emit("page-load", this, params, sender);
-
-    // Properties in |filter| must match those in the |recipient|
-    // parameter of sendMessage.
-    let filter = {extensionId: extension.id};
-    // Addon-generated messages (not necessarily from the same process as the
-    // addon itself) are sent to the main process, which forwards them via the
-    // parent process message manager. Specific replies can be sent to the frame
-    // message manager.
-    this.messenger = new Messenger(this, [Services.cpmm, this.messageManager], sender, filter);
-
-    if (this.externallyVisible) {
-      this.extension.views.add(this);
-    }
-  }
-
-  get cloneScope() {
-    return this.contentWindow;
-  }
-
-  get principal() {
-    return this.contentWindow.document.nodePrincipal;
-  }
-
-  get externallyVisible() {
-    return true;
-  }
-
-  // Called when the extension shuts down.
-  shutdown() {
-    Management.emit("page-shutdown", this);
-    this.unload();
-  }
-
-  // This method is called when an extension page navigates away or
-  // its tab is closed.
-  unload() {
-    // Note that without this guard, we end up running unload code
-    // multiple times for tab pages closed by the "page-unload" handlers
-    // triggered below.
-    if (this.unloaded) {
-      return;
-    }
-
-    super.unload();
-
-    Management.emit("page-unload", this);
-
-    if (this.externallyVisible) {
-      this.extension.views.delete(this);
-    }
-  }
-};
-
 // Subscribes to messages related to the extension messaging API and forwards it
 // to the relevant message manager. The "sender" field for the `onMessage` and
 // `onConnect` events are updated if needed.
 let ProxyMessenger = {
   _initialized: false,
   init() {
     if (this._initialized) {
       return;
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -0,0 +1,119 @@
+/* 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";
+
+this.EXPORTED_SYMBOLS = ["ExtensionContext"];
+
+/*
+ * This file handles addon logic that is independent of the chrome process.
+ * When addons run out-of-process, this is the main entry point.
+ * Its primary function is managing addon globals.
+ *
+ * Don't put contentscript logic here, use ExtensionContent.jsm instead.
+ */
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+Cu.import("resource://gre/modules/ExtensionUtils.jsm");
+var {
+  BaseContext,
+  Messenger,
+} = 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, "Management",
+  () => Cu.import("resource://gre/modules/Extension.jsm", {}).Management);
+
+// An extension page is an execution context for any extension content
+// that runs in the chrome process. It's used for background pages
+// (type="background"), popups (type="popup"), and any extension
+// content loaded into browser tabs (type="tab").
+//
+// |params| is an object with the following properties:
+// |type| is one of "background", "popup", or "tab".
+// |contentWindow| is the DOM window the content runs in.
+// |uri| is the URI of the content (optional).
+// |docShell| is the docshell the content runs in (optional).
+this.ExtensionContext = class extends BaseContext {
+  constructor(extension, params) {
+    // 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;
+    this.uri = uri || extension.baseURI;
+
+    this.setContentWindow(params.contentWindow);
+
+    // This is the MessageSender property passed to extension.
+    // It can be augmented by the "page-open" hook.
+    let sender = {id: extension.uuid};
+    if (uri) {
+      sender.url = uri.spec;
+    }
+    Management.emit("page-load", this, params, sender);
+
+    // Properties in |filter| must match those in the |recipient|
+    // parameter of sendMessage.
+    let filter = {extensionId: extension.id};
+    // Addon-generated messages (not necessarily from the same process as the
+    // addon itself) are sent to the main process, which forwards them via the
+    // parent process message manager. Specific replies can be sent to the frame
+    // message manager.
+    this.messenger = new Messenger(this, [Services.cpmm, this.messageManager], sender, filter);
+
+    if (this.externallyVisible) {
+      this.extension.views.add(this);
+    }
+  }
+
+  get cloneScope() {
+    return this.contentWindow;
+  }
+
+  get principal() {
+    return this.contentWindow.document.nodePrincipal;
+  }
+
+  get externallyVisible() {
+    return true;
+  }
+
+  // Called when the extension shuts down.
+  shutdown() {
+    Management.emit("page-shutdown", this);
+    this.unload();
+  }
+
+  // This method is called when an extension page navigates away or
+  // its tab is closed.
+  unload() {
+    // Note that without this guard, we end up running unload code
+    // multiple times for tab pages closed by the "page-unload" handlers
+    // triggered below.
+    if (this.unloaded) {
+      return;
+    }
+
+    super.unload();
+
+    Management.emit("page-unload", this);
+
+    if (this.externallyVisible) {
+      this.extension.views.delete(this);
+    }
+  }
+};
+
+
--- a/toolkit/components/extensions/moz.build
+++ b/toolkit/components/extensions/moz.build
@@ -2,16 +2,17 @@
 # vim: set filetype=python:
 # 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/.
 
 EXTRA_JS_MODULES += [
     'Extension.jsm',
     'ExtensionAPI.jsm',
+    'ExtensionChild.jsm',
     'ExtensionContent.jsm',
     'ExtensionManagement.jsm',
     'ExtensionStorage.jsm',
     'ExtensionUtils.jsm',
     'LegacyExtensionsUtils.jsm',
     'MessageChannel.jsm',
     'NativeMessaging.jsm',
     'Schemas.jsm',