forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			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.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);
 | 
						|
});
 |