From 7a9af1e313c8ae279b62e5f9a56bf1f3b972cdca Mon Sep 17 00:00:00 2001 From: Csoregi Natalia Date: Thu, 24 Oct 2019 23:51:59 +0300 Subject: [PATCH] Backed out changeset 530bcc00246e (bug 1576918) for browser-chrome failures on browser_dismissFooter.js. CLOSED TREE --- browser/actors/PageStyleChild.jsm | 123 ++++++++++-------- browser/actors/PageStyleParent.jsm | 33 ----- browser/actors/moz.build | 1 - browser/base/content/browser.js | 82 ++---------- .../test/general/browser_page_style_menu.js | 2 +- .../general/browser_page_style_menu_update.js | 7 +- browser/base/content/test/general/head.js | 24 ++-- browser/components/BrowserGlue.jsm | 31 ++--- 8 files changed, 113 insertions(+), 190 deletions(-) delete mode 100644 browser/actors/PageStyleParent.jsm diff --git a/browser/actors/PageStyleChild.jsm b/browser/actors/PageStyleChild.jsm index 891e85e6be09..76149e7d31dc 100644 --- a/browser/actors/PageStyleChild.jsm +++ b/browser/actors/PageStyleChild.jsm @@ -1,90 +1,103 @@ /* 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"; const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); 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"); - } +const { ActorChild } = ChromeUtils.import( + "resource://gre/modules/ActorChild.jsm" +); - let window = event.target.ownerGlobal; - window.requestIdleCallback(() => { - if (!window || window.closed) { - return; - } - let styleSheets = Array.from(this.document.styleSheets); - let filteredStyleSheets = this._filterStyleSheets(styleSheets, window); +class PageStyleChild extends ActorChild { + getViewer(content) { + return content.docShell.contentViewer; + } - this.sendAsyncMessage("PageStyle:Add", { - filteredStyleSheets, - authorStyleDisabled: this.docShell.contentViewer.authorStyleDisabled, - preferredStyleSheetSet: this.document.preferredStyleSheetSet, - }); + sendStyleSheetInfo(mm) { + let content = mm.content; + content.requestIdleCallback(() => { + let filteredStyleSheets = this._filterStyleSheets( + this.getAllStyleSheets(content), + content + ); + + mm.sendAsyncMessage("PageStyle:StyleSheets", { + filteredStyleSheets, + authorStyleDisabled: this.getViewer(content).authorStyleDisabled, + preferredStyleSheetSet: content.document.preferredStyleSheetSet, }); - } + }); + } + + getAllStyleSheets(frameset) { + let selfSheets = Array.from(frameset.document.styleSheets); + let subSheets = Array.from(frameset.frames, frame => + this.getAllStyleSheets(frame) + ); + return selfSheets.concat(...subSheets); } receiveMessage(msg) { + let content = msg.target.content; switch (msg.name) { - // Sent when the page's enabled style sheet is changed. case "PageStyle:Switch": - this.docShell.contentViewer.authorStyleDisabled = false; - this._switchStylesheet(msg.data.title); + this.getViewer(content).authorStyleDisabled = false; + this._stylesheetSwitchAll(content, msg.data.title); break; - // Sent when "No Style" is chosen. + case "PageStyle:Disable": - this.docShell.contentViewer.authorStyleDisabled = true; + this.getViewer(content).authorStyleDisabled = true; break; } + + this.sendStyleSheetInfo(msg.target); + } + + handleEvent(event) { + let win = event.target.ownerGlobal; + if (win != win.top) { + return; + } + + let mm = win.docShell.messageManager; + this.sendStyleSheetInfo(mm); + } + + _stylesheetSwitchAll(frameset, title) { + if (!title || this._stylesheetInFrame(frameset, title)) { + this._stylesheetSwitchFrame(frameset, title); + } + + for (let i = 0; i < frameset.frames.length; i++) { + // Recurse into sub-frames. + this._stylesheetSwitchAll(frameset.frames[i], title); + } } - /** - * Switch the stylesheet so that only the sheet with the given title is enabled. - */ - _switchStylesheet(title) { - let docStyleSheets = this.document.styleSheets; + _stylesheetSwitchFrame(frame, title) { + var docStyleSheets = frame.document.styleSheets; - // Does this doc contain a stylesheet with this title? - // If not, it's a subframe's stylesheet that's being changed, - // so no need to disable stylesheets here. - let docContainsStyleSheet = false; - for (let docStyleSheet of docStyleSheets) { - if (docStyleSheet.title === title) { - docContainsStyleSheet = true; - break; - } - } - - for (let docStyleSheet of docStyleSheets) { + for (let i = 0; i < docStyleSheets.length; ++i) { + let docStyleSheet = docStyleSheets[i]; if (docStyleSheet.title) { - if (docContainsStyleSheet) { - docStyleSheet.disabled = docStyleSheet.title !== title; - } + docStyleSheet.disabled = docStyleSheet.title != title; } else if (docStyleSheet.disabled) { docStyleSheet.disabled = false; } } } - /** - * Filter the stylesheets that actually apply to this webpage. - * @param styleSheets The list of stylesheets from the document. - * @param content The window object that the webpage lives in. - */ + _stylesheetInFrame(frame, title) { + return Array.from(frame.document.styleSheets).some( + styleSheet => styleSheet.title == title + ); + } + _filterStyleSheets(styleSheets, content) { let result = []; - // Only stylesheets with a title can act as an alternative stylesheet. for (let currentStyleSheet of styleSheets) { if (!currentStyleSheet.title) { continue; @@ -102,7 +115,7 @@ class PageStyleChild extends JSWindowActorChild { try { if ( !currentStyleSheet.ownerNode || - // Special-case style nodes, which have no href. + // special-case style nodes, which have no href currentStyleSheet.ownerNode.nodeName.toLowerCase() != "style" ) { URI = Services.io.newURI(currentStyleSheet.href); diff --git a/browser/actors/PageStyleParent.jsm b/browser/actors/PageStyleParent.jsm deleted file mode 100644 index 034380bdb5f1..000000000000 --- a/browser/actors/PageStyleParent.jsm +++ /dev/null @@ -1,33 +0,0 @@ -/* 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 = ["PageStyleParent"]; - -class PageStyleParent extends JSWindowActorParent { - receiveMessage(msg) { - // The top browser. - let browser = this.browsingContext.top.embedderElement; - let permanentKey = browser.permanentKey; - let window = browser.ownerGlobal; - if (window.closed) { - return; - } - let styleMenu = window.gPageStyleMenu; - - switch (msg.name) { - case "PageStyle:Add": - if (browser.outerBrowser) { - // We are in RDM mode and we probably - // want to work with the outer browser. - browser = browser.outerBrowser; - } - styleMenu.addBrowserStyleSheets(msg.data, permanentKey); - break; - case "PageStyle:Clear": - styleMenu.clearBrowserStyleSheets(permanentKey); - break; - } - } -} diff --git a/browser/actors/moz.build b/browser/actors/moz.build index 2f5f7c58ca0a..c8aa7237ed1e 100644 --- a/browser/actors/moz.build +++ b/browser/actors/moz.build @@ -41,7 +41,6 @@ FINAL_TARGET_FILES.actors += [ 'OfflineAppsChild.jsm', 'PageInfoChild.jsm', 'PageStyleChild.jsm', - 'PageStyleParent.jsm', 'PluginChild.jsm', 'PluginParent.jsm', 'PromptParent.jsm', diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 753a7af7034b..51fa8cc096e6 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1808,6 +1808,7 @@ var gBrowserInit = { // message sent between when the frame script is loaded and when // the listener is registered. DOMEventHandler.init(); + gPageStyleMenu.init(); LanguageDetectionListener.init(); BrowserOnClick.init(); CaptivePortalWatcher.init(); @@ -7729,28 +7730,17 @@ var gPageStyleMenu = { // _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; + init() { + let mm = window.messageManager; + mm.addMessageListener("PageStyle:StyleSheets", msg => { + if (msg.target.permanentKey) { + this._pageStyleSheets.set(msg.target.permanentKey, msg.data); + } + }); }, /** - * Return an array of Objects representing stylesheets in a + * Returns an array of Objects representing stylesheets in a * browser. Note that the pageshow event needs to fire in content * before this information will be available. * @@ -7774,10 +7764,6 @@ var gPageStyleMenu = { return data.filteredStyleSheets; }, - clearBrowserStyleSheets(permanentKey) { - this._pageStyleSheets.delete(permanentKey); - }, - _getStyleSheetInfo(browser) { let data = this._pageStyleSheets.get(browser.permanentKey); if (!data) { @@ -7846,56 +7832,14 @@ var gPageStyleMenu = { sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets; }, - /** - * Send a message to all PageStyleParents by walking the BrowsingContext tree. - * @param message - * The string message to send to each PageStyleChild. - * @param data - * The data to send to each PageStyleChild within the message. - */ - _sendMessageToAll(message, data) { - let contextsToVisit = [gBrowser.selectedBrowser.browsingContext]; - while (contextsToVisit.length) { - let currentContext = contextsToVisit.pop(); - let global = currentContext.currentWindowGlobal; - - if (!global) { - continue; - } - - let actor = global.getActor("PageStyle"); - actor.sendAsyncMessage(message, data); - - contextsToVisit.push(...currentContext.getChildren()); - } - }, - - /** - * Switch the stylesheet of all documents in the current browser. - * @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; - } - } - this._sendMessageToAll("PageStyle:Switch", { title }); + let mm = gBrowser.selectedBrowser.messageManager; + mm.sendAsyncMessage("PageStyle:Switch", { title }); }, - /** - * 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; - } - this._sendMessageToAll("PageStyle:Disable", {}); + let mm = gBrowser.selectedBrowser.messageManager; + mm.sendAsyncMessage("PageStyle:Disable"); }, }; diff --git a/browser/base/content/test/general/browser_page_style_menu.js b/browser/base/content/test/general/browser_page_style_menu.js index 6703a643f0ec..56c12ccff41c 100644 --- a/browser/base/content/test/general/browser_page_style_menu.js +++ b/browser/base/content/test/general/browser_page_style_menu.js @@ -15,7 +15,7 @@ add_task(async function() { ); let browser = tab.linkedBrowser; await BrowserTestUtils.loadURI(browser, PAGE); - await promiseStylesheetsLoaded(tab, 17); + await promiseStylesheetsUpdated(browser); let menupopup = document.getElementById("pageStyleMenu").menupopup; gPageStyleMenu.fillPopup(menupopup); diff --git a/browser/base/content/test/general/browser_page_style_menu_update.js b/browser/base/content/test/general/browser_page_style_menu_update.js index eaebdd234ec4..144a13829081 100644 --- a/browser/base/content/test/general/browser_page_style_menu_update.js +++ b/browser/base/content/test/general/browser_page_style_menu_update.js @@ -14,8 +14,9 @@ add_task(async function() { false ); let browser = tab.linkedBrowser; + await BrowserTestUtils.loadURI(browser, PAGE); - await promiseStylesheetsLoaded(tab, 17); + await promiseStylesheetsUpdated(browser); let menupopup = document.getElementById("pageStyleMenu").menupopup; gPageStyleMenu.fillPopup(menupopup); @@ -33,6 +34,10 @@ add_task(async function() { let target = menupopup.querySelector("menuitem[label='1']"); target.click(); + // Now we need to wait for the content process to send its stylesheet + // update for the selected tab to the parent. + await promiseStylesheetsUpdated(browser); + gPageStyleMenu.fillPopup(menupopup); // gPageStyleMenu empties out the menu between opens, so we need // to get a new reference to the selected menuitem diff --git a/browser/base/content/test/general/head.js b/browser/base/content/test/general/head.js index 15d247525fdd..6f6aaf19f6b1 100644 --- a/browser/base/content/test/general/head.js +++ b/browser/base/content/test/general/head.js @@ -530,20 +530,18 @@ async function loadBadCertPage(url) { } /** - * Waits for the stylesheets to be loaded into the browser menu. + * Waits for the message from content to update the Page Style menu. * - * @param tab - * The tab that contains the webpage we're testing. - * @param styleSheetCount - * How many stylesheets we expect to be loaded. + * @param browser + * The to wait for. * @return Promise */ -async function promiseStylesheetsLoaded(tab, styleSheetCount) { - let styleMenu = tab.ownerGlobal.gPageStyleMenu; - let permanentKey = tab.permanentKey; - - await TestUtils.waitForCondition(() => { - let menu = styleMenu._pageStyleSheets.get(permanentKey); - return menu && menu.filteredStyleSheets.length >= styleSheetCount; - }, "waiting for style sheets to load"); +async function promiseStylesheetsUpdated(browser) { + await BrowserTestUtils.waitForMessage( + browser.messageManager, + "PageStyle:StyleSheets" + ); + // Resolve on the next tick of the event loop to give the Page Style + // menu code an opportunity to update. + await new Promise(resolve => Services.tm.dispatchToMainThread(resolve)); } diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index 5a392dbc1976..6c18c46062aa 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -104,23 +104,6 @@ let ACTORS = { allFrames: true, }, - PageStyle: { - parent: { - moduleURI: "resource:///actors/PageStyleParent.jsm", - }, - child: { - moduleURI: "resource:///actors/PageStyleChild.jsm", - events: { - pageshow: {}, - }, - }, - - // 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: ["*://*/*"], - allFrames: true, - }, - Plugin: { parent: { moduleURI: "resource:///actors/PluginParent.jsm", @@ -330,6 +313,20 @@ let LEGACY_ACTORS = { }, }, + PageStyle: { + child: { + module: "resource:///actors/PageStyleChild.jsm", + group: "browsers", + events: { + pageshow: {}, + }, + messages: ["PageStyle:Switch", "PageStyle:Disable"], + // 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: ["*://*/*"], + }, + }, + SearchTelemetry: { child: { module: "resource:///actors/SearchTelemetryChild.jsm",