summaryrefslogtreecommitdiffstats
path: root/docshell/test/browser/browser_targetTopLevelLinkClicksToBlank.js
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/test/browser/browser_targetTopLevelLinkClicksToBlank.js')
-rw-r--r--docshell/test/browser/browser_targetTopLevelLinkClicksToBlank.js285
1 files changed, 285 insertions, 0 deletions
diff --git a/docshell/test/browser/browser_targetTopLevelLinkClicksToBlank.js b/docshell/test/browser/browser_targetTopLevelLinkClicksToBlank.js
new file mode 100644
index 0000000000..9035750b93
--- /dev/null
+++ b/docshell/test/browser/browser_targetTopLevelLinkClicksToBlank.js
@@ -0,0 +1,285 @@
+/* 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.loadURIString(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.loadURIString(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.loadURIString(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", e => {
+ 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", e => {
+ content.location.href = newPageURL;
+ });
+ let userInput = content.windowUtils.setHandlingUserInput(true);
+ try {
+ anchor.click();
+ } finally {
+ userInput.destruct();
+ }
+ });
+ await sameBrowserLoad;
+ ensureSingleBrowser();
+
+ await BrowserTestUtils.closeWindow(win);
+});