Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,39 @@
assert_equals(history.length, startingHistoryLength + 1,
"history.length increases after normal navigation from non-initial empty document");
}, "form submission");

// This test is very similar to the `location.href` test a few cases above, but
// the difference is that instead of navigating from:
// initial about:blank Document => HTTP => HTTP
// ... we navigate from:
// initial about:blank Document => (non-initial) about:blank Document => HTTP
//
// We do this to ensure/assert that an explicit navigation to about:blank
// *after* the iframe has finished initializing, is counted as a normal
// navigation away from the initial about:blank Document, and the "initial-ness"
// of the initial about:blank Document is not carried over to the next
// about:blank Document.
promise_test(async t => {
const startingHistoryLength = history.length;
// Create an iframe with src not set, which will stay on the initial empty
// document.
const iframe = insertIframe(t);
assert_equals(history.length, startingHistoryLength,
"Inserting iframe with no src must not change history.length");

// Navigate away from the initial empty document through setting location.href
// to `about:blank`. This should do a replacement TO ANOTHER about:blank
// Document, which is not the initial about:blank Document.
iframe.contentWindow.location.href = 'about:blank';
await waitForLoad(t, iframe, 'about:blank');
assert_equals(history.length, startingHistoryLength,
"history.length must not change after normal navigation on document loaded by iframe with no src");

// Navigate again using the same method, but this time it shouldn't do a
// replacement since it's no longer on the initial empty document.
iframe.contentWindow.location.href = url2;
await waitForLoad(t, iframe, url2);
assert_equals(history.length, startingHistoryLength + 1,
"history.length increases after normal navigation from non-initial empty document");
}, "initial about:blank => non-initial about:blank (via location.href) => normal HTTP navigation");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,42 @@

promise_test(async t => {
const startingHistoryLength = history.length;
// Create an iframe with src set to about:blank. This would trigger a
// navigation to a non-initial about:blank document.
// Create an iframe with src set to about:blank. Per the HTML Standard, this
// stays on the "initial about:blank Document" [1], because the "process the
// iframe attributes" algorithm [2] catches the "about:blank" navigation and
// fires a special synchronous `load` event at the initial about:blank
// Document, instead of replacing it with a non-initial, second about:blank
// Document. This is documented in the note at the end of [3].
//
// [1]: https://html.spec.whatwg.org/#is-initial-about:blank.
// [2]: https://html.spec.whatwg.org/#process-the-iframe-attributes
// [3]: https://html.spec.whatwg.org/#completely-finish-loading
const iframe = insertIframeWithAboutBlankSrc(t);
assert_equals(history.length, startingHistoryLength,
"Inserting iframe with src='about:blank' must not change history.length");

// Trigger a navigation to url1 through the iframe's src attribute.
// The iframe should still be on the initial empty document, and the
// navigation should do replacement.
// Trigger a navigation from the initial about:blank Document, to url1 through
// the iframe's src attribute. Because we're navigating from the initial
// about:blank Document, the navigation should be a replacement.
iframe.src = url1;

// Wait for the latest navigation to finish.
await waitForLoad(t, iframe, url1);
assert_equals(history.length, startingHistoryLength,
"history.length must not change after normal navigation on initial empty document");
}, "Navigating to a different document with src");
"history.length must not change after normal navigation from initial " +
"about:blank Document");
}, "Navigating away from the initial about:blank Document to a different " +
"one, with src");

