Jacky Zhao
2025-03-10 9e3e711646e3db281da11aeb08fc7a10a8dd3be4
quartz/components/scripts/spa.inline.ts
@@ -56,8 +56,10 @@
  }, 100)
}
let isNavigating = false
let p: DOMParser
async function navigate(url: URL, isBack: boolean = false) {
async function _navigate(url: URL, isBack: boolean = false) {
  isNavigating = true
  startLoading()
  p = p || new DOMParser()
  const contents = await fetchCanonical(url)
@@ -75,6 +77,10 @@
  if (!contents) return
  // notify about to nav
  const event: CustomEventMap["prenav"] = new CustomEvent("prenav", { detail: {} })
  document.dispatchEvent(event)
  // cleanup old
  cleanupFns.forEach((fn) => fn())
  cleanupFns.clear()
@@ -108,7 +114,7 @@
    }
  }
  // now, patch head
  // now, patch head, re-executing scripts
  const elementsToRemove = document.head.querySelectorAll(":not([spa-preserve])")
  elementsToRemove.forEach((el) => el.remove())
  const elementsToAdd = html.head.querySelectorAll(":not([spa-preserve])")
@@ -124,6 +130,19 @@
  delete announcer.dataset.persist
}
async function navigate(url: URL, isBack: boolean = false) {
  if (isNavigating) return
  isNavigating = true
  try {
    await _navigate(url, isBack)
  } catch (e) {
    console.error(e)
    window.location.assign(url)
  } finally {
    isNavigating = false
  }
}
window.spaNavigate = navigate
function createRouter() {
@@ -141,21 +160,13 @@
        return
      }
      try {
        navigate(url, false)
      } catch (e) {
        window.location.assign(url)
      }
      navigate(url, false)
    })
    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) {
        window.location.reload()
      }
      navigate(new URL(window.location.toString()), true)
      return
    })
  }