summaryrefslogtreecommitdiffstats
path: root/docshell/test/navigation
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/test/navigation')
-rw-r--r--docshell/test/navigation/NavigationUtils.js213
-rw-r--r--docshell/test/navigation/blank.html1
-rw-r--r--docshell/test/navigation/browser.ini12
-rw-r--r--docshell/test/navigation/browser_bug343515.js262
-rw-r--r--docshell/test/navigation/browser_test-content-chromeflags.js45
-rw-r--r--docshell/test/navigation/bug343515_pg1.html5
-rw-r--r--docshell/test/navigation/bug343515_pg2.html7
-rw-r--r--docshell/test/navigation/bug343515_pg3.html7
-rw-r--r--docshell/test/navigation/bug343515_pg3_1.html6
-rw-r--r--docshell/test/navigation/bug343515_pg3_1_1.html1
-rw-r--r--docshell/test/navigation/bug343515_pg3_2.html1
-rw-r--r--docshell/test/navigation/file_bug1300461.html63
-rw-r--r--docshell/test/navigation/file_bug1300461_back.html31
-rw-r--r--docshell/test/navigation/file_bug1300461_redirect.html10
-rw-r--r--docshell/test/navigation/file_bug1300461_redirect.html^headers^2
-rw-r--r--docshell/test/navigation/file_bug462076_1.html55
-rw-r--r--docshell/test/navigation/file_bug462076_2.html52
-rw-r--r--docshell/test/navigation/file_bug462076_3.html52
-rw-r--r--docshell/test/navigation/file_bug508537_1.html34
-rw-r--r--docshell/test/navigation/file_bug534178.html31
-rw-r--r--docshell/test/navigation/file_document_write_1.html30
-rw-r--r--docshell/test/navigation/file_fragment_handling_during_load.html24
-rw-r--r--docshell/test/navigation/file_nested_frames.html28
-rw-r--r--docshell/test/navigation/file_scrollRestoration.html137
-rw-r--r--docshell/test/navigation/file_shiftReload_and_pushState.html29
-rw-r--r--docshell/test/navigation/file_static_and_dynamic_1.html32
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_frame_1.html27
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_frame_2.html8
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html6
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html6
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html15
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html6
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html6
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_subframe.html15
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_subframe_nav.html21
-rw-r--r--docshell/test/navigation/file_triggeringprincipal_window_open.html6
-rw-r--r--docshell/test/navigation/frame0.html3
-rw-r--r--docshell/test/navigation/frame1.html3
-rw-r--r--docshell/test/navigation/frame2.html3
-rw-r--r--docshell/test/navigation/frame3.html3
-rw-r--r--docshell/test/navigation/goback.html5
-rw-r--r--docshell/test/navigation/iframe.html8
-rw-r--r--docshell/test/navigation/mochitest.ini64
-rw-r--r--docshell/test/navigation/navigate.html36
-rw-r--r--docshell/test/navigation/open.html9
-rw-r--r--docshell/test/navigation/parent.html14
-rw-r--r--docshell/test/navigation/test_bug13871.html81
-rw-r--r--docshell/test/navigation/test_bug270414.html93
-rw-r--r--docshell/test/navigation/test_bug278916.html37
-rw-r--r--docshell/test/navigation/test_bug279495.html48
-rw-r--r--docshell/test/navigation/test_bug344861.html35
-rw-r--r--docshell/test/navigation/test_bug386782.html137
-rw-r--r--docshell/test/navigation/test_bug430624.html56
-rw-r--r--docshell/test/navigation/test_bug430723.html138
-rw-r--r--docshell/test/navigation/test_child.html48
-rw-r--r--docshell/test/navigation/test_grandchild.html48
-rw-r--r--docshell/test/navigation/test_not-opener.html51
-rw-r--r--docshell/test/navigation/test_opener.html52
-rw-r--r--docshell/test/navigation/test_popup-navigates-children.html62
-rw-r--r--docshell/test/navigation/test_reserved.html100
-rw-r--r--docshell/test/navigation/test_sessionhistory.html68
-rw-r--r--docshell/test/navigation/test_sibling-matching-parent.html46
-rw-r--r--docshell/test/navigation/test_sibling-off-domain.html46
-rw-r--r--docshell/test/navigation/test_triggeringprincipal_frame_nav.html69
-rw-r--r--docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html87
-rw-r--r--docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html70
-rw-r--r--docshell/test/navigation/test_triggeringprincipal_window_open.html101
67 files changed, 2907 insertions, 0 deletions
diff --git a/docshell/test/navigation/NavigationUtils.js b/docshell/test/navigation/NavigationUtils.js
new file mode 100644
index 000000000..c90ea74d5
--- /dev/null
+++ b/docshell/test/navigation/NavigationUtils.js
@@ -0,0 +1,213 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Utilities for navigation tests
+//
+///////////////////////////////////////////////////////////////////////////
+
+var body = "This frame was navigated.";
+var target_url = "data:text/html,<html><body>" + body + "</body></html>";
+
+var popup_body = "This is a popup";
+var target_popup_url = "data:text/html,<html><body>" + popup_body + "</body></html>";
+
+///////////////////////////////////////////////////////////////////////////
+// Functions that navigate frames
+///////////////////////////////////////////////////////////////////////////
+
+function navigateByLocation(wnd) {
+ try {
+ wnd.location = target_url;
+ } catch(ex) {
+ // We need to keep our finished frames count consistent.
+ // Oddly, this ends up simulating the behavior of IE7.
+ window.open(target_url, "_blank", "width=10,height=10");
+ }
+}
+
+function navigateByOpen(name) {
+ window.open(target_url, name, "width=10,height=10");
+}
+
+function navigateByForm(name) {
+ var form = document.createElement("form");
+ form.action = target_url;
+ form.method = "POST";
+ form.target = name; document.body.appendChild(form);
+ form.submit();
+}
+
+var hyperlink_count = 0;
+
+function navigateByHyperlink(name) {
+ var link = document.createElement("a");
+ link.href = target_url;
+ link.target = name;
+ link.id = "navigation_hyperlink_" + hyperlink_count++;
+ document.body.appendChild(link);
+ sendMouseEvent({type:"click"}, link.id);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Functions that call into Mochitest framework
+///////////////////////////////////////////////////////////////////////////
+
+function isNavigated(wnd, message) {
+ var result = null;
+ try {
+ result = SpecialPowers.wrap(wnd).document.body.innerHTML;
+ } catch(ex) {
+ result = ex;
+ }
+ is(result, body, message);
+}
+
+function isBlank(wnd, message) {
+ var result = null;
+ try {
+ result = wnd.document.body.innerHTML;
+ } catch(ex) {
+ result = ex;
+ }
+ is(result, "This is a blank document.", message);
+}
+
+function isAccessible(wnd, message) {
+ try {
+ wnd.document.body.innerHTML;
+ ok(true, message);
+ } catch(ex) {
+ ok(false, message);
+ }
+}
+
+function isInaccessible(wnd, message) {
+ try {
+ wnd.document.body.innerHTML;
+ ok(false, message);
+ } catch(ex) {
+ ok(true, message);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Functions that require UniversalXPConnect privilege
+///////////////////////////////////////////////////////////////////////////
+
+function xpcEnumerateContentWindows(callback) {
+
+ var Ci = SpecialPowers.Ci;
+ var ww = SpecialPowers.Cc["@mozilla.org/embedcomp/window-watcher;1"]
+ .getService(Ci.nsIWindowWatcher);
+ var enumerator = ww.getWindowEnumerator();
+
+ var contentWindows = [];
+
+ while (enumerator.hasMoreElements()) {
+ var win = enumerator.getNext();
+ if (/ChromeWindow/.exec(win)) {
+ var docshellTreeNode = win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem);
+ var childCount = docshellTreeNode.childCount;
+ for (var i = 0; i < childCount; ++i) {
+ var childTreeNode = docshellTreeNode.getChildAt(i);
+
+ // we're only interested in content docshells
+ if (SpecialPowers.unwrap(childTreeNode.itemType) != Ci.nsIDocShellTreeItem.typeContent)
+ continue;
+
+ var webNav = childTreeNode.QueryInterface(Ci.nsIWebNavigation);
+ contentWindows.push(webNav.document.defaultView);
+ }
+ } else {
+ contentWindows.push(win);
+ }
+ }
+
+ while (contentWindows.length > 0)
+ callback(contentWindows.pop());
+}
+
+// Note: This only searches for top-level frames with this name.
+function xpcGetFramesByName(name) {
+ var results = [];
+
+ xpcEnumerateContentWindows(function(win) {
+ if (win.name == name)
+ results.push(win);
+ });
+
+ return results;
+}
+
+function xpcCleanupWindows() {
+ xpcEnumerateContentWindows(function(win) {
+ if (win.location && win.location.protocol == "data:")
+ win.close();
+ });
+}
+
+function xpcWaitForFinishedFrames(callback, numFrames) {
+ var finishedFrameCount = 0;
+ function frameFinished() {
+ finishedFrameCount++;
+
+ if (finishedFrameCount == numFrames) {
+ clearInterval(frameWaitInterval);
+ setTimeout(callback, 0);
+ return;
+ }
+
+ if (finishedFrameCount > numFrames)
+ throw "Too many frames loaded.";
+ }
+
+ var finishedWindows = [];
+
+ function contains(obj, arr) {
+ for (var i = 0; i < arr.length; i++) {
+ if (obj === arr[i])
+ return true;
+ }
+ return false;
+ }
+
+ function searchForFinishedFrames(win) {
+ if ((escape(unescape(win.location)) == escape(target_url) ||
+ escape(unescape(win.location)) == escape(target_popup_url)) &&
+ win.document &&
+ win.document.body &&
+ (win.document.body.textContent == body ||
+ win.document.body.textContent == popup_body) &&
+ win.document.readyState == "complete") {
+
+ var util = win.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
+ .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils);
+ var windowId = util.outerWindowID;
+ if (!contains(windowId, finishedWindows)) {
+ finishedWindows.push(windowId);
+ frameFinished();
+ }
+ }
+ for (var i = 0; i < win.frames.length; i++)
+ searchForFinishedFrames(win.frames[i]);
+ }
+
+ function poll() {
+ try {
+ // This only gives us UniversalXPConnect for the current stack frame
+ // We're using setInterval, so the main page's privileges are still normal
+ xpcEnumerateContentWindows(searchForFinishedFrames);
+ } catch(ex) {
+ // We might be accessing windows before they are fully constructed,
+ // which can throw. We'll find those frames on our next poll().
+ }
+ }
+
+ var frameWaitInterval = setInterval(poll, 500);
+}
+
diff --git a/docshell/test/navigation/blank.html b/docshell/test/navigation/blank.html
new file mode 100644
index 000000000..5360333f1
--- /dev/null
+++ b/docshell/test/navigation/blank.html
@@ -0,0 +1 @@
+<html><body>This is a blank document.</body></html> \ No newline at end of file
diff --git a/docshell/test/navigation/browser.ini b/docshell/test/navigation/browser.ini
new file mode 100644
index 000000000..f25853f89
--- /dev/null
+++ b/docshell/test/navigation/browser.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+support-files =
+ bug343515_pg1.html
+ bug343515_pg2.html
+ bug343515_pg3.html
+ bug343515_pg3_1.html
+ bug343515_pg3_1_1.html
+ bug343515_pg3_2.html
+
+[browser_bug343515.js]
+[browser_test-content-chromeflags.js]
+tags = openwindow \ No newline at end of file
diff --git a/docshell/test/navigation/browser_bug343515.js b/docshell/test/navigation/browser_bug343515.js
new file mode 100644
index 000000000..74152b493
--- /dev/null
+++ b/docshell/test/navigation/browser_bug343515.js
@@ -0,0 +1,262 @@
+// Test for bug 343515 - Need API for tabbrowsers to tell docshells they're visible/hidden
+
+// Globals
+var testPath = "http://mochi.test:8888/browser/docshell/test/navigation/";
+var ctx = {};
+
+// We need to wait until the page from each testcase is fully loaded,
+// including all of its descendant iframes. To do that we manually count
+// how many load events should happen on that page (one for the toplevel doc
+// and one for each subframe) and wait until we receive the expected number
+// of events.
+function nShotsListener(aElem, aType, aCallback, aCount) {
+ let count = aCount;
+ aElem.addEventListener(aType, function listenerCallback() {
+ if (--count == 0) {
+ aElem.removeEventListener(aType, listenerCallback, true);
+
+ // aCallback is executed asynchronously, which is handy because load
+ // events fire before mIsDocumentLoaded is actually set to true. :(
+ executeSoon(aCallback);
+ }
+ }, true);
+}
+
+function oneShotListener(aElem, aType, aCallback) {
+ nShotsListener(aElem, aType, aCallback, 1);
+}
+
+function waitForPageshow(aBrowser, callback) {
+ return ContentTask.spawn(aBrowser, null, function* () {
+ yield ContentTaskUtils.waitForEvent(this, "pageshow");
+ }).then(callback);
+}
+
+// Entry point from Mochikit
+function test() {
+
+ // Lots of callbacks going on here
+ waitForExplicitFinish();
+
+ // Begin the test
+ step1();
+}
+
+function step1() {
+
+ // Get a handle on the initial tab
+ ctx.tab0 = gBrowser.selectedTab;
+ ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0);
+
+ // Our current tab should be active
+ ok(ctx.tab0Browser.docShellIsActive, "Tab 0 should be active at test start");
+
+ // Open a New Tab
+ ctx.tab1 = gBrowser.addTab(testPath + "bug343515_pg1.html");
+ ctx.tab1Browser = gBrowser.getBrowserForTab(ctx.tab1);
+ oneShotListener(ctx.tab1Browser, "load", step2);
+}
+
+function step2() {
+ is(testPath + "bug343515_pg1.html", ctx.tab1Browser.currentURI.spec,
+ "Got expected tab 1 url in step 2");
+
+ // Our current tab should still be active
+ ok(ctx.tab0Browser.docShellIsActive, "Tab 0 should still be active");
+ ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should not be active");
+
+ // Switch to tab 1
+ BrowserTestUtils.switchTab(gBrowser, ctx.tab1).then(() => {
+ // Tab 1 should now be active
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+
+ // Open another tab
+ ctx.tab2 = gBrowser.addTab(testPath + "bug343515_pg2.html");
+ ctx.tab2Browser = gBrowser.getBrowserForTab(ctx.tab2);
+
+ // bug343515_pg2.html consists of a page with two iframes,
+ // which will therefore generate 3 load events.
+ nShotsListener(ctx.tab2Browser, "load", step3, 3);
+ });
+}
+
+function step3() {
+ is(testPath + "bug343515_pg2.html", ctx.tab2Browser.currentURI.spec,
+ "Got expected tab 2 url in step 3");
+
+ // Tab 0 should be inactive, Tab 1 should be active
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+
+ // Tab 2's window _and_ its iframes should be inactive
+ ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
+ ContentTask.spawn(ctx.tab2Browser, null, function* () {
+ Assert.equal(content.frames.length, 2, "Tab 2 should have 2 iframes");
+ for (var i = 0; i < content.frames.length; i++) {
+ info("step 3, frame " + i + " info: " + content.frames[i].location);
+ let docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+
+ Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`);
+ }
+ }).then(() => {
+ // Navigate tab 2 to a different page
+ ctx.tab2Browser.loadURI(testPath + "bug343515_pg3.html");
+
+ // bug343515_pg3.html consists of a page with two iframes, one of which
+ // contains another iframe, so there'll be a total of 4 load events
+ nShotsListener(ctx.tab2Browser, "load", step4, 4);
+ });
+}
+
+function step4() {
+ function checkTab2Active(expected) {
+ return ContentTask.spawn(ctx.tab2Browser, expected, function* (expected) {
+ function isActive(aWindow) {
+ var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+ return docshell.isActive;
+ }
+
+ let active = expected ? "active" : "inactive";
+ Assert.equal(content.frames.length, 2, "Tab 2 should have 2 iframes");
+ for (var i = 0; i < content.frames.length; i++)
+ info("step 4, frame " + i + " info: " + content.frames[i].location);
+ Assert.equal(content.frames[0].frames.length, 1, "Tab 2 iframe 0 should have 1 iframes");
+ Assert.equal(isActive(content.frames[0]), expected, `Tab2 iframe 0 should be ${active}`);
+ Assert.equal(isActive(content.frames[0].frames[0]), expected,
+ `Tab2 iframe 0 subiframe 0 should be ${active}`);
+ Assert.equal(isActive(content.frames[1]), expected, `Tab2 iframe 1 should be ${active}`);
+ });
+ }
+
+ is(testPath + "bug343515_pg3.html", ctx.tab2Browser.currentURI.spec,
+ "Got expected tab 2 url in step 4");
+
+ // Tab 0 should be inactive, Tab 1 should be active
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+
+ // Tab2 and all descendants should be inactive
+ checkTab2Active(false).then(() => {
+ // Switch to Tab 2
+ return BrowserTestUtils.switchTab(gBrowser, ctx.tab2);
+ }).then(() => {
+ // Check everything
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should be inactive");
+ ok(ctx.tab2Browser.docShellIsActive, "Tab 2 should be active");
+
+ return checkTab2Active(true);
+ }).then(() => {
+ // Go back
+ waitForPageshow(ctx.tab2Browser, step5);
+ ctx.tab2Browser.goBack();
+ });
+}
+
+function step5() {
+ // Check everything
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should be inactive");
+ ok(ctx.tab2Browser.docShellIsActive, "Tab 2 should be active");
+ ContentTask.spawn(ctx.tab2Browser, null, function* () {
+ for (var i = 0; i < content.frames.length; i++) {
+ let docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+
+ Assert.ok(docShell.isActive, `Tab2 iframe ${i} should be active`);
+ }
+ }).then(() => {
+ // Switch to tab 1
+ return BrowserTestUtils.switchTab(gBrowser, ctx.tab1);
+ }).then(() => {
+ // Navigate to page 3
+ ctx.tab1Browser.loadURI(testPath + "bug343515_pg3.html");
+
+ // bug343515_pg3.html consists of a page with two iframes, one of which
+ // contains another iframe, so there'll be a total of 4 load events
+ nShotsListener(ctx.tab1Browser, "load", step6, 4);
+ });
+}
+
+function step6() {
+
+ // Check everything
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+ ContentTask.spawn(ctx.tab1Browser, null, function* () {
+ function isActive(aWindow) {
+ var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+ return docshell.isActive;
+ }
+
+ Assert.ok(isActive(content.frames[0]), "Tab1 iframe 0 should be active");
+ Assert.ok(isActive(content.frames[0].frames[0]), "Tab1 iframe 0 subiframe 0 should be active");
+ Assert.ok(isActive(content.frames[1]), "Tab1 iframe 1 should be active");
+ }).then(() => {
+ ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
+ return ContentTask.spawn(ctx.tab2Browser, null, function* () {
+ for (var i = 0; i < content.frames.length; i++) {
+ let docshell = content.frames[i].QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+
+ Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`);
+ }
+ });
+ }).then(() => {
+ // Go forward on tab 2
+ waitForPageshow(ctx.tab2Browser, step7);
+ ctx.tab2Browser.goForward();
+ });
+}
+
+function step7() {
+ function checkBrowser(browser, tabNum, active) {
+ return ContentTask.spawn(browser, { tabNum, active },
+ function* ({ tabNum, active }) {
+ function isActive(aWindow) {
+ var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+ return docshell.isActive;
+ }
+
+ let activestr = active ? "active" : "inactive";
+ Assert.equal(isActive(content.frames[0]), active,
+ `Tab${tabNum} iframe 0 should be ${activestr}`);
+ Assert.equal(isActive(content.frames[0].frames[0]), active,
+ `Tab${tabNum} iframe 0 subiframe 0 should be ${activestr}`);
+ Assert.equal(isActive(content.frames[1]), active,
+ `Tab${tabNum} iframe 1 should be ${activestr}`);
+ });
+ }
+
+ // Check everything
+ ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
+ ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
+ checkBrowser(ctx.tab1Browser, 1, true).then(() => {
+ ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
+ return checkBrowser(ctx.tab2Browser, 2, false);
+ }).then(() => {
+ // That's probably enough
+ allDone();
+ });
+}
+
+function allDone() {
+
+ // Close the tabs we made
+ gBrowser.removeTab(ctx.tab1);
+ gBrowser.removeTab(ctx.tab2);
+
+ // Tell the framework we're done
+ finish();
+}
diff --git a/docshell/test/navigation/browser_test-content-chromeflags.js b/docshell/test/navigation/browser_test-content-chromeflags.js
new file mode 100644
index 000000000..64559897c
--- /dev/null
+++ b/docshell/test/navigation/browser_test-content-chromeflags.js
@@ -0,0 +1,45 @@
+const TEST_PAGE = `data:text/html,<html><body><a href="about:blank" target="_blank">Test</a></body></html>`;
+const CHROME_ALL = Ci.nsIWebBrowserChrome.CHROME_ALL;
+const CHROME_REMOTE_WINDOW = Ci.nsIWebBrowserChrome.CHROME_REMOTE_WINDOW;
+
+/**
+ * Tests that when we open new browser windows from content they
+ * get the full browser chrome.
+ */
+add_task(function* () {
+ // Make sure that the window.open call will open a new
+ // window instead of a new tab.
+ yield new Promise(resolve => {
+ SpecialPowers.pushPrefEnv({
+ "set": [
+ ["browser.link.open_newwindow", 2],
+ ]
+ }, resolve);
+ });
+
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: TEST_PAGE
+ }, function*(browser) {
+ let openedPromise = BrowserTestUtils.waitForNewWindow();
+ BrowserTestUtils.synthesizeMouse("a", 0, 0, {}, browser);
+ let win = yield openedPromise;
+
+ let chromeFlags = win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .treeOwner
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIXULWindow)
+ .chromeFlags;
+
+ // In the multi-process case, the new window will have the
+ // CHROME_REMOTE_WINDOW flag set.
+ const EXPECTED = gMultiProcessBrowser ? CHROME_ALL | CHROME_REMOTE_WINDOW
+ : CHROME_ALL;
+
+ is(chromeFlags, EXPECTED, "Window should have opened with all chrome");
+
+ BrowserTestUtils.closeWindow(win);
+ });
+});
diff --git a/docshell/test/navigation/bug343515_pg1.html b/docshell/test/navigation/bug343515_pg1.html
new file mode 100644
index 000000000..a8337c7f7
--- /dev/null
+++ b/docshell/test/navigation/bug343515_pg1.html
@@ -0,0 +1,5 @@
+<html>
+ <head><meta charset="UTF-8"/></head>
+ <body>Page 1
+ </body>
+</html>
diff --git a/docshell/test/navigation/bug343515_pg2.html b/docshell/test/navigation/bug343515_pg2.html
new file mode 100644
index 000000000..c5f5665de
--- /dev/null
+++ b/docshell/test/navigation/bug343515_pg2.html
@@ -0,0 +1,7 @@
+<html>
+ <head><meta charset="UTF-8"/></head>
+ <body>Page 2
+ <iframe src="data:text/html;charset=UTF8,<html><head></head><body>pg2 iframe 0</body></html>"></iframe>
+ <iframe src="data:text/html;charset=UTF8,<html><head></head><body>pg2 iframe 1</body></html>"></iframe>
+ </body>
+</html>
diff --git a/docshell/test/navigation/bug343515_pg3.html b/docshell/test/navigation/bug343515_pg3.html
new file mode 100644
index 000000000..fdc79fbf7
--- /dev/null
+++ b/docshell/test/navigation/bug343515_pg3.html
@@ -0,0 +1,7 @@
+<html>
+ <head><meta charset="UTF-8"/></head>
+ <body>Page 3
+ <iframe src="bug343515_pg3_1.html"></iframe>
+ <iframe src="bug343515_pg3_2.html"></iframe>
+ </body>
+</html>
diff --git a/docshell/test/navigation/bug343515_pg3_1.html b/docshell/test/navigation/bug343515_pg3_1.html
new file mode 100644
index 000000000..254164c9f
--- /dev/null
+++ b/docshell/test/navigation/bug343515_pg3_1.html
@@ -0,0 +1,6 @@
+<html>
+ <head><meta charset="UTF-8"/></head>
+ <body>pg3 - iframe 0
+ <iframe src="bug343515_pg3_1_1.html"></iframe>
+ </body>
+</html>
diff --git a/docshell/test/navigation/bug343515_pg3_1_1.html b/docshell/test/navigation/bug343515_pg3_1_1.html
new file mode 100644
index 000000000..be05b7488
--- /dev/null
+++ b/docshell/test/navigation/bug343515_pg3_1_1.html
@@ -0,0 +1 @@
+<html><head><meta charset="UTF-8"/></head><body>How far does the rabbit hole go?</body></html>
diff --git a/docshell/test/navigation/bug343515_pg3_2.html b/docshell/test/navigation/bug343515_pg3_2.html
new file mode 100644
index 000000000..7655eb526
--- /dev/null
+++ b/docshell/test/navigation/bug343515_pg3_2.html
@@ -0,0 +1 @@
+<html><head><meta charset="UTF-8"/></head><body>pg3 iframe 1</body></html>
diff --git a/docshell/test/navigation/file_bug1300461.html b/docshell/test/navigation/file_bug1300461.html
new file mode 100644
index 000000000..1ba935046
--- /dev/null
+++ b/docshell/test/navigation/file_bug1300461.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Bug 1300461</title>
+ </head>
+ <body onload="test();">
+ <script>
+ /**
+ * Bug 1300461 identifies that if a history entry was not bfcached, and
+ * a http redirection happens when navigating to that entry, the history
+ * index would mess up.
+ *
+ * The test case emulates the circumstance by the following steps
+ * 1) Navigate to file_bug1300461_back.html which is not bf-cachable.
+ * 2) In file_bug1300461_back.html, replace its own history state to
+ * file_bug1300461_redirect.html.
+ * 3) Back, and then forward. Since the document is not in bfcache, it
+ * tries to load file_bug1300461_redirect.html directly.
+ * 4) file_bug1300461_redirect.html redirects UA to
+ * file_bug1300461_back.html through HTTP 301 header.
+ *
+ * We verify the history index, canGoBack, canGoForward, etc. keep correct
+ * in this process.
+ */
+ let Ci = SpecialPowers.Ci;
+ let webNav = SpecialPowers.wrap(window)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation);
+ let shistory = webNav.sessionHistory;
+ let testSteps = [
+ function() {
+ opener.is(shistory.count, 1, 'check history length');
+ opener.is(shistory.index, 0, 'check history index');
+ opener.ok(!webNav.canGoForward, 'check canGoForward');
+ setTimeout(() => window.location = 'file_bug1300461_back.html', 0);
+ },
+ function() {
+ opener.is(shistory.count, 2, 'check history length');
+ opener.is(shistory.index, 0, 'check history index');
+ opener.ok(webNav.canGoForward, 'check canGoForward');
+ window.history.forward();
+ opener.is(shistory.requestedIndex, 1, 'check requestedIndex');
+ },
+ function() {
+ opener.is(shistory.count, 2, 'check history length');
+ opener.is(shistory.index, 0, 'check history index');
+ opener.ok(webNav.canGoForward, 'check canGoForward');
+ opener.info('file_bug1300461.html tests finished');
+ opener.nextTest();
+ window.close();
+ }
+ ];
+
+ function test() {
+ if (opener) {
+ opener.info('file_bug1300461.html test ' + opener.testCount);
+ testSteps[opener.testCount++]();
+ }
+ }
+ </script>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_bug1300461_back.html b/docshell/test/navigation/file_bug1300461_back.html
new file mode 100644
index 000000000..7b187742f
--- /dev/null
+++ b/docshell/test/navigation/file_bug1300461_back.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Bug 1300461</title>
+ </head>
+ <!-- The empty unload handler is to prevent bfcache. -->
+ <body onload="test();" onunload="">
+ <script>
+ let Ci = SpecialPowers.Ci;
+ let webNav = SpecialPowers.wrap(window)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation);
+ let shistory = webNav.sessionHistory;
+ function test() {
+ if (opener) {
+ opener.info("file_bug1300461_back.html");
+ opener.is(shistory.count, 2, 'check history length');
+ opener.is(shistory.index, 1, 'check history index');
+ opener.is(shistory.requestedIndex, -1, 'check requestedIndex');
+ opener.ok(webNav.canGoBack, 'check canGoBack');
+ if (opener.testCount == 1) {
+ opener.info('replaceState to redirect.html');
+ window.history.replaceState({}, '', 'file_bug1300461_redirect.html');
+ }
+ window.history.back();
+ }
+ }
+ </script>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_bug1300461_redirect.html b/docshell/test/navigation/file_bug1300461_redirect.html
new file mode 100644
index 000000000..979530c5c
--- /dev/null
+++ b/docshell/test/navigation/file_bug1300461_redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Bug 1300461</title>
+ </head>
+ <body>
+ Redirect to file_bug1300461_back.html.
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_bug1300461_redirect.html^headers^ b/docshell/test/navigation/file_bug1300461_redirect.html^headers^
new file mode 100644
index 000000000..241b89182
--- /dev/null
+++ b/docshell/test/navigation/file_bug1300461_redirect.html^headers^
@@ -0,0 +1,2 @@
+HTTP 301 Moved Permanently
+Location: file_bug1300461_back.html
diff --git a/docshell/test/navigation/file_bug462076_1.html b/docshell/test/navigation/file_bug462076_1.html
new file mode 100644
index 000000000..5b7bf2b11
--- /dev/null
+++ b/docshell/test/navigation/file_bug462076_1.html
@@ -0,0 +1,55 @@
+<html>
+ <head>
+ <title>Bug 462076</title>
+ <script>
+ var srcs = [ "frame0.html",
+ "frame1.html",
+ "frame2.html",
+ "frame3.html" ];
+
+ var checkCount = 0;
+
+ function makeFrame(index) {
+ var ifr = document.createElement("iframe");
+ ifr.src = srcs[index];
+ ifr.onload = checkFrame;
+ document.getElementById("container" + index).appendChild(ifr);
+ }
+
+ function runTest() {
+ var randomNumber = Math.floor(Math.random() * 4);
+ for (var i = randomNumber; i < 4; ++i) {
+ makeFrame(i);
+ }
+ for (var i = 0; i < randomNumber; ++i) {
+ makeFrame(i);
+ }
+ }
+
+ function checkFrame(evt) {
+ var ifr = evt.target;
+ opener.ok(new String(ifr.contentWindow.location).indexOf(ifr.src) >= 0,
+ "Wrong document loaded (" + ifr.src + ", " +
+ ifr.contentWindow.location + ")!");
+
+ if (++checkCount == 4) {
+ if (++opener.testCount == 10) {
+ opener.nextTest();
+ window.close();
+ } else {
+ window.location.reload();
+ }
+ }
+ }
+ </script>
+ </head>
+ <body>
+ <div id="container0"></div>
+ <div id="container1"></div>
+ <div id="container2"></div>
+ <div id="container3"></div>
+ <script>
+ runTest();
+ </script>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_bug462076_2.html b/docshell/test/navigation/file_bug462076_2.html
new file mode 100644
index 000000000..813a6d840
--- /dev/null
+++ b/docshell/test/navigation/file_bug462076_2.html
@@ -0,0 +1,52 @@
+<html>
+ <head>
+ <title>Bug 462076</title>
+ <script>
+ var srcs = [ "frame0.html",
+ "frame1.html",
+ "frame2.html",
+ "frame3.html" ];
+
+ var checkCount = 0;
+
+ function makeFrame(index) {
+ var ifr = document.createElement("iframe");
+ ifr.src = srcs[index];
+ ifr.onload = checkFrame;
+ document.getElementById("container" + index).appendChild(ifr);
+ }
+
+ function runTest() {
+ var randomNumber = Math.floor(Math.random() * 4);
+ for (var i = randomNumber; i < 4; ++i) {
+ makeFrame(i);
+ }
+ for (var i = 0; i < randomNumber; ++i) {
+ makeFrame(i);
+ }
+ }
+
+ function checkFrame(evt) {
+ var ifr = evt.target;
+ opener.ok(new String(ifr.contentWindow.location).indexOf(ifr.src) >= 0,
+ "Wrong document loaded (" + ifr.src + ", " +
+ ifr.contentWindow.location + ")!");
+
+ if (++checkCount == 4) {
+ if (++opener.testCount == 10) {
+ opener.nextTest();
+ window.close();
+ } else {
+ window.location.reload();
+ }
+ }
+ }
+ </script>
+ </head>
+ <body onload="runTest();">
+ <div id="container0"></div>
+ <div id="container1"></div>
+ <div id="container2"></div>
+ <div id="container3"></div>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_bug462076_3.html b/docshell/test/navigation/file_bug462076_3.html
new file mode 100644
index 000000000..0079b9cdf
--- /dev/null
+++ b/docshell/test/navigation/file_bug462076_3.html
@@ -0,0 +1,52 @@
+<html>
+ <head>
+ <title>Bug 462076</title>
+ <script>
+ var srcs = [ "frame0.html",
+ "frame1.html",
+ "frame2.html",
+ "frame3.html" ];
+
+ var checkCount = 0;
+
+ function makeFrame(index) {
+ var ifr = document.createElement("iframe");
+ ifr.src = srcs[index];
+ ifr.onload = checkFrame;
+ document.getElementById("container" + index).appendChild(ifr);
+ }
+
+ function runTest() {
+ var randomNumber = Math.floor(Math.random() * 4);
+ for (var i = randomNumber; i < 4; ++i) {
+ makeFrame(i);
+ }
+ for (var i = 0; i < randomNumber; ++i) {
+ makeFrame(i);
+ }
+ }
+
+ function checkFrame(evt) {
+ var ifr = evt.target;
+ opener.ok(new String(ifr.contentWindow.location).indexOf(ifr.src) >= 0,
+ "Wrong document loaded (" + ifr.src + ", " +
+ ifr.contentWindow.location + ")!");
+
+ if (++checkCount == 4) {
+ if (++opener.testCount == 10) {
+ opener.nextTest();
+ window.close();
+ } else {
+ window.location.reload();
+ }
+ }
+ }
+ </script>
+ </head>
+ <body onload="setTimeout(runTest, 0);">
+ <div id="container0"></div>
+ <div id="container1"></div>
+ <div id="container2"></div>
+ <div id="container3"></div>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_bug508537_1.html b/docshell/test/navigation/file_bug508537_1.html
new file mode 100644
index 000000000..194165f43
--- /dev/null
+++ b/docshell/test/navigation/file_bug508537_1.html
@@ -0,0 +1,34 @@
+<html>
+ <head>
+ <script>
+ function dynFrameLoad() {
+ var ifrs = document.getElementsByTagName("iframe");
+ opener.ok(new String(ifrs[0].contentWindow.location).indexOf(ifrs[0].src) >= 0,
+ "Wrong document loaded (1)\n");
+ opener.ok(new String(ifrs[1].contentWindow.location).indexOf(ifrs[1].src) >= 0,
+ "Wrong document loaded (2)\n");
+ if (opener && ++opener.testCount == 1) {
+ window.location = "goback.html";
+ } else {
+ opener.nextTest();
+ window.close();
+ }
+ }
+
+ window.addEventListener("load",
+ function () {
+ var container = document.getElementById("t1");
+ container.addEventListener("load", dynFrameLoad, true);
+ container.appendChild(container.appendChild(document.getElementById("i1")));
+ }, false);
+ </script>
+ </head>
+ <body>
+ <h5>Container:</h5>
+ <div id="t1"></div>
+ <h5>Original frames:</h5>
+ <iframe id="i1" src="frame0.html"></iframe>
+ <iframe src="frame1.html"></iframe>
+ </body>
+</html>
+
diff --git a/docshell/test/navigation/file_bug534178.html b/docshell/test/navigation/file_bug534178.html
new file mode 100644
index 000000000..8bcedb6fb
--- /dev/null
+++ b/docshell/test/navigation/file_bug534178.html
@@ -0,0 +1,31 @@
+<html>
+ <head>
+ <script>
+
+ function testDone() {
+ document.body.removeChild(document.body.firstChild);
+ var isOK = false;
+ try {
+ isOK = history.previous != location;
+ } catch(ex) {
+ // history.previous should throw if this is the first page in shistory.
+ isOK = true;
+ }
+ document.body.textContent = isOK ? "PASSED" : "FAILED";
+ opener.ok(isOK, "Duplicate session history transactions should have been removed!");
+ opener.nextTest();
+ window.close();
+ }
+ function ifrload() {
+ setTimeout(testDone, 0);
+ }
+ function test() {
+ var ifr = document.getElementsByTagName("iframe")[0];
+ ifr.onload = ifrload;
+ ifr.src = "data:text/html,doc2";
+ }
+ </script>
+ </head>
+ <body onload="setTimeout(test, 0)"><iframe src="data:text/html,doc1"></iframe>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_document_write_1.html b/docshell/test/navigation/file_document_write_1.html
new file mode 100644
index 000000000..e0281f7cd
--- /dev/null
+++ b/docshell/test/navigation/file_document_write_1.html
@@ -0,0 +1,30 @@
+<html>
+ <head>
+ <script>
+ function run() {
+ document.open();
+ document.write("<h5 id='dynamic'>document.written content</h5>");
+ document.close();
+ window.history.go(-1);
+ }
+
+ function start() {
+ if (++opener.testCount == 1) {
+ setTimeout(run, 0);
+ }
+ }
+
+ window.addEventListener("pageshow",
+ function() {
+ ++opener.file_document_write_1_loadCount;
+ if (opener.file_document_write_1_loadCount == 2) {
+ opener.setTimeout("isTestDynamic()", 0);
+ }
+ opener.ok(opener.file_document_write_1_loadCount <= 2);
+ });
+ </script>
+ </head>
+ <body onload="start();">
+ <h5>static content</h5>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_fragment_handling_during_load.html b/docshell/test/navigation/file_fragment_handling_during_load.html
new file mode 100644
index 000000000..fbfa0cb38
--- /dev/null
+++ b/docshell/test/navigation/file_fragment_handling_during_load.html
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <script>
+ var timerID = 0;
+ function testDone() {
+ clearTimeout(timerID);
+ var l = document.body.firstChild.contentWindow.location.href;
+ opener.is(l, "data:text/html,bar", "Should have loaded a new document");
+ opener.nextTest();
+ window.close();
+ }
+ function test() {
+ var ifr = document.getElementsByTagName("iframe")[0];
+ ifr.onload = testDone;
+ ifr.contentWindow.location.hash = "b";
+ ifr.contentWindow.location.href = "data:text/html,bar";
+ history.back();
+ timerID = setTimeout(testDone, 2000);
+ }
+ </script>
+ </head>
+ <body onload="setTimeout(test, 0)"><iframe src="data:text/html,foo#a"></iframe>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_nested_frames.html b/docshell/test/navigation/file_nested_frames.html
new file mode 100644
index 000000000..f65d8e01b
--- /dev/null
+++ b/docshell/test/navigation/file_nested_frames.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <script>
+ function nestedIframeLoaded() {
+ var tf = document.getElementById("testframe");
+ var innerf = tf.contentDocument.getElementsByTagName("iframe")[0];
+ if (innerf.contentDocument.documentURI.indexOf("frame0") < 0) {
+ innerf.contentWindow.location.href = "http://mochi.test:8888/tests/docshell/test/navigation/frame0.html";
+ return;
+ }
+ innerf.onload = null;
+ innerf.src = "about:blank";
+ var d = innerf.contentDocument;
+ d.open();
+ d.write("test");
+ d.close();
+ opener.is(window.history.length, 1, "Unexpected history length");
+ opener.nextTest();
+ window.close();
+ }
+ </script>
+ </head>
+ <body>
+ <iframe id="testframe" src="data:text/html,<iframe onload='parent.nestedIframeLoaded();'></iframe>" onload="frameLoaded()"></iframe>
+ <script>
+ </script>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_scrollRestoration.html b/docshell/test/navigation/file_scrollRestoration.html
new file mode 100644
index 000000000..5450c2724
--- /dev/null
+++ b/docshell/test/navigation/file_scrollRestoration.html
@@ -0,0 +1,137 @@
+<html>
+ <head>
+ <script>
+ var oldHistoryObject = null;
+
+ function test(event) {
+ if (!opener.scrollRestorationTest) {
+ opener.scrollRestorationTest = 0;
+ }
+ ++opener.scrollRestorationTest;
+
+ switch (opener.scrollRestorationTest) {
+ case 1: {
+ opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
+ opener.ok(history.scrollRestoration, "History object has scrollRestoration property.");
+ opener.ok(history.scrollRestoration, "auto", "history.scrollRestoration's default value should be 'auto'.");
+ history.scrollRestoration = "foobar";
+ opener.ok(history.scrollRestoration, "auto", "Invalid enum value should not change the value of an attribute.");
+ history.scrollRestoration = "manual";
+ opener.ok(history.scrollRestoration, "manual", "Valid enum value should change the value of an attribute.");
+ history.scrollRestoration = "auto";
+ opener.ok(history.scrollRestoration, "auto", "Valid enum value should change the value of an attribute.");
+ document.getElementById("bottom").scrollIntoView();
+ window.location.reload(false);
+ break;
+ }
+ case 2: {
+ opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
+ opener.isnot(window.scrollY, 0, "Should have restored scrolling.");
+ opener.is(history.scrollRestoration, "auto", "Should have the same scrollRestoration as before reload.");
+ history.scrollRestoration = "manual";
+ window.onunload = function() {} // Disable bfcache.
+ window.location.reload(false);
+ break;
+ }
+ case 3: {
+ opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
+ opener.is(window.scrollY, 0, "Should not have restored scrolling.");
+ opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
+ document.getElementById("bottom").scrollIntoView();
+ window.onunload = null; // Should get bfcache behavior.
+ opener.setTimeout("testWindow.history.back();", 250);
+ window.location.href = 'data:text/html,';
+ break;
+ }
+ case 4: {
+ opener.is(event.persisted, true, "Should have persisted session history entry.");
+ opener.isnot(window.scrollY, 0, "Should have kept the old scroll position.");
+ opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
+ window.scrollTo(0, 0);
+ window.location.hash = "hash";
+ requestAnimationFrame(test);
+ break;
+ }
+ case 5: {
+ opener.isnot(window.scrollY, 0, "Should have scrolled to #hash.");
+ opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
+ window.onunload = function() {} // Disable bfcache.
+ opener.setTimeout("is(testWindow.history.scrollRestoration, 'auto'); testWindow.history.back();", 250);
+ window.location.href = 'data:text/html,';
+ break;
+ }
+ case 6: {
+ opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
+ opener.is(window.scrollY, 0, "Shouldn't have kept the old scroll position.");
+ opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
+ history.scrollRestoration = "auto";
+ document.getElementById("bottom").scrollIntoView();
+ history.pushState({ state: "state1" }, "state1");
+ history.pushState({ state: "state2" }, "state2");
+ window.scrollTo(0, 0);
+ history.back();
+ opener.isnot(window.scrollY, 0, "Should have scrolled back to the state1's position");
+ opener.is(history.state.state, "state1", "Unexpected state.");
+
+ history.scrollRestoration = "manual";
+ document.getElementById("bottom").scrollIntoView();
+ history.pushState({ state: "state3" }, "state3");
+ history.pushState({ state: "state4" }, "state4");
+ window.scrollTo(0, 0);
+ history.back();
+ opener.is(window.scrollY, 0, "Shouldn't have scrolled back to the state3's position");
+ opener.is(history.state.state, "state3", "Unexpected state.");
+
+ history.pushState({ state: "state5" }, "state5");
+ history.scrollRestoration = "auto";
+ document.getElementById("bottom").scrollIntoView();
+ opener.isnot(window.scrollY, 0, "Should have scrolled to 'bottom'.");
+ history.back();
+ window.scrollTo(0, 0);
+ history.forward();
+ opener.isnot(window.scrollY, 0, "Should have scrolled back to the state5's position");
+
+ var ifr = document.createElement("iframe");
+ ifr.src = "data:text/html,";
+ document.body.appendChild(ifr);
+ ifr.onload = test;
+ break;
+ }
+ case 7: {
+ oldHistoryObject = event.target.contentWindow.history;
+ event.target.src = "about:blank";
+ break;
+ }
+ case 8: {
+ try {
+ var sr = oldHistoryObject.scrollRestoration;
+ opener.ok(false, "Should have thrown an exception.");
+ } catch(ex) {
+ opener.isnot(ex, null, "Did get an exception");
+ }
+ try {
+ oldHistoryObject.scrollRestoration = "auto";
+ opener.ok(false, "Should have thrown an exception.");
+ } catch(ex) {
+ opener.isnot(ex, null, "Did get an exception");
+ }
+ opener.nextTest();
+ window.close();
+ break;
+ }
+ }
+ }
+
+ window.addEventListener("pageshow",
+ function(e) {
+ setTimeout(test, 0, e);
+ });
+ </script>
+ </head>
+ <body>
+ <div style="border: 1px solid black; height: 5000px;">
+ &nbsp;</div>
+ <div id="bottom">Hello world</div>
+ <a href="#hash" name="hash">hash</a>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_shiftReload_and_pushState.html b/docshell/test/navigation/file_shiftReload_and_pushState.html
new file mode 100644
index 000000000..5a777894b
--- /dev/null
+++ b/docshell/test/navigation/file_shiftReload_and_pushState.html
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <script>
+ function test() {
+ try {
+ frames[0].history.pushState({}, "state", "?pushed");
+ } catch(ex) {
+ opener.ok(false, "history.pushState shouldn't throw");
+ }
+
+ if (!opener.shiftReloadPushStateFirstRound) {
+ opener.shiftReloadPushStateFirstRound = true;
+ window.location.reload(true);
+ } else {
+ opener.ok(true, "Did run history.push");
+ opener.nextTest();
+ window.close();
+ }
+ }
+
+ window.addEventListener("load", function() { setTimeout(test, 0); });
+ </script>
+ </head>
+ <body>
+ <iframe src="frame0.html"></iframe>
+ <script>
+ </script>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_static_and_dynamic_1.html b/docshell/test/navigation/file_static_and_dynamic_1.html
new file mode 100644
index 000000000..692a5a9ab
--- /dev/null
+++ b/docshell/test/navigation/file_static_and_dynamic_1.html
@@ -0,0 +1,32 @@
+<html>
+ <head>
+ <script>
+ function test() {
+ var ifr = document.createElement("iframe");
+ ifr.src = "frame0.html";
+ document.getElementById("dynamic").appendChild(ifr);
+ var staticFrame = document.getElementById("staticframe");
+ staticFrame.onload = window.location = "goback.html";
+ staticFrame.contentWindow.location = "frame1.html";
+ }
+
+ function start() {
+ if (++opener.testCount == 1) {
+ test();
+ } else {
+ var staticFrame = document.getElementById("staticframe");
+ opener.ok(new String(staticFrame.contentWindow.location).indexOf(staticFrame.src) >= 0,
+ "Wrong document loaded!");
+ opener.nextTest();
+ window.close();
+ }
+ }
+ </script>
+ </head>
+ <body onload="setTimeout('start()', 0)">
+ <h5>Dynamic</h5>
+ <div id="dynamic"></div>
+ <h5>Static</h5>
+ <div id="static"><iframe id="staticframe" src="frame0.html"></iframe></div>
+ </body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_frame_1.html b/docshell/test/navigation/file_triggeringprincipal_frame_1.html
new file mode 100644
index 000000000..1e21e6421
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_frame_1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head><meta charset="utf-8"></head>
+<body>
+<b>Frame 1</b><br/>
+<a href="#"" id="testlink" onclick="parent.frames[1].frames[0].location='http://test2.mochi.test:8888/tests/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html'">click me</a>
+
+<script type="application/javascript">
+ // make sure to set document.domain to the same domain as the subframe
+ window.onload = function() {
+ document.domain = 'mochi.test';
+ };
+ window.addEventListener('message', receiveMessage, false);
+ function receiveMessage(event) {
+ // make sure to get the right start command, otherwise
+ // let the parent know and fail the test
+ if (event.data.start !== 'startTest') {
+ window.removeEventListener("message", receiveMessage, false);
+ window.parent.postMessage({triggeringPrincipalURI: 'false'}, '*');
+ }
+ // click the link to navigate the subframe
+ document.getElementById('testlink').click();
+ }
+</script>
+
+</body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_frame_2.html b/docshell/test/navigation/file_triggeringprincipal_frame_2.html
new file mode 100644
index 000000000..ef7cdfc17
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_frame_2.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<html>
+<head><meta charset="utf-8"></head>
+<body>
+<b>Frame 2</b><br/>
+<iframe src="http://test2.mochi.test:8888/tests/docshell/test/navigation/file_triggeringprincipal_subframe.html"></iframe>
+</body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html
new file mode 100644
index 000000000..75b2933c1
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+Frame A
+</body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html
new file mode 100644
index 000000000..0479f5e1e
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+Frame A navigated by Frame B
+</body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html
new file mode 100644
index 000000000..e5d40b267
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<body>
+Frame B navigating Frame A
+
+<script type="text/javascript">
+
+window.open("file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html", "framea");
+
+</script>
+
+</body>
+</html>
+
+
diff --git a/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html b/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html
new file mode 100644
index 000000000..caa6b275b
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_base.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+base test frame
+</body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html b/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html
new file mode 100644
index 000000000..f4a4d0e63
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_parent_iframe_window_open_nav.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+navigated by window.open()
+</body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_subframe.html b/docshell/test/navigation/file_triggeringprincipal_subframe.html
new file mode 100644
index 000000000..0db1349f2
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_subframe.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head><meta charset='utf-8'></head>
+<body>
+<b>Sub Frame 2</b><br/>
+<script type='application/javascript'>
+ // make sure to set document.domain to same domain as frame 1
+ window.onload = function() {
+ document.domain = 'mochi.test';
+ // let Frame 1 know that we are ready to run the test
+ window.parent.parent.frames[0].postMessage({start: 'startTest'}, '*');
+ };
+</script>
+</body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html b/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html
new file mode 100644
index 000000000..3bf7097a6
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_subframe_nav.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head><meta charset="utf-8"></head>
+<body onload="checkResults()">
+<b>Sub Frame 2 Navigated</b><br/>
+
+<script type='application/javascript'>
+ function checkResults() {
+ // query the uri of the loadingPrincipal and the TriggeringPrincipal and pass
+ // that information on to the parent for verification.
+ var channel = SpecialPowers.wrap(document).docShell.currentDocumentChannel;
+ var triggeringPrincipalURI = channel.loadInfo.triggeringPrincipal.URI.asciiSpec;
+ var loadingPrincipalURI = channel.loadInfo.loadingPrincipal.URI.asciiSpec;
+ var referrerURI = document.referrer;
+ window.parent.parent.postMessage({triggeringPrincipalURI,
+ loadingPrincipalURI,
+ referrerURI}, '*');
+ }
+</script>
+</body>
+</html>
diff --git a/docshell/test/navigation/file_triggeringprincipal_window_open.html b/docshell/test/navigation/file_triggeringprincipal_window_open.html
new file mode 100644
index 000000000..d0644a4d5
--- /dev/null
+++ b/docshell/test/navigation/file_triggeringprincipal_window_open.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+http
+</body>
+</html>
diff --git a/docshell/test/navigation/frame0.html b/docshell/test/navigation/frame0.html
new file mode 100644
index 000000000..93d1c9c82
--- /dev/null
+++ b/docshell/test/navigation/frame0.html
@@ -0,0 +1,3 @@
+<html>
+ <body>Frame 0</body>
+</html>
diff --git a/docshell/test/navigation/frame1.html b/docshell/test/navigation/frame1.html
new file mode 100644
index 000000000..4d06c09d1
--- /dev/null
+++ b/docshell/test/navigation/frame1.html
@@ -0,0 +1,3 @@
+<html>
+ <body>Frame 1</body>
+</html>
diff --git a/docshell/test/navigation/frame2.html b/docshell/test/navigation/frame2.html
new file mode 100644
index 000000000..7a3b5e0b9
--- /dev/null
+++ b/docshell/test/navigation/frame2.html
@@ -0,0 +1,3 @@
+<html>
+ <body>Frame 2</body>
+</html>
diff --git a/docshell/test/navigation/frame3.html b/docshell/test/navigation/frame3.html
new file mode 100644
index 000000000..fd2429387
--- /dev/null
+++ b/docshell/test/navigation/frame3.html
@@ -0,0 +1,3 @@
+<html>
+ <body>Frame 3</body>
+</html>
diff --git a/docshell/test/navigation/goback.html b/docshell/test/navigation/goback.html
new file mode 100644
index 000000000..ce2968374
--- /dev/null
+++ b/docshell/test/navigation/goback.html
@@ -0,0 +1,5 @@
+<html>
+ <body onload="setTimeout('window.history.go(-1)', 1000);">
+ window.history.go(-1);
+ </body>
+</html>
diff --git a/docshell/test/navigation/iframe.html b/docshell/test/navigation/iframe.html
new file mode 100644
index 000000000..4685fea7b
--- /dev/null
+++ b/docshell/test/navigation/iframe.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<script>
+var src = window.location.hash.substring(1);
+document.write('<iframe src="' + src + '"></iframe>');
+</script>
+</body>
+</html>
diff --git a/docshell/test/navigation/mochitest.ini b/docshell/test/navigation/mochitest.ini
new file mode 100644
index 000000000..0c35cf352
--- /dev/null
+++ b/docshell/test/navigation/mochitest.ini
@@ -0,0 +1,64 @@
+[DEFAULT]
+support-files =
+ NavigationUtils.js
+ blank.html
+ file_bug462076_1.html
+ file_bug462076_2.html
+ file_bug462076_3.html
+ file_bug508537_1.html
+ file_bug534178.html
+ file_document_write_1.html
+ file_fragment_handling_during_load.html
+ file_nested_frames.html
+ file_scrollRestoration.html
+ file_shiftReload_and_pushState.html
+ file_static_and_dynamic_1.html
+ frame0.html
+ frame1.html
+ frame2.html
+ frame3.html
+ goback.html
+ iframe.html
+ navigate.html
+ open.html
+ parent.html
+ file_triggeringprincipal_frame_1.html
+ file_triggeringprincipal_frame_2.html
+ file_triggeringprincipal_subframe.html
+ file_triggeringprincipal_subframe_nav.html
+ file_triggeringprincipal_window_open.html
+ file_triggeringprincipal_parent_iframe_window_open_base.html
+ file_triggeringprincipal_parent_iframe_window_open_nav.html
+ file_triggeringprincipal_iframe_iframe_window_open_frame_a.html
+ file_triggeringprincipal_iframe_iframe_window_open_frame_b.html
+ file_triggeringprincipal_iframe_iframe_window_open_frame_a_nav.html
+ file_bug1300461.html
+ file_bug1300461_redirect.html
+ file_bug1300461_redirect.html^headers^
+ file_bug1300461_back.html
+
+[test_bug13871.html]
+[test_bug270414.html]
+[test_bug278916.html]
+[test_bug279495.html]
+[test_bug344861.html]
+skip-if = toolkit == "android" || toolkit == "windows" # disabled on Windows because of bug 1234520
+[test_bug386782.html]
+[test_bug430624.html]
+[test_bug430723.html]
+skip-if = (toolkit == 'android') || (!debug && (os == 'mac' || os == 'win')) # Bug 874423
+[test_child.html]
+[test_grandchild.html]
+[test_not-opener.html]
+[test_opener.html]
+[test_popup-navigates-children.html]
+[test_reserved.html]
+skip-if = (toolkit == 'android') || (debug && e10s) #too slow on Android 4.3 aws only; bug 1030403; bug 1263213 for debug e10s
+[test_sessionhistory.html]
+skip-if = toolkit == 'android' #RANDOM
+[test_sibling-matching-parent.html]
+[test_sibling-off-domain.html]
+[test_triggeringprincipal_frame_nav.html]
+[test_triggeringprincipal_window_open.html]
+[test_triggeringprincipal_parent_iframe_window_open.html]
+[test_triggeringprincipal_iframe_iframe_window_open.html]
diff --git a/docshell/test/navigation/navigate.html b/docshell/test/navigation/navigate.html
new file mode 100644
index 000000000..e686da423
--- /dev/null
+++ b/docshell/test/navigation/navigate.html
@@ -0,0 +1,36 @@
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script src="NavigationUtils.js"></script>
+ <script>
+ function navigate() {
+ var arguments = window.location.hash.substring(1).split(",");
+ var target = arguments[0];
+ var mechanism = arguments[1];
+
+ switch(mechanism) {
+ case "location":
+ navigateByLocation(eval(target));
+ break;
+ case "open":
+ navigateByOpen(target);
+ break;
+ case "form":
+ navigateByForm(target);
+ break;
+ case "hyperlink":
+ navigateByHyperlink(target);
+ break;
+ }
+ }
+ </script>
+</head>
+<body onload="navigate();">
+<script>
+var arguments = window.location.hash.substring(1).split(",");
+var target = arguments[0];
+var mechanism = arguments[1];
+document.write("target=" + target + " mechanism=" + mechanism);
+</script>
+</body>
+</html>
diff --git a/docshell/test/navigation/open.html b/docshell/test/navigation/open.html
new file mode 100644
index 000000000..1bb70f865
--- /dev/null
+++ b/docshell/test/navigation/open.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+<script>
+var target = window.location.hash.substring(1);
+document.write("target=" + target);
+window.open("data:text/html,<html><body>This is a popup</body></html>", target, "width=10,height=10");
+</script>
+</body>
+</html>
diff --git a/docshell/test/navigation/parent.html b/docshell/test/navigation/parent.html
new file mode 100644
index 000000000..74722b8bd
--- /dev/null
+++ b/docshell/test/navigation/parent.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<body>
+This document contains a frame.
+<div><iframe src="blank.html"></iframe></div>
+<script>
+frames[0].name = window.name + "_child0";
+window.onload = function() {
+ opener.postMessage("ready", "*");
+};
+</script>
+</body>
+</html>
+
diff --git a/docshell/test/navigation/test_bug13871.html b/docshell/test/navigation/test_bug13871.html
new file mode 100644
index 000000000..e0b563a4a
--- /dev/null
+++ b/docshell/test/navigation/test_bug13871.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 50px; }
+ </style>
+<script>
+function runTest() {
+ navigateByLocation(window0.frames[0]);
+ navigateByOpen("window1_child0");
+ navigateByForm("window2_child0");
+ navigateByHyperlink("window3_child0");
+
+ xpcWaitForFinishedFrames(function() {
+ isInaccessible(window0.frames[0], "Should not be able to navigate off-domain frame by setting location.");
+ isInaccessible(window1.frames[0], "Should not be able to navigate off-domain frame by calling window.open.");
+ isInaccessible(window2.frames[0], "Should not be able to navigate off-domain frame by submitting form.");
+ isInaccessible(window3.frames[0], "Should not be able to navigate off-domain frame by targeted hyperlink.");
+
+ window0.close();
+ window1.close();
+ window2.close();
+ window3.close();
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 4);
+}
+
+// Because our open()'d windows are cross-origin, we can't wait for onload.
+// We instead wait for a postMessage from parent.html.
+var windows = new Map();
+addEventListener("message", function windowLoaded(evt) {
+ // Because window.open spins the event loop in order to open new windows,
+ // we might receive the "ready" message before we call waitForLoad.
+ // In that case, windows won't contain evt.source and we just note that the
+ // window is ready. Otherwise, windows contains the "resolve" function for
+ // that window's promise and we just have to call it.
+ if (windows.has(evt.source)) {
+ windows.get(evt.source)();
+ } else {
+ windows.set(evt.source, true);
+ }
+});
+
+var window0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window0", "width=10,height=10");
+var window1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window1", "width=10,height=10");
+var window2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window2", "width=10,height=10");
+var window3 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window3", "width=10,height=10");
+
+function waitForLoad(w) {
+ return new Promise(function(resolve, reject) {
+ // If we already got the "ready" message, resolve immediately.
+ if (windows.has(w)) {
+ resolve();
+ } else {
+ windows.set(w, resolve);
+ }
+ });
+}
+
+Promise.all([ waitForLoad(window0),
+ waitForLoad(window1),
+ waitForLoad(window2),
+ waitForLoad(window3) ])
+ .then(runTest);
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=13871">Mozilla Bug 13871</a>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_bug270414.html b/docshell/test/navigation/test_bug270414.html
new file mode 100644
index 000000000..98dcf42f8
--- /dev/null
+++ b/docshell/test/navigation/test_bug270414.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 50px; }
+ </style>
+<script>
+var headerHTML = "<html><head>" +
+ "<script src='/tests/SimpleTest/EventUtils.js'></scr" + "ipt>" +
+ "<script src='NavigationUtils.js'></scr" + "ipt>" +
+ "</head><body>";
+var footerHTML = "</body></html>";
+
+function testChild0() {
+ if (!window.window0) {
+ window0 = window.open("", "window0", "width=10,height=10");
+ window0.document.open();
+ window0.document.write(headerHTML);
+ window0.document.write("<script>navigateByLocation(opener.frames[0])</scr" + "ipt>");
+ window0.document.write(footerHTML);
+ window0.document.close();
+ }
+}
+
+function testChild1() {
+ if (!window.window1) {
+ window1 = window.open("", "window1", "width=10,height=10");
+ window1.document.open();
+ window1.document.write(headerHTML);
+ window1.document.write("<script>navigateByOpen('child1');</scr" + "ipt>");
+ window1.document.write(footerHTML);
+ window1.document.close();
+ }
+}
+
+function testChild2() {
+ if (!window.window2) {
+ window2 = window.open("", "window2", "width=10,height=10");
+ window2.document.open();
+ window2.document.write(headerHTML);
+ window2.document.write("<script>navigateByForm('child2');</scr" + "ipt>");
+ window2.document.write(footerHTML);
+ window2.document.close();
+ }
+}
+
+function testChild3() {
+ if (!window.window3) {
+ window3 = window.open("", "window3", "width=10,height=10");
+ window3.document.open();
+ window3.document.write(headerHTML);
+ window3.document.write("<script>navigateByHyperlink('child3');</scr" + "ipt>");
+ window3.document.write(footerHTML);
+ window3.document.close();
+ }
+}
+
+xpcWaitForFinishedFrames(function() {
+ isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location.");
+ isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open.");
+ isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form.");
+ isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
+
+ window0.close();
+ window1.close();
+ window2.close();
+ window3.close();
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+}, 4);
+
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=270414">Mozilla Bug 270414</a>
+<div id="frames">
+<iframe onload="testChild0();" name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe onload="testChild1();" name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe onload="testChild2();" name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe onload="testChild3();" name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+</div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_bug278916.html b/docshell/test/navigation/test_bug278916.html
new file mode 100644
index 000000000..3ad6a9666
--- /dev/null
+++ b/docshell/test/navigation/test_bug278916.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+<script>
+window.onload = function () {
+ document.getElementById("link0").href = target_url;
+ sendMouseEvent({type:"click"}, "link0");
+
+ xpcWaitForFinishedFrames(function() {
+ var array_of_frames = xpcGetFramesByName("window0");
+ is(array_of_frames.length, 1, "Should only open one window using a fancy hyperlink.");
+
+ for (var i=0; i < array_of_frames.length; ++i)
+ array_of_frames[i].close();
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 1);
+}
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=278916">Mozilla Bug 278916</a>
+<div id="links">
+<a id="link0" target="window0" onclick="window.open('', 'window0', 'width=10,height=10');">This is a fancy hyperlink</a>
+</div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_bug279495.html b/docshell/test/navigation/test_bug279495.html
new file mode 100644
index 000000000..79a169567
--- /dev/null
+++ b/docshell/test/navigation/test_bug279495.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+<script>
+window.onload = function () {
+ document.getElementById("link0").href = target_url;
+ document.getElementById("link1").href = target_url;
+
+ sendMouseEvent({type:"click"}, "link0");
+ sendMouseEvent({type:"click"}, "link1");
+
+ xpcWaitForFinishedFrames(function() {
+ countAndClose("window0", 1);
+ countAndClose("window1", 1);
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 2);
+}
+
+function countAndClose(name, expected_count) {
+ var array_of_frames = xpcGetFramesByName(name);
+ is(array_of_frames.length, expected_count,
+ "Should only open " + expected_count +
+ " window(s) with name " + name + " using a fancy hyperlink.");
+
+ for (var i=0; i < array_of_frames.length; ++i)
+ array_of_frames[i].close();
+}
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=279495">Mozilla Bug 279495</a>
+<div id="links">
+<a id="link0" target="window0" onclick="window.open('blank.html', 'window0', 'width=10,height=10');">This is a fancy hyperlink</a>
+<a id="link1" target="window1" onclick="window.open('http://test1.example.org:80/tests/docshell/test/navigation/blank.html', 'window1', 'width=10,height=10');">This is a fancy hyperlink</a>
+</div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_bug344861.html b/docshell/test/navigation/test_bug344861.html
new file mode 100644
index 000000000..f9759751c
--- /dev/null
+++ b/docshell/test/navigation/test_bug344861.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=344861
+-->
+<head>
+ <title>Test for Bug 344861</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=344861">Mozilla Bug 344861</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 344861 **/
+SimpleTest.waitForExplicitFinish();
+
+var newwindow = window.open("/", "testwindow", "width=200,height=200");
+newwindow.onload = function() {
+ is(newwindow.innerHeight, 200, "window.open has correct height dimensions");
+ is(newwindow.innerWidth, 200, "window.open has correct width dimensions");
+ SimpleTest.finish();
+ newwindow.close();
+}
+</script>
+</pre>
+</body>
+</html>
+
+
diff --git a/docshell/test/navigation/test_bug386782.html b/docshell/test/navigation/test_bug386782.html
new file mode 100644
index 000000000..2434963f1
--- /dev/null
+++ b/docshell/test/navigation/test_bug386782.html
@@ -0,0 +1,137 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=386782
+-->
+<head>
+ <title>Test for Bug 386782</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+ <script>
+
+ // This tests if we can load a document whose root is in designMode,
+ // edit it, navigate to a new page, navigate back, still edit, and still
+ // undo/redo. Note that this is different from the case where the
+ // designMode document is in a frame inside the window, as this means
+ // the editable region is not in the root docshell (a less complicated case).
+
+ var pageShowChecker = '<scr' + 'ipt>' +
+ 'window.addEventListener("pageshow", function(event) {' +
+ 'window.opener.postMessage({persisted:event.persisted}, "*");' +
+ '});</scr' + 'ipt>';
+
+ var gTests = [
+ {
+ // <html><body><p>designModeDocument</p></body></html>
+ url: "data:text/html;charset=utf-8,<html><head>" + pageShowChecker + "</head><body><p>designModeDocument</p></body></html>",
+ name: 'designModeNavigate',
+ onload(doc) { doc.designMode = "on"; },
+ expectedBodyBeforeEdit: '<p>designModeDocument</p>',
+ expectedBodyAfterEdit: '<p>EDITED designModeDocument</p>',
+ expectedBodyAfterSecondEdit: '<p>EDITED TWICE designModeDocument</p>',
+ },
+ {
+ // <html><body contentEditable="true"><p>contentEditable</p></body></html>
+ url: "data:text/html;charset=utf-8,<html><head>" + pageShowChecker + "</head><body contentEditable=\"true\"><p>contentEditable</p></body></html>",
+ name: 'contentEditableNavigate',
+ expectedBodyBeforeEdit: '<p>contentEditable</p>',
+ expectedBodyAfterEdit: 'EDITED <br><p>contentEditable</p>',
+ expectedBodyAfterSecondEdit: 'EDITED TWICE <br><p>contentEditable</p>',
+ }
+ ];
+
+ var gTestNum = -1;
+ var gTest = null;
+
+ window.onload = goNext();
+
+ function goNext() {
+ gTestNum++;
+ if (gTestNum >= gTests.length) {
+ SimpleTest.finish();
+ return;
+ }
+ gTest = gTests[gTestNum];
+ gTest.window = window.open(gTest.url, gTest.name, "width=500,height=500");
+ window.onmessage = function(e) {
+ is(e.data.persisted, false, "Initial load cannot be persisted");
+ window.onmessage = null;
+ if ("onload" in gTest) {
+ gTest.onload(gTest.window.document);
+ }
+ SimpleTest.waitForFocus(beginTest, gTest.window);
+ };
+ }
+
+ function beginTest() {
+ gTest.window.document.body.focus();
+
+ // WARNING: If the following test fails, give the setTimeout() in the onload()
+ // a bit longer; the doc hasn't had enough time to setup its editor.
+ is(gTest.window.document.body.innerHTML, gTest.expectedBodyBeforeEdit, "Is doc setup yet");
+ sendString('EDITED ', gTest.window);
+ is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterEdit, "Editing failed.");
+
+ gTest.window.location = 'data:text/html;charset=utf-8,SomeOtherDocument';
+ SimpleTest.waitForFocus(goBack, gTest.window);
+ }
+
+ function goBack() {
+ window.onmessage = function(e) {
+ window.onmessage = null;
+ // Skip the test if the page is not loaded from the bf-cache when going back.
+ if (e.data.persisted) {
+ checkStillEditable();
+ } else {
+ gTest.window.close();
+ goNext();
+ }
+ };
+ gTest.window.history.back();
+ }
+
+ function checkStillEditable() {
+
+ // Check that the contents are correct.
+ is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterEdit, "Edited contents still correct?");
+
+ // Check that we can undo/redo and the contents are correct.
+ gTest.window.document.execCommand("undo", false, null);
+ is(gTest.window.document.body.innerHTML, gTest.expectedBodyBeforeEdit, "Can we undo?");
+
+ gTest.window.document.execCommand("redo", false, null);
+ is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterEdit, "Can we redo?");
+
+ // Check that we can still edit the page.
+ gTest.window.document.body.focus();
+ sendString('TWICE ', gTest.window);
+ is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterSecondEdit, "Can we still edit?");
+
+ gTest.window.close();
+ goNext();
+
+ }
+
+ </script>
+
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=386782">Mozilla Bug 386782</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 386782 **/
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/docshell/test/navigation/test_bug430624.html b/docshell/test/navigation/test_bug430624.html
new file mode 100644
index 000000000..9fc92e4cd
--- /dev/null
+++ b/docshell/test/navigation/test_bug430624.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=430624
+-->
+<head>
+ <title>Test for Bug 430624</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=430624">Mozilla Bug 430624</a>
+<p id="display"></p>
+
+
+
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 430624 **/
+
+function onLoad() {
+ window.frames[0].frameElement.onload = onReload;
+ window.frames[0].location = window.frames[0].location;
+}
+
+function onReload() {
+ var iframe = window.frames[0].frameElement;
+ SimpleTest.waitForFocus(doTest, iframe.contentWindow);
+ iframe.contentDocument.body.focus();
+}
+
+function doTest() {
+ var bodyElement = window.frames[0].frameElement.contentDocument.body;
+ bodyElement.focus();
+ sendString('Still ', window.frames[0].frameElement.contentWindow);
+
+ is(bodyElement.innerHTML, "Still contentEditable", "Check we're contentEditable after reload");
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+
+<iframe onload="onLoad()" src="data:text/html;charset=utf-8,<body contenteditable>contentEditable</body>"></iframe>
+
+</body>
+</html>
+
diff --git a/docshell/test/navigation/test_bug430723.html b/docshell/test/navigation/test_bug430723.html
new file mode 100644
index 000000000..eb53e0d22
--- /dev/null
+++ b/docshell/test/navigation/test_bug430723.html
@@ -0,0 +1,138 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=430723
+-->
+<head>
+ <title>Test for Bug 430723</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=430723">Mozilla Bug 430723</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+//<![CDATA[
+
+/** Test for Bug 430723 **/
+
+var gTallRedBoxURI = "data:text/html;charset=utf-8;base64,PGh0bWw%2BPGhlYWQ%2BPHNjcmlwdD53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncGFnZXNob3cnLCBmdW5jdGlvbigpe29wZW5lci5uZXh0VGVzdCgpO30sIGZhbHNlKTs8L3NjcmlwdD48L2hlYWQ%2BPGJvZHk%2BPGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7IGxlZnQ6MHB4OyB0b3A6MHB4OyB3aWR0aDo1MCU7IGhlaWdodDoxNTAlOyBiYWNrZ3JvdW5kLWNvbG9yOnJlZCI%2BPHA%2BVGhpcyBpcyBhIHZlcnkgdGFsbCByZWQgYm94LjwvcD48L2Rpdj48L2JvZHk%2BPC9odG1sPg%3D%3D";
+// <html><head>
+// < script > window.addEventListener("pageshow", function(){opener.nextTest();}, false); < /script >
+// </head><body>
+// <div style="position:absolute; left:0px; top:0px; width:50%; height:150%; background-color:red">
+// <p>This is a very tall red box.</p>
+// </div></body></html>
+
+var gTallBlueBoxURI = "data:text/html;charset=utf-8;base64,PGh0bWw%2BPGhlYWQ%2BPHNjcmlwdD53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncGFnZXNob3cnLCBmdW5jdGlvbigpe29wZW5lci5uZXh0VGVzdCgpO30sIGZhbHNlKTs8L3NjcmlwdD48L2hlYWQ%2BPGJvZHk%2BPGRpdiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7IGxlZnQ6MHB4OyB0b3A6MHB4OyB3aWR0aDo1MCU7IGhlaWdodDoxNTAlOyBiYWNrZ3JvdW5kLWNvbG9yOmJsdWUiPjxwPlRoaXMgaXMgYSB2ZXJ5IHRhbGwgYmx1ZSBib3guPC9wPjwvZGl2PjwvYm9keT48L2h0bWw%2B";
+// <html><head>
+// < script > window.addEventListener("pageshow", function(){opener.nextTest();}, false); < /script >
+// </head><body>
+// <div style="position:absolute; left:0px; top:0px; width:50%; height:150%; background-color:blue">
+// <p>This is a very tall blue box.</p>
+// </div></body></html>
+
+window.onload = runTest;
+
+var testWindow;
+var testNum = 0;
+
+var smoothScrollPref = "general.smoothScroll";
+function runTest() {
+ SpecialPowers.pushPrefEnv({"set":[[smoothScrollPref, false]]}, function(){
+ testWindow = window.open(gTallRedBoxURI, "testWindow", "width=300,height=300,location=yes,scrollbars=yes");
+ });
+}
+
+var nextTest =function() {
+ testNum++;
+ switch (testNum) {
+ case 1: setTimeout(step1, 0); break;
+ case 2: setTimeout(step2, 0); break;
+ case 3: setTimeout(step3, 0); break;
+ };
+}
+
+var step1 =function() {
+ window.is(String(testWindow.location), gTallRedBoxURI, "Ensure red page loaded.");
+
+ // Navigate down and up.
+ is(testWindow.document.body.scrollTop, 0,
+ "Page1: Ensure the scrollpane is at the top before we start scrolling.");
+ testWindow.addEventListener("scroll", function () {
+ testWindow.removeEventListener("scroll", arguments.callee, true);
+ isnot(testWindow.document.body.scrollTop, 0,
+ "Page1: Ensure we can scroll down.");
+ SimpleTest.executeSoon(step1_2);
+ }, true);
+ sendKey('DOWN', testWindow);
+
+ function step1_2() {
+ testWindow.addEventListener("scroll", function () {
+ testWindow.removeEventListener("scroll", arguments.callee, true);
+ is(testWindow.document.body.scrollTop, 0,
+ "Page1: Ensure we can scroll up, back to the top.");
+
+ // Nav to blue box page. This should fire step2.
+ testWindow.location = gTallBlueBoxURI;
+ }, true);
+ sendKey('UP', testWindow);
+ }
+}
+
+
+var step2 =function() {
+ window.is(String(testWindow.location), gTallBlueBoxURI, "Ensure blue page loaded.");
+
+ // Scroll around a bit.
+ is(testWindow.document.body.scrollTop, 0,
+ "Page2: Ensure the scrollpane is at the top before we start scrolling.");
+
+ var count = 0;
+ testWindow.addEventListener("scroll", function () {
+ if (++count < 2) {
+ SimpleTest.executeSoon(function () { sendKey('DOWN', testWindow); });
+ } else {
+ testWindow.removeEventListener("scroll", arguments.callee, true);
+
+ isnot(testWindow.document.body.scrollTop, 0,
+ "Page2: Ensure we could scroll.");
+
+ // Navigate backwards. This should fire step3.
+ testWindow.history.back();
+ }
+ }, true);
+ sendKey('DOWN', testWindow);
+}
+
+var step3 =function() {
+ window.is(String(testWindow.location), gTallRedBoxURI,
+ "Ensure red page restored from history.");
+
+ // Check we can still scroll with the keys.
+ is(testWindow.document.body.scrollTop, 0,
+ "Page1Again: Ensure scroll pane at top before we scroll.");
+ testWindow.addEventListener("scroll", function () {
+ testWindow.removeEventListener("scroll", arguments.callee, true);
+
+ isnot(testWindow.document.body.scrollTop, 0,
+ "Page2Again: Ensure we can still scroll.");
+
+ testWindow.close();
+ window.SimpleTest.finish();
+ }, true);
+ sendKey('DOWN', testWindow);
+}
+
+SimpleTest.waitForExplicitFinish();
+
+//]]>
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_child.html b/docshell/test/navigation/test_child.html
new file mode 100644
index 000000000..c43e1a6cf
--- /dev/null
+++ b/docshell/test/navigation/test_child.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 50px; }
+ </style>
+<script>
+if (!navigator.platform.startsWith("Win")) {
+ SimpleTest.expectAssertions(0, 1);
+}
+
+window.onload = function() {
+ navigateByLocation(frames[0]);
+ navigateByOpen("child1");
+ navigateByForm("child2");
+ navigateByHyperlink("child3");
+
+ xpcWaitForFinishedFrames(function() {
+ isNavigated(frames[0], "Should be able to navigate off-domain child by setting location.");
+ isNavigated(frames[1], "Should be able to navigate off-domain child by calling window.open.");
+ isNavigated(frames[2], "Should be able to navigate off-domain child by submitting form.");
+ isNavigated(frames[3], "Should be able to navigate off-domain child by targeted hyperlink.");
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 4);
+}
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
+<div id="frames">
+<iframe name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+</div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_grandchild.html b/docshell/test/navigation/test_grandchild.html
new file mode 100644
index 000000000..439145b3e
--- /dev/null
+++ b/docshell/test/navigation/test_grandchild.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 200px; }
+ </style>
+<script>
+if (!navigator.platform.startsWith("Win")) {
+ SimpleTest.expectAssertions(0, 1);
+}
+
+window.onload = function () {
+ navigateByLocation(frames[0].frames[0]);
+ navigateByOpen("child1_child0");
+ navigateByForm("child2_child0");
+ navigateByHyperlink("child3_child0");
+
+ xpcWaitForFinishedFrames(function() {
+ isNavigated(frames[0].frames[0], "Should be able to navigate off-domain grandchild by setting location.");
+ isNavigated(frames[1].frames[0], "Should be able to navigate off-domain grandchild by calling window.open.");
+ isNavigated(frames[2].frames[0], "Should be able to navigate off-domain grandchild by submitting form.");
+ isNavigated(frames[3].frames[0], "Should be able to navigate off-domain grandchild by targeted hyperlink.");
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 4);
+}
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
+<div id="frames">
+<iframe name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/parent.html"></iframe>
+<iframe name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/parent.html"></iframe>
+<iframe name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/parent.html"></iframe>
+<iframe name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/parent.html"></iframe>
+</div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_not-opener.html b/docshell/test/navigation/test_not-opener.html
new file mode 100644
index 000000000..d778f71d9
--- /dev/null
+++ b/docshell/test/navigation/test_not-opener.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 50px; }
+ </style>
+<script>
+if (!navigator.platform.startsWith("Win")) {
+ SimpleTest.expectAssertions(0, 1);
+}
+
+window.onload = function () {
+ //navigateByLocation(window0); // Don't have a handle to the window.
+ navigateByOpen("window1");
+ navigateByForm("window2");
+ navigateByHyperlink("window3");
+
+ xpcWaitForFinishedFrames(function() {
+ is(xpcGetFramesByName("window1").length, 2, "Should not be able to navigate popup's popup by calling window.open.");
+ is(xpcGetFramesByName("window2").length, 2, "Should not be able to navigate popup's popup by submitting form.");
+ is(xpcGetFramesByName("window3").length, 2, "Should not be able to navigate popup's popup by targeted hyperlink.");
+
+ //opener0.close();
+ opener1.close();
+ opener2.close();
+ opener3.close();
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 6);
+}
+
+//opener0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window0", "_blank", "width=10,height=10");
+opener1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window1", "_blank", "width=10,height=10");
+opener2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window2", "_blank", "width=10,height=10");
+opener3 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/open.html#window3", "_blank", "width=10,height=10");
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_opener.html b/docshell/test/navigation/test_opener.html
new file mode 100644
index 000000000..bfb1dde9f
--- /dev/null
+++ b/docshell/test/navigation/test_opener.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 50px; }
+ </style>
+<script>
+if (navigator.platform.startsWith("Linux")) {
+ SimpleTest.expectAssertions(0, 1);
+}
+
+window.onload = function () {
+ navigateByLocation(window0);
+ navigateByOpen("window1");
+ navigateByForm("window2");
+ navigateByHyperlink("window3");
+
+ xpcWaitForFinishedFrames(function() {
+ isNavigated(window0, "Should be able to navigate popup by setting location.");
+ isNavigated(window1, "Should be able to navigate popup by calling window.open.");
+ isNavigated(window2, "Should be able to navigate popup by submitting form.");
+ isNavigated(window3, "Should be able to navigate popup by targeted hyperlink.");
+
+ window0.close();
+ window1.close();
+ window2.close();
+ window3.close();
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 4);
+}
+
+var window0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/blank.html", "window0", "width=10,height=10");
+var window1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/blank.html", "window1", "width=10,height=10");
+var window2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/blank.html", "window2", "width=10,height=10");
+var window3 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/blank.html", "window3", "width=10,height=10");
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_popup-navigates-children.html b/docshell/test/navigation/test_popup-navigates-children.html
new file mode 100644
index 000000000..692f35713
--- /dev/null
+++ b/docshell/test/navigation/test_popup-navigates-children.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 50px; }
+ </style>
+<script>
+function testChild0() {
+ if (!window.window0)
+ window0 = window.open("navigate.html#opener.frames[0],location", "window0", "width=10,height=10");
+}
+
+function testChild1() {
+ if (!window.window1)
+ window1 = window.open("navigate.html#child1,open", "window1", "width=10,height=10");
+}
+
+function testChild2() {
+ if (!window.window2)
+ window2 = window.open("navigate.html#child2,form", "window2", "width=10,height=10");
+}
+
+function testChild3() {
+ if (!window.window3)
+ window3 = window.open("navigate.html#child3,hyperlink", "window3", "width=10,height=10");
+}
+
+xpcWaitForFinishedFrames(function() {
+ isNavigated(frames[0], "Should be able to navigate on-domain opener's children by setting location.");
+ isNavigated(frames[1], "Should be able to navigate on-domain opener's children by calling window.open.");
+ isNavigated(frames[2], "Should be able to navigate on-domain opener's children by submitting form.");
+ isNavigated(frames[3], "Should be able to navigate on-domain opener's children by targeted hyperlink.");
+
+ window0.close();
+ window1.close();
+ window2.close();
+ window3.close();
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+}, 4);
+
+</script>
+</head>
+<body>
+<div id="frames">
+<iframe onload="testChild0()" name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe onload="testChild1()" name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe onload="testChild2()" name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe onload="testChild3()" name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+</div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_reserved.html b/docshell/test/navigation/test_reserved.html
new file mode 100644
index 000000000..b2389078c
--- /dev/null
+++ b/docshell/test/navigation/test_reserved.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 200px; }
+ </style>
+<script>
+if (navigator.platform.startsWith("Mac")) {
+ SimpleTest.expectAssertions(0, 2);
+}
+
+function testTop() {
+ window0 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#top,location", "_blank", "width=10,height=10");
+
+ xpcWaitForFinishedFrames(function() {
+ isInaccessible(window0, "Should be able to navigate off-domain top by setting location.");
+ window0.close();
+ xpcCleanupWindows();
+
+ window1 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,open", "_blank", "width=10,height=10");
+
+ xpcWaitForFinishedFrames(function() {
+ isInaccessible(window1, "Should be able to navigate off-domain top by calling window.open.");
+ window1.close();
+ xpcCleanupWindows();
+
+ window2 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,form", "_blank", "width=10,height=10");
+
+ xpcWaitForFinishedFrames(function() {
+ isInaccessible(window2, "Should be able to navigate off-domain top by submitting form.");
+ window2.close();
+ xpcCleanupWindows();
+
+ window3 = window.open("iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_top,hyperlink", "_blank", "width=10,height=10");
+
+ xpcWaitForFinishedFrames(function() {
+ isInaccessible(window3, "Should be able to navigate off-domain top by targeted hyperlink.");
+ window3.close();
+ xpcCleanupWindows();
+
+ testParent();
+ }, 1);
+ }, 1);
+ }, 1);
+ }, 1);
+}
+
+function testParent() {
+ document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#parent,location"></iframe>';
+
+ xpcWaitForFinishedFrames(function() {
+ isAccessible(frames[0], "Should not be able to navigate off-domain parent by setting location.");
+ xpcCleanupWindows();
+
+ document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,open"></iframe>';
+
+ xpcWaitForFinishedFrames(function() {
+ isAccessible(frames[0], "Should not be able to navigate off-domain parent by calling window.open.");
+ xpcCleanupWindows();
+
+ document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,form"></iframe>';
+
+ xpcWaitForFinishedFrames(function() {
+ isAccessible(frames[0], "Should not be able to navigate off-domain parent by submitting form.");
+ xpcCleanupWindows();
+
+ document.getElementById("frames").innerHTML = '<iframe src="iframe.html#http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#_parent,hyperlink"></iframe>';
+
+ xpcWaitForFinishedFrames(function() {
+ isAccessible(frames[0], "Should not be able to navigate off-domain parent by targeted hyperlink.");
+ xpcCleanupWindows();
+
+ document.getElementById("frames").innerHTML = "";
+ SimpleTest.finish();
+ }, 1);
+ }, 1);
+ }, 1);
+ }, 1);
+}
+
+window.onload = function() {
+ testTop();
+}
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
+<div id="frames">
+</div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_sessionhistory.html b/docshell/test/navigation/test_sessionhistory.html
new file mode 100644
index 000000000..452271a41
--- /dev/null
+++ b/docshell/test/navigation/test_sessionhistory.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=
+-->
+<head>
+ <title>Test for Bug </title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="nextTest()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug **/
+
+var testFiles =
+ [ "file_bug462076_1.html", // Dynamic frames before onload
+ "file_bug462076_2.html", // Dynamic frames when handling onload
+ "file_bug462076_3.html", // Dynamic frames after onload
+ "file_bug508537_1.html", // Dynamic frames and forward-back
+ "file_document_write_1.html", // Session history + document.write
+ //"file_static_and_dynamic_1.html",// Static and dynamic frames and forward-back
+ "file_bug534178.html", // Session history transaction clean-up.
+ "file_fragment_handling_during_load.html",
+ "file_nested_frames.html",
+ "file_shiftReload_and_pushState.html",
+ "file_scrollRestoration.html",
+ "file_bug1300461.html"
+ ];
+var testCount = 0; // Used by the test files.
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+
+var testWindow;
+function nextTest_() {
+ if (testFiles.length) {
+ testCount = 0;
+ testWindow = window.open(testFiles.shift(), "", "width=300,height=300");
+ testWindow.onunload = function () { } // to prevent bfcache
+ } else {
+ SimpleTest.finish();
+ }
+}
+
+// Needed by file_document_write_1.html
+window.file_document_write_1_loadCount = 0;
+function isTestDynamic() {
+ var dyn = testWindow.document.getElementById("dynamic");
+ is(dyn, null, "Should have gone back to the static page!");
+ nextTest();
+ testWindow.close();
+}
+
+function nextTest() {
+ setTimeout(nextTest_, 0);
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_sibling-matching-parent.html b/docshell/test/navigation/test_sibling-matching-parent.html
new file mode 100644
index 000000000..dc8ec2f90
--- /dev/null
+++ b/docshell/test/navigation/test_sibling-matching-parent.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 50px; }
+ </style>
+<script>
+window.onload = function () {
+ document.getElementById('active').innerHTML =
+ '<iframe src="navigate.html#parent.frames[0],location"></iframe>' +
+ '<iframe src="navigate.html#child1,open"></iframe>' +
+ '<iframe src="navigate.html#child2,form"></iframe>' +
+ '<iframe src="navigate.html#child3,hyperlink"></iframe>';
+
+ xpcWaitForFinishedFrames(function() {
+ isNavigated(frames[0], "Should be able to navigate sibling with on-domain parent by setting location.");
+ isNavigated(frames[1], "Should be able to navigate sibling with on-domain parent by calling window.open.");
+ isNavigated(frames[2], "Should be able to navigate sibling with on-domain parent by submitting form.");
+ isNavigated(frames[3], "Should be able to navigate sibling with on-domain parent by targeted hyperlink.");
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 4);
+}
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
+<div id="frames">
+<iframe name="child0" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe name="child1" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe name="child2" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+<iframe name="child3" src="http://test1.example.org:80/tests/docshell/test/navigation/blank.html"></iframe>
+</div>
+<div id="active"></div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_sibling-off-domain.html b/docshell/test/navigation/test_sibling-off-domain.html
new file mode 100644
index 000000000..ba7942798
--- /dev/null
+++ b/docshell/test/navigation/test_sibling-off-domain.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+ <style type="text/css">
+ iframe { width: 90%; height: 50px; }
+ </style>
+<script>
+window.onload = function () {
+ document.getElementById('active').innerHTML =
+ '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#parent.frames[0],location"></iframe>' +
+ '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child1,open"></iframe>' +
+ '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child2,form"></iframe>' +
+ '<iframe src="http://test1.example.org:80/tests/docshell/test/navigation/navigate.html#child3,hyperlink"></iframe>';
+
+ xpcWaitForFinishedFrames(function() {
+ isBlank(frames[0], "Should not be able to navigate off-domain sibling by setting location.");
+ isBlank(frames[1], "Should not be able to navigate off-domain sibling by calling window.open.");
+ isBlank(frames[2], "Should not be able to navigate off-domain sibling by submitting form.");
+ isBlank(frames[3], "Should not be able to navigate off-domain sibling by targeted hyperlink.");
+
+ xpcCleanupWindows();
+ SimpleTest.finish();
+ }, 4);
+}
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408052">Mozilla Bug 408052</a>
+<div id="frames">
+<iframe name="child0" src="blank.html"></iframe>
+<iframe name="child1" src="blank.html"></iframe>
+<iframe name="child2" src="blank.html"></iframe>
+<iframe name="child3" src="blank.html"></iframe>
+</div>
+<div id="active"></div>
+<pre id="test">
+<script type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_triggeringprincipal_frame_nav.html b/docshell/test/navigation/test_triggeringprincipal_frame_nav.html
new file mode 100644
index 000000000..f8f97c678
--- /dev/null
+++ b/docshell/test/navigation/test_triggeringprincipal_frame_nav.html
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1181370 - Test triggeringPrincipal for iframe navigations</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe1"></iframe>
+<iframe style="width:100%;" id="testframe2"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ *
+ * +------------------------------------+
+ * | +----------+ +--------------+ |
+ * | | Frame 1 | | Frame 2 | |
+ * | +----------+ | | |
+ * | | +----------+ | |
+ * | | | Subframe | | |
+ * | | +----------+ | |
+ * | +--------------+ |
+ * +------------------------------------+
+ *
+ * Frame1: test1.mochi.test
+ * Frame2: test2.mochi.test
+ * Subframe: test2.mochi.test
+ *
+ * (*) Frame1 and Subframe set their document.domain to mochi.test
+ * (*) Frame1 navigates the Subframe
+ * (*) TriggeringPrincipal for the Subframe navigation should be
+ * ==> test1.mochi.test
+ * (*) LoadingPrincipal for the Subframe navigation should be
+ * ==> test2.mochi.test
+ */
+
+const BASEURL1 = "http://test1.mochi.test:8888/tests/docshell/test/navigation/";
+const BASEURL2 = "http://test2.mochi.test:8888/tests/docshell/test/navigation/";
+const TRIGGERINGPRINCIPALURI = BASEURL1 + "file_triggeringprincipal_frame_1.html";
+const LOADINGPRINCIPALURI = BASEURL2 + "file_triggeringprincipal_frame_2.html";
+
+SimpleTest.waitForExplicitFinish();
+
+window.addEventListener("message", receiveMessage, false);
+
+function receiveMessage(event) {
+ is(event.data.triggeringPrincipalURI, TRIGGERINGPRINCIPALURI,
+ "TriggeringPrincipal should be the navigating iframe (Frame 1)");
+ is(event.data.loadingPrincipalURI, LOADINGPRINCIPALURI,
+ "LoadingPrincipal should be the enclosing iframe (Frame 2)");
+ is(event.data.referrerURI, TRIGGERINGPRINCIPALURI,
+ "Referrer and TriggeringPrincipal should be identical (Frame 1)");
+
+ window.removeEventListener("message", receiveMessage, false);
+ SimpleTest.finish();
+}
+
+var frame1 = document.getElementById("testframe1");
+frame1.src = BASEURL1 + "file_triggeringprincipal_frame_1.html";
+
+var frame2 = document.getElementById("testframe2");
+frame2.src = BASEURL2 + "file_triggeringprincipal_frame_2.html";
+
+</script>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html b/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html
new file mode 100644
index 000000000..cd6a9c056
--- /dev/null
+++ b/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+</head>
+<body>
+
+<iframe name="framea" id="framea" src="file_triggeringprincipal_iframe_iframe_window_open_frame_a.html"></iframe>
+<iframe name="frameb" id="frameb"></iframe>
+
+<script type="text/javascript">
+
+/* We load an iframe (Frame A) which then gets navigated by another iframe (Frame B)
+ * by calling window.open("http://", "Frame A") later in the test. We then verify the
+ * TriggeringPrincipal and LoadingPrincipal of the navigated iframe (Frame A).
+ *
+ * +---------------------------------------+
+ * | Parent |
+ * | |
+ * | +----------------------------+ |
+ * | | Frame A | |
+ * | | | |
+ * | | | |
+ * | +----------------------------+ |
+ * | |
+ * | +----------------------------+ |
+ * | | Frame B | |
+ * | | | |
+ * | | win.open("http://", "A") | |
+ * | +----------------------------+ |
+ * | |
+ * +---------------------------------------+
+ *
+ * Sequence of the test:
+ * [1] load Frame A
+ * [2] load Frame B which navigates A
+ * [3] load navigated Frame A and check triggeringPrincipal and loadingPrincipal
+ */
+
+const TRIGGERING_PRINCIPAL_URI =
+ "http://mochi.test:8888/tests/docshell/test/navigation/file_triggeringprincipal_iframe_iframe_window_open_frame_b.html";
+
+const LOADING_PRINCIPAL_URI =
+ "http://mochi.test:8888/tests/docshell/test/navigation/test_triggeringprincipal_iframe_iframe_window_open.html";
+
+var frameA = document.getElementById("framea");
+
+function checkResults() {
+ frameA.removeEventListener('load', checkResults, false);
+
+ var channel = SpecialPowers.wrap(frameA.contentDocument).docShell.currentDocumentChannel;
+ var triggeringPrincipal = channel.loadInfo.triggeringPrincipal.URI.asciiSpec;
+ var loadingPrincipal = channel.loadInfo.loadingPrincipal.URI.asciiSpec;
+
+ is(triggeringPrincipal, TRIGGERING_PRINCIPAL_URI,
+ "TriggeringPrincipal for targeted window.open() should be the iframe triggering the load");
+
+ is(frameA.contentDocument.referrer, TRIGGERING_PRINCIPAL_URI,
+ "Referrer for targeted window.open() should be the principal of the iframe triggering the load");
+
+ is(loadingPrincipal, LOADING_PRINCIPAL_URI,
+ "LoadingPrincipal for targeted window.open() should be the containing document");
+
+ SimpleTest.finish();
+}
+
+function performNavigation() {
+ frameA.removeEventListener('load', performNavigation, false);
+ frameA.addEventListener('load', checkResults, false);
+
+ // load Frame B which then navigates Frame A
+ var frameB = document.getElementById("frameb");
+ frameB.src = "file_triggeringprincipal_iframe_iframe_window_open_frame_b.html";
+}
+
+// start the test
+SimpleTest.waitForExplicitFinish();
+
+frameA.addEventListener('load', performNavigation, false);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html b/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html
new file mode 100644
index 000000000..7cc6ee97d
--- /dev/null
+++ b/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+</head>
+<body>
+
+<iframe name="testframe" id="testframe" src="file_triggeringprincipal_iframe_iframe_window_open_base.html"></iframe>
+
+<script type="text/javascript">
+
+/* We load an iframe which then gets navigated by the iframe's parent by calling
+ * window.open("http://", iframe) later in the test. We then verify the
+ * TriggeringPrincipal and LoadingPrincipal of the navigated iframe.
+ *
+ * +------------------------------------------+
+ * | |
+ * | +------------------+ |
+ * | | testframe | |
+ * | +------------------+ |
+ * | |
+ * | window.open("http://", "testframe"); |
+ * | |
+ * +------------------------------------------+
+ */
+
+const TRIGGERING_PRINCIPAL_URI =
+ "http://mochi.test:8888/tests/docshell/test/navigation/test_triggeringprincipal_parent_iframe_window_open.html";
+
+const LOADING_PRINCIPAL_URI = TRIGGERING_PRINCIPAL_URI;
+
+var testframe = document.getElementById("testframe");
+
+function checkResults() {
+ testframe.removeEventListener('load', checkResults, false);
+
+ var channel = SpecialPowers.wrap(testframe.contentDocument).docShell.currentDocumentChannel;
+ var triggeringPrincipal = channel.loadInfo.triggeringPrincipal.URI.asciiSpec;
+ var loadingPrincipal = channel.loadInfo.loadingPrincipal.URI.asciiSpec;
+
+ is(triggeringPrincipal, TRIGGERING_PRINCIPAL_URI,
+ "TriggeringPrincipal for targeted window.open() should be the principal of the document");
+
+ is(testframe.contentDocument.referrer, TRIGGERING_PRINCIPAL_URI,
+ "Referrer for targeted window.open() should be the principal of the document");
+
+ is(loadingPrincipal, LOADING_PRINCIPAL_URI,
+ "LoadingPrincipal for targeted window.open() should be the <iframe>.ownerDocument");
+
+ SimpleTest.finish();
+}
+
+function performNavigation() {
+ testframe.removeEventListener('load', performNavigation, false);
+ testframe.addEventListener('load', checkResults, false);
+ win = window.open("file_triggeringprincipal_parent_iframe_window_open_nav.html", "testframe");
+}
+
+// start the test
+SimpleTest.waitForExplicitFinish();
+
+testframe.addEventListener('load', performNavigation, false);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/docshell/test/navigation/test_triggeringprincipal_window_open.html b/docshell/test/navigation/test_triggeringprincipal_window_open.html
new file mode 100644
index 000000000..d5d7f210b
--- /dev/null
+++ b/docshell/test/navigation/test_triggeringprincipal_window_open.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="NavigationUtils.js"></script>
+</head>
+<body>
+
+<script type="text/javascript">
+
+/* We call window.open() using different URIs and make sure the triggeringPrincipal
+ * loadingPrincipal are correct.
+ * Test1: window.open(http:)
+ * Test2: window.open(data:)
+ * Test3: window.open(javascript:)
+ */
+
+const TRIGGERING_PRINCIPAL_URI =
+ "http://mochi.test:8888/tests/docshell/test/navigation/test_triggeringprincipal_window_open.html";
+
+SimpleTest.waitForExplicitFinish();
+
+const NUM_TESTS = 3;
+var test_counter = 0;
+
+function checkFinish() {
+ test_counter++;
+ if (test_counter === NUM_TESTS) {
+ SimpleTest.finish();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Test 1: window.open(http:)
+var httpWin = window.open("file_triggeringprincipal_window_open.html", "_blank", "width=10,height=10");
+httpWin.onload = function() {
+ var httpChannel = SpecialPowers.wrap(httpWin.document).docShell.currentDocumentChannel;
+ var httpTriggeringPrincipal = httpChannel.loadInfo.triggeringPrincipal.URI.asciiSpec;
+ var httpLoadingPrincipal = httpChannel.loadInfo.loadingPrincipal;
+
+ is(httpTriggeringPrincipal, TRIGGERING_PRINCIPAL_URI,
+ "TriggeringPrincipal for window.open(http:) should be the principal of the document");
+
+ is(httpWin.document.referrer, TRIGGERING_PRINCIPAL_URI,
+ "Referrer for window.open(http:) should be the principal of the document");
+
+ is(httpLoadingPrincipal, null,
+ "LoadingPrincipal for window.open(http:) should be null");
+
+ httpWin.close();
+ checkFinish();
+}
+
+// ----------------------------------------------------------------------------
+// Test 2: window.open(data:)
+var dataWin = window.open("data:text/html,<html><body>data</body></html>", "_blank", "width=10,height=10");
+dataWin.onload = function() {
+ var dataChannel = SpecialPowers.wrap(dataWin.document).docShell.currentDocumentChannel;
+ var dataTriggeringPrincipal = dataChannel.loadInfo.triggeringPrincipal.URI.asciiSpec;
+ var dataLoadingPrincipal = dataChannel.loadInfo.loadingPrincipal;
+
+ is(dataTriggeringPrincipal, TRIGGERING_PRINCIPAL_URI,
+ "TriggeringPrincipal for window.open(data:) should be the principal of the document");
+
+ is(dataWin.document.referrer, "",
+ "Referrer for window.open(data:) should be empty");
+
+ is(dataLoadingPrincipal, null,
+ "LoadingPrincipal for window.open(data:) should be null");
+
+ dataWin.close();
+ checkFinish();
+}
+
+// ----------------------------------------------------------------------------
+// Test 3: window.open(javascript:)
+var jsWin = window.open("javascript:'<html><body>js</body></html>';", "_blank", "width=10,height=10");
+jsWin.onload = function() {
+ var jsChannel = SpecialPowers.wrap(jsWin.document).docShell.currentDocumentChannel;
+ var jsTriggeringPrincipal = jsChannel.loadInfo.triggeringPrincipal.URI.asciiSpec;
+ var jsLoadingPrincipal = jsChannel.loadInfo.loadingPrincipal;
+
+ is(jsTriggeringPrincipal, TRIGGERING_PRINCIPAL_URI,
+ "TriggeringPrincipal for window.open(javascript:) should be the principal of the document");
+
+ is(jsWin.document.referrer, "",
+ "Referrer for window.open(javascript:) should be empty");
+
+ is(jsLoadingPrincipal, null,
+ "LoadingPrincipal for window.open(javascript:) should be null");
+
+ jsWin.close();
+ checkFinish();
+}
+
+</script>
+</pre>
+</body>
+</html>