зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1784369: Make opening in new window target for inheritance of sponsored sessions. r=daleharvey
Differential Revision: https://phabricator.services.mozilla.com/D154483
This commit is contained in:
Родитель
da11385641
Коммит
9a83490432
|
@ -1186,6 +1186,11 @@ class ContextMenuChild extends JSWindowActorChild {
|
|||
context.onMozExtLink = context.linkProtocol == "moz-extension";
|
||||
context.onSaveableLink = this._isLinkSaveable(context.link);
|
||||
|
||||
context.isSponsoredLink =
|
||||
(elem.ownerDocument.URL === "about:newtab" ||
|
||||
elem.ownerDocument.URL === "about:home") &&
|
||||
elem.dataset.isSponsoredLink === "true";
|
||||
|
||||
try {
|
||||
if (elem.download) {
|
||||
// Ignore download attribute on cross-origin links
|
||||
|
|
|
@ -2260,6 +2260,7 @@ var gBrowserInit = {
|
|||
|
||||
let hasValidUserGestureActivation = undefined;
|
||||
let fromExternal = undefined;
|
||||
let globalHistoryOptions = undefined;
|
||||
if (window.arguments[1]) {
|
||||
if (!(window.arguments[1] instanceof Ci.nsIPropertyBag2)) {
|
||||
throw new Error(
|
||||
|
@ -2276,6 +2277,18 @@ var gBrowserInit = {
|
|||
if (extraOptions.hasKey("fromExternal")) {
|
||||
fromExternal = extraOptions.getPropertyAsBool("fromExternal");
|
||||
}
|
||||
if (extraOptions.hasKey("triggeringSponsoredURL")) {
|
||||
globalHistoryOptions = {
|
||||
triggeringSponsoredURL: extraOptions.getPropertyAsACString(
|
||||
"triggeringSponsoredURL"
|
||||
),
|
||||
};
|
||||
if (extraOptions.hasKey("triggeringSponsoredURLVisitTimeMS")) {
|
||||
globalHistoryOptions.triggeringSponsoredURLVisitTimeMS = extraOptions.getPropertyAsUint64(
|
||||
"triggeringSponsoredURLVisitTimeMS"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -2296,6 +2309,7 @@ var gBrowserInit = {
|
|||
forceAboutBlankViewerInCurrent: !!window.arguments[6],
|
||||
hasValidUserGestureActivation,
|
||||
fromExternal,
|
||||
globalHistoryOptions,
|
||||
});
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
|
|
|
@ -243,6 +243,8 @@ class nsContextMenu {
|
|||
this.inSyntheticDoc = context.inSyntheticDoc;
|
||||
this.inAboutDevtoolsToolbox = context.inAboutDevtoolsToolbox;
|
||||
|
||||
this.isSponsoredLink = context.isSponsoredLink;
|
||||
|
||||
// Everything after this isn't sent directly from ContextMenu
|
||||
if (this.target) {
|
||||
this.ownerDoc = this.target.ownerDocument;
|
||||
|
@ -1390,7 +1392,25 @@ class nsContextMenu {
|
|||
|
||||
// Open linked-to URL in a new window.
|
||||
openLink() {
|
||||
openLinkIn(this.linkURL, "window", this._openLinkInParameters());
|
||||
let params;
|
||||
if (this.isSponsoredLink) {
|
||||
params = {
|
||||
globalHistoryOptions: { triggeringSponsoredURL: this.linkURL },
|
||||
};
|
||||
} else if (this.browser.hasAttribute("triggeringSponsoredURL")) {
|
||||
params = {
|
||||
globalHistoryOptions: {
|
||||
triggeringSponsoredURL: this.browser.getAttribute(
|
||||
"triggeringSponsoredURL"
|
||||
),
|
||||
triggeringSponsoredURLVisitTimeMS: this.browser.getAttribute(
|
||||
"triggeringSponsoredURLVisitTimeMS"
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
openLinkIn(this.linkURL, "window", this._openLinkInParameters(params));
|
||||
}
|
||||
|
||||
// Open linked-to URL in a new private window.
|
||||
|
|
|
@ -421,6 +421,18 @@ function openLinkIn(url, where, params) {
|
|||
if (params.fromExternal !== undefined) {
|
||||
extraOptions.setPropertyAsBool("fromExternal", params.fromExternal);
|
||||
}
|
||||
if (aGlobalHistoryOptions?.triggeringSponsoredURL) {
|
||||
extraOptions.setPropertyAsACString(
|
||||
"triggeringSponsoredURL",
|
||||
aGlobalHistoryOptions.triggeringSponsoredURL
|
||||
);
|
||||
if (aGlobalHistoryOptions.triggeringSponsoredURLVisitTimeMS) {
|
||||
extraOptions.setPropertyAsUint64(
|
||||
"triggeringSponsoredURLVisitTimeMS",
|
||||
aGlobalHistoryOptions.triggeringSponsoredURLVisitTimeMS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var allowThirdPartyFixupSupports = Cc[
|
||||
"@mozilla.org/supports-PRBool;1"
|
||||
|
|
|
@ -288,6 +288,7 @@ export class TopSiteLink extends React.PureComponent {
|
|||
onKeyPress={this.onKeyPress}
|
||||
onClick={onClick}
|
||||
draggable={true}
|
||||
data-is-sponsored-link={!!link.sponsored_tile_id}
|
||||
>
|
||||
<div className="tile" aria-hidden={true}>
|
||||
<div
|
||||
|
|
|
@ -11610,7 +11610,8 @@ class TopSiteLink extends (external_React_default()).PureComponent {
|
|||
tabIndex: "0",
|
||||
onKeyPress: this.onKeyPress,
|
||||
onClick: onClick,
|
||||
draggable: true
|
||||
draggable: true,
|
||||
"data-is-sponsored-link": !!link.sponsored_tile_id
|
||||
}, /*#__PURE__*/external_React_default().createElement("div", {
|
||||
className: "tile",
|
||||
"aria-hidden": true
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
// Test whether a visit information is annotated correctly when clicking a tile.
|
||||
|
||||
if (AppConstants.platform === "macosx") {
|
||||
requestLongerTimeout(3);
|
||||
} else {
|
||||
requestLongerTimeout(2);
|
||||
}
|
||||
|
||||
|
@ -22,6 +24,7 @@ const OPEN_TYPE = {
|
|||
CURRENT_BY_CLICK: 0,
|
||||
NEWTAB_BY_CLICK: 1,
|
||||
NEWTAB_BY_CONTEXTMENU: 2,
|
||||
NEWWINDOW_BY_CONTEXTMENU: 3,
|
||||
};
|
||||
|
||||
const FRECENCY = {
|
||||
|
@ -29,6 +32,8 @@ const FRECENCY = {
|
|||
VISITED: 100,
|
||||
SPONSORED: -1,
|
||||
BOOKMARKED: 2075,
|
||||
NEWWINDOW_TYPED: 100,
|
||||
NEWWINDOW_BOOKMARKED: 175,
|
||||
};
|
||||
|
||||
const {
|
||||
|
@ -61,30 +66,12 @@ async function assertDatabase({ targetURL, expected }) {
|
|||
);
|
||||
}
|
||||
|
||||
async function openAndTest({
|
||||
linkSelector,
|
||||
linkURL,
|
||||
redirectTo = null,
|
||||
openType = OPEN_TYPE.CURRENT_BY_CLICK,
|
||||
expected,
|
||||
}) {
|
||||
const destinationURL = redirectTo || linkURL;
|
||||
|
||||
info("Open specific link and wait for loading.");
|
||||
const isNewTab = openType !== OPEN_TYPE.CURRENT_BY_CLICK;
|
||||
const onLoad = isNewTab
|
||||
? BrowserTestUtils.waitForNewTab(gBrowser, destinationURL, true)
|
||||
: BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser,
|
||||
false,
|
||||
destinationURL
|
||||
);
|
||||
|
||||
async function waitForLocationChanged(destinationURL) {
|
||||
// If nodeIconChanged of browserPlacesViews.js is called after the target node
|
||||
// is lost during test, "No DOM node set for aPlacesNode" error occur. To avoid
|
||||
// this failure, wait for the onLocationChange event that triggers
|
||||
// nodeIconChanged to occur.
|
||||
const onLocationChanged = new Promise(resolve => {
|
||||
return new Promise(resolve => {
|
||||
gBrowser.addTabsProgressListener({
|
||||
async onLocationChange(aBrowser, aWebProgress, aRequest, aLocation) {
|
||||
if (aLocation.spec === destinationURL) {
|
||||
|
@ -97,6 +84,16 @@ async function openAndTest({
|
|||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function openAndTest({
|
||||
linkSelector,
|
||||
linkURL,
|
||||
redirectTo = null,
|
||||
openType = OPEN_TYPE.CURRENT_BY_CLICK,
|
||||
expected,
|
||||
}) {
|
||||
const destinationURL = redirectTo || linkURL;
|
||||
|
||||
// Wait for content is ready.
|
||||
await SpecialPowers.spawn(
|
||||
|
@ -109,14 +106,48 @@ async function openAndTest({
|
|||
}
|
||||
);
|
||||
|
||||
// Open the link by type.
|
||||
if (openType === OPEN_TYPE.NEWTAB_BY_CLICK) {
|
||||
info("Open specific link by type and wait for loading.");
|
||||
if (openType === OPEN_TYPE.CURRENT_BY_CLICK) {
|
||||
const onLoad = BrowserTestUtils.browserLoaded(
|
||||
gBrowser.selectedBrowser,
|
||||
false,
|
||||
destinationURL
|
||||
);
|
||||
const onLocationChanged = waitForLocationChanged(destinationURL);
|
||||
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
linkSelector,
|
||||
{ ctrlKey: isNewTab, metaKey: isNewTab },
|
||||
{},
|
||||
gBrowser.selectedBrowser
|
||||
);
|
||||
|
||||
await onLoad;
|
||||
await onLocationChanged;
|
||||
} else if (openType === OPEN_TYPE.NEWTAB_BY_CLICK) {
|
||||
const onLoad = BrowserTestUtils.waitForNewTab(
|
||||
gBrowser,
|
||||
destinationURL,
|
||||
true
|
||||
);
|
||||
const onLocationChanged = waitForLocationChanged(destinationURL);
|
||||
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
linkSelector,
|
||||
{ ctrlKey: true, metaKey: true },
|
||||
gBrowser.selectedBrowser
|
||||
);
|
||||
|
||||
const tab = await onLoad;
|
||||
await onLocationChanged;
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
} else if (openType === OPEN_TYPE.NEWTAB_BY_CONTEXTMENU) {
|
||||
const onLoad = BrowserTestUtils.waitForNewTab(
|
||||
gBrowser,
|
||||
destinationURL,
|
||||
true
|
||||
);
|
||||
const onLocationChanged = waitForLocationChanged(destinationURL);
|
||||
|
||||
const onPopup = BrowserTestUtils.waitForEvent(document, "popupshown");
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
linkSelector,
|
||||
|
@ -130,19 +161,27 @@ async function openAndTest({
|
|||
);
|
||||
openLinkMenuItem.click();
|
||||
contextMenu.hidePopup();
|
||||
} else {
|
||||
|
||||
const tab = await onLoad;
|
||||
await onLocationChanged;
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
} else if (openType === OPEN_TYPE.NEWWINDOW_BY_CONTEXTMENU) {
|
||||
const onLoad = BrowserTestUtils.waitForNewWindow({ url: destinationURL });
|
||||
|
||||
const onPopup = BrowserTestUtils.waitForEvent(document, "popupshown");
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
linkSelector,
|
||||
{},
|
||||
{ type: "contextmenu" },
|
||||
gBrowser.selectedBrowser
|
||||
);
|
||||
}
|
||||
await onPopup;
|
||||
const contextMenu = document.getElementById("contentAreaContextMenu");
|
||||
const openLinkMenuItem = contextMenu.querySelector("#context-openlink");
|
||||
openLinkMenuItem.click();
|
||||
contextMenu.hidePopup();
|
||||
|
||||
const maybeNewTab = await onLoad;
|
||||
await onLocationChanged;
|
||||
|
||||
if (isNewTab) {
|
||||
BrowserTestUtils.removeTab(maybeNewTab);
|
||||
const win = await onLoad;
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
}
|
||||
|
||||
info("Check database for the destination.");
|
||||
|
@ -174,17 +213,48 @@ add_setup(async function() {
|
|||
});
|
||||
|
||||
add_task(async function basic() {
|
||||
const SPONSORED_LINK = {
|
||||
label: "test_label",
|
||||
url: "http://example.com/",
|
||||
sponsored_position: 1,
|
||||
sponsored_tile_id: 12345,
|
||||
sponsored_impression_url: "http://impression.example.com/",
|
||||
sponsored_click_url: "http://click.example.com/",
|
||||
};
|
||||
const NORMAL_LINK = {
|
||||
label: "test_label",
|
||||
url: "http://example.com/",
|
||||
};
|
||||
const BOOKMARKS = [
|
||||
{
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
url: Services.io.newURI("http://example.com/"),
|
||||
title: "test bookmark",
|
||||
},
|
||||
];
|
||||
|
||||
const testData = [
|
||||
{
|
||||
description: "Sponsored tile",
|
||||
link: {
|
||||
label: "test_label",
|
||||
url: "http://example.com/",
|
||||
sponsored_position: 1,
|
||||
sponsored_tile_id: 12345,
|
||||
sponsored_impression_url: "http://impression.example.com/",
|
||||
sponsored_click_url: "http://click.example.com/",
|
||||
link: SPONSORED_LINK,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_SPONSORED,
|
||||
frecency: FRECENCY.SPONSORED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Sponsored tile in new tab",
|
||||
link: SPONSORED_LINK,
|
||||
openType: OPEN_TYPE.NEWTAB_BY_CLICK,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_SPONSORED,
|
||||
frecency: FRECENCY.SPONSORED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Sponsored tile in new window",
|
||||
link: SPONSORED_LINK,
|
||||
openType: OPEN_TYPE.NEWWINDOW_BY_CONTEXTMENU,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_SPONSORED,
|
||||
frecency: FRECENCY.SPONSORED,
|
||||
|
@ -192,88 +262,110 @@ add_task(async function basic() {
|
|||
},
|
||||
{
|
||||
description: "Bookmarked result",
|
||||
link: {
|
||||
label: "test_label",
|
||||
url: "http://example.com/",
|
||||
},
|
||||
bookmarks: [
|
||||
{
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
url: Services.io.newURI("http://example.com/"),
|
||||
title: "test bookmark",
|
||||
},
|
||||
],
|
||||
link: NORMAL_LINK,
|
||||
bookmarks: BOOKMARKS,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_BOOKMARKED,
|
||||
frecency: FRECENCY.BOOKMARKED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Sponsored and bookmarked result",
|
||||
link: {
|
||||
label: "test_label",
|
||||
url: "http://example.com/",
|
||||
sponsored_position: 1,
|
||||
sponsored_tile_id: 12345,
|
||||
sponsored_impression_url: "http://impression.example.com/",
|
||||
sponsored_click_url: "http://click.example.com/",
|
||||
description: "Bookmarked result in new tab",
|
||||
link: NORMAL_LINK,
|
||||
openType: OPEN_TYPE.NEWTAB_BY_CLICK,
|
||||
bookmarks: BOOKMARKS,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_BOOKMARKED,
|
||||
frecency: FRECENCY.BOOKMARKED,
|
||||
},
|
||||
bookmarks: [
|
||||
{
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
url: Services.io.newURI("http://example.com/"),
|
||||
title: "test bookmark",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
description: "Bookmarked result in new window",
|
||||
link: NORMAL_LINK,
|
||||
openType: OPEN_TYPE.NEWWINDOW_BY_CONTEXTMENU,
|
||||
bookmarks: BOOKMARKS,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_BOOKMARKED,
|
||||
frecency: FRECENCY.NEWWINDOW_BOOKMARKED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Sponsored and bookmarked result",
|
||||
link: SPONSORED_LINK,
|
||||
bookmarks: BOOKMARKS,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_SPONSORED,
|
||||
frecency: FRECENCY.BOOKMARKED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Organic tile",
|
||||
link: {
|
||||
label: "test_label",
|
||||
url: "http://example.com/",
|
||||
description: "Sponsored and bookmarked result in new tab",
|
||||
link: SPONSORED_LINK,
|
||||
openType: OPEN_TYPE.NEWTAB_BY_CLICK,
|
||||
bookmarks: BOOKMARKS,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_SPONSORED,
|
||||
frecency: FRECENCY.BOOKMARKED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Sponsored and bookmarked result in new window",
|
||||
link: SPONSORED_LINK,
|
||||
openType: OPEN_TYPE.NEWWINDOW_BY_CONTEXTMENU,
|
||||
bookmarks: BOOKMARKS,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_SPONSORED,
|
||||
frecency: FRECENCY.NEWWINDOW_BOOKMARKED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Organic tile",
|
||||
link: NORMAL_LINK,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_ORGANIC,
|
||||
frecency: FRECENCY.TYPED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Organic tile in new tab",
|
||||
link: NORMAL_LINK,
|
||||
openType: OPEN_TYPE.NEWTAB_BY_CLICK,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_ORGANIC,
|
||||
frecency: FRECENCY.TYPED,
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Organic tile in new window",
|
||||
link: NORMAL_LINK,
|
||||
openType: OPEN_TYPE.NEWWINDOW_BY_CONTEXTMENU,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_ORGANIC,
|
||||
frecency: FRECENCY.NEWWINDOW_TYPED,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
for (const { description, link, bookmarks, expected } of testData) {
|
||||
for (const { description, link, openType, bookmarks, expected } of testData) {
|
||||
info(description);
|
||||
|
||||
await BrowserTestUtils.withNewTab("about:home", async () => {
|
||||
// Setup test tile.
|
||||
await pin(link);
|
||||
|
||||
// Test with new tab.
|
||||
for (const bookmark of bookmarks || []) {
|
||||
await PlacesUtils.bookmarks.insert(bookmark);
|
||||
}
|
||||
|
||||
await openAndTest({
|
||||
linkSelector: ".top-site-button",
|
||||
linkURL: link.url,
|
||||
openType: OPEN_TYPE.NEWTAB_BY_CLICK,
|
||||
openType,
|
||||
expected,
|
||||
});
|
||||
|
||||
await clearHistoryAndBookmarks();
|
||||
|
||||
// Test with same tab.
|
||||
for (const bookmark of bookmarks || []) {
|
||||
await PlacesUtils.bookmarks.insert(bookmark);
|
||||
}
|
||||
await openAndTest({
|
||||
linkSelector: ".top-site-button",
|
||||
linkURL: link.url,
|
||||
expected,
|
||||
});
|
||||
await clearHistoryAndBookmarks();
|
||||
|
||||
unpin(link);
|
||||
});
|
||||
}
|
||||
|
@ -375,6 +467,19 @@ add_task(async function inherit() {
|
|||
},
|
||||
});
|
||||
|
||||
info("Open link on first page to show second page in new window");
|
||||
await openAndTest({
|
||||
linkSelector: "a",
|
||||
linkURL: secondURL,
|
||||
openType: OPEN_TYPE.NEWWINDOW_BY_CONTEXTMENU,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_SPONSORED,
|
||||
frecency: FRECENCY.SPONSORED,
|
||||
triggerURL: link.url,
|
||||
},
|
||||
});
|
||||
await PlacesTestUtils.clearHistoryVisits();
|
||||
|
||||
info("Open link on first page to show second page in new tab");
|
||||
await openAndTest({
|
||||
linkSelector: "a",
|
||||
|
@ -399,6 +504,19 @@ add_task(async function inherit() {
|
|||
},
|
||||
});
|
||||
|
||||
info("Open link on first page to show second page in new window");
|
||||
await openAndTest({
|
||||
linkSelector: "a",
|
||||
linkURL: thirdURL,
|
||||
openType: OPEN_TYPE.NEWWINDOW_BY_CONTEXTMENU,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_SPONSORED,
|
||||
frecency: FRECENCY.SPONSORED,
|
||||
triggerURL: link.url,
|
||||
},
|
||||
});
|
||||
await PlacesTestUtils.clearHistoryVisits();
|
||||
|
||||
info(
|
||||
"Open link on second page to show third page in new tab by context menu"
|
||||
);
|
||||
|
@ -500,6 +618,18 @@ add_task(async function timeout() {
|
|||
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
info("Open link on first page to show second page in new window");
|
||||
await openAndTest({
|
||||
linkSelector: "a",
|
||||
linkURL: secondURL,
|
||||
openType: OPEN_TYPE.NEWWINDOW_BY_CONTEXTMENU,
|
||||
expected: {
|
||||
source: VISIT_SOURCE_ORGANIC,
|
||||
frecency: FRECENCY.VISITED,
|
||||
},
|
||||
});
|
||||
await PlacesTestUtils.clearHistoryVisits();
|
||||
|
||||
info("Open link on first page to show second page in new tab");
|
||||
await openAndTest({
|
||||
linkSelector: "a",
|
||||
|
|
Загрузка…
Ссылка в новой задаче