285 lines
8.7 KiB
JavaScript
285 lines
8.7 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* This test exercises the behaviour where user-initiated link clicks on
|
|
* the top-level document result in pageloads in a _blank target in a new
|
|
* browser window.
|
|
*/
|
|
|
|
const TEST_PAGE = "https://example.com/browser/";
|
|
const TEST_PAGE_2 = "https://example.com/browser/components/";
|
|
const TEST_IFRAME_PAGE =
|
|
getRootDirectory(gTestPath).replace(
|
|
"chrome://mochitests/content",
|
|
"https://example.com"
|
|
) + "dummy_iframe_page.html";
|
|
|
|
// There is an <a> element with this href=".." in the TEST_PAGE
|
|
// that we will click, which should take us up a level.
|
|
const LINK_URL = "https://example.com/";
|
|
|
|
/**
|
|
* Test that a user-initiated link click results in targeting to a new
|
|
* <browser> element, and that this properly sets the referrer on the newly
|
|
* loaded document.
|
|
*/
|
|
add_task(async function target_to_new_blank_browser() {
|
|
let win = await BrowserTestUtils.openNewBrowserWindow();
|
|
let originalTab = win.gBrowser.selectedTab;
|
|
let originalBrowser = originalTab.linkedBrowser;
|
|
BrowserTestUtils.startLoadingURIString(originalBrowser, TEST_PAGE);
|
|
await BrowserTestUtils.browserLoaded(originalBrowser, false, TEST_PAGE);
|
|
|
|
// Now set the targetTopLevelLinkClicksToBlank property to true, since it
|
|
// defaults to false.
|
|
originalBrowser.browsingContext.targetTopLevelLinkClicksToBlank = true;
|
|
|
|
let newTabPromise = BrowserTestUtils.waitForNewTab(win.gBrowser, LINK_URL);
|
|
await SpecialPowers.spawn(originalBrowser, [], async () => {
|
|
let anchor = content.document.querySelector(`a[href=".."]`);
|
|
let userInput = content.windowUtils.setHandlingUserInput(true);
|
|
try {
|
|
anchor.click();
|
|
} finally {
|
|
userInput.destruct();
|
|
}
|
|
});
|
|
let newTab = await newTabPromise;
|
|
let newBrowser = newTab.linkedBrowser;
|
|
|
|
Assert.ok(
|
|
originalBrowser !== newBrowser,
|
|
"A new browser should have been created."
|
|
);
|
|
await SpecialPowers.spawn(newBrowser, [TEST_PAGE], async referrer => {
|
|
Assert.equal(
|
|
content.document.referrer,
|
|
referrer,
|
|
"Should have gotten the right referrer set"
|
|
);
|
|
});
|
|
await BrowserTestUtils.switchTab(win.gBrowser, originalTab);
|
|
BrowserTestUtils.removeTab(newTab);
|
|
|
|
// Now do the same thing with a subframe targeting "_top". This should also
|
|
// get redirected to "_blank".
|
|
BrowserTestUtils.startLoadingURIString(originalBrowser, TEST_IFRAME_PAGE);
|
|
await BrowserTestUtils.browserLoaded(
|
|
originalBrowser,
|
|
false,
|
|
TEST_IFRAME_PAGE
|
|
);
|
|
|
|
newTabPromise = BrowserTestUtils.waitForNewTab(win.gBrowser, LINK_URL);
|
|
let frameBC1 = originalBrowser.browsingContext.children[0];
|
|
Assert.ok(frameBC1, "Should have found a subframe BrowsingContext");
|
|
|
|
await SpecialPowers.spawn(frameBC1, [LINK_URL], async linkUrl => {
|
|
let anchor = content.document.createElement("a");
|
|
anchor.setAttribute("href", linkUrl);
|
|
anchor.setAttribute("target", "_top");
|
|
content.document.body.appendChild(anchor);
|
|
let userInput = content.windowUtils.setHandlingUserInput(true);
|
|
try {
|
|
anchor.click();
|
|
} finally {
|
|
userInput.destruct();
|
|
}
|
|
});
|
|
newTab = await newTabPromise;
|
|
newBrowser = newTab.linkedBrowser;
|
|
|
|
Assert.ok(
|
|
originalBrowser !== newBrowser,
|
|
"A new browser should have been created."
|
|
);
|
|
await SpecialPowers.spawn(
|
|
newBrowser,
|
|
[frameBC1.currentURI.spec],
|
|
async referrer => {
|
|
Assert.equal(
|
|
content.document.referrer,
|
|
referrer,
|
|
"Should have gotten the right referrer set"
|
|
);
|
|
}
|
|
);
|
|
await BrowserTestUtils.switchTab(win.gBrowser, originalTab);
|
|
BrowserTestUtils.removeTab(newTab);
|
|
|
|
await BrowserTestUtils.closeWindow(win);
|
|
});
|
|
|
|
/**
|
|
* Test that we don't target to _blank loads caused by:
|
|
* 1. POST requests
|
|
* 2. Any load that isn't "normal" (in the nsIDocShell.LOAD_CMD_NORMAL sense)
|
|
* 3. Any loads that are caused by location.replace
|
|
* 4. Any loads that were caused by setting location.href
|
|
* 5. Link clicks fired without user interaction.
|
|
*/
|
|
add_task(async function skip_blank_target_for_some_loads() {
|
|
let win = await BrowserTestUtils.openNewBrowserWindow();
|
|
let currentBrowser = win.gBrowser.selectedBrowser;
|
|
BrowserTestUtils.startLoadingURIString(currentBrowser, TEST_PAGE);
|
|
await BrowserTestUtils.browserLoaded(currentBrowser, false, TEST_PAGE);
|
|
|
|
// Now set the targetTopLevelLinkClicksToBlank property to true, since it
|
|
// defaults to false.
|
|
currentBrowser.browsingContext.targetTopLevelLinkClicksToBlank = true;
|
|
|
|
let ensureSingleBrowser = () => {
|
|
Assert.equal(
|
|
win.gBrowser.browsers.length,
|
|
1,
|
|
"There should only be 1 browser."
|
|
);
|
|
|
|
Assert.ok(
|
|
currentBrowser.browsingContext.targetTopLevelLinkClicksToBlank,
|
|
"Should still be targeting top-level clicks to _blank"
|
|
);
|
|
};
|
|
|
|
// First we'll test a POST request
|
|
let sameBrowserLoad = BrowserTestUtils.browserLoaded(
|
|
currentBrowser,
|
|
false,
|
|
TEST_PAGE
|
|
);
|
|
await SpecialPowers.spawn(currentBrowser, [], async () => {
|
|
let doc = content.document;
|
|
let form = doc.createElement("form");
|
|
form.setAttribute("method", "post");
|
|
doc.body.appendChild(form);
|
|
let userInput = content.windowUtils.setHandlingUserInput(true);
|
|
try {
|
|
form.submit();
|
|
} finally {
|
|
userInput.destruct();
|
|
}
|
|
});
|
|
await sameBrowserLoad;
|
|
ensureSingleBrowser();
|
|
|
|
// Next, we'll try a non-normal load - specifically, we'll try a reload.
|
|
// Since we've got a page loaded via a POST request, an attempt to reload
|
|
// will cause the "repost" dialog to appear, so we temporarily allow the
|
|
// repost to go through with the always_accept testing pref.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [["dom.confirm_repost.testing.always_accept", true]],
|
|
});
|
|
sameBrowserLoad = BrowserTestUtils.browserLoaded(
|
|
currentBrowser,
|
|
false,
|
|
TEST_PAGE
|
|
);
|
|
await SpecialPowers.spawn(currentBrowser, [], async () => {
|
|
let userInput = content.windowUtils.setHandlingUserInput(true);
|
|
try {
|
|
content.location.reload();
|
|
} finally {
|
|
userInput.destruct();
|
|
}
|
|
});
|
|
await sameBrowserLoad;
|
|
ensureSingleBrowser();
|
|
await SpecialPowers.popPrefEnv();
|
|
|
|
// Next, we'll try a location.replace
|
|
sameBrowserLoad = BrowserTestUtils.browserLoaded(
|
|
currentBrowser,
|
|
false,
|
|
TEST_PAGE_2
|
|
);
|
|
await SpecialPowers.spawn(currentBrowser, [TEST_PAGE_2], async page2 => {
|
|
let userInput = content.windowUtils.setHandlingUserInput(true);
|
|
try {
|
|
content.location.replace(page2);
|
|
} finally {
|
|
userInput.destruct();
|
|
}
|
|
});
|
|
await sameBrowserLoad;
|
|
ensureSingleBrowser();
|
|
|
|
// Finally we'll try setting location.href
|
|
sameBrowserLoad = BrowserTestUtils.browserLoaded(
|
|
currentBrowser,
|
|
false,
|
|
TEST_PAGE
|
|
);
|
|
await SpecialPowers.spawn(currentBrowser, [TEST_PAGE], async page1 => {
|
|
let userInput = content.windowUtils.setHandlingUserInput(true);
|
|
try {
|
|
content.location.href = page1;
|
|
} finally {
|
|
userInput.destruct();
|
|
}
|
|
});
|
|
await sameBrowserLoad;
|
|
ensureSingleBrowser();
|
|
|
|
// Now that we're back at TEST_PAGE, let's try a scripted link click. This
|
|
// shouldn't target to _blank.
|
|
sameBrowserLoad = BrowserTestUtils.browserLoaded(
|
|
currentBrowser,
|
|
false,
|
|
LINK_URL
|
|
);
|
|
await SpecialPowers.spawn(currentBrowser, [], async () => {
|
|
let anchor = content.document.querySelector(`a[href=".."]`);
|
|
anchor.click();
|
|
});
|
|
await sameBrowserLoad;
|
|
ensureSingleBrowser();
|
|
|
|
// A javascript:void(0); link should also not target to _blank.
|
|
sameBrowserLoad = BrowserTestUtils.browserLoaded(
|
|
currentBrowser,
|
|
false,
|
|
TEST_PAGE
|
|
);
|
|
await SpecialPowers.spawn(currentBrowser, [TEST_PAGE], async newPageURL => {
|
|
let anchor = content.document.querySelector(`a[href=".."]`);
|
|
anchor.href = "javascript:void(0);";
|
|
anchor.addEventListener("click", () => {
|
|
content.location.href = newPageURL;
|
|
});
|
|
let userInput = content.windowUtils.setHandlingUserInput(true);
|
|
try {
|
|
anchor.click();
|
|
} finally {
|
|
userInput.destruct();
|
|
}
|
|
});
|
|
await sameBrowserLoad;
|
|
ensureSingleBrowser();
|
|
|
|
// Let's also try a non-void javascript: location.
|
|
sameBrowserLoad = BrowserTestUtils.browserLoaded(
|
|
currentBrowser,
|
|
false,
|
|
TEST_PAGE
|
|
);
|
|
await SpecialPowers.spawn(currentBrowser, [TEST_PAGE], async newPageURL => {
|
|
let anchor = content.document.querySelector(`a[href=".."]`);
|
|
anchor.href = `javascript:"string-to-navigate-to"`;
|
|
anchor.addEventListener("click", () => {
|
|
content.location.href = newPageURL;
|
|
});
|
|
let userInput = content.windowUtils.setHandlingUserInput(true);
|
|
try {
|
|
anchor.click();
|
|
} finally {
|
|
userInput.destruct();
|
|
}
|
|
});
|
|
await sameBrowserLoad;
|
|
ensureSingleBrowser();
|
|
|
|
await BrowserTestUtils.closeWindow(win);
|
|
});
|