Fix Fetch+History loading with same-page fragment links
authorLanius Trolling <lanius@laniustrolling.dev>
Tue, 27 Aug 2024 10:18:53 +0000 (06:18 -0400)
committerLanius Trolling <lanius@laniustrolling.dev>
Tue, 27 Aug 2024 10:18:53 +0000 (06:18 -0400)
src/jvmMain/resources/static/init.js

index 766cc5a54be5e448d680c13a101d53a1f301c6fd..b377ef2c92e0c2ea050ff796d1c50fd9be65b1ec 100644 (file)
                }
 
                (async function () {
-                       const newState = {"href": url.pathname, "index": history.state.index + 1};
+                       const prevUrl = new URL(window.location.href);
+                       const newState = {"href": url.href, "index": history.state.index + 1};
+
+                       if (stateMode === "pop" && history.state.href === "") {
+                               window.scroll(0, history.state.scroll);
+                               return;
+                       } else if (stateMode !== "pop" && url.pathname === prevUrl.pathname && url.search === prevUrl.search) {
+                               newState.href = "";
+
+                               if (stateMode === "push") {
+                                       history.replaceState({...history.state, "scroll": window.scrollY}, "");
+                                       history.pushState(newState, "", url);
+                               } else if (stateMode === "replace") {
+                                       history.replaceState(newState, "", url);
+                               }
+
+                               const scrollToElement = document.querySelector(url.hash);
+                               if (scrollToElement != null) {
+                                       scrollToElement.scrollIntoView(true);
+                               }
+
+                               return;
+                       }
 
                        if (stateMode === "push") {
                                history.replaceState({...history.state, "scroll": window.scrollY}, "");
                                mode: "same-origin"
                        });
 
-                       htmlResponse.headers.forEach(console.log);
                        const redirectJson = htmlResponse.headers.get("X-Redirect-Json");
                        if (redirectJson != null && redirectJson.toLowerCase() === "true") {
                                const redirectJsonBody = await htmlResponse.json();
                                }
 
                                const redirectUrl = new URL(redirectJsonBody.target, window.location.origin)
-                               if (!goToPage(redirectUrl, "replace")) {
+                               if (!goToPage(redirectUrl, "push")) {
                                        window.location.href = redirectUrl.href;
                                }
 
                return true;
        }
 
-       history.replaceState({"href": window.location.pathname, "index": 0}, "");
+       history.replaceState({"href": window.location.href, "index": 0}, "");
 
        let isWindowScrollTicking = false;
        window.addEventListener("scroll", () => {
 
        window.addEventListener("popstate", e => {
                e.preventDefault();
-               const url = new URL(e.state.href, window.location.origin);
+               const url = new URL(e.state.href);
                if (!goToPage(url, "pop")) {
                        window.location.href = url.href;
                }
 
                        const anchors = dom.querySelectorAll("a");
                        for (const anchor of anchors) {
-                               if (anchor.hasAttribute("data-csrf-token") || anchor.classList.contains("comment-edit-link") || anchor.classList.contains("copy-text")) {
+                               if (!anchor.hasAttribute("href") || anchor.getAttribute("href") === "#" || anchor.hasAttribute("data-csrf-token")) {
                                        continue;
                                }