Bug 1277765 - No referrer when a link is opened by middle-click or the context menu and containers are involved, r=mconley

This commit is contained in:
Andrea Marchesini 2016-06-09 17:02:50 +02:00
parent 313f1bfddf
commit cede39dd18
14 changed files with 295 additions and 23 deletions

View File

@ -5540,6 +5540,12 @@ function handleLinkClick(event, href, linkNode) {
referrerURI: referrerURI,
referrerPolicy: referrerPolicy,
noReferrer: BrowserUtils.linkHasNoReferrer(linkNode) };
// The new tab/window must use the same userContextId
if (doc.nodePrincipal.originAttributes.userContextId) {
params.userContextId = doc.nodePrincipal.originAttributes.userContextId;
}
openLinkIn(href, where, params);
event.preventDefault();
return true;

View File

@ -454,7 +454,8 @@ var ClickEventHandler = {
let json = { button: event.button, shiftKey: event.shiftKey,
ctrlKey: event.ctrlKey, metaKey: event.metaKey,
altKey: event.altKey, href: null, title: null,
bookmark: false, referrerPolicy: referrerPolicy };
bookmark: false, referrerPolicy: referrerPolicy,
originAttributes: principal ? principal.originAttributes : {} };
if (href) {
try {

View File

@ -955,8 +955,17 @@ nsContextMenu.prototype = {
referrerURI: gContextMenuContentData.documentURIObject,
referrerPolicy: gContextMenuContentData.referrerPolicy,
noReferrer: this.linkHasNoReferrer };
for (let p in extra)
for (let p in extra) {
params[p] = extra[p];
}
// If we want to change userContextId, we must be sure that we don't
// propagate the referrer.
if ("userContextId" in params &&
params.userContextId != this.principal.originAttributes.userContextId) {
params.noReferrer = true;
}
return params;
},
@ -998,10 +1007,6 @@ nsContextMenu.prototype = {
userContextId: parseInt(event.target.getAttribute('usercontextid'))
};
if (params.userContextId != this.principal.originAttributes.userContextId) {
params.noReferrer = true;
}
openLinkIn(this.linkURL, "tab", this._openLinkInParameters(params));
},

View File

@ -6,12 +6,21 @@ support-files =
head.js
[browser_referrer_middle_click.js]
[browser_referrer_middle_click_in_container.js]
[browser_referrer_open_link_in_private.js]
skip-if = os == 'linux' # Bug 1145199
[browser_referrer_open_link_in_tab.js]
skip-if = os == 'linux' # Bug 1144816
[browser_referrer_open_link_in_tab_in_container.js]
skip-if = os == 'linux' # Bug 1144816
[browser_referrer_open_link_in_window.js]
skip-if = os == 'linux' # Bug 1145199
[browser_referrer_open_link_in_window_in_container.js]
skip-if = os == 'linux' # Bug 1145199
[browser_referrer_simple_click.js]
[browser_referrer_open_link_in_container_tab.js]
skip-if = os == 'linux' # Bug 1144816
[browser_referrer_open_link_in_container_tab2.js]
skip-if = os == 'linux' # Bug 1144816
[browser_referrer_open_link_in_container_tab3.js]
skip-if = os == 'linux' # Bug 1144816

View File

@ -0,0 +1,20 @@
// Tests referrer on middle-click navigation.
// Middle-clicks on the link, which opens it in a new tab, same container.
function startMiddleClickTestCase(aTestNumber) {
info("browser_referrer_middle_click: " +
getReferrerTestDescription(aTestNumber));
someTabLoaded(gTestWindow).then(function(aNewTab) {
gTestWindow.gBrowser.selectedTab = aNewTab;
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
startMiddleClickTestCase,
{ userContextId: 3 });
});
clickTheLink(gTestWindow, "testlink", {button: 1});
}
function test() {
requestLongerTimeout(10); // slowwww shutdown on e10s
startReferrerTest(startMiddleClickTestCase, { userContextId: 3 });
}

View File

