const cache = {} const main = document.querySelector("html > body > main") const originalMain = main.innerHTML cache[window.location.href] = [originalMain, document.title] history.replaceState([window.location.href, 0, 0], "") const MINUTE_MS = 1000 * 60 async function putCache(href) { if (cache[href] === undefined && href != window.location.href) { cache[href] = ["", ""] console.debug(`Preloading ${href}...`) const html = await (await fetch(href)).text() const doc = new DOMParser().parseFromString(html, "text/html") cache[href] = [doc.querySelector("html > body > main").innerHTML, doc.title] console.debug(`Preloaded ${href}`) setTimeout(() => { delete cache[href] console.debug(`Cleared cached page: ${href}`) }, 5 * MINUTE_MS) } } function loadCache(href) { if (cache[href]) { const [html, title] = cache[href] if (html != "" || title != "") { main.innerHTML = html document.title = title return true } } return false } function preloadinate() { // TODO: some kind of expiration? document.querySelectorAll("a").forEach(el => { // TODO: this would ideally happen in the background (service worker)? if (el.href.indexOf("#") == -1 && el.href.indexOf(".") == -1 && (el.href.startsWith("https://lyte.dev") || el.href.startsWith("http://localhost:1313"))) { const router = async function(ev) { if (el.href == window.location.href) { ev.preventDefault() return false } if (cache[el.href] && cache[el.href][0] != "") { const rep = [window.location.href, window.scrollX, window.scrollY] history.replaceState(rep, "") console.log("replaceState: ", rep) if (!loadCache(el.href)) { window.location.href = el.href window.location.reload() return true } window.scrollTo(0, 0) history.pushState([el.href, 0, 0], "", el.href) preloadinate() ev.preventDefault() return false } else { ev.preventDefault() await putCache(el.href) return router(ev) } } el.addEventListener("mouseover", (_ev) => putCache(el.href)) el.addEventListener("click", router) } }) } window.addEventListener("popstate", ev => { if (ev.state) { const [href, x, y] = ev.state if (!loadCache(href)) { window.location.reload() } requestAnimationFrame(() => { console.log(`Scrolling to ${x}, ${y}`) window.scrollTo(x, y) }) preloadinate() } else { } }) window.addEventListener("load", preloadinate);