88 lines
2.4 KiB
JavaScript
88 lines
2.4 KiB
JavaScript
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);
|