@ -23,18 +23,27 @@ function startNewTabTestCase(aTestNumber) {
});
let menu = gTestWindow.document.getElementById("context-openlinkinusercontext-menu");
let menupopup = menu.menupopup;
menu.addEventListener("popupshown", function onPopupShown() {
menu.removeEventListener("popupshown", onPopupShown);
is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup.");
ok(menupopup.firstChild, "We have a first container entry.");
let firstContext = menupopup.firstChild;
is(firstContext.nodeType, Node.ELEMENT_NODE, "We have a first container entry.");
ok(firstContext.hasAttribute("usercontextid"), "We have a usercontextid value.");
aContextMenu.addEventListener("popuphidden", function onPopupHidden() {
aContextMenu.removeEventListener("popuphidden", onPopupHidden);
firstContext.doCommand();
});
aContextMenu.hidePopup();
});
menupopup.showPopup();
is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup.");
ok(menupopup.firstChild, "We have a first container entry.");
let firstContext = menupopup.firstChild;
is(firstContext.nodeType, Node.ELEMENT_NODE, "We have a first container entry.");
ok(firstContext.hasAttribute('usercontextid'), "We have a usercontextid value.");
firstContext.doCommand();
aContextMenu.hidePopup();
});
}

View File

@ -0,0 +1,52 @@
// Tests referrer on context menu navigation - open link in new container tab.
// Selects "open link in new container tab" from the context menu.
// The test runs from a container ID 1.
// Output: we have the correct referrer policy applied.
function startNewTabTestCase(aTestNumber) {
info("browser_referrer_open_link_in_container_tab: " +
getReferrerTestDescription(aTestNumber));
contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
someTabLoaded(gTestWindow).then(function(aNewTab) {
gTestWindow.gBrowser.selectedTab = aNewTab;
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
startNewTabTestCase, { userContextId: 1 });
});
let menu = gTestWindow.document.getElementById("context-openlinkinusercontext-menu");
let menupopup = menu.menupopup;
menu.addEventListener("popupshown", function onPopupShown() {
menu.removeEventListener("popupshown", onPopupShown);
is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup.");
ok(menupopup.firstChild, "We have a first container entry.");
let firstContext = menupopup.firstChild;
is(firstContext.nodeType, Node.ELEMENT_NODE, "We have a first container entry.");
ok(firstContext.hasAttribute("usercontextid"), "We have a usercontextid value.");
is("1", firstContext.getAttribute("usercontextid"), "We have the right usercontextid value.");
aContextMenu.addEventListener("popuphidden", function onPopupHidden() {
aContextMenu.removeEventListener("popuphidden", onPopupHidden);
firstContext.doCommand();
});
aContextMenu.hidePopup();
});
menupopup.showPopup();
});
}
function test() {
waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{set: [["privacy.userContext.enabled", true]]},
function() {
requestLongerTimeout(10); // slowwww shutdown on e10s
startReferrerTest(startNewTabTestCase, { userContextId: 1 });
});
}

View File

@ -0,0 +1,63 @@
// Tests referrer on context menu navigation - open link in new container tab.
// Selects "open link in new container tab" from the context menu.
// The test runs from a container ID 2.
// Output: we have no referrer.
function getReferrerTest(aTestNumber) {
let test = _referrerTests[aTestNumber];
if (test) {
// We want all the referrer tests to fail!
test.result = "";
}
return test;
}
function startNewTabTestCase(aTestNumber) {
info("browser_referrer_open_link_in_container_tab: " +
getReferrerTestDescription(aTestNumber));
contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
someTabLoaded(gTestWindow).then(function(aNewTab) {
gTestWindow.gBrowser.selectedTab = aNewTab;
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
startNewTabTestCase, { userContextId: 2 });
});
let menu = gTestWindow.document.getElementById("context-openlinkinusercontext-menu");
let menupopup = menu.menupopup;
menu.addEventListener("popupshown", function onPopupShown() {
menu.removeEventListener("popupshown", onPopupShown);
is(menupopup.nodeType, Node.ELEMENT_NODE, "We have a menupopup.");
ok(menupopup.firstChild, "We have a first container entry.");
let firstContext = menupopup.firstChild;
is(firstContext.nodeType, Node.ELEMENT_NODE, "We have a first container entry.");
ok(firstContext.hasAttribute("usercontextid"), "We have a usercontextid value.");
is("1", firstContext.getAttribute("usercontextid"), "We have the right usercontextid value.");
aContextMenu.addEventListener("popuphidden", function onPopupHidden() {
aContextMenu.removeEventListener("popuphidden", onPopupHidden);
firstContext.doCommand();
});
aContextMenu.hidePopup();
});
menupopup.showPopup();
});
}
function test() {
waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{set: [["privacy.userContext.enabled", true]]},
function() {
requestLongerTimeout(10); // slowwww shutdown on e10s
startReferrerTest(startNewTabTestCase, { userContextId: 2 });
});
}

