From 07a327e05aa2a48aa11faf9aa0e049201d622f8f Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Thu, 17 Aug 2023 01:34:50 -0700 Subject: [PATCH] fix back button in spa not working between two pages that both have hash fragments --- content/features/upcoming features.md | 3 --- quartz/components/scripts/graph.inline.ts | 1 - quartz/components/scripts/search.inline.ts | 1 - quartz/components/scripts/spa.inline.ts | 21 +++++++++++++++------ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/content/features/upcoming features.md b/content/features/upcoming features.md index 2045be7b..7093a5bf 100644 --- a/content/features/upcoming features.md +++ b/content/features/upcoming features.md @@ -4,9 +4,6 @@ draft: true ## todo -- static icon path (in head) never gets updated - - do we update relative links on spa? -- back button with anchors / popovers + spa is broken - debounce cfg rebuild on large repos - investigate content rebuild triggering multiple times even when debounced, causing an esbuild deadlock - dereference symlink for npx quartz sync diff --git a/quartz/components/scripts/graph.inline.ts b/quartz/components/scripts/graph.inline.ts index 0a7c19ee..bea32eb3 100644 --- a/quartz/components/scripts/graph.inline.ts +++ b/quartz/components/scripts/graph.inline.ts @@ -179,7 +179,6 @@ async function renderGraph(container: string, slug: CanonicalSlug) { const neighbourNodes = d3 .selectAll(".node") .filter((d) => neighbours.includes(d.id)) - console.log(neighbourNodes) const currentId = d.id const linkNodes = d3 .selectAll(".link") diff --git a/quartz/components/scripts/search.inline.ts b/quartz/components/scripts/search.inline.ts index 5c7dae01..b94cdfbc 100644 --- a/quartz/components/scripts/search.inline.ts +++ b/quartz/components/scripts/search.inline.ts @@ -148,7 +148,6 @@ document.addEventListener("nav", async (e: unknown) => { async function onType(e: HTMLElementEventMap["input"]) { const term = (e.target as HTMLInputElement).value const searchResults = (await index?.searchAsync(term, numSearchResults)) ?? [] - console.log(searchResults) const getByField = (field: string): number[] => { const results = searchResults.filter((x) => x.field === field) return results.length === 0 ? [] : ([...results[0].result] as number[]) diff --git a/quartz/components/scripts/spa.inline.ts b/quartz/components/scripts/spa.inline.ts index 1b44ade0..e0a83731 100644 --- a/quartz/components/scripts/spa.inline.ts +++ b/quartz/components/scripts/spa.inline.ts @@ -46,10 +46,6 @@ async function navigate(url: URL, isBack: boolean = false) { }) if (!contents) return - if (!isBack) { - history.pushState({}, "", url) - window.scrollTo({ top: 0 }) - } const html = p.parseFromString(contents, "text/html") let title = html.querySelector("title")?.textContent @@ -65,8 +61,20 @@ async function navigate(url: URL, isBack: boolean = false) { announcer.dataset.persist = "" html.body.appendChild(announcer) + // morph body micromorph(document.body, html.body) + // scroll into place and add history + if (!isBack) { + history.pushState({}, "", url) + if (url.hash) { + const el = document.getElementById(url.hash.substring(1)) + el?.scrollIntoView() + } else { + window.scrollTo({ top: 0 }) + } + } + // now, patch head const elementsToRemove = document.head.querySelectorAll(":not([spa-preserve])") elementsToRemove.forEach((el) => el.remove()) @@ -92,8 +100,9 @@ function createRouter() { } }) - window.addEventListener("popstate", () => { - if (window.location.hash) return + window.addEventListener("popstate", (event) => { + const { url } = getOpts(event) ?? {} + if (window.location.hash && window.location.pathname === url?.pathname) return try { navigate(new URL(window.location.toString()), true) } catch (e) {