Bug 1592157, convert LinkHandlerChild.jsm to JSWindowActor to support fission, r=mak

Differential Revision: https://phabricator.services.mozilla.com/D51026

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Neil Deakin 2019-11-04 14:48:04 +00:00
Родитель 11c3c57ab3
Коммит d12fb42226
9 изменённых файлов: 221 добавлений и 173 удалений

Просмотреть файл

@ -7,9 +7,6 @@
const EXPORTED_SYMBOLS = ["LinkHandlerChild"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { ActorChild } = ChromeUtils.import(
"resource://gre/modules/ActorChild.jsm"
);
ChromeUtils.defineModuleGetter(
this,
@ -17,7 +14,7 @@ ChromeUtils.defineModuleGetter(
"resource:///modules/FaviconLoader.jsm"
);
class LinkHandlerChild extends ActorChild {
class LinkHandlerChild extends JSWindowActorChild {
constructor(dispatcher) {
super(dispatcher);
@ -27,7 +24,7 @@ class LinkHandlerChild extends ActorChild {
get iconLoader() {
if (!this._iconLoader) {
this._iconLoader = new FaviconLoader(this.mm);
this._iconLoader = new FaviconLoader(this);
}
return this._iconLoader;
}
@ -40,7 +37,7 @@ class LinkHandlerChild extends ActorChild {
) {
// Inject the default icon. Use documentURIObject so that we do the right
// thing with about:-style error pages. See bug 453442
let pageURI = this.content.document.documentURIObject;
let pageURI = this.document.documentURIObject;
if (["http", "https"].includes(pageURI.scheme)) {
this.seenTabIcon = true;
this.iconLoader.addDefaultIcon(pageURI);
@ -49,7 +46,7 @@ class LinkHandlerChild extends ActorChild {
}
onHeadParsed(event) {
if (event.target.ownerDocument != this.content.document) {
if (event.target.ownerDocument != this.document) {
return;
}
@ -65,7 +62,7 @@ class LinkHandlerChild extends ActorChild {
}
onPageShow(event) {
if (event.target != this.content.document) {
if (event.target != this.document) {
return;
}
@ -77,7 +74,7 @@ class LinkHandlerChild extends ActorChild {
}
onPageHide(event) {
if (event.target != this.content.document) {
if (event.target != this.document) {
return;
}
@ -91,7 +88,7 @@ class LinkHandlerChild extends ActorChild {
onLinkEvent(event) {
let link = event.target;
// Ignore sub-frames (bugs 305472, 479408).
if (link.ownerGlobal != this.content) {
if (link.ownerGlobal != this.contentWindow) {
return;
}
@ -156,7 +153,7 @@ class LinkHandlerChild extends ActorChild {
re.test(link.href)
) {
let engine = { title: link.title, href: link.href };
this.mm.sendAsyncMessage("Link:AddSearch", {
this.sendAsyncMessage("Link:AddSearch", {
engine,
url: link.ownerDocument.documentURI,
});

Просмотреть файл

@ -0,0 +1,161 @@
/* 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;
if (!gBrowser) {
return;
}
switch (aMsg.name) {
case "Link:LoadingIcon":
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":
this.setIconFromLink(
gBrowser,
browser,
aMsg.data.pageURL,
aMsg.data.originalURL,
aMsg.data.canUseForTab,
aMsg.data.expiration,
aMsg.data.iconURL
);
this.notifyTestListeners("SetIcon", aMsg.data);
break;
case "Link:SetFailedIcon":
if (aMsg.data.canUseForTab) {
this.clearPendingIcon(gBrowser, browser);
}
this.notifyTestListeners("SetFailedIcon", aMsg.data);
break;
case "Link:AddSearch":
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,
aBrowser,
aPageURL,
aOriginalURL,
aCanUseForTab,
aExpiration,
aIconURL
) {
let tab = gBrowser.getTabForBrowser(aBrowser);
if (!tab) {
return;
}
if (aCanUseForTab) {
this.clearPendingIcon(gBrowser, aBrowser);
}
let iconURI;
try {
iconURI = Services.io.newURI(aIconURL);
} catch (ex) {
Cu.reportError(ex);
return;
}
if (iconURI.scheme != "data") {
try {
Services.scriptSecurityManager.checkLoadURIWithPrincipal(
aBrowser.contentPrincipal,
iconURI,
Services.scriptSecurityManager.ALLOW_CHROME
);
} catch (ex) {
return;
}
}
try {
PlacesUIUtils.loadFavicon(
aBrowser,
Services.scriptSecurityManager.getSystemPrincipal(),
Services.io.newURI(aPageURL),
Services.io.newURI(aOriginalURL),
aExpiration,
iconURI
);
} catch (ex) {
Cu.reportError(ex);
}
if (aCanUseForTab) {
gBrowser.setIcon(tab, aIconURL, aOriginalURL);
}
}
}

Просмотреть файл

@ -39,6 +39,7 @@ FINAL_TARGET_FILES.actors += [
'FormValidationParent.jsm',
'LightweightThemeChild.jsm',
'LinkHandlerChild.jsm',
'LinkHandlerParent.jsm',
'NetErrorChild.jsm',
'OfflineAppsChild.jsm',
'PageInfoChild.jsm',

Просмотреть файл

@ -1807,7 +1807,6 @@ var gBrowserInit = {
// loading the frame script to ensure that we don't miss any
// message sent between when the frame script is loaded and when
// the listener is registered.
DOMEventHandler.init();
LanguageDetectionListener.init();
BrowserOnClick.init();
CaptivePortalWatcher.init();
@ -4147,120 +4146,6 @@ var newWindowButtonObserver = {
}
},
};
const DOMEventHandler = {
init() {
let mm = window.messageManager;
mm.addMessageListener("Link:LoadingIcon", this);
mm.addMessageListener("Link:SetIcon", this);
mm.addMessageListener("Link:SetFailedIcon", this);
mm.addMessageListener("Link:AddSearch", this);
},
receiveMessage(aMsg) {
switch (aMsg.name) {
case "Link:LoadingIcon":
if (aMsg.data.canUseForTab) {
this.setPendingIcon(aMsg.target);
}
break;
case "Link:SetIcon":
this.setIconFromLink(
aMsg.target,
aMsg.data.pageURL,
aMsg.data.originalURL,
aMsg.data.canUseForTab,
aMsg.data.expiration,
aMsg.data.iconURL
);
break;
case "Link:SetFailedIcon":
if (aMsg.data.canUseForTab) {
this.clearPendingIcon(aMsg.target);
}
break;
case "Link:AddSearch":
this.addSearch(aMsg.target, aMsg.data.engine, aMsg.data.url);
break;
}
},
setPendingIcon(aBrowser) {
let tab = gBrowser.getTabForBrowser(aBrowser);
if (tab.hasAttribute("busy")) {
tab.setAttribute("pendingicon", "true");
}
},
clearPendingIcon(aBrowser) {
let tab = gBrowser.getTabForBrowser(aBrowser);
tab.removeAttribute("pendingicon");
},
setIconFromLink(
aBrowser,
aPageURL,
aOriginalURL,
aCanUseForTab,
aExpiration,
aIconURL
) {
let tab = gBrowser.getTabForBrowser(aBrowser);
if (!tab) {
return;
}
if (aCanUseForTab) {
this.clearPendingIcon(aBrowser);
}
let iconURI;
try {
iconURI = Services.io.newURI(aIconURL);
} catch (ex) {
Cu.reportError(ex);
return;
}
if (iconURI.scheme != "data") {
try {
Services.scriptSecurityManager.checkLoadURIWithPrincipal(
aBrowser.contentPrincipal,
iconURI,
Services.scriptSecurityManager.ALLOW_CHROME
);
} catch (ex) {
return;
}
}
try {
PlacesUIUtils.loadFavicon(
aBrowser,
Services.scriptSecurityManager.getSystemPrincipal(),
makeURI(aPageURL),
makeURI(aOriginalURL),
aExpiration,
iconURI
);
} catch (ex) {
Cu.reportError(ex);
}
if (aCanUseForTab) {
gBrowser.setIcon(tab, aIconURL, aOriginalURL);
}
},
addSearch(aBrowser, aEngine, aURL) {
let tab = gBrowser.getTabForBrowser(aBrowser);
if (!tab) {
return;
}
BrowserSearch.addEngine(aBrowser, aEngine, makeURI(aURL));
},
};
const BrowserSearch = {
_searchInitComplete: false,

Просмотреть файл

@ -18,11 +18,11 @@ function waitForAttributeChange(tab, attr) {
function waitForPendingIcon() {
return new Promise(resolve => {
let listener = () => {
window.messageManager.removeMessageListener("Link:LoadingIcon", listener);
LinkHandlerParent.removeListenerForTests(listener);
resolve();
};
window.messageManager.addMessageListener("Link:LoadingIcon", listener);
LinkHandlerParent.addListenerForTests(listener);
});
}

Просмотреть файл

@ -11,43 +11,48 @@ ChromeUtils.defineModuleGetter(
"resource://gre/modules/PlacesUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"LinkHandlerParent",
"resource:///actors/LinkHandlerParent.jsm"
);
// Clear the network cache between every test to make sure we get a stable state
Services.cache2.clear();
function waitForFaviconMessage(isTabIcon = undefined, expectedURL = undefined) {
return new Promise((resolve, reject) => {
let listener = msg => {
let listener = (name, data) => {
if (name != "SetIcon" && name != "SetFailedIcon") {
return; // Ignore unhandled messages
}
// If requested filter out loads of the wrong kind of icon.
if (isTabIcon != undefined && isTabIcon != msg.data.canUseForTab) {
if (isTabIcon != undefined && isTabIcon != data.canUseForTab) {
return;
}
if (expectedURL && msg.data.originalURL != expectedURL) {
if (expectedURL && data.originalURL != expectedURL) {
return;
}
window.messageManager.removeMessageListener("Link:SetIcon", listener);
window.messageManager.removeMessageListener(
"Link:SetFailedIcon",
listener
);
LinkHandlerParent.removeListenerForTests(listener);
if (msg.name == "Link:SetIcon") {
if (name == "SetIcon") {
resolve({
iconURL: msg.data.originalURL,
dataURL: msg.data.iconURL,
canUseForTab: msg.data.canUseForTab,
iconURL: data.originalURL,
dataURL: data.iconURL,
canUseForTab: data.canUseForTab,
});
} else {
reject({
iconURL: msg.data.originalURL,
canUseForTab: msg.data.canUseForTab,
iconURL: data.originalURL,
canUseForTab: data.canUseForTab,
});
}
};
window.messageManager.addMessageListener("Link:SetIcon", listener);
window.messageManager.addMessageListener("Link:SetFailedIcon", listener);
LinkHandlerParent.addListenerForTests(listener);
});
}

Просмотреть файл

@ -110,6 +110,22 @@ let ACTORS = {
allFrames: true,
},
LinkHandler: {
parent: {
moduleURI: "resource:///actors/LinkHandlerParent.jsm",
},
child: {
moduleURI: "resource:///actors/LinkHandlerChild.jsm",
events: {
DOMHeadElementParsed: {},
DOMLinkAdded: {},
DOMLinkChanged: {},
pageshow: {},
pagehide: {},
},
},
},
PageInfo: {
child: {
moduleURI: "resource:///actors/PageInfoChild.jsm",
@ -308,19 +324,6 @@ let LEGACY_ACTORS = {
},
},
LinkHandler: {
child: {
module: "resource:///actors/LinkHandlerChild.jsm",
events: {
DOMHeadElementParsed: {},
DOMLinkAdded: {},
DOMLinkChanged: {},
pageshow: {},
pagehide: {},
},
},
},
NetError: {
child: {
module: "resource:///actors/NetErrorChild.jsm",

Просмотреть файл

@ -504,8 +504,8 @@ function selectIcons(iconInfos, preferredWidth) {
}
class IconLoader {
constructor(mm) {
this.mm = mm;
constructor(actor) {
this.actor = actor;
}
async load(iconInfo) {
@ -525,7 +525,7 @@ class IconLoader {
} catch (ex) {
return;
}
this.mm.sendAsyncMessage("Link:SetIcon", {
this.actor.sendAsyncMessage("Link:SetIcon", {
pageURL: iconInfo.pageUri.spec,
originalURL: iconInfo.iconUri.spec,
canUseForTab: !iconInfo.isRichIcon,
@ -536,7 +536,7 @@ class IconLoader {
}
// Let the main process that a tab icon is possibly coming.
this.mm.sendAsyncMessage("Link:LoadingIcon", {
this.actor.sendAsyncMessage("Link:LoadingIcon", {
originalURL: iconInfo.iconUri.spec,
canUseForTab: !iconInfo.isRichIcon,
});
@ -545,7 +545,7 @@ class IconLoader {
this._loader = new FaviconLoad(iconInfo);
let { dataURL, expiration } = await this._loader.load();
this.mm.sendAsyncMessage("Link:SetIcon", {
this.actor.sendAsyncMessage("Link:SetIcon", {
pageURL: iconInfo.pageUri.spec,
originalURL: iconInfo.iconUri.spec,
canUseForTab: !iconInfo.isRichIcon,
@ -557,7 +557,7 @@ class IconLoader {
Cu.reportError(e);
// Used mainly for tests currently.
this.mm.sendAsyncMessage("Link:SetFailedIcon", {
this.actor.sendAsyncMessage("Link:SetFailedIcon", {
originalURL: iconInfo.iconUri.spec,
canUseForTab: !iconInfo.isRichIcon,
});
@ -578,14 +578,14 @@ class IconLoader {
}
class FaviconLoader {
constructor(mm) {
this.mm = mm;
constructor(actor) {
this.actor = actor;
this.iconInfos = [];
// 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(actor);
this.tabIconLoader = new IconLoader(actor);
this.iconTask = new DeferredTask(
() => this.loadIcons(),
@ -603,7 +603,7 @@ class FaviconLoader {
}
let preferredWidth =
PREFERRED_WIDTH * Math.ceil(this.mm.content.devicePixelRatio);
PREFERRED_WIDTH * Math.ceil(this.actor.contentWindow.devicePixelRatio);
let { richIcon, tabIcon } = selectIcons(this.iconInfos, preferredWidth);
this.iconInfos = [];
@ -638,7 +638,7 @@ class FaviconLoader {
width: -1,
isRichIcon: false,
type: TYPE_ICO,
node: this.mm.content.document,
node: this.actor.document,
});
this.iconTask.arm();
}

Просмотреть файл

@ -462,10 +462,6 @@ MessageManagerTunnel.prototype = {
INNER_TO_OUTER_MESSAGES: [
// Messages sent to browser.js
"Browser:LoadURI",
"Link:SetIcon",
"Link:SetFailedIcon",
"Link:AddFeed",
"Link:AddSearch",
"PageStyle:StyleSheets",
// Messages sent to browser.js
"DOMTitleChanged",