View File

@ -0,0 +1,34 @@
// Tests referrer on context menu navigation - open link in new tab.
// Selects "open link in new tab" from the context menu.
// This test starts from a container tab. We don't want to propagate the
// referrer.
function getReferrerTest(aTestNumber) {
let test = _referrerTests[aTestNumber];
if (test) {
// We want all the referrer tests to fail!
test.result = "";
}
return test;
}
function startNewTabTestCase(aTestNumber) {
info("browser_referrer_open_link_in_tab: " +
getReferrerTestDescription(aTestNumber));
contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
someTabLoaded(gTestWindow).then(function(aNewTab) {
gTestWindow.gBrowser.selectedTab = aNewTab;
checkReferrerAndStartNextTest(aTestNumber, null, aNewTab,
startNewTabTestCase,
{ userContextId: 4 });
});
doContextMenuCommand(gTestWindow, aContextMenu, "context-openlinkintab");
});
}
function test() {
requestLongerTimeout(10); // slowwww shutdown on e10s
startReferrerTest(startNewTabTestCase, { userContextId: 4 });
}

View File

@ -0,0 +1,26 @@
// Tests referrer on context menu navigation - open link in new window.
// Selects "open link in new window" from the context menu.
// This test runs from a container tab. The new tab/window will be loaded in
// the same container.
function startNewWindowTestCase(aTestNumber) {
info("browser_referrer_open_link_in_window: " +
getReferrerTestDescription(aTestNumber));
contextMenuOpened(gTestWindow, "testlink").then(function(aContextMenu) {
newWindowOpened().then(function(aNewWindow) {
someTabLoaded(aNewWindow).then(function() {
checkReferrerAndStartNextTest(aTestNumber, aNewWindow, null,
startNewWindowTestCase,
{ userContextId: 1 });
});
});
doContextMenuCommand(gTestWindow, aContextMenu, "context-openlink");
});
}
function test() {
requestLongerTimeout(10); // slowwww shutdown on e10s
startReferrerTest(startNewWindowTestCase, { userContextId: 1 });
}

View File

