Skip to content

Commit

Permalink
update test page
Browse files Browse the repository at this point in the history
  • Loading branch information
mmocny committed Nov 27, 2023
1 parent 70e52ab commit 5e87dea
Show file tree
Hide file tree
Showing 8 changed files with 1,205 additions and 3 deletions.
2 changes: 1 addition & 1 deletion sandbox/snippets/dist/measure-history-events.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions sandbox/snippets/measure-history-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ function oncePerPageLoad() {

document.addEventListener("click", logEvent);
document.addEventListener('visibilitychange', logEvent);

navigation.addEventListener('navigate', logEvent);


window.addEventListener("beforeunload", logEvent);
window.addEventListener('pagehide', logEvent);
window.addEventListener('pageshow', logEvent);
window.addEventListener("popstate", logEvent);
Expand Down
173 changes: 173 additions & 0 deletions sandbox/soft-nav-hard-navigation-tests/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:image/x-icon;base64,">
<title>Forked: (Hard) Navigation API demo</title>
<link rel="stylesheet" href="style.css">

<h1><a href="https://github.com/WICG/navigation-api/">Navigation API</a> demo</h1>

<main>
<p>I am <code>index.html</code>! I contain a normal link to <code>subpage.html</code>:</p>

<p><a href="subpage.html">subpage.html</a></p>

<p>This link works without JavaScript and in all browsers. If you <kbd>Ctrl</kbd> click or middle-click or right-click to open in a new tab, that will all work as usual.</p>

<p>But if you're using Chromium &geq;105, and just activate it without trying to open it in a new window, then it will do a single-page app navigation!</p>

<p>Here is another link, but it's a hash navigation, so it shouldn't get intercepted. You can still watch the console to see what happens with the <code>navigate</code> event:</p>

<p><a href="#console">#console</a></p>

<p>Here are some buttons for other tests; you can watch your console to see what happens.</p>

<p>
<form action="subpage.html" method="GET">
<input type="submit" value="Navigate via Form Submit" />
</form>
</p>

<p><button onclick="navigation.navigate('subpage.html')">navigation.navigate</button></p>

<p><button onclick="location.href = 'subpage.html'">location.href immediately</button></p>

<p><button onclick="history.back()">history.back()</button></p>

<p><button onclick="location.reload()">location.reload()</button></p>

<p><button onclick="setTimeout(() => location.href = 'subpage.html', 2_000)">Go to subpage in 2 seconds</button></p>
</main>

<div id="console">
</div>

<label>
<input type="checkbox" id="use-navigation-intercept">
Use event.intercept()
</label>

<label>
<input type="checkbox" id="add-unload">
Add unload handler to break bfcache
</label>

<label>
<input type="checkbox" id="cancel-navigation">
Use event.preventDefault() to show a "please don't leave" dialog (Chromium &geq;112.0.5613.0 for traversals)
</label>

<label>
<input type="checkbox" id="add-delay">
Add an artificial two-second delay to all navigations (should impact the loading spinner/scroll restoration/focus reset/accessibility announcements).
</label>

<p>(Note: loading spinner control does not yet work for back/forward traversals; that's happening next.)</p>

<footer><a href="https://glitch.com/edit/#!/gigantic-honored-octagon?path=index.html">View source and edit on Glitch</a></footer>

<p><a href="https://example.com">example.com link for accessibility testing</a></p>

<dialog id="are-you-sure">
<h2>Please don't leave this page</h2>

<p>
I've canceled the navigation! Please don't leave!
</p>

<p>
(You can still leave by changing the URL in the URL bar, or closing the window, or using the back button twice in a row without clicking on the page in between.)
</p>

<form method="dialog">
<input type="submit" value="OK">
</form>
</dialog>

<script type="module">
const output = document.querySelector("#console");
window.addEventListener("error", e => {
output.textContent += e.error.message + "\n" + e.error.stack + "\n\n";
});
</script>

<script type="module">
const addDelay = document.querySelector("#add-delay");
const addUnload = document.querySelector("#add-unload");
const cancelNavigation = document.querySelector("#cancel-navigation");
const useNavigationIntercept = document.querySelector("#use-navigation-intercept");
const areYouSure = document.querySelector("#are-you-sure");

navigation.addEventListener("navigate", e => {
console.log(e);

if (addUnload.checked) {
window.addEventListener("unload", () => {
console.log("unload");
});
}

if (!e.canIntercept || e.hashChange) {
return;
}

if (cancelNavigation.checked) {
if (!e.cancelable) {
console.log("Tried to cancel the navigation, but it was not cancelable. Maybe because of lack of user activation; maybe because of Chromium <112.0.5613.0 and traversal.");
} else {
e.preventDefault();
areYouSure.showModal();
return;
}
}

if (useNavigationIntercept.checked) {
e.intercept({
async handler() {
e.signal.addEventListener("abort", () => {
const newMain = document.createElement("main");
newMain.textContent = "Navigation was aborted, potentially by the browser stop button!";
document.querySelector("main").replaceWith(newMain);
});

if (addDelay.checked) {
await delay(2_000, { signal: e.signal });
}

const body = await (await fetch(e.destination.url, { signal: e.signal })).text();
const { title, main } = getResult(body);

document.title = title;
document.querySelector("main").replaceWith(main);
}
});
}
});

navigation.addEventListener("navigatesuccess", () => {
console.log("navigatesuccess");
areYouSure.close();
});
navigation.addEventListener("navigateerror", ev => {
console.log("navigateerror", ev.error);
});

function getResult(htmlString) {
const parser = new DOMParser();
const doc = parser.parseFromString(htmlString, "text/html");
return { title: doc.title, main: doc.querySelector("main") };
}

function delay(ms, { signal = null } = {}) {
signal?.throwIfAborted();
return new Promise((resolve, reject) => {
const id = setTimeout(resolve, ms);

signal.addEventListener('abort', () => {
clearTimeout(id);
reject(new DOMException('Aborted', 'AbortError'));
})
});
}
</script>
17 changes: 17 additions & 0 deletions sandbox/soft-nav-hard-navigation-tests/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "soft-nav-hard-navigation-tests",
"type": "module",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"vite": "^5.0.2"
}
}
Loading

0 comments on commit 5e87dea

Please sign in to comment.