chore(repo): save local work
This commit is contained in:
+47
-2
@@ -343,6 +343,7 @@
|
||||
await navigateUrl(pageRequestUrl(form, source), rootOf(form) || rootOf(el), mode);
|
||||
return;
|
||||
}
|
||||
savePage(roots()[0]);
|
||||
const response = await fetch(requestUrl(form, data, method), {
|
||||
method,
|
||||
body,
|
||||
@@ -382,7 +383,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
function snapshotPage(root) {
|
||||
return root ? {
|
||||
hemx: true,
|
||||
pageHtml: root.innerHTML,
|
||||
pageTitle: document.title,
|
||||
scrollX: window.scrollX,
|
||||
scrollY: window.scrollY,
|
||||
} : null;
|
||||
}
|
||||
|
||||
function savePage(root) {
|
||||
const snapshot = snapshotPage(root);
|
||||
if (snapshot) history.replaceState(snapshot, "", location.href);
|
||||
}
|
||||
|
||||
function restorePage(state, root) {
|
||||
if (!root || !state || typeof state.pageHtml !== "string") return false;
|
||||
root.innerHTML = state.pageHtml;
|
||||
if (state.pageTitle) document.title = state.pageTitle;
|
||||
bindRoot(root);
|
||||
requestAnimationFrame(() => scrollTo(state.scrollX, state.scrollY));
|
||||
return true;
|
||||
}
|
||||
|
||||
async function navigateUrl(href, root, mode = "replace") {
|
||||
if (mode === "push") savePage(root);
|
||||
const response = await fetch(href, {
|
||||
headers: { "X-HEMX-Partial": "1", "Accept": "text/html" },
|
||||
credentials: "same-origin",
|
||||
@@ -443,6 +469,8 @@
|
||||
return;
|
||||
}
|
||||
for (const op of batch.ops) applyOp(scope, op);
|
||||
bindPolling(scope);
|
||||
bindRevealed(scope);
|
||||
}
|
||||
|
||||
function canApplyOp(scope, op) {
|
||||
@@ -1101,6 +1129,19 @@
|
||||
stopDescendantPolling(root);
|
||||
}
|
||||
|
||||
function restoreRevealed(event) {
|
||||
if (!event.persisted) return;
|
||||
roots().forEach((root) => {
|
||||
const observer = revealObservers.get(root);
|
||||
if (observer) observer.disconnect();
|
||||
revealObservers.delete(root);
|
||||
forEachElement(root, (el) => {
|
||||
if (attrEquals(el, "data-hemx-on", "revealed") || el.hasAttribute("data-hemx-revealed")) revealed.delete(el);
|
||||
});
|
||||
bindRevealed(root);
|
||||
});
|
||||
}
|
||||
|
||||
function start() {
|
||||
roots().forEach((root) => {
|
||||
root.setAttribute("data-hemx-request-timeout-ms", String(REQUEST_TIMEOUT_MS));
|
||||
@@ -1147,9 +1188,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener("popstate", () => {
|
||||
window.addEventListener("pageshow", restoreRevealed);
|
||||
|
||||
addEventListener("popstate", (event) => {
|
||||
const root = roots()[0];
|
||||
if (root) navigateUrl(location.href, root, "none").catch((error) => emit(root, "hemx:error", String(error)));
|
||||
if (root && !restorePage(event.state, root)) {
|
||||
if (root) navigateUrl(location.href, root, "none").catch((error) => emit(root, "hemx:error", String(error)));
|
||||
}
|
||||
});
|
||||
|
||||
window.hemx = Object.freeze({
|
||||
|
||||
@@ -148,11 +148,16 @@ fn runtime_supports_tiny_delay_and_revealed_scheduling() {
|
||||
assert!(source.contains("data-hemx-revealed"));
|
||||
assert!(source.contains("typeof IntersectionObserver === \"undefined\""));
|
||||
assert!(source.contains("schedule(entry.target, \"revealed\")"));
|
||||
assert!(source.contains("window.addEventListener(\"pageshow\", restoreRevealed)"));
|
||||
assert!(source.contains("revealed.delete(el)")); // req: convention/014 test
|
||||
assert!(source.contains("record.addedNodes.forEach((node) =>"));
|
||||
assert!(source.contains("descendantRoots(node).forEach(bindRoot)"));
|
||||
assert!(source.contains("const owner = rootOf(node.parentElement)"));
|
||||
assert!(source.contains("bindPolling(owner)"));
|
||||
assert!(source.contains("bindRevealed(owner)")); // req: runtime/007 test
|
||||
assert!(source.contains("bindRevealed(owner)"));
|
||||
assert!(source.contains(
|
||||
"for (const op of batch.ops) applyOp(scope, op);\n bindPolling(scope);\n bindRevealed(scope);"
|
||||
)); // req: runtime/007 test
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -312,6 +317,9 @@ fn runtime_exposes_page_swap_hooks() {
|
||||
assert!(source.contains("data-hemx-nav"));
|
||||
assert!(source.contains("data-hemx-boost"));
|
||||
assert!(source.contains("history.pushState"));
|
||||
assert!(source.contains("snapshotPage(root)"));
|
||||
assert!(source.contains("restorePage(event.state, root)"));
|
||||
assert!(source.contains("scrollTo(state.scrollX, state.scrollY)")); // req: page_swap/005 test
|
||||
assert!(source.contains("popstate"));
|
||||
assert!(source.contains("x-hemx-title"));
|
||||
assert!(source.contains("x-hemx-fingerprint"));
|
||||
|
||||
Reference in New Issue
Block a user