@ -195,7 +195,7 @@ function doContextMenuCommand(aWindow, aMenu, aItemId) {
* @return {Promise}
* @resolves When the source url for this test case is loaded.
*/
function referrerTestCaseLoaded(aTestNumber) {
function referrerTestCaseLoaded(aTestNumber, aParams) {
let test = getReferrerTest(aTestNumber);
let server = rounds == 0 ? REFERRER_POLICYSERVER_URL :
REFERRER_POLICYSERVER_URL_ATTRIBUTE;
@ -204,7 +204,7 @@ function referrerTestCaseLoaded(aTestNumber) {
"&policy=" + escape(test.policy || "") +
"&rel=" + escape(test.rel || "");
var browser = gTestWindow.gBrowser;
browser.selectedTab = browser.addTab(url);
browser.selectedTab = browser.addTab(url, aParams);
return BrowserTestUtils.browserLoaded(browser.selectedBrowser);
}
@ -216,7 +216,7 @@ function referrerTestCaseLoaded(aTestNumber) {
* @param aStartTestCase The callback to start the next test, aTestNumber + 1.
*/
function checkReferrerAndStartNextTest(aTestNumber, aNewWindow, aNewTab,
aStartTestCase) {
aStartTestCase, aParams = {}) {
referrerResultExtracted(aNewWindow || gTestWindow).then(function(result) {
// Compare the actual result against the expected one.
let test = getReferrerTest(aTestNumber);
@ -232,13 +232,13 @@ function checkReferrerAndStartNextTest(aTestNumber, aNewWindow, aNewTab,
// Move on to the next test. Or finish if we're done.
var nextTestNumber = aTestNumber + 1;
if (getReferrerTest(nextTestNumber)) {
referrerTestCaseLoaded(nextTestNumber).then(function() {
referrerTestCaseLoaded(nextTestNumber, aParams).then(function() {
aStartTestCase(nextTestNumber);
});
} else if (rounds == 0) {
nextTestNumber = 0;
rounds = 1;
referrerTestCaseLoaded(nextTestNumber).then(function() {
referrerTestCaseLoaded(nextTestNumber, aParams).then(function() {
aStartTestCase(nextTestNumber);
});
} else {
@ -253,7 +253,7 @@ function checkReferrerAndStartNextTest(aTestNumber, aNewWindow, aNewTab,
* the test number - 0, 1, 2... Needs to trigger the navigation from the source
* page, and call checkReferrerAndStartNextTest() when the target is loaded.
*/
function startReferrerTest(aStartTestCase) {
function startReferrerTest(aStartTestCase, params = {}) {
waitForExplicitFinish();
// Open the window where we'll load the source URLs.
@ -264,7 +264,7 @@ function startReferrerTest(aStartTestCase) {
// Load and start the first test.
delayedStartupFinished(gTestWindow).then(function() {
referrerTestCaseLoaded(0).then(function() {
referrerTestCaseLoaded(0, params).then(function() {
aStartTestCase(0);
});
});

View File

@ -19,4 +19,5 @@ tags = openwindow
[browser_serviceworkers.js]
[browser_broadcastchannel.js]
[browser_blobUrl.js]
[browser_middleClick.js]
[browser_imageCache.js]

View File

@ -0,0 +1,41 @@
"use strict";
const BASE_ORIGIN = "http://example.com";
const URI = BASE_ORIGIN +
"/browser/browser/components/contextualidentity/test/browser/empty_file.html";
add_task(function* () {
info("Opening a new container tab...");
let tab = gBrowser.addTab(URI, { userContextId: 1 });
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
yield BrowserTestUtils.browserLoaded(browser);
info("Create a HTMLAnchorElement...");
let position = yield ContentTask.spawn(browser, URI,
function(URI) {
let anchor = content.document.createElement("a");
anchor.setAttribute('id', 'clickMe');
anchor.setAttribute("href", URI);
anchor.appendChild(content.document.createTextNode("click me!"));
content.document.body.appendChild(anchor);
}
);
info("Synthesize a mouse click and wait for a new tab...");
let newTab = yield new Promise((resolve, reject) => {
gBrowser.tabContainer.addEventListener("TabOpen", function onTabOpen(openEvent) {
gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen);
resolve(openEvent.target);
})
BrowserTestUtils.synthesizeMouseAtCenter("#clickMe", { button: 1 }, browser);
});
is(newTab.getAttribute("usercontextid"), 1, "Correct UserContextId?");
yield BrowserTestUtils.removeTab(tab);
yield BrowserTestUtils.removeTab(newTab);
});

View File

@ -83,6 +83,11 @@ var ContentClick = {
noReferrer: json.noReferrer,
allowMixedContent: json.allowMixedContent };
// The new tab/window must use the same userContextId.
if (json.originAttributes.userContextId) {
params.userContextId = json.originAttributes.userContextId;
}
window.openLinkIn(json.href, where, params);
}
};