promise_test(async t => {
const startingHistoryLength = history.length;
// Create an iframe with src set to about:blank but navigate away from it immediately below.
const iframe = insertIframeWithAboutBlankSrc(t);
assert_equals(history.length, startingHistoryLength,
"Inserting iframe with src='about:blank' must not change history.length");

// Navigate away from the initial empty document through setting
// location.href. The iframe should still be on the initial empty document,
// and the navigation should do replacement.
// Trigger a navigation from the initial about:blank Document, to url1 through
// location.href. Because we're navigating from the initial about:blank
// Document, the navigation should be a replacement.
iframe.contentWindow.location.href = url1;
await waitForLoad(t, iframe, url1);
assert_equals(history.length, startingHistoryLength,
Expand All @@ -50,14 +60,13 @@

promise_test(async t => {
const startingHistoryLength = history.length;
// Create an iframe with src set to about:blank but navigate away from it immediately below.
const iframe = insertIframeWithAboutBlankSrc(t);
assert_equals(history.length, startingHistoryLength,
"Inserting iframe with src='about:blank' must not change history.length");

// Navigate away from the initial empty document through location.assign().
// The iframe should still be on the initial empty document, and the
// navigation should do replacement.
// Trigger a navigation from the initial about:blank Document, to url1 through
// location.assign(). Because we're navigating from the initial about:blank
// Document, the navigation should be a replacement.
iframe.contentWindow.location.assign(url1);
await waitForLoad(t, iframe, url1);
assert_equals(history.length, startingHistoryLength,
Expand All @@ -66,14 +75,13 @@

promise_test(async t => {
const startingHistoryLength = history.length;
// Create an iframe with src set to about:blank but navigate away from it immediately below.
const iframe = insertIframeWithAboutBlankSrc(t);
assert_equals(history.length, startingHistoryLength,
"Inserting iframe with src='about:blank' must not change history.length");

// Navigate away from the initial empty document through window.open().
// The iframe should still be on the initial empty document, and the
// navigation should do replacement.
// Trigger a navigation from the initial about:blank Document, to url1 through
// window.open(). Because we're navigating from the initial about:blank
// Document, the navigation should be a replacement.
iframe.contentWindow.open(url1, "_self");
await waitForLoad(t, iframe, url1);
assert_equals(history.length, startingHistoryLength,
Expand All @@ -82,14 +90,13 @@

promise_test(async t => {
const startingHistoryLength = history.length;
// Create an iframe with src set to about:blank but navigate away from it immediately below.
const iframe = insertIframeWithAboutBlankSrc(t);
assert_equals(history.length, startingHistoryLength,
"Inserting iframe with src='about:blank' must not change history.length");

// Navigate away from the initial empty document through clicking an <a>
// element. The iframe should still be on the initial empty document, and the
// navigation should do replacement.
// Trigger a navigation from the initial about:blank Document, to url1 through
// clicking an `<a>` element. Because we're navigating from the initial
// about:blank Document, the navigation should be a replacement.
const a = iframe.contentDocument.createElement("a");
a.href = url1;
iframe.contentDocument.body.appendChild(a);
Expand All @@ -101,14 +108,13 @@

promise_test(async t => {
const startingHistoryLength = history.length;
// Create an iframe with src set to about:blank but navigate away from it immediately below.
const iframe = insertIframeWithAboutBlankSrc(t);
assert_equals(history.length, startingHistoryLength,
"Inserting iframe with src='about:blank' must not change history.length");

// Navigate away from the initial empty document through form submission.
// The iframe should still be on the initial empty document, and the
// navigation should do replacement.
// Trigger a navigation from the initial about:blank Document, to url1 through
// a form submission. Because we're navigating from the initial about:blank
// Document, the navigation should be a replacement.
const form = iframe.contentDocument.createElement("form");
form.action = "/common/blank.html";
iframe.contentDocument.body.appendChild(form);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,16 @@ window.insertIframeWith204Src = (t) => {
return iframe;
};

// Creates an iframe with src="about:blank" and appends it to the document.
// Creates an iframe with src="about:blank" and appends it to the document. The
// resulting document in the iframe is the initial about:blank Document [1],
// because during the "process the iframe attributes" algorithm [2], `src`
// navigations to `about:blank` are caught and result in a synchronous load
// event; not a SEPARATE navigation to a non-initial `about:blank` Document. See
// the documentation in [3] as well.
//
// [1]: https://html.spec.whatwg.org/#is-initial-about:blank
// [2]: https://html.spec.whatwg.org/#process-the-iframe-attributes
// [3]: https://html.spec.whatwg.org/#completely-finish-loading
window.insertIframeWithAboutBlankSrc = (t) => {
const iframe = document.createElement("iframe");
t.add_cleanup(() => iframe.remove());
Expand All @@ -47,12 +56,14 @@ window.insertIframeWithAboutBlankSrc = (t) => {
};

// Creates an iframe with src="about:blank", appends it to the document, and
// waits for the non-initial about:blank document finished loading.
// waits for initial about:blank Document to finish loading.
window.insertIframeWithAboutBlankSrcWaitForLoad = async (t) => {
const iframe = insertIframeWithAboutBlankSrc(t);
const aboutBlankLoad = new Promise(resolve => {
// In some browsers, the non-initial about:blank navigation commits
// In some browsers, when the initial about:blank Document is influenced by
// a `src=about:blank` attribute, the about:blank navigation commits
// asynchronously, while in other browsers, it would commit synchronously.
//
// This means we can't wait for the "load" event as it might have already
// ran. Instead, just wait for 100ms before resolving, as the non-initial
// about:blank navigation will most likely take less than 100 ms to commit.
Expand Down