Bug 1818026 - stop loading page style actor stuff for every process all the time, r=mconley,emilio
Differential Revision: https://phabricator.services.mozilla.com/D170498
This commit is contained in:
@@ -6,28 +6,38 @@
|
||||
var EXPORTED_SYMBOLS = ["PageStyleChild"];
|
||||
|
||||
class PageStyleChild extends JSWindowActorChild {
|
||||
handleEvent(event) {
|
||||
// On page show, tell the parent all of the stylesheets this document has.
|
||||
if (event.type == "pageshow") {
|
||||
// If we are in the topmost browsing context,
|
||||
// delete the stylesheets from the previous page.
|
||||
if (this.browsingContext.top === this.browsingContext) {
|
||||
this.sendAsyncMessage("PageStyle:Clear");
|
||||
}
|
||||
|
||||
let window = event.target.ownerGlobal;
|
||||
window.requestIdleCallback(() => {
|
||||
if (!window || window.closed) {
|
||||
return;
|
||||
}
|
||||
let filteredStyleSheets = this._collectStyleSheets(window);
|
||||
this.sendAsyncMessage("PageStyle:Add", {
|
||||
filteredStyleSheets,
|
||||
authorStyleDisabled: this.docShell.contentViewer.authorStyleDisabled,
|
||||
preferredStyleSheetSet: this.document.preferredStyleSheetSet,
|
||||
});
|
||||
});
|
||||
actorCreated() {
|
||||
// C++ can create the actor and call us here once an "interesting" link
|
||||
// element gets added to the DOM. If pageload hasn't finished yet, just
|
||||
// wait for that by doing nothing; the actor registration event
|
||||
// listeners will ensure we get the pageshow event.
|
||||
// It is also possible we get created in response to the parent
|
||||
// sending us a message - in that case, it's still worth doing the
|
||||
// same things here:
|
||||
if (!this.browsingContext || !this.browsingContext.associatedWindow) {
|
||||
return;
|
||||
}
|
||||
let { document } = this.browsingContext.associatedWindow;
|
||||
if (document.readyState != "complete") {
|
||||
return;
|
||||
}
|
||||
// If we've already seen a pageshow, send stylesheets now:
|
||||
this.#collectAndSendSheets();
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
if (event?.type != "pageshow") {
|
||||
throw new Error("Unexpected event!");
|
||||
}
|
||||
|
||||
// On page show, tell the parent all of the stylesheets this document
|
||||
// has. If we are in the topmost browsing context, delete the stylesheets
|
||||
// from the previous page.
|
||||
if (this.browsingContext.top === this.browsingContext) {
|
||||
this.sendAsyncMessage("PageStyle:Clear");
|
||||
}
|
||||
|
||||
this.#collectAndSendSheets();
|
||||
}
|
||||
|
||||
receiveMessage(msg) {
|
||||
@@ -117,13 +127,28 @@ class PageStyleChild extends JSWindowActorChild {
|
||||
}
|
||||
}
|
||||
|
||||
#collectAndSendSheets() {
|
||||
let window = this.browsingContext.associatedWindow;
|
||||
window.requestIdleCallback(() => {
|
||||
if (!window || window.closed) {
|
||||
return;
|
||||
}
|
||||
let filteredStyleSheets = this.#collectStyleSheets(window);
|
||||
this.sendAsyncMessage("PageStyle:Add", {
|
||||
filteredStyleSheets,
|
||||
authorStyleDisabled: this.docShell.contentViewer.authorStyleDisabled,
|
||||
preferredStyleSheetSet: this.document.preferredStyleSheetSet,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stylesheets that have a title (and thus can be switched) in this
|
||||
* webpage.
|
||||
*
|
||||
* @param content The window object for the page.
|
||||
*/
|
||||
_collectStyleSheets(content) {
|
||||
#collectStyleSheets(content) {
|
||||
let result = [];
|
||||
let document = content.document;
|
||||
|
||||
|
||||
@@ -6,27 +6,76 @@
|
||||
var EXPORTED_SYMBOLS = ["PageStyleParent"];
|
||||
|
||||
class PageStyleParent extends JSWindowActorParent {
|
||||
// This has the most recent information about the content stylesheets for
|
||||
// that actor. It's populated via the PageStyle:Add and PageStyle:Clear
|
||||
// messages from the content process. It has the following structure:
|
||||
//
|
||||
// filteredStyleSheets (Array):
|
||||
// An Array of objects with a filtered list representing all stylesheets
|
||||
// that the current page offers. Each object has the following members:
|
||||
//
|
||||
// title (String):
|
||||
// The title of the stylesheet
|
||||
//
|
||||
// disabled (bool):
|
||||
// Whether or not the stylesheet is currently applied
|
||||
//
|
||||
// href (String):
|
||||
// The URL of the stylesheet. Stylesheets loaded via a data URL will
|
||||
// have this property set to null.
|
||||
//
|
||||
// authorStyleDisabled (bool):
|
||||
// Whether or not the user currently has "No Style" selected for
|
||||
// the current page.
|
||||
//
|
||||
// preferredStyleSheetSet (bool):
|
||||
// Whether or not the user currently has the "Default" style selected
|
||||
// for the current page.
|
||||
#styleSheetInfo = null;
|
||||
|
||||
receiveMessage(msg) {
|
||||
// The top browser.
|
||||
// Check if things are alive:
|
||||
let browser = this.browsingContext.top.embedderElement;
|
||||
if (!browser) {
|
||||
return;
|
||||
}
|
||||
|
||||
let permanentKey = browser.permanentKey;
|
||||
let window = browser.ownerGlobal;
|
||||
let styleMenu = window.gPageStyleMenu;
|
||||
if (window.closed || !styleMenu) {
|
||||
if (!browser || browser.ownerGlobal.closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We always store information at the top of the frame tree.
|
||||
let actor = this.browsingContext.top.currentWindowGlobal.getActor(
|
||||
"PageStyle"
|
||||
);
|
||||
switch (msg.name) {
|
||||
case "PageStyle:Add":
|
||||
styleMenu.addBrowserStyleSheets(msg.data, permanentKey);
|
||||
actor.addSheetInfo(msg.data);
|
||||
break;
|
||||
case "PageStyle:Clear":
|
||||
styleMenu.clearBrowserStyleSheets(permanentKey);
|
||||
if (actor == this) {
|
||||
this.#styleSheetInfo = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add/append styleSheets to the _pageStyleSheets weakmap.
|
||||
* @param newSheetData
|
||||
* The stylesheet data, including new stylesheets to add,
|
||||
* and the preferred stylesheet set for this document.
|
||||
*/
|
||||
addSheetInfo(newSheetData) {
|
||||
let info = this.getSheetInfo();
|
||||
info.filteredStyleSheets.push(...newSheetData.filteredStyleSheets);
|
||||
info.preferredStyleSheetSet ||= newSheetData.preferredStyleSheetSet;
|
||||
}
|
||||
|
||||
getSheetInfo() {
|
||||
if (!this.#styleSheetInfo) {
|
||||
this.#styleSheetInfo = {
|
||||
filteredStyleSheets: [],
|
||||
authorStyleDisabled: false,
|
||||
preferredStyleSheetSet: true,
|
||||
};
|
||||
}
|
||||
return this.#styleSheetInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,71 +6,24 @@
|
||||
/* eslint-env mozilla/browser-window */
|
||||
|
||||
var gPageStyleMenu = {
|
||||
// This maps from a <browser> element (or, more specifically, a
|
||||
// browser's permanentKey) to an Object that contains the most recent
|
||||
// information about the browser content's stylesheets. That Object
|
||||
// is populated via the PageStyle:StyleSheets message from the content
|
||||
// process. The Object should have the following structure:
|
||||
//
|
||||
// filteredStyleSheets (Array):
|
||||
// An Array of objects with a filtered list representing all stylesheets
|
||||
// that the current page offers. Each object has the following members:
|
||||
//
|
||||
// title (String):
|
||||
// The title of the stylesheet
|
||||
//
|
||||
// disabled (bool):
|
||||
// Whether or not the stylesheet is currently applied
|
||||
//
|
||||
// href (String):
|
||||
// The URL of the stylesheet. Stylesheets loaded via a data URL will
|
||||
// have this property set to null.
|
||||
//
|
||||
// authorStyleDisabled (bool):
|
||||
// Whether or not the user currently has "No Style" selected for
|
||||
// the current page.
|
||||
//
|
||||
// preferredStyleSheetSet (bool):
|
||||
// Whether or not the user currently has the "Default" style selected
|
||||
// for the current page.
|
||||
//
|
||||
_pageStyleSheets: new WeakMap(),
|
||||
|
||||
/**
|
||||
* Add/append styleSheets to the _pageStyleSheets weakmap.
|
||||
* @param styleSheets
|
||||
* The stylesheets to add, including the preferred
|
||||
* stylesheet set for this document.
|
||||
* @param permanentKey
|
||||
* The permanent key of the browser that
|
||||
* these stylesheets come from.
|
||||
*/
|
||||
addBrowserStyleSheets(styleSheets, permanentKey) {
|
||||
let sheetData = this._pageStyleSheets.get(permanentKey);
|
||||
if (!sheetData) {
|
||||
this._pageStyleSheets.set(permanentKey, styleSheets);
|
||||
return;
|
||||
}
|
||||
sheetData.filteredStyleSheets.push(...styleSheets.filteredStyleSheets);
|
||||
sheetData.preferredStyleSheetSet =
|
||||
sheetData.preferredStyleSheetSet || styleSheets.preferredStyleSheetSet;
|
||||
},
|
||||
|
||||
clearBrowserStyleSheets(permanentKey) {
|
||||
this._pageStyleSheets.delete(permanentKey);
|
||||
},
|
||||
|
||||
_getStyleSheetInfo(browser) {
|
||||
let data = this._pageStyleSheets.get(browser.permanentKey);
|
||||
if (!data) {
|
||||
return {
|
||||
let actor = browser.browsingContext.currentWindowGlobal?.getActor(
|
||||
"PageStyle"
|
||||
);
|
||||
let styleSheetInfo;
|
||||
if (actor) {
|
||||
styleSheetInfo = actor.getSheetInfo();
|
||||
} else {
|
||||
// Fallback if the actor is missing or we don't have a window global.
|
||||
// It's unlikely things will work well but let's be optimistic,
|
||||
// rather than throwing exceptions immediately.
|
||||
styleSheetInfo = {
|
||||
filteredStyleSheets: [],
|
||||
authorStyleDisabled: false,
|
||||
preferredStyleSheetSet: true,
|
||||
};
|
||||
}
|
||||
|
||||
return data;
|
||||
return styleSheetInfo;
|
||||
},
|
||||
|
||||
fillPopup(menuPopup) {
|
||||
@@ -157,13 +110,10 @@ var gPageStyleMenu = {
|
||||
* @param title The title of the stylesheet to switch to.
|
||||
*/
|
||||
switchStyleSheet(title) {
|
||||
let { permanentKey } = gBrowser.selectedBrowser;
|
||||
let sheetData = this._pageStyleSheets.get(permanentKey);
|
||||
if (sheetData && sheetData.filteredStyleSheets) {
|
||||
sheetData.authorStyleDisabled = false;
|
||||
for (let sheet of sheetData.filteredStyleSheets) {
|
||||
sheet.disabled = sheet.title !== title;
|
||||
}
|
||||
let sheetData = this._getStyleSheetInfo(gBrowser.selectedBrowser);
|
||||
sheetData.authorStyleDisabled = false;
|
||||
for (let sheet of sheetData.filteredStyleSheets) {
|
||||
sheet.disabled = sheet.title !== title;
|
||||
}
|
||||
this._sendMessageToAll("PageStyle:Switch", { title });
|
||||
},
|
||||
@@ -172,11 +122,8 @@ var gPageStyleMenu = {
|
||||
* Disable all stylesheets. Called with View > Page Style > No Style.
|
||||
*/
|
||||
disableStyle() {
|
||||
let { permanentKey } = gBrowser.selectedBrowser;
|
||||
let sheetData = this._pageStyleSheets.get(permanentKey);
|
||||
if (sheetData) {
|
||||
sheetData.authorStyleDisabled = true;
|
||||
}
|
||||
let sheetData = this._getStyleSheetInfo(gBrowser.selectedBrowser);
|
||||
sheetData.authorStyleDisabled = true;
|
||||
this._sendMessageToAll("PageStyle:Disable", {});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -34,7 +34,6 @@ const known_scripts = {
|
||||
"resource:///actors/AboutReaderChild.sys.mjs",
|
||||
"resource:///actors/BrowserTabChild.sys.mjs",
|
||||
"resource:///actors/LinkHandlerChild.jsm",
|
||||
"resource:///actors/PageStyleChild.jsm",
|
||||
"resource:///actors/SearchSERPTelemetryChild.jsm",
|
||||
"resource://gre/actors/ContentMetaChild.jsm",
|
||||
"resource://gre/modules/Readerable.jsm",
|
||||
|
||||
@@ -44,9 +44,6 @@ const known_scripts = {
|
||||
// Logging related
|
||||
"resource://gre/modules/Log.sys.mjs",
|
||||
|
||||
// Browser front-end
|
||||
"resource:///actors/PageStyleChild.jsm",
|
||||
|
||||
// Telemetry
|
||||
"resource://gre/modules/TelemetryControllerBase.sys.mjs", // bug 1470339
|
||||
"resource://gre/modules/TelemetryControllerContent.sys.mjs", // bug 1470339
|
||||
|
||||
@@ -646,13 +646,10 @@ let JSWINDOWACTORS = {
|
||||
child: {
|
||||
moduleURI: "resource:///actors/PageStyleChild.jsm",
|
||||
events: {
|
||||
pageshow: {},
|
||||
pageshow: { createActor: false },
|
||||
},
|
||||
},
|
||||
|
||||
// Only matching web pages, as opposed to internal about:, chrome: or
|
||||
// resource: pages. See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns
|
||||
matches: ["*://*/*", "file:///*"],
|
||||
messageManagerGroups: ["browsers"],
|
||||
allFrames: true,
|
||||
},
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIThreadInternal.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
#include "nsQueryActor.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "mozilla/dom/MediaList.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
@@ -1617,6 +1618,13 @@ void Loader::NotifyObservers(SheetLoadData& aData, nsresult aStatus) {
|
||||
DecrementOngoingLoadCount();
|
||||
}
|
||||
}
|
||||
if (!aData.mTitle.IsEmpty() && NS_SUCCEEDED(aStatus)) {
|
||||
// Force creating the page style actor, if available. This will no-op
|
||||
// if no actor with this name is registered (outside of desktop Firefox).
|
||||
nsCOMPtr<nsISupports> pageStyleActor =
|
||||
do_QueryActor("PageStyle", mDocument);
|
||||
Unused << pageStyleActor;
|
||||
}
|
||||
|
||||
if (aData.mMustNotify) {
|
||||
if (nsCOMPtr<nsICSSLoaderObserver> observer = std::move(aData.mObserver)) {
|
||||
|
||||
Reference in New Issue
Block a user