Bug 1470023: Lazily load PluginContent.jsm when it's first required. r?felipe draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 24 Jun 2018 17:33:55 -0700
changeset 810040 2e4520f8dcf159d42d59f761a0c6a8bb25e11451
parent 810039 23e45c60204fa8e7f1dba3294a8c1266fd3d1be7
push id113865
push usermaglione.k@gmail.com
push dateMon, 25 Jun 2018 00:35:02 +0000
reviewersfelipe
bugs1470023
milestone62.0a1
Bug 1470023: Lazily load PluginContent.jsm when it's first required. r?felipe MozReview-Commit-ID: 2n9NP5mEEcG
browser/base/content/content.js
browser/modules/PluginContent.jsm
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -319,18 +319,77 @@ var ClickEventHandler = {
             node && node.ownerDocument.nodePrincipal];
   }
 };
 ClickEventHandler.init();
 
 ContentLinkHandler.init(this);
 ContentMetaHandler.init(this);
 
-// TODO: Load this lazily so the JSM is run only if a relevant event/message fires.
-void new PluginContent(global);
+var PluginContentStub = {
+  EVENTS: [
+    "PluginCrashed",
+    "PluginOutdated",
+    "PluginInstantiated",
+    "PluginRemoved",
+    "HiddenPlugin",
+  ],
+
+  MESSAGES: [
+    "BrowserPlugins:ActivatePlugins",
+    "BrowserPlugins:NotificationShown",
+    "BrowserPlugins:ContextMenuCommand",
+    "BrowserPlugins:NPAPIPluginProcessCrashed",
+    "BrowserPlugins:CrashReportSubmitted",
+    "BrowserPlugins:Test:ClearCrashData",
+  ],
+
+  _pluginContent: null,
+  get pluginContent() {
+    if (!this._pluginContent) {
+      this._pluginContent = new PluginContent(global);
+    }
+    return this._pluginContent;
+  },
+
+  init() {
+    addEventListener("unload", this);
+
+    addEventListener("PluginBindingAttached", this, true, true);
+
+    for (let event of this.EVENTS) {
+      addEventListener(event, this, true);
+    }
+    for (let msg of this.MESSAGES) {
+      addMessageListener(msg, this);
+    }
+    Services.obs.addObserver(this, "decoder-doctor-notification");
+  },
+
+  uninit() {
+    Services.obs.removeObserver(this, "decoder-doctor-notification");
+  },
+
+  observe(subject, topic, data) {
+    return this.pluginContent.observe(subject, topic, data);
+  },
+
+  handleEvent(event) {
+    if (event.type === "unload") {
+      return this.uninit();
+    }
+    return this.pluginContent.handleEvent(event);
+  },
+
+  receiveMessage(msg) {
+    return this.pluginContent.receiveMessage(msg);
+  },
+};
+
+PluginContentStub.init();
 
 addEventListener("DOMWindowFocus", function(event) {
   sendAsyncMessage("DOMWindowFocus", {});
 }, false);
 
 // We use this shim so that ContentWebRTC.jsm will not be loaded until
 // it is actually needed.
 var ContentWebRTCShim = message => ContentWebRTC.receiveMessage(message);
--- a/browser/modules/PluginContent.jsm
+++ b/browser/modules/PluginContent.jsm
@@ -37,61 +37,18 @@ PluginContent.prototype = {
     this.global = global;
     // Need to hold onto the content window or else it'll get destroyed
     this.content = this.global.content;
     // Cache of plugin actions for the current page.
     this.pluginData = new Map();
     // Cache of plugin crash information sent from the parent
     this.pluginCrashData = new Map();
 
-    // Note that the XBL binding is untrusted
-    global.addEventListener("PluginBindingAttached", this, true, true);
-    global.addEventListener("PluginCrashed", this, true);
-    global.addEventListener("PluginOutdated", this, true);
-    global.addEventListener("PluginInstantiated", this, true);
-    global.addEventListener("PluginRemoved", this, true);
     global.addEventListener("pagehide", this, true);
     global.addEventListener("pageshow", this, true);
-    global.addEventListener("unload", this);
-    global.addEventListener("HiddenPlugin", this, true);
-
-    global.addMessageListener("BrowserPlugins:ActivatePlugins", this);
-    global.addMessageListener("BrowserPlugins:NotificationShown", this);
-    global.addMessageListener("BrowserPlugins:ContextMenuCommand", this);
-    global.addMessageListener("BrowserPlugins:NPAPIPluginProcessCrashed", this);
-    global.addMessageListener("BrowserPlugins:CrashReportSubmitted", this);
-    global.addMessageListener("BrowserPlugins:Test:ClearCrashData", this);
-
-    Services.obs.addObserver(this, "decoder-doctor-notification");
-  },
-
-  uninit() {
-    let global = this.global;
-
-    global.removeEventListener("PluginBindingAttached", this, true);
-    global.removeEventListener("PluginCrashed", this, true);
-    global.removeEventListener("PluginOutdated", this, true);
-    global.removeEventListener("PluginInstantiated", this, true);
-    global.removeEventListener("PluginRemoved", this, true);
-    global.removeEventListener("pagehide", this, true);
-    global.removeEventListener("pageshow", this, true);
-    global.removeEventListener("unload", this);
-    global.removeEventListener("HiddenPlugin", this, true);
-
-    global.removeMessageListener("BrowserPlugins:ActivatePlugins", this);
-    global.removeMessageListener("BrowserPlugins:NotificationShown", this);
-    global.removeMessageListener("BrowserPlugins:ContextMenuCommand", this);
-    global.removeMessageListener("BrowserPlugins:NPAPIPluginProcessCrashed", this);
-    global.removeMessageListener("BrowserPlugins:CrashReportSubmitted", this);
-    global.removeMessageListener("BrowserPlugins:Test:ClearCrashData", this);
-
-    Services.obs.removeObserver(this, "decoder-doctor-notification");
-
-    delete this.global;
-    delete this.content;
   },
 
   receiveMessage(msg) {
     switch (msg.name) {
       case "BrowserPlugins:ActivatePlugins":
         this.activatePlugins(msg.data.pluginInfo, msg.data.newState);
         break;
       case "BrowserPlugins:NotificationShown":
@@ -439,21 +396,16 @@ PluginContent.prototype = {
         // Not all states map to a handler
         return null;
     }
   },
 
   handleEvent(event) {
     let eventType = event.type;
 
-    if (eventType == "unload") {
-      this.uninit();
-      return;
-    }
-
     if (eventType == "pagehide") {
       this.onPageHide(event);
       return;
     }
 
     if (eventType == "pageshow") {
       this.onPageShow(event);
       return;