Files
pear-docs/lib/app-router.js
rafapaezbas 636b931276 Fix router (#39)
* on click, do not add route if included in pathname

* corrected readme tools table links

* remove code blocks inside links

* corrected hypercore and hyperwarm links

---------

Co-authored-by: rafapaezbas <rafa@holepunch.com>
2024-02-14 14:11:39 +01:00

62 lines
1.9 KiB
JavaScript

/* eslint-env browser */
customElements.define('app-router', class AppRouter extends HTMLElement {
constructor () {
super()
this.routes = {}
}
unload () {
for (const element of Object.values(this.routes)) element?.unload && element.unload()
}
async load (pathname = '/', opts = {}) {
for (const [route, element] of Object.entries(this.routes)) {
if (pathname.startsWith(route)) {
const page = pathname.slice(route.length) || '/'
this.unload()
document.documentElement.scrollTop = 0
this.dataset.load = element.tagName.toLowerCase()
await element.load(page)
document.documentElement.scrollTop = 0
if (!opts.back) history.pushState({ pathname }, null, pathname)
break
}
}
}
link (evt) {
if (evt.target?.tagName !== 'A') return
evt.preventDefault()
if (evt.target.origin !== location.origin) return window.open(evt.target.href)
const { tagName } = evt.target.getRootNode().host || {}
const route = tagName ? this.getAttribute(tagName) : ''
if (evt.target.pathname.startsWith(route)) {
this.load(evt.target.pathname).catch(console.error)
} else {
this.load(route + evt.target.pathname).catch(console.error)
}
}
connectedCallback () {
for (const { name, value } of Array.from(this.attributes)) {
if (name.startsWith('data-')) continue
this.routes[value] = this.querySelector(name)
this.routes[value].router = this
}
this.addEventListener('click', (evt) => this.link(evt))
window.addEventListener('popstate', (evt) => {
this.load(evt.state?.pathname, { back: true }).catch(console.error)
})
window.addEventListener('load', () => {
if (Pear.config.link.indexOf('pear://runtime/') === 0) {
this.load(Pear.config.link.slice(14)).catch(console.error)
} else {
this.load('/')
}
})
}
})