Bug 1529762 - Send PageStyle information up from pageshow events only after idle. r=Felipe
authorMike Conley <mconley@mozilla.com>
Fri, 08 Mar 2019 20:22:37 +0000
changeset 521181 92aa678ac36b
parent 521180 cd0a4ead024e
child 521182 8ac8ed5ac772
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersFelipe
bugs1529762
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1529762 - Send PageStyle information up from pageshow events only after idle. r=Felipe Differential Revision: https://phabricator.services.mozilla.com/D22521
browser/actors/PageStyleChild.jsm
browser/base/content/browser.js
browser/base/content/test/general/browser_page_style_menu.js
browser/base/content/test/general/browser_page_style_menu_update.js
browser/base/content/test/general/head.js
--- a/browser/actors/PageStyleChild.jsm
+++ b/browser/actors/PageStyleChild.jsm
@@ -10,22 +10,24 @@ const {ActorChild} = ChromeUtils.import(
 
 class PageStyleChild extends ActorChild {
   getViewer(content) {
     return content.docShell.contentViewer;
   }
 
   sendStyleSheetInfo(mm) {
     let content = mm.content;
-    let filteredStyleSheets = this._filterStyleSheets(this.getAllStyleSheets(content), 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,
+      mm.sendAsyncMessage("PageStyle:StyleSheets", {
+        filteredStyleSheets,
+        authorStyleDisabled: this.getViewer(content).authorStyleDisabled,
+        preferredStyleSheetSet: content.document.preferredStyleSheetSet,
+      });
     });
   }
 
   getAllStyleSheets(frameset) {
     let selfSheets = Array.slice(frameset.document.styleSheets);
     let subSheets = Array.map(frameset.frames, frame => this.getAllStyleSheets(frame));
     return selfSheets.concat(...subSheets);
   }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6500,17 +6500,19 @@ var gPageStyleMenu = {
   //   Whether or not the user currently has the "Default" style selected
   //   for the current page.
   //
   _pageStyleSheets: new WeakMap(),
 
   init() {
     let mm = window.messageManager;
     mm.addMessageListener("PageStyle:StyleSheets", (msg) => {
-      this._pageStyleSheets.set(msg.target.permanentKey, msg.data);
+      if (msg.target.permanentKey) {
+        this._pageStyleSheets.set(msg.target.permanentKey, msg.data);
+      }
     });
   },
 
   /**
    * 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.
    *
--- a/browser/base/content/test/general/browser_page_style_menu.js
+++ b/browser/base/content/test/general/browser_page_style_menu.js
@@ -1,33 +1,10 @@
 "use strict";
 
-/**
- * Stylesheets are updated for a browser after the pageshow event.
- * This helper function returns a Promise that waits for that pageshow
- * event, and then resolves on the next tick to ensure that gPageStyleMenu
- * has had a chance to update the stylesheets.
- *
- * @param browser
- *        The <xul:browser> to wait for.
- * @return Promise
- */
-function promiseStylesheetsUpdated(browser) {
-  return ContentTask.spawn(browser, { PAGE }, async function(args) {
-    return new Promise((resolve) => {
-      addEventListener("pageshow", function onPageShow(e) {
-        if (e.target.location == args.PAGE) {
-          removeEventListener("pageshow", onPageShow);
-          content.setTimeout(resolve, 0);
-        }
-      });
-    });
-  });
-}
-
 const PAGE = "http://example.com/browser/browser/base/content/test/general/page_style_sample.html";
 
 /*
  * Test that the right stylesheets do (and others don't) show up
  * in the page style menu.
  */
 add_task(async function() {
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", false);
--- a/browser/base/content/test/general/browser_page_style_menu_update.js
+++ b/browser/base/content/test/general/browser_page_style_menu_update.js
@@ -1,36 +1,13 @@
 "use strict";
 
 const PAGE = "http://example.com/browser/browser/base/content/test/general/page_style_sample.html";
 
 /**
- * Stylesheets are updated for a browser after the pageshow event.
- * This helper function returns a Promise that waits for that pageshow
- * event, and then resolves on the next tick to ensure that gPageStyleMenu
- * has had a chance to update the stylesheets.
- *
- * @param browser
- *        The <xul:browser> to wait for.
- * @return Promise
- */
-function promiseStylesheetsUpdated(browser) {
-  return ContentTask.spawn(browser, { PAGE }, async function(args) {
-    return new Promise((resolve) => {
-      addEventListener("pageshow", function onPageShow(e) {
-        if (e.target.location == args.PAGE) {
-          removeEventListener("pageshow", onPageShow);
-          content.setTimeout(resolve, 0);
-        }
-      });
-    });
-  });
-}
-
-/**
  * Tests that the Page Style menu shows the currently
  * selected Page Style after a new one has been selected.
  */
 add_task(async function() {
   let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", false);
   let browser = tab.linkedBrowser;
 
   await BrowserTestUtils.loadURI(browser, PAGE);
@@ -44,23 +21,18 @@ add_task(async function() {
   let selected = menupopup.querySelector("menuitem[checked='true']");
   is(selected.getAttribute("label"), "6", "Should have '6' stylesheet selected by default");
 
   // Now select stylesheet "1"
   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. Because messages are
-  // guaranteed to be sent in order, we'll make sure we do the check
-  // after the parent has been updated by yielding until the child
-  // has finished running a ContentTask for us.
-  await ContentTask.spawn(browser, {}, async function() {
-    dump("\nJust wasting some time.\n");
-  });
+  // 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
   selected = menupopup.querySelector("menuitem[checked='true']");
   is(selected.getAttribute("label"), "1", "Should now have stylesheet 1 selected");
 
   BrowserTestUtils.removeTab(tab);
--- a/browser/base/content/test/general/head.js
+++ b/browser/base/content/test/general/head.js
@@ -505,8 +505,23 @@ function getCertExceptionDialog(aLocatio
     for (let {domWindow} of containedDocShells) {
       if (domWindow.location.href == aLocation) {
         return domWindow.document;
       }
     }
   }
   return undefined;
 }
+
+/**
+ * Waits for the message from content to update the Page Style menu.
+ *
+ * @param browser
+ *        The <xul:browser> to wait for.
+ * @return Promise
+ */
+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));
+}