Bug 1480244: Part 5 - Run most framescripts in shared scope. r=mconley
Creating non-shared scopes for frame scripts is fairly expensive. After these
changes it's even more expensive. However, many frame scripts have no use for
the shared scopes at all. Run-once scripts which execute in closures, for
instance, make no use of them. And after
bug 1472491, neither do most of our
default frame scripts.
MozReview-Commit-ID: 9PK7bYdQ0yh
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1312,18 +1312,18 @@ var gBrowserInit = {
LanguageDetectionListener.init();
BrowserOnClick.init();
FeedHandler.init();
TrackingProtection.init();
CaptivePortalWatcher.init();
ZoomUI.init(window);
let mm = window.getGroupMessageManager("browsers");
- mm.loadFrameScript("chrome://browser/content/tab-content.js", true);
- mm.loadFrameScript("chrome://browser/content/content.js", true);
+ mm.loadFrameScript("chrome://browser/content/tab-content.js", true, true);
+ mm.loadFrameScript("chrome://browser/content/content.js", true, true);
mm.loadFrameScript("chrome://global/content/content-HybridContentTelemetry.js", true);
window.messageManager.addMessageListener("Browser:LoadURI", RedirectLoad);
if (!gMultiProcessBrowser) {
// There is a Content:Click message manually sent from content.
Services.els.addSystemEventListener(gBrowser.tabpanels, "click",
contentAreaClick, true);
@@ -5202,17 +5202,17 @@ const AccessibilityRefreshBlocker = {
Services.prefs.removeObserver(this.PREF, this);
}
},
loadFrameScript() {
if (!this._loaded) {
this._loaded = true;
let mm = window.getGroupMessageManager("browsers");
- mm.loadFrameScript("chrome://browser/content/content-refreshblocker.js", true);
+ mm.loadFrameScript("chrome://browser/content/content-refreshblocker.js", true, true);
}
}
};
var TabsProgressListener = {
onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
// Collect telemetry data about tab load times.
if (aWebProgress.isTopLevel && (!aRequest.originalURI || aRequest.originalURI.spec.scheme != "about")) {
--- a/browser/base/content/webext-panels.js
+++ b/browser/base/content/webext-panels.js
@@ -59,22 +59,22 @@ function getBrowser(sidebar) {
} else {
readyPromise = Promise.resolve();
}
stack.appendChild(browser);
document.documentElement.appendChild(stack);
return readyPromise.then(() => {
- browser.messageManager.loadFrameScript("chrome://browser/content/content.js", false);
+ browser.messageManager.loadFrameScript("chrome://browser/content/content.js", false, true);
ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
if (sidebar.browserStyle) {
browser.messageManager.loadFrameScript(
- "chrome://extensions/content/ext-browser-content.js", false);
+ "chrome://extensions/content/ext-browser-content.js", false, true);
browser.messageManager.sendAsyncMessage("Extension:InitBrowser", {
stylesheets: ExtensionParent.extensionStylesheets,
});
}
return browser;
});
}
--- a/browser/components/extensions/ExtensionPopups.jsm
+++ b/browser/components/extensions/ExtensionPopups.jsm
@@ -306,20 +306,20 @@ class BasePopup {
return setupBrowser(browser);
}
return readyPromise.then(() => {
setupBrowser(browser);
let mm = browser.messageManager;
// Sets the context information for context menus.
- mm.loadFrameScript("chrome://browser/content/content.js", true);
+ mm.loadFrameScript("chrome://browser/content/content.js", true, true);
mm.loadFrameScript(
- "chrome://extensions/content/ext-browser-content.js", false);
+ "chrome://extensions/content/ext-browser-content.js", false, true);
mm.sendAsyncMessage("Extension:InitBrowser", {
allowScriptsToClose: true,
blockParser: this.blockParser,
fixedWidth: this.fixedWidth,
maxWidth: 800,
maxHeight: 600,
stylesheets: this.STYLESHEETS,
--- a/browser/components/extensions/test/browser/browser_ext_find.js
+++ b/browser/components/extensions/test/browser/browser_ext_find.js
@@ -137,17 +137,17 @@ add_task(async function testDuplicatePin
await extension.startup();
let rectData = await extension.awaitMessage("test:find:WebExtensionFinished");
let {top, left} = rectData[5].rectsAndTexts.rectList[0];
await extension.unload();
let {selectedBrowser} = gBrowser;
let frameScriptUrl = `data:,(${frameScript}).call(this)`;
- selectedBrowser.messageManager.loadFrameScript(frameScriptUrl, false);
+ selectedBrowser.messageManager.loadFrameScript(frameScriptUrl, false, true);
let message = await waitForMessage(selectedBrowser.messageManager, "test:find:selectionTest");
info("Test that text was highlighted properly.");
is(message.data.text, "bananA", `The text that was highlighted: - Expected: bananA, Actual: ${message.data.text}`);
info("Test that rectangle data returned from the search matches the highlighted result.");
is(message.data.rect.top, top, `rect.top: - Expected: ${message.data.rect.top}, Actual: ${top}`);
is(message.data.rect.left, left, `rect.left: - Expected: ${message.data.rect.left}, Actual: ${left}`);
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -1096,17 +1096,17 @@ var SessionStoreInternal = {
let mm = aWindow.getGroupMessageManager("browsers");
MESSAGES.forEach(msg => {
let listenWhenClosed = CLOSED_MESSAGES.has(msg);
mm.addMessageListener(msg, this, listenWhenClosed);
});
// Load the frame script after registering listeners.
- mm.loadFrameScript("chrome://browser/content/content-sessionStore.js", true);
+ mm.loadFrameScript("chrome://browser/content/content-sessionStore.js", true, true);
// and create its data object
this._windows[aWindow.__SSi] = { tabs: [], selected: 0, _closedTabs: [], busy: false };
if (PrivateBrowsingUtils.isWindowPrivate(aWindow))
this._windows[aWindow.__SSi].isPrivate = true;
if (!this._isWindowLoaded(aWindow))
this._windows[aWindow.__SSi]._restoring = true;
--- a/browser/extensions/formautofill/bootstrap.js
+++ b/browser/extensions/formautofill/bootstrap.js
@@ -126,17 +126,17 @@ function startup(data) {
Services.mm.addMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
formAutofillParent.init().catch(Cu.reportError);
/* eslint-disable no-unused-vars */
Services.ppmm.loadProcessScript("data:,new " + function() {
ChromeUtils.import("resource://formautofill/FormAutofillContent.jsm");
}, true);
/* eslint-enable no-unused-vars */
- Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillFrameScript.js", true);
+ Services.mm.loadFrameScript("chrome://formautofill/content/FormAutofillFrameScript.js", true, true);
}
function shutdown() {
resProto.setSubstitution(RESOURCE_HOST, null);
Services.mm.removeMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
let enumerator = Services.wm.getEnumerator("navigator:browser");
--- a/browser/extensions/onboarding/bootstrap.js
+++ b/browser/extensions/onboarding/bootstrap.js
@@ -169,17 +169,17 @@ function initContentMessageListener() {
/**
* onBrowserReady - Continues startup of the add-on after browser is ready.
*/
function onBrowserReady() {
waitingForBrowserReady = false;
OnboardingTourType.check();
OnboardingTelemetry.init(startupData);
- Services.mm.loadFrameScript("resource://onboarding/onboarding.js", true);
+ Services.mm.loadFrameScript("resource://onboarding/onboarding.js", true, true);
initContentMessageListener();
}
/**
* observe - nsIObserver callback to handle various browser notifications.
*/
function observe(subject, topic, data) {
switch (topic) {
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -502,20 +502,20 @@ var BrowserApp = {
let logsDir = OS.Path.join(downloadsDir, "memory-reports");
yield OS.File.removeDir(logsDir);
});
});
// Don't delay loading content.js because when we restore reader mode tabs,
// we require the reader mode scripts in content.js right away.
let mm = window.getGroupMessageManager("browsers");
- mm.loadFrameScript("chrome://browser/content/content.js", true);
+ mm.loadFrameScript("chrome://browser/content/content.js", true, true);
// Listen to manifest messages
- mm.loadFrameScript("chrome://global/content/manifestMessages.js", true);
+ mm.loadFrameScript("chrome://global/content/manifestMessages.js", true, true);
// We can't delay registering WebChannel listeners: if the first page is
// about:accounts, which can happen when starting the Firefox Account flow
// from the first run experience, or via the Firefox Account Status
// Activity, we can and do miss messages from the fxa-content-server.
// However, we never allow suitably restricted profiles from listening to
// fxa-content-server messages.
if (ParentalControls.isAllowed(ParentalControls.MODIFY_ACCOUNTS)) {
--- a/services/sync/tps/extensions/tps/resource/modules/tabs.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/tabs.jsm
@@ -20,17 +20,17 @@ ChromeUtils.import("resource://tps/logge
// hence the hackiness here and in BrowserTabs.Add.
Services
.mm
.loadFrameScript("data:application/javascript;charset=utf-8," + encodeURIComponent(`
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
addEventListener("load", function(event) {
let subframe = event.target != content.document;
sendAsyncMessage("tps:loadEvent", {subframe: subframe, url: event.target.documentURI});
- }, true)`), true);
+ }, true)`), true, true);
var BrowserTabs = {
/**
* Add
*
* Opens a new tab in the current browser window for the
* given uri. Rejects on error.
*
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -518,17 +518,17 @@ GlobalManager = {
}
},
_onExtensionBrowser(type, browser, additionalData = {}) {
browser.messageManager.loadFrameScript(`data:,
Components.utils.import("resource://gre/modules/Services.jsm");
Services.obs.notifyObservers(this, "tab-content-frameloader-created", "");
- `, false);
+ `, false, true);
let viewType = browser.getAttribute("webextension-view-type");
if (viewType) {
let data = {viewType};
let {tabTracker} = apiManager.global;
Object.assign(data, tabTracker.getBrowserData(browser), additionalData);
--- a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
+++ b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
@@ -30,17 +30,17 @@ ChromeUtils.defineModuleGetter(this, "Se
ChromeUtils.defineModuleGetter(this, "TestUtils",
"resource://testing-common/TestUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "Management", () => {
const {Management} = ChromeUtils.import("resource://gre/modules/Extension.jsm", {});
return Management;
});
-Services.mm.loadFrameScript("chrome://global/content/browser-content.js", true);
+Services.mm.loadFrameScript("chrome://global/content/browser-content.js", true, true);
ActorManagerParent.flush();
/* exported ExtensionTestUtils */
const {
promiseDocumentLoaded,
promiseEvent,
@@ -163,17 +163,17 @@ class ContentPage {
}
sendMessage(msg, data) {
return MessageChannel.sendMessage(this.browser.messageManager, msg, data);
}
loadFrameScript(func) {
let frameScript = `data:text/javascript,(${encodeURI(func)}).call(this)`;
- this.browser.messageManager.loadFrameScript(frameScript, true);
+ this.browser.messageManager.loadFrameScript(frameScript, true, true);
}
addFrameScriptHelper(func) {
let frameScript = `data:text/javascript,${encodeURI(func)}`;
this.browser.messageManager.loadFrameScript(frameScript, false, true);
}
async loadURL(url, redirectUrl = undefined) {
@@ -673,17 +673,17 @@ var ExtensionTestUtils = {
this.fetchScopes = new Map();
// We need to load at least one frame script into every message
// manager to ensure that the scriptable wrapper for its global gets
// created before we try to access it externally. If we don't, we
// fail sanity checks on debug builds the first time we try to
// create a wrapper, because we should never have a global without a
// cached wrapper.
- Services.mm.loadFrameScript("data:text/javascript,//", true);
+ Services.mm.loadFrameScript("data:text/javascript,//", true, true);
let tmpD = this.profileDir.clone();
tmpD.append("tmp");
tmpD.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
let dirProvider = {
getFile(prop, persistent) {
--- a/toolkit/components/extensions/test/xpcshell/test_ext_content_security_policy.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_content_security_policy.js
@@ -102,17 +102,17 @@ async function testPolicy(customCSP = nu
function getCSP() {
let {cspJSON} = Cu.getObjectPrincipal(win);
return win.wrappedJSObject.JSON.parse(cspJSON);
}
Cu.exportFunction(getCSP, win, {defineAs: "getCSP"});
}, true);
}
let frameScriptURL = `data:,(${encodeURI(frameScript)}).call(this)`;
- Services.mm.loadFrameScript(frameScriptURL, true);
+ Services.mm.loadFrameScript(frameScriptURL, true, true);
info(`Testing CSP for policy: ${content_security_policy}`);
await extension.startup();
baseURL = await extension.awaitMessage("base-url");
--- a/toolkit/components/extensions/test/xpcshell/test_ext_permissions.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_permissions.js
@@ -31,17 +31,17 @@ function frameScript() {
},
});
}
async function withHandlingUserInput(extension, fn) {
let {messageManager} = extension.extension.groupFrameLoader;
if (!extensionHandlers.has(extension)) {
- messageManager.loadFrameScript(`data:,(${frameScript}).call(this)`, false);
+ messageManager.loadFrameScript(`data:,(${frameScript}).call(this)`, false, true);
extensionHandlers.add(extension);
}
await MessageChannel.sendMessage(messageManager, "ExtensionTest:HandleUserInput", true);
await fn();
await MessageChannel.sendMessage(messageManager, "ExtensionTest:HandleUserInput", false);
}
--- a/toolkit/components/processsingleton/MainProcessSingleton.js
+++ b/toolkit/components/processsingleton/MainProcessSingleton.js
@@ -60,18 +60,18 @@ MainProcessSingleton.prototype = {
observe(subject, topic, data) {
switch (topic) {
case "app-startup": {
Services.obs.addObserver(this, "xpcom-shutdown");
Services.obs.addObserver(this, "document-element-inserted");
// Load this script early so that console.* is initialized
// before other frame scripts.
- Services.mm.loadFrameScript("chrome://global/content/browser-content.js", true);
- Services.ppmm.loadProcessScript("chrome://global/content/process-content.js", true);
+ Services.mm.loadFrameScript("chrome://global/content/browser-content.js", true, true);
+ Services.ppmm.loadProcessScript("chrome://global/content/process-content.js", true, true);
Services.mm.addMessageListener("Search:AddEngine", this.addSearchEngine);
Services.ppmm.loadProcessScript("resource:///modules/ContentObservers.js", true);
break;
}
case "document-element-inserted":
// Set up Custom Elements for XUL windows before anything else happens
// in the document. Anything loaded here should be considered part of
--- a/toolkit/mozapps/extensions/addonManager.js
+++ b/toolkit/mozapps/extensions/addonManager.js
@@ -38,17 +38,17 @@ ChromeUtils.import("resource://gre/modul
ChromeUtils.import("resource://gre/modules/Services.jsm");
var gSingleton = null;
function amManager() {
ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
/* globals AddonManagerPrivate*/
- Services.mm.loadFrameScript(CHILD_SCRIPT, true);
+ Services.mm.loadFrameScript(CHILD_SCRIPT, true, true);
Services.mm.addMessageListener(MSG_INSTALL_ENABLED, this);
Services.mm.addMessageListener(MSG_INSTALL_ADDON, this);
Services.mm.addMessageListener(MSG_PROMISE_REQUEST, this);
Services.mm.addMessageListener(MSG_INSTALL_CLEANUP, this);
Services.mm.addMessageListener(MSG_ADDON_EVENT_REQ, this);
Services.obs.addObserver(this, "message-manager-close");
Services.obs.addObserver(this, "message-manager-disconnect");
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -3089,18 +3089,18 @@ var gDetailView = {
// removed from the document in the meantime (e.g. due to a rapid sequence
// of addon reload), ensure that the stack is also removed and return null.
stack.remove();
resolve(null);
return;
}
mm.loadFrameScript("chrome://extensions/content/ext-browser-content.js",
- false);
- mm.loadFrameScript("chrome://browser/content/content.js", false);
+ false, true);
+ mm.loadFrameScript("chrome://browser/content/content.js", false, true);
mm.addMessageListener("Extension:BrowserContentLoaded", messageListener);
mm.addMessageListener("Extension:BrowserResized", messageListener);
let browserOptions = {
fixedWidth: true,
isInline: true,
};