gecko-dev/browser/actors/LinkHandlerChild.jsm

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

181 строка
4.6 KiB
JavaScript
Исходник Обычный вид История

/* 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"];
Bug 1514594: Part 3 - Change ChromeUtils.import API. *** Bug 1514594: Part 3a - Change ChromeUtils.import to return an exports object; not pollute global. r=mccr8 This changes the behavior of ChromeUtils.import() to return an exports object, rather than a module global, in all cases except when `null` is passed as a second argument, and changes the default behavior not to pollute the global scope with the module's exports. Thus, the following code written for the old model: ChromeUtils.import("resource://gre/modules/Services.jsm"); is approximately the same as the following, in the new model: var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); Since the two behaviors are mutually incompatible, this patch will land with a scripted rewrite to update all existing callers to use the new model rather than the old. *** Bug 1514594: Part 3b - Mass rewrite all JS code to use the new ChromeUtils.import API. rs=Gijs This was done using the followng script: https://bitbucket.org/kmaglione/m-c-rewrites/src/tip/processors/cu-import-exports.jsm *** Bug 1514594: Part 3c - Update ESLint plugin for ChromeUtils.import API changes. r=Standard8 Differential Revision: https://phabricator.services.mozilla.com/D16747 *** Bug 1514594: Part 3d - Remove/fix hundreds of duplicate imports from sync tests. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16748 *** Bug 1514594: Part 3e - Remove no-op ChromeUtils.import() calls. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16749 *** Bug 1514594: Part 3f.1 - Cleanup various test corner cases after mass rewrite. r=Gijs *** Bug 1514594: Part 3f.2 - Cleanup various non-test corner cases after mass rewrite. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D16750 --HG-- extra : rebase_source : 359574ee3064c90f33bf36c2ebe3159a24cc8895 extra : histedit_source : b93c8f42808b1599f9122d7842d2c0b3e656a594%2C64a3a4e3359dc889e2ab2b49461bab9e27fc10a7
2019-01-17 21:18:31 +03:00
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(
this,
"FaviconLoader",
"resource:///modules/FaviconLoader.jsm"
);
class LinkHandlerChild extends JSWindowActorChild {
constructor() {
super();
this.seenTabIcon = false;
this._iconLoader = null;
}
get iconLoader() {
if (!this._iconLoader) {
this._iconLoader = new FaviconLoader(this);
}
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 pageURI = this.document.documentURIObject;
if (["http", "https"].includes(pageURI.scheme)) {
this.seenTabIcon = true;
this.iconLoader.addDefaultIcon(pageURI);
}
}
}
onHeadParsed(event) {
if (event.target.ownerDocument != this.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.document) {
return;
}
this.addRootIcon();
if (this._iconLoader) {
this._iconLoader.onPageShow();
}
}
onPageHide(event) {
if (event.target != this.document) {
return;
}
if (this._iconLoader) {
this._iconLoader.onPageHide();
}
this.seenTabIcon = false;
}
onLinkEvent(event) {
let link = event.target;
// Ignore sub-frames (bugs 305472, 479408).
if (link.ownerGlobal != this.contentWindow) {
return;
}
let rel = link.rel && link.rel.toLowerCase();
// We also check .getAttribute, since an empty href attribute will give us
// a link.href that is the same as the document.
if (!rel || !link.href || !link.getAttribute("href")) {
return;
}
// Note: following booleans only work for the current link, not for the
// whole content
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 "apple-touch-icon":
case "apple-touch-icon-precomposed":
case "fluid-icon":
isRichIcon = true;
// fall through
case "icon":
if (iconAdded || link.hasAttribute("mask")) {
// Masked icons are not supported yet.
break;
}
if (!Services.prefs.getBoolPref("browser.chrome.site_icons", true)) {
return;
}
if (this.iconLoader.addIconFromLink(link, isRichIcon)) {
iconAdded = true;
if (!isRichIcon) {
this.seenTabIcon = true;
}
}
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.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);
}
}
}