Improve page swap fallback
This commit is contained in:
+15
-7
@@ -144,7 +144,10 @@
|
|||||||
|
|
||||||
async function navigateUrl(href, root, mode = "replace") {
|
async function navigateUrl(href, root, mode = "replace") {
|
||||||
const response = await fetch(href, { headers: { "X-SLHX-Partial": "1", "Accept": "text/html" } });
|
const response = await fetch(href, { headers: { "X-SLHX-Partial": "1", "Accept": "text/html" } });
|
||||||
await applyResponse(response, root);
|
if (!await applyResponse(response, root) && mode !== "none") {
|
||||||
|
location.href = href;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mode === "push") history.pushState({ slhx: true }, "", href);
|
if (mode === "push") history.pushState({ slhx: true }, "", href);
|
||||||
else if (mode === "replace") history.replaceState({ slhx: true }, "", href);
|
else if (mode === "replace") history.replaceState({ slhx: true }, "", href);
|
||||||
}
|
}
|
||||||
@@ -152,15 +155,19 @@
|
|||||||
async function applyResponse(response, root) {
|
async function applyResponse(response, root) {
|
||||||
if (response.redirected) {
|
if (response.redirected) {
|
||||||
location.href = response.url;
|
location.href = response.url;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (!compatibleFingerprint(response, root)) {
|
if (!compatibleFingerprint(response, root)) {
|
||||||
location.reload();
|
location.reload();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
const type = response.headers.get("content-type") || "";
|
const type = response.headers.get("content-type") || "";
|
||||||
if (type.includes("text/html")) applyHtml(await response.text(), root, response.headers.get("x-slhx-title"));
|
if (type.includes("text/html")) return applyHtml(await response.text(), root, response.headers.get("x-slhx-title"));
|
||||||
else if (type.includes("application/slhx")) applyBatch(await response.arrayBuffer(), root);
|
if (type.includes("application/slhx")) {
|
||||||
|
applyBatch(await response.arrayBuffer(), root);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function compatibleFingerprint(response, root) {
|
function compatibleFingerprint(response, root) {
|
||||||
@@ -335,12 +342,13 @@
|
|||||||
const doc = new DOMParser().parseFromString(html, "text/html");
|
const doc = new DOMParser().parseFromString(html, "text/html");
|
||||||
const template = doc.querySelector("template[data-slhx]");
|
const template = doc.querySelector("template[data-slhx]");
|
||||||
if (!replaceSlot(scope, doc, "content", template ? template.innerHTML : html)) {
|
if (!replaceSlot(scope, doc, "content", template ? template.innerHTML : html)) {
|
||||||
location.reload();
|
emit(scope, "slhx:missing-content-slot", null);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
replaceSlot(scope, doc, "nav");
|
replaceSlot(scope, doc, "nav");
|
||||||
const nextTitle = title || (doc.querySelector("title") && doc.querySelector("title").textContent);
|
const nextTitle = title || (doc.querySelector("title") && doc.querySelector("title").textContent);
|
||||||
if (nextTitle) document.title = nextTitle;
|
if (nextTitle) document.title = nextTitle;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function replaceSlot(scope, doc, name, fallback) {
|
function replaceSlot(scope, doc, name, fallback) {
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ fn runtime_exposes_page_swap_hooks() {
|
|||||||
assert!(source.contains("popstate"));
|
assert!(source.contains("popstate"));
|
||||||
assert!(source.contains("x-slhx-title"));
|
assert!(source.contains("x-slhx-title"));
|
||||||
assert!(source.contains("x-slhx-fingerprint"));
|
assert!(source.contains("x-slhx-fingerprint"));
|
||||||
|
assert!(source.contains("slhx:missing-content-slot"));
|
||||||
|
assert!(source.contains("location.href = href"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user