From 749141f4bf3b7d73996a015a521d106695533c92 Mon Sep 17 00:00:00 2001 From: Hiroshige Hayashizaki Date: Tue, 8 Feb 2022 19:42:34 -0800 Subject: [PATCH] [WPT] BFCache: pushState() in BFCache/non-BFCache cases When doing history navigation to an entry that's created via pushState, the page should be: - With BFCache: Restored from BFCache. - Without BFCache: Loaded from the URL set by `pushState()`. While this test contradicts the current spec but matches the desired behavior, and the spec will be fixed as part of https://github.com/whatwg/html/pull/6315. Bug: 1107415, https://github.com/whatwg/html/issues/6207 Change-Id: I609276fe865fa92409fd7a547777dba222bac36c --- .../back-forward-cache/pushstate.https.html | 63 +++++++++++++++++++ .../resources/executor-pushstate.html | 13 ++++ .../resources/executor.html | 50 +-------------- .../back-forward-cache/resources/executor.js | 62 ++++++++++++++++++ 4 files changed, 139 insertions(+), 49 deletions(-) create mode 100644 html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html create mode 100644 html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html create mode 100644 html/browsers/browsing-the-web/back-forward-cache/resources/executor.js diff --git a/html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html b/html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html new file mode 100644 index 00000000000000..59912fc983c148 --- /dev/null +++ b/html/browsers/browsing-the-web/back-forward-cache/pushstate.https.html @@ -0,0 +1,63 @@ + + + + + + + + diff --git a/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html b/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html new file mode 100644 index 00000000000000..dcf4a798d00de3 --- /dev/null +++ b/html/browsers/browsing-the-web/back-forward-cache/resources/executor-pushstate.html @@ -0,0 +1,13 @@ + + + + + + diff --git a/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html b/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html index a93f68cce72e3b..2d118bbe2b2b80 100644 --- a/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html +++ b/html/browsers/browsing-the-web/back-forward-cache/resources/executor.html @@ -2,52 +2,4 @@ - + diff --git a/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js b/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js new file mode 100644 index 00000000000000..c0fd248ae2faf1 --- /dev/null +++ b/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js @@ -0,0 +1,62 @@ +const params = new URLSearchParams(window.location.search); +const uuid = params.get('uuid'); + +// Executor and BFCache detection + +// When navigating out from this page, always call +// `prepareNavigation(callback)` synchronously from the script injected by +// `RemoteContext.execute_script()`, and trigger navigation on or after the +// callback is called. +// prepareNavigation() suspends task polling and avoid in-flight fetch +// requests during navigation that might evict the page from BFCache. +// +// When we navigate to the page again, task polling is resumed, either +// - (BFCache cases) when the pageshow event listener added by +// prepareNavigation() is executed, or +// - (Non-BFCache cases) when `Executor.execute()` is called again during +// non-BFCache page loading. +// +// In such scenarios, `assert_bfcached()` etc. in `helper.sub.js` can determine +// whether the page is restored from BFCache or not, by observing +// - `isPageshowFired`: whether the pageshow event listener added by the +// prepareNavigation() before navigating out, and +// - `loadCount`: whether this inline script is evaluated again. +// - `isPageshowPersisted` is used to assert that `event.persisted` is true +// when restored from BFCache. + +window.isPageshowFired = false; +window.isPageshowPersisted = null; +window.loadCount = parseInt(localStorage.getItem(uuid + '.loadCount') || '0') + 1; +localStorage.setItem(uuid + '.loadCount', loadCount); + +window.pageShowPromise = new Promise(resolve => + window.addEventListener('pageshow', resolve, {once: true})); + +const executor = new Executor(uuid); + +window.prepareNavigation = function(callback) { + window.addEventListener( + 'pageshow', + (event) => { + window.isPageshowFired = true; + window.isPageshowPersisted = event.persisted; + executor.resume(); + }, + {once: true}); + executor.suspend(callback); +} + +// Try to disable BFCache by acquiring and never releasing a Web Lock. +// This requires HTTPS. +// Note: This is a workaround depending on non-specified WebLock+BFCache +// behavior. We might want to introduce a test-only BFCache-disabling API +// instead in the future. +window.disableBFCache = () => { + return new Promise(resolve => { + // Use page's UUID as a unique lock name. + navigator.locks.request(uuid, () => { + resolve(); + return new Promise(() => {}); + }); + }); +};