Bug 1479309: Don't load shield-content-frame.js until needed. r?mythmon
MozReview-Commit-ID: 5usNkHYjifd
--- a/toolkit/components/normandy/content/AboutPages.jsm
+++ b/toolkit/components/normandy/content/AboutPages.jsm
@@ -15,18 +15,16 @@ ChromeUtils.defineModuleGetter(
ChromeUtils.defineModuleGetter(
this, "RecipeRunner", "resource://normandy/lib/RecipeRunner.jsm",
);
var EXPORTED_SYMBOLS = ["AboutPages"];
const SHIELD_LEARN_MORE_URL_PREF = "app.normandy.shieldLearnMoreUrl";
-const FRAME_SCRIPT = "resource://normandy-content/shield-content-frame.js";
-
/**
* Class for managing an about: page that Normandy provides. Adapted from
* browser/extensions/pocket/content/AboutPocket.jsm.
*
* @implements nsIFactory
* @implements nsIAboutModule
*/
class AboutPage {
@@ -56,26 +54,22 @@ class AboutPage {
}
AboutPage.prototype.QueryInterface = ChromeUtils.generateQI([Ci.nsIAboutModule]);
/**
* The module exported by this file.
*/
var AboutPages = {
async init() {
- // Load scripts in content processes and tabs
- Services.mm.loadFrameScript(FRAME_SCRIPT, true);
-
// Register about: pages and their listeners
this.aboutStudies.registerParentListeners();
CleanupManager.addCleanupHandler(() => {
// Stop loading processs scripts and notify existing scripts to clean up.
Services.ppmm.broadcastAsyncMessage("Shield:ShuttingDown");
- Services.mm.removeDelayedFrameScript(FRAME_SCRIPT);
Services.mm.broadcastAsyncMessage("Shield:ShuttingDown");
// Clean up about pages
this.aboutStudies.unregisterParentListeners();
});
},
};
rename from toolkit/components/normandy/content/shield-content-frame.js
rename to toolkit/components/normandy/content/ShieldFrameListener.jsm
--- a/toolkit/components/normandy/content/shield-content-frame.js
+++ b/toolkit/components/normandy/content/ShieldFrameListener.jsm
@@ -1,28 +1,27 @@
/* 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";
+var EXPORTED_SYMBOLS = ["ShieldFrameListener"];
+
/**
* Listen for DOM events bubbling up from the about:studies page, and perform
* privileged actions in response to them. If we need to do anything that the
* content process can't handle (such as reading IndexedDB), we send a message
* to the parent process and handle it there.
*
* This file is loaded as a frame script. It will be loaded once per tab that
* is opened.
*/
-/* global content addMessageListener removeMessageListener sendAsyncMessage */
-
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
const frameGlobal = {};
ChromeUtils.defineModuleGetter(
frameGlobal, "AboutPages", "resource://normandy-content/AboutPages.jsm",
);
XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
return Services.strings.createBundle("chrome://branding/locale/brand.properties");
@@ -33,41 +32,45 @@ XPCOMUtils.defineLazyGetter(this, "gStri
});
/**
* Handles incoming events from the parent process and about:studies.
* @implements nsIMessageListener
* @implements EventListener
*/
class ShieldFrameListener {
+ constructor(mm) {
+ this.mm = mm;
+ }
+
handleEvent(event) {
// Abort if the current page isn't about:studies.
if (!this.ensureTrustedOrigin()) {
return;
}
// We waited until after we received an event to register message listeners
// in order to save resources for tabs that don't ever load about:studies.
- addMessageListener("Shield:ShuttingDown", this);
- addMessageListener("Shield:ReceiveStudyList", this);
- addMessageListener("Shield:ReceiveStudiesEnabled", this);
+ this.mm.addMessageListener("Shield:ShuttingDown", this);
+ this.mm.addMessageListener("Shield:ReceiveStudyList", this);
+ this.mm.addMessageListener("Shield:ReceiveStudiesEnabled", this);
switch (event.detail.action) {
// Actions that require the parent process
case "GetRemoteValue:StudyList":
- sendAsyncMessage("Shield:GetStudyList");
+ this.mm.sendAsyncMessage("Shield:GetStudyList");
break;
case "RemoveStudy":
- sendAsyncMessage("Shield:RemoveStudy", event.detail.data);
+ this.mm.sendAsyncMessage("Shield:RemoveStudy", event.detail.data);
break;
case "GetRemoteValue:StudiesEnabled":
- sendAsyncMessage("Shield:GetStudiesEnabled");
+ this.mm.sendAsyncMessage("Shield:GetStudiesEnabled");
break;
case "NavigateToDataPreferences":
- sendAsyncMessage("Shield:OpenDataPreferences");
+ this.mm.sendAsyncMessage("Shield:OpenDataPreferences");
break;
// Actions that can be performed in the content process
case "GetRemoteValue:ShieldLearnMoreHref":
this.triggerPageCallback(
"ReceiveRemoteValue:ShieldLearnMoreHref",
frameGlobal.AboutPages.aboutStudies.getShieldLearnMoreHref()
);
break;
@@ -89,17 +92,17 @@ class ShieldFrameListener {
}
}
/**
* Check that the current webpage's origin is about:studies.
* @return {Boolean}
*/
ensureTrustedOrigin() {
- return content.document.documentURI.startsWith("about:studies");
+ return this.mm.content.document.documentURI.startsWith("about:studies");
}
/**
* Handle messages from the parent process.
* @param {Object} message
* See the nsIMessageListener docs.
*/
receiveMessage(message) {
@@ -122,24 +125,24 @@ class ShieldFrameListener {
* @param {Object} detail
*/
triggerPageCallback(type, detail) {
// Do not communicate with untrusted pages.
if (!this.ensureTrustedOrigin()) {
return;
}
+ let {content} = this.mm;
+
// Clone details and use the event class from the unprivileged context.
const event = new content.document.defaultView.CustomEvent(type, {
bubbles: true,
detail: Cu.cloneInto(detail, content.document.defaultView),
});
content.document.dispatchEvent(event);
}
onShutdown() {
- removeMessageListener("Shield:SendStudyList", this);
- removeMessageListener("Shield:ShuttingDown", this);
- removeEventListener("Shield", this);
+ this.mm.removeMessageListener("Shield:SendStudyList", this);
+ this.mm.removeMessageListener("Shield:ShuttingDown", this);
+ this.mm.removeEventListener("Shield", this);
}
}
-
-addEventListener("ShieldPageEvent", new ShieldFrameListener(), false, true);
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -32,16 +32,22 @@ XPCOMUtils.defineLazyServiceGetter(this,
var global = this;
XPCOMUtils.defineLazyProxy(this, "PopupBlocking", () => {
let tmp = {};
ChromeUtils.import("resource://gre/modules/PopupBlocking.jsm", tmp);
return new tmp.PopupBlocking(global);
});
+XPCOMUtils.defineLazyProxy(this, "ShieldFrameListener", () => {
+ let tmp = {};
+ ChromeUtils.import("resource://normandy-content/ShieldFrameListener.jsm", tmp);
+ return new tmp.ShieldFrameListener(global);
+});
+
XPCOMUtils.defineLazyProxy(this, "SelectionSourceContent",
"resource://gre/modules/SelectionSourceContent.jsm");
XPCOMUtils.defineLazyProxy(this, "WebChannelContent",
"resource://gre/modules/WebChannelContent.jsm");
XPCOMUtils.defineLazyProxy(this, "DateTimePickerContent", () => {
let tmp = {};
@@ -518,8 +524,10 @@ let ExtFind = {
case "ext-Finder:clearHighlighting":
this._findContent.highlighter.highlight(false);
break;
}
},
};
ExtFind.init();
+
+addEventListener("ShieldPageEvent", ShieldFrameListener, false, true);