Backed out 4 changesets (bug 1480319) for mochitest failures on test_ext_webrequest_filter.html. CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Thu, 16 Aug 2018 03:46:56 +0300
changeset 486940 e19fc7991514a647468e3b80c798db58b06cf15b
parent 486939 dc2c0b075c0ec9bb9277835fbe510f81a3d0d2f9
child 486941 542197624ba293765e206322c3e828242d2fd875
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1480319
milestone63.0a1
backs out186ad2d171c1f2348703b119ad5983515ead58a7
0161b3bbc9d21cb915ffb3fe6b0aead720141c0b
30a0f8cede1eb5d4bde81fd3d05006d2d2062433
aa14dcca91fb46a6e44a68d2b0370dd0eff8d400
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
Backed out 4 changesets (bug 1480319) for mochitest failures on test_ext_webrequest_filter.html. CLOSED TREE Backed out changeset 186ad2d171c1 (bug 1480319) Backed out changeset 0161b3bbc9d2 (bug 1480319) Backed out changeset 30a0f8cede1e (bug 1480319) Backed out changeset aa14dcca91fb (bug 1480319)
browser/actors/LinkHandlerChild.jsm
browser/actors/moz.build
browser/base/content/content.js
browser/base/content/test/performance/browser_startup_content.js
browser/components/nsBrowserGlue.js
browser/modules/ContentLinkHandler.jsm
browser/modules/FaviconLoader.jsm
browser/modules/moz.build
deleted file mode 100644
--- a/browser/actors/LinkHandlerChild.jsm
+++ /dev/null
@@ -1,182 +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";
-
-const EXPORTED_SYMBOLS = ["LinkHandlerChild"];
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
-
-ChromeUtils.defineModuleGetter(this, "Feeds",
-  "resource:///modules/Feeds.jsm");
-ChromeUtils.defineModuleGetter(this, "FaviconLoader",
-  "resource:///modules/FaviconLoader.jsm");
-
-class LinkHandlerChild extends ActorChild {
-  constructor(mm) {
-    super(mm);
-
-    this.seenTabIcon = false;
-    this._iconLoader = null;
-  }
-
-  get iconLoader() {
-    if (!this._iconLoader) {
-      this._iconLoader = new FaviconLoader(this.mm);
-    }
-    return this._iconLoader;
-  }
-
-  addRootIcon() {
-    if (!this.seenTabIcon && Services.prefs.getBoolPref("browser.chrome.guess_favicon", true) &&
-        Services.prefs.getBoolPref("browser.chrome.site_icons", true)) {
-      // Inject the default icon. Use documentURIObject so that we do the right
-      // thing with about:-style error pages. See bug 453442
-      let baseURI = this.content.document.documentURIObject;
-      if (["http", "https"].includes(baseURI.scheme)) {
-        this.seenTabIcon = true;
-        this.iconLoader.addDefaultIcon(baseURI);
-      }
-    }
-  }
-
-  onHeadParsed(event) {
-    if (event.target.ownerDocument != this.content.document) {
-      return;
-    }
-
-    // Per spec icons are meant to be in the <head> tag so we should have seen
-    // all the icons now so add the root icon if no other tab icons have been
-    // seen.
-    this.addRootIcon();
-
-    // We're likely done with icon parsing so load the pending icons now.
-    if (this._iconLoader) {
-      this._iconLoader.onPageShow();
-    }
-  }
-
-  onPageShow(event) {
-    if (event.target != this.content.document) {
-      return;
-    }
-
-    this.addRootIcon();
-
-    if (this._iconLoader) {
-      this._iconLoader.onPageShow();
-    }
-  }
-
-  onPageHide(event) {
-    if (event.target != this.content.document) {
-      return;
-    }
-
-    if (this._iconLoader) {
-      this._iconLoader.onPageHide();
-    }
-  }
-
-  onLinkEvent(event) {
-    let link = event.target;
-    // Ignore sub-frames (bugs 305472, 479408).
-    if (link.ownerGlobal != this.content) {
-      return;
-    }
-
-    let rel = link.rel && link.rel.toLowerCase();
-    if (!rel || !link.href)
-      return;
-
-    // Note: following booleans only work for the current link, not for the
-    // whole content
-    let feedAdded = false;
-    let iconAdded = false;
-    let searchAdded = false;
-    let rels = {};
-    for (let relString of rel.split(/\s+/))
-      rels[relString] = true;
-
-    for (let relVal in rels) {
-      let isRichIcon = false;
-
-      switch (relVal) {
-        case "feed":
-        case "alternate":
-          if (!feedAdded && event.type == "DOMLinkAdded") {
-            if (!rels.feed && rels.alternate && rels.stylesheet)
-              break;
-
-            if (Feeds.isValidFeed(link, link.ownerDocument.nodePrincipal, "feed" in rels)) {
-              this.mm.sendAsyncMessage("Link:AddFeed", {
-                type: link.type,
-                href: link.href,
-                title: link.title,
-              });
-              feedAdded = true;
-            }
-          }
-          break;
-        case "apple-touch-icon":
-        case "apple-touch-icon-precomposed":
-        case "fluid-icon":
-          isRichIcon = true;
-        case "icon":
-          if (iconAdded || link.hasAttribute("mask")) { // Masked icons are not supported yet.
-            break;
-          }
-
-          if (!Services.prefs.getBoolPref("browser.chrome.site_icons", true)) {
-            return;
-          }
-
-          let iconInfo = FaviconLoader.makeFaviconFromLink(link, isRichIcon);
-          if (iconInfo) {
-            iconAdded = true;
-            if (!isRichIcon) {
-              this.seenTabIcon = true;
-            }
-            this.iconLoader.addIcon(iconInfo);
-          }
-          break;
-        case "search":
-          if (Services.policies && !Services.policies.isAllowed("installSearchEngine")) {
-            break;
-          }
-
-          if (!searchAdded && event.type == "DOMLinkAdded") {
-            let type = link.type && link.type.toLowerCase();
-            type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
-
-            let re = /^(?:https?|ftp):/i;
-            if (type == "application/opensearchdescription+xml" && link.title &&
-                re.test(link.href)) {
-              let engine = { title: link.title, href: link.href };
-              this.mm.sendAsyncMessage("Link:AddSearch", {
-                engine,
-                url: link.ownerDocument.documentURI,
-              });
-              searchAdded = true;
-            }
-          }
-          break;
-      }
-    }
-  }
-
-  handleEvent(event) {
-    switch (event.type) {
-      case "pageshow":
-        return this.onPageShow(event);
-      case "pagehide":
-        return this.onPageHide(event);
-      case "DOMHeadElementParsed":
-        return this.onHeadParsed(event);
-      default:
-        return this.onLinkEvent(event);
-    }
-  }
-}
--- a/browser/actors/moz.build
+++ b/browser/actors/moz.build
@@ -26,17 +26,16 @@ FINAL_TARGET_FILES.actors += [
     'AboutReaderChild.jsm',
     'BlockedSiteChild.jsm',
     'BrowserTabChild.jsm',
     'ClickHandlerChild.jsm',
     'ContentSearchChild.jsm',
     'ContextMenuChild.jsm',
     'DOMFullscreenChild.jsm',
     'LightWeightThemeInstallChild.jsm',
-    'LinkHandlerChild.jsm',
     'NetErrorChild.jsm',
     'OfflineAppsChild.jsm',
     'PageInfoChild.jsm',
     'PageMetadataChild.jsm',
     'PageStyleChild.jsm',
     'PluginChild.jsm',
     'URIFixupChild.jsm',
     'WebRTCChild.jsm',
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -11,16 +11,17 @@
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 // TabChildGlobal
 var global = this;
 
 XPCOMUtils.defineLazyModuleGetters(this, {
+  ContentLinkHandler: "resource:///modules/ContentLinkHandler.jsm",
   ContentMetaHandler: "resource:///modules/ContentMetaHandler.jsm",
   LoginFormFactory: "resource://gre/modules/LoginManagerContent.jsm",
   InsecurePasswordUtils: "resource://gre/modules/InsecurePasswordUtils.jsm",
   FormSubmitObserver: "resource:///modules/FormSubmitObserver.jsm",
   ContextMenuChild: "resource:///actors/ContextMenuChild.jsm",
 });
 
 XPCOMUtils.defineLazyGetter(this, "LoginManagerContent", () => {
@@ -54,16 +55,17 @@ addEventListener("DOMInputPasswordAdded"
   LoginManagerContent.onDOMInputPasswordAdded(event, content);
   let formLike = LoginFormFactory.createFromField(event.originalTarget);
   InsecurePasswordUtils.reportInsecurePasswords(formLike);
 });
 addEventListener("DOMAutoComplete", function(event) {
   LoginManagerContent.onUsernameInput(event);
 });
 
+new ContentLinkHandler(this);
 ContentMetaHandler.init(this);
 
 // This is a temporary hack to prevent regressions (bug 1471327).
 void content;
 
 addEventListener("DOMWindowFocus", function(event) {
   sendAsyncMessage("DOMWindowFocus", {});
 }, false);
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -45,18 +45,18 @@ const whitelist = {
 
     // Forms and passwords
     "resource://formautofill/FormAutofill.jsm",
     "resource://formautofill/FormAutofillContent.jsm",
 
     // Browser front-end
     "resource:///actors/AboutReaderChild.jsm",
     "resource:///actors/BrowserTabChild.jsm",
+    "resource:///modules/ContentLinkHandler.jsm",
     "resource:///modules/ContentMetaHandler.jsm",
-    "resource:///actors/LinkHandlerChild.jsm",
     "resource:///actors/PageStyleChild.jsm",
     "resource://gre/modules/ActorChild.jsm",
     "resource://gre/modules/ActorManagerChild.jsm",
     "resource://gre/modules/E10SUtils.jsm",
     "resource://gre/modules/PrivateBrowsingUtils.jsm",
     "resource://gre/modules/ReaderMode.jsm",
     "resource://gre/modules/WebProgressChild.jsm",
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -126,29 +126,16 @@ let ACTORS = {
       events: {
         "InstallBrowserTheme": {wantUntrusted: true},
         "PreviewBrowserTheme": {wantUntrusted: true},
         "ResetBrowserThemePreview": {wantUntrusted: true},
       },
     },
   },
 
-  LinkHandler: {
-    child: {
-      module: "resource:///actors/LinkHandlerChild.jsm",
-      events: {
-        "DOMHeadElementParsed": {},
-        "DOMLinkAdded": {},
-        "DOMLinkChanged": {},
-        "pageshow": {},
-        "pagehide": {},
-      },
-    },
-  },
-
   NetError: {
     child: {
       module: "resource:///actors/NetErrorChild.jsm",
       events: {
         "AboutNetErrorLoad": {wantUntrusted: true},
         "AboutNetErrorOpenCaptivePortal": {wantUntrusted: true},
         "AboutNetErrorSetAutomatic": {wantUntrusted: true},
         "AboutNetErrorResetPreferences": {wantUntrusted: true},
rename from browser/modules/FaviconLoader.jsm
rename to browser/modules/ContentLinkHandler.jsm
--- a/browser/modules/FaviconLoader.jsm
+++ b/browser/modules/ContentLinkHandler.jsm
@@ -1,21 +1,23 @@
 /* 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 EXPORTED_SYMBOLS = ["FaviconLoader"];
+const EXPORTED_SYMBOLS = ["ContentLinkHandler"];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGlobalGetters(this, ["Blob", "FileReader"]);
 
+ChromeUtils.defineModuleGetter(this, "Feeds",
+  "resource:///modules/Feeds.jsm");
 ChromeUtils.defineModuleGetter(this, "DeferredTask",
   "resource://gre/modules/DeferredTask.jsm");
 ChromeUtils.defineModuleGetter(this, "PromiseUtils",
   "resource://gre/modules/PromiseUtils.jsm");
 
 const BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1",
                                                  "nsIBinaryInputStream", "setInputStream");
 
@@ -360,52 +362,69 @@ function selectIcons(iconInfos, preferre
   }
 
   return {
     richIcon: largestRichIcon,
     tabIcon
   };
 }
 
+function makeFaviconFromLink(aLink, aIsRichIcon) {
+  let iconUri = getLinkIconURI(aLink);
+  if (!iconUri)
+    return null;
+
+  // Extract the size type and width.
+  let width = extractIconSize(aLink.sizes);
+
+  return {
+    iconUri,
+    width,
+    isRichIcon: aIsRichIcon,
+    type: aLink.type,
+    node: aLink,
+  };
+}
+
 class IconLoader {
-  constructor(mm) {
-    this.mm = mm;
+  constructor(chromeGlobal) {
+    this.chromeGlobal = chromeGlobal;
   }
 
   async load(iconInfo) {
     if (this._loader) {
       this._loader.cancel();
     }
 
     if (LOCAL_FAVICON_SCHEMES.includes(iconInfo.iconUri.scheme)) {
-      this.mm.sendAsyncMessage("Link:SetIcon", {
+      this.chromeGlobal.sendAsyncMessage("Link:SetIcon", {
         originalURL: iconInfo.iconUri.spec,
         canUseForTab: !iconInfo.isRichIcon,
         expiration: undefined,
         iconURL: iconInfo.iconUri.spec,
       });
       return;
     }
 
     try {
       this._loader = new FaviconLoad(iconInfo);
       let { dataURL, expiration } = await this._loader.load();
 
-      this.mm.sendAsyncMessage("Link:SetIcon", {
+      this.chromeGlobal.sendAsyncMessage("Link:SetIcon", {
         originalURL: iconInfo.iconUri.spec,
         canUseForTab: !iconInfo.isRichIcon,
         expiration,
         iconURL: dataURL,
       });
     } catch (e) {
-      if (e.result != Cr.NS_BINDING_ABORTED) {
+      if (e.resultCode != Cr.NS_BINDING_ABORTED) {
         Cu.reportError(e);
 
         // Used mainly for tests currently.
-        this.mm.sendAsyncMessage("Link:SetFailedIcon", {
+        this.chromeGlobal.sendAsyncMessage("Link:SetFailedIcon", {
           originalURL: iconInfo.iconUri.spec,
           canUseForTab: !iconInfo.isRichIcon,
         });
       }
     } finally {
       this._loader = null;
     }
   }
@@ -415,85 +434,224 @@ class IconLoader {
       return;
     }
 
     this._loader.cancel();
     this._loader = null;
   }
 }
 
-class FaviconLoader {
-  constructor(mm) {
-    this.mm = mm;
+class ContentLinkHandler {
+  constructor(chromeGlobal) {
+    this.chromeGlobal = chromeGlobal;
     this.iconInfos = [];
+    this.seenTabIcon = false;
+
+    chromeGlobal.addEventListener("DOMLinkAdded", this);
+    chromeGlobal.addEventListener("DOMLinkChanged", this);
+    chromeGlobal.addEventListener("pageshow", this);
+    chromeGlobal.addEventListener("pagehide", this);
+    chromeGlobal.addEventListener("DOMHeadElementParsed", this);
 
     // For every page we attempt to find a rich icon and a tab icon. These
     // objects take care of the load process for each.
-    this.richIconLoader = new IconLoader(mm);
-    this.tabIconLoader = new IconLoader(mm);
+    this.richIconLoader = new IconLoader(chromeGlobal);
+    this.tabIconLoader = new IconLoader(chromeGlobal);
 
     this.iconTask = new DeferredTask(() => this.loadIcons(), FAVICON_PARSING_TIMEOUT);
   }
 
   loadIcons() {
-    let preferredWidth = PREFERRED_WIDTH * Math.ceil(this.mm.content.devicePixelRatio);
+    let preferredWidth = PREFERRED_WIDTH * Math.ceil(this.chromeGlobal.content.devicePixelRatio);
     let { richIcon, tabIcon } = selectIcons(this.iconInfos, preferredWidth);
     this.iconInfos = [];
 
     if (richIcon) {
       this.richIconLoader.load(richIcon);
     }
 
     if (tabIcon) {
       this.tabIconLoader.load(tabIcon);
     }
   }
 
   addIcon(iconInfo) {
+    if (!Services.prefs.getBoolPref("browser.chrome.site_icons", true)) {
+      return;
+    }
+
+    if (!iconInfo.isRichIcon) {
+      this.seenTabIcon = true;
+    }
     this.iconInfos.push(iconInfo);
     this.iconTask.arm();
   }
 
-  addDefaultIcon(baseURI) {
+  addRootIcon(document) {
+    // If we've already seen a tab icon or if root favicons are disabled then
+    // bail out.
+    if (this.seenTabIcon || !Services.prefs.getBoolPref("browser.chrome.guess_favicon", true)) {
+      return;
+    }
+
     // Currently ImageDocuments will just load the default favicon, see bug
     // 403651 for discussion.
-    this.addIcon({
-      iconUri: baseURI.mutate().setPathQueryRef("/favicon.ico").finalize(),
-      width: -1,
-      isRichIcon: false,
-      type: TYPE_ICO,
-      node: this.mm.content.document,
-    });
+
+    // Inject the default icon. Use documentURIObject so that we do the right
+    // thing with about:-style error pages. See bug 453442
+    let baseURI = document.documentURIObject;
+    if (baseURI.schemeIs("http") || baseURI.schemeIs("https")) {
+      let iconUri = baseURI.mutate().setPathQueryRef("/favicon.ico").finalize();
+      this.addIcon({
+        iconUri,
+        width: -1,
+        isRichIcon: false,
+        type: TYPE_ICO,
+        node: document,
+      });
+    }
   }
 
-  onPageShow() {
+  onHeadParsed(event) {
+    let document = this.chromeGlobal.content.document;
+    if (event.target.ownerDocument != document) {
+      return;
+    }
+
+    // Per spec icons are meant to be in the <head> tag so we should have seen
+    // all the icons now so add the root icon if no other tab icons have been
+    // seen.
+    this.addRootIcon(document);
+
     // We're likely done with icon parsing so load the pending icons now.
     if (this.iconTask.isArmed) {
       this.iconTask.disarm();
       this.loadIcons();
     }
   }
 
-  onPageHide() {
+  onPageShow(event) {
+    let document = this.chromeGlobal.content.document;
+    if (event.target != document) {
+      return;
+    }
+
+    // Add the root icon if it hasn't already been added. We encounter this case
+    // for documents that do not have a <head> tag.
+    this.addRootIcon(document);
+
+    // If we've seen any additional icons since the start of the body element
+    // load them now.
+    if (this.iconTask.isArmed) {
+      this.iconTask.disarm();
+      this.loadIcons();
+    }
+  }
+
+  onPageHide(event) {
+    if (event.target != this.chromeGlobal.content.document) {
+      return;
+    }
+
     this.richIconLoader.cancel();
     this.tabIconLoader.cancel();
 
     this.iconTask.disarm();
     this.iconInfos = [];
+    this.seenTabIcon = false;
   }
 
-  static makeFaviconFromLink(aLink, aIsRichIcon) {
-    let iconUri = getLinkIconURI(aLink);
-    if (!iconUri)
-      return null;
+  onLinkEvent(event) {
+    let link = event.target;
+    // Ignore sub-frames (bugs 305472, 479408).
+    if (link.ownerGlobal != this.chromeGlobal.content) {
+      return;
+    }
+
+    let rel = link.rel && link.rel.toLowerCase();
+    if (!rel || !link.href)
+      return;
 
-    // Extract the size type and width.
-    let width = extractIconSize(aLink.sizes);
+    // Note: following booleans only work for the current link, not for the
+    // whole content
+    let feedAdded = false;
+    let iconAdded = false;
+    let searchAdded = false;
+    let rels = {};
+    for (let relString of rel.split(/\s+/))
+      rels[relString] = true;
+
+    for (let relVal in rels) {
+      let isRichIcon = true;
+
+      switch (relVal) {
+        case "feed":
+        case "alternate":
+          if (!feedAdded && event.type == "DOMLinkAdded") {
+            if (!rels.feed && rels.alternate && rels.stylesheet)
+              break;
 
-    return {
-      iconUri,
-      width,
-      isRichIcon: aIsRichIcon,
-      type: aLink.type,
-      node: aLink,
-    };
+            if (Feeds.isValidFeed(link, link.ownerDocument.nodePrincipal, "feed" in rels)) {
+              this.chromeGlobal.sendAsyncMessage("Link:AddFeed", {
+                type: link.type,
+                href: link.href,
+                title: link.title,
+              });
+              feedAdded = true;
+            }
+          }
+          break;
+        case "icon":
+          isRichIcon = false;
+          // Fall through to rich icon handling
+        case "apple-touch-icon":
+        case "apple-touch-icon-precomposed":
+        case "fluid-icon":
+          if (iconAdded || link.hasAttribute("mask")) { // Masked icons are not supported yet.
+            break;
+          }
+
+          let iconInfo = makeFaviconFromLink(link, isRichIcon);
+          if (iconInfo) {
+            iconAdded = this.addIcon(iconInfo);
+          }
+          break;
+        case "search":
+          if (Services.policies && !Services.policies.isAllowed("installSearchEngine")) {
+            break;
+          }
+
+          if (!searchAdded && event.type == "DOMLinkAdded") {
+            let type = link.type && link.type.toLowerCase();
+            type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
+
+            let re = /^(?:https?|ftp):/i;
+            if (type == "application/opensearchdescription+xml" && link.title &&
+                re.test(link.href)) {
+              let engine = { title: link.title, href: link.href };
+              this.chromeGlobal.sendAsyncMessage("Link:AddSearch", {
+                engine,
+                url: link.ownerDocument.documentURI,
+              });
+              searchAdded = true;
+            }
+          }
+          break;
+      }
+    }
+  }
+
+  handleEvent(event) {
+    switch (event.type) {
+      case "pageshow":
+        this.onPageShow(event);
+        break;
+      case "pagehide":
+        this.onPageHide(event);
+        break;
+      case "DOMHeadElementParsed":
+        this.onHeadParsed(event);
+        break;
+      default:
+        this.onLinkEvent(event);
+    }
   }
 }
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -119,21 +119,21 @@ XPCSHELL_TESTS_MANIFESTS += ['test/unit/
 EXTRA_JS_MODULES += [
     'AboutNewTab.jsm',
     'AsyncTabSwitcher.jsm',
     'BrowserErrorReporter.jsm',
     'BrowserUsageTelemetry.jsm',
     'BrowserWindowTracker.jsm',
     'ContentClick.jsm',
     'ContentCrashHandlers.jsm',
+    'ContentLinkHandler.jsm',
     'ContentMetaHandler.jsm',
     'ContentObservers.js',
     'ContentSearch.jsm',
     'ExtensionsUI.jsm',
-    'FaviconLoader.jsm',
     'Feeds.jsm',
     'FormSubmitObserver.jsm',
     'FormValidationHandler.jsm',
     'HomePage.jsm',
     'LaterRun.jsm',
     'LightweightThemeChildHelper.jsm',
     'OpenInTabsUtils.jsm',
     'PageActions.jsm',