Skip to content

Commit 92bdbab

Browse files
committed
Bug 1863646 [wpt PR 43008] - Fire the navigate event earlier for cross-document traversals, a=testonly
Automatic update from web-platform-tests Fire the navigate event earlier for cross-document traversals This earlier timing ensures that we fire the navigate event in the old document when a traversal is served from the bfcache, and is more consistent with non-history cross-document navigate events. Currently, cross-document traversals fire the navigate event at the last possible time: during commit in the renderer, the navigate event is fired in the old document immediately before it is unloaded. The navigate event is not allowed to cancel or intercept a cross-document traversal, otherwise this timing would be too late. We did not reach a firm conclusion on when to fire the navigate event for cross-document traversals during the design of the Navigation API (see WICG/navigation-api#207), and this was the latest of the options considered. This timing has two problems: 1. Traversals served by the back forward cache don't "commit". So the navigate event is erroneously omitted. 2. The navigate event fires after redirects, where for other cross-document navigations, it fires before redirects. This CL adds plumbing for the browser to trigger the navigate event to fire in the renderer in the cross-document traversal case, and moves the time of the navigate event earlier. It now fires after the browser process has decided to allow the traversal to start (i.e., after beforeunload has been fired in any relevant frames, and after start throttles). In the cross-document traversal case where the navigation is not served from bfcache, this will fire the navigate event in parallel with the network request (which is ok because the navigate event can't intercept or cancel the navigation, this timing would not be permissible for other navigation types where the navigate event has more power over the navigation). In the case where no network request is needed (bfcache, about:blank, etc.), the navigate event task gets sent to the renderer immediately before the commit/activation task. Bug: 1475907 Change-Id: I1ef7337e2d85f9cdbfc0110f9f4fe3bcd4dea75d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5011394 Reviewed-by: Domenic Denicola <domenicchromium.org> Commit-Queue: Nate Chapin <japhetchromium.org> Reviewed-by: Charlie Reis <creischromium.org> Reviewed-by: Will Harris <wfhchromium.org> Cr-Commit-Position: refs/heads/main{#1229455} -- wpt-commits: b92c3a8c78b102518261a78e17a27b5e6f2efb8a wpt-pr: 43008 UltraBlame original commit: 86b3ba75ab49e48c031d5abaebdf2aa406ca5cc8
1 parent aa09471 commit 92bdbab

File tree

4 files changed

+66
-6
lines changed

4 files changed

+66
-6
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!doctype html>
2+
<script src="/resources/testharness.js"></script>
3+
<script src="/resources/testharnessreport.js"></script>
4+
<script src="/common/utils.js"></script>
5+
<script src="/common/dispatcher/dispatcher.js"></script>
6+
<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
7+
8+
<script>
9+
runBfcacheTest({
10+
targetOrigin: originSameOrigin,
11+
funcBeforeBackNavigation: () => {
12+
window.did_navigate = false;
13+
navigation.onnavigate = () => window.did_navigate = true;
14+
},
15+
async funcAfterAssertion(pageA, pageB) {
16+
// When `funcAfterAssertion` is called, we've already navigated to pageB,
17+
// then gone back to pageA with bfcache. Now go forward to pageB so we can
18+
// observe whether the navigate event fired.
19+
await pageA.execute_script(() => history.forward());
20+
await pageB.execute_script(waitForPageShow);
21+
assert_true(await pageB.execute_script(() => window.did_navigate));
22+
}
23+
}, "navigate event should fire when traversing to a bfcache hit");
24+
</script>

testing/web-platform/tests/navigation-api/navigation-methods/return-value/back-204-205-download.html

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,9 @@
3232

3333
const indexBefore = i.contentWindow.navigation.currentEntry.index;
3434

35-
// One might be surprised that navigate does not fire. (It does fire for the
36-
// corresponding tests of navigation.navigate(), i.e., this is
37-
// traversal-specific behavior.) See https://github.com/WICG/navigation-api/issues/207
38-
// for some discussion.
39-
i.contentWindow.navigation.onnavigate = t.unreached_func("onnavigate should not be called");
35+
let onnavigate_called = false;
36+
i.contentWindow.navigation.onnavigate = () => onnavigate_called = true;
37+
i.contentWindow.onunload = t.unreached_func("onunload should not be called");
4038
i.contentWindow.navigation.onnavigatesuccess = t.unreached_func("onnavigatesuccess should not be called");
4139
i.contentWindow.navigation.onnavigateerror = t.unreached_func("onnavigateerror should not be called");
4240

@@ -47,6 +45,7 @@
4745
await new Promise(resolve => t.step_timeout(resolve, 50));
4846
assert_equals(i.contentWindow.navigation.currentEntry.index, indexBefore);
4947
assert_equals(i.contentWindow.navigation.transition, null);
48+
assert_true(onnavigate_called);
5049
}, `back() promises to ${description} never settle`);
5150
}
5251
</script>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!doctype html>
2+
<script src="/resources/testharness.js"></script>
3+
<script src="/resources/testharnessreport.js"></script>
4+
<iframe id="i" src="resources/notify-top-early.html"></iframe>
5+
<script>
6+
async_test(t => {
7+
let events = [];
8+
function finish() {
9+
assert_array_equals(events, ["onnavigate", "onunload", "readystateinteractive", "domcontentloaded", "readystatecomplete", "onload", "onpageshow"]);
10+
t.done();
11+
};
12+
13+
window.onload = t.step_func(() => {
14+
i.contentWindow.navigation.navigate("?1");
15+
i.onload = t.step_func(() => {
16+
window.childStarted = () => {
17+
i.contentWindow.navigation.onnavigatesuccess = () => events.push("onnavigatesuccess");
18+
i.contentWindow.navigation.onnavigateerror = () => events.push("onnavigateerror");
19+
i.contentWindow.onpageshow = () => events.push("onpageshow");
20+
i.contentWindow.onhashchange = () => events.push("onhashchange");
21+
i.contentWindow.onpopstate = () => events.push("onpopstate");
22+
i.onload = t.step_func(() => {
23+
events.push("onload");
24+
t.step_timeout(finish, 0);
25+
});
26+
i.contentDocument.addEventListener("DOMContentLoaded", () => events.push("domcontentloaded"));
27+
i.contentDocument.onreadystatechange = () => events.push("readystate" + i.contentDocument.readyState);
28+
};
29+
i.contentWindow.onunload = () => events.push("onunload");
30+
i.contentWindow.navigation.onnavigate = () => events.push("onnavigate");
31+
i.contentWindow.navigation.back().committed.then(
32+
() => events.push("promisefulfilled"), () => events.push("promiserejected"));
33+
})
34+
});
35+
}, "back() event ordering for cross-document traversal");
36+
</script>

testing/web-platform/tests/navigation-api/ordering-and-transition/navigate-cross-document-event-order.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
async_test(t => {
77
let events = [];
88
function finish() {
9-
assert_array_equals(events, ["onnavigate", "readystateinteractive", "domcontentloaded", "readystatecomplete", "onload", "onpageshow"]);
9+
assert_array_equals(events, ["onnavigate", "onunload", "readystateinteractive", "domcontentloaded", "readystatecomplete", "onload", "onpageshow"]);
1010
t.done();
1111
};
1212

@@ -24,6 +24,7 @@
2424
i.contentDocument.addEventListener("DOMContentLoaded", () => events.push("domcontentloaded"));
2525
i.contentDocument.onreadystatechange = () => events.push("readystate" + i.contentDocument.readyState);
2626
};
27+
i.contentWindow.onunload = () => events.push("onunload");
2728
i.contentWindow.navigation.onnavigate = () => events.push("onnavigate");
2829
i.contentWindow.navigation.navigate("?1").committed.then(
2930
() => events.push("promisefulfilled"), () => events.push("promiserejected"));

0 commit comments

Comments
 (0)