зеркало из https://github.com/mozilla/gecko-dev.git
172 строки
3.8 KiB
JavaScript
172 строки
3.8 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 = ["LinkHandlerParent"];
|
|
|
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
|
|
ChromeUtils.defineModuleGetter(
|
|
this,
|
|
"PlacesUIUtils",
|
|
"resource:///modules/PlacesUIUtils.jsm"
|
|
);
|
|
|
|
let gTestListeners = new Set();
|
|
|
|
class LinkHandlerParent extends JSWindowActorParent {
|
|
static addListenerForTests(listener) {
|
|
gTestListeners.add(listener);
|
|
}
|
|
|
|
static removeListenerForTests(listener) {
|
|
gTestListeners.delete(listener);
|
|
}
|
|
|
|
receiveMessage(aMsg) {
|
|
let browser = this.browsingContext.top.embedderElement;
|
|
if (!browser) {
|
|
return;
|
|
}
|
|
|
|
if (browser.outerBrowser) {
|
|
// Responsive design mode check
|
|
browser = browser.outerBrowser;
|
|
}
|
|
|
|
let win = browser.ownerGlobal;
|
|
|
|
let gBrowser = win.gBrowser;
|
|
|
|
switch (aMsg.name) {
|
|
case "Link:LoadingIcon":
|
|
if (!gBrowser) {
|
|
return;
|
|
}
|
|
|
|
if (aMsg.data.canUseForTab) {
|
|
let tab = gBrowser.getTabForBrowser(browser);
|
|
if (tab.hasAttribute("busy")) {
|
|
tab.setAttribute("pendingicon", "true");
|
|
}
|
|
}
|
|
|
|
this.notifyTestListeners("LoadingIcon", aMsg.data);
|
|
break;
|
|
|
|
case "Link:SetIcon":
|
|
// Cache the most recent icon and rich icon locally.
|
|
if (aMsg.data.canUseForTab) {
|
|
this.icon = aMsg.data;
|
|
} else {
|
|
this.richIcon = aMsg.data;
|
|
}
|
|
|
|
if (!gBrowser) {
|
|
return;
|
|
}
|
|
|
|
this.setIconFromLink(gBrowser, browser, aMsg.data);
|
|
|
|
this.notifyTestListeners("SetIcon", aMsg.data);
|
|
break;
|
|
|
|
case "Link:SetFailedIcon":
|
|
if (!gBrowser) {
|
|
return;
|
|
}
|
|
|
|
if (aMsg.data.canUseForTab) {
|
|
this.clearPendingIcon(gBrowser, browser);
|
|
}
|
|
|
|
this.notifyTestListeners("SetFailedIcon", aMsg.data);
|
|
break;
|
|
|
|
case "Link:AddSearch":
|
|
if (!gBrowser) {
|
|
return;
|
|
}
|
|
|
|
let tab = gBrowser.getTabForBrowser(browser);
|
|
if (!tab) {
|
|
break;
|
|
}
|
|
|
|
if (win.BrowserSearch) {
|
|
win.BrowserSearch.addEngine(
|
|
browser,
|
|
aMsg.data.engine,
|
|
Services.io.newURI(aMsg.data.url)
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
notifyTestListeners(name, data) {
|
|
for (let listener of gTestListeners) {
|
|
listener(name, data);
|
|
}
|
|
}
|
|
|
|
clearPendingIcon(gBrowser, aBrowser) {
|
|
let tab = gBrowser.getTabForBrowser(aBrowser);
|
|
tab.removeAttribute("pendingicon");
|
|
}
|
|
|
|
setIconFromLink(
|
|
gBrowser,
|
|
browser,
|
|
{ pageURL, originalURL, canUseForTab, expiration, iconURL, canStoreIcon }
|
|
) {
|
|
let tab = gBrowser.getTabForBrowser(browser);
|
|
if (!tab) {
|
|
return;
|
|
}
|
|
|
|
if (canUseForTab) {
|
|
this.clearPendingIcon(gBrowser, browser);
|
|
}
|
|
|
|
let iconURI;
|
|
try {
|
|
iconURI = Services.io.newURI(iconURL);
|
|
} catch (ex) {
|
|
Cu.reportError(ex);
|
|
return;
|
|
}
|
|
if (iconURI.scheme != "data") {
|
|
try {
|
|
Services.scriptSecurityManager.checkLoadURIWithPrincipal(
|
|
browser.contentPrincipal,
|
|
iconURI,
|
|
Services.scriptSecurityManager.ALLOW_CHROME
|
|
);
|
|
} catch (ex) {
|
|
return;
|
|
}
|
|
}
|
|
if (canStoreIcon) {
|
|
try {
|
|
PlacesUIUtils.loadFavicon(
|
|
browser,
|
|
Services.scriptSecurityManager.getSystemPrincipal(),
|
|
Services.io.newURI(pageURL),
|
|
Services.io.newURI(originalURL),
|
|
expiration,
|
|
iconURI
|
|
);
|
|
} catch (ex) {
|
|
Cu.reportError(ex);
|
|
}
|
|
}
|
|
|
|
if (canUseForTab) {
|
|
gBrowser.setIcon(tab, iconURL, originalURL);
|
|
}
|
|
}
|
|
}
|