/* eslint-env browser */
import { marked } from 'marked'
customElements.define('docs-viewer', class extends HTMLElement {
static get observedAttributes () { return ['data-load'] }
attributeChangedCallback (name, _, page) { if (name === 'data-load') this.load(page).catch((err) => this.#error(err)) }
constructor () {
super()
this.template = document.createElement('template')
this.template.innerHTML = `
`
this.root = this.attachShadow({ mode: 'open' })
this.root.appendChild(this.template.content.cloneNode(true))
this.panel = this.root.querySelector('#panel')
this.header = this.root.querySelector('header')
this.panel.addEventListener('click', (evt) => {
if (evt.target?.tagName !== 'A') return
const href = evt.target.getAttribute('href')
const { origin } = new URL(location.href)
const url = new URL(href, location.href)
if (url.origin !== origin) return window.open(href)
evt.preventDefault()
document.documentElement.scrollTo(0, 0)
this.load(url.pathname).catch((err) => this.#error(err)).finally(() => {
this.header.querySelector('a').style.display = 'inline-block'
})
})
window.addEventListener('popstate', (evt) => {
document.documentElement.scrollTo(0, 0)
if (evt.state?.page === 'readme.md') this.header.querySelector('a').style.display = 'none'
evt.preventDefault()
this.load(evt.state?.page || this.page, true).catch((err) => this.#error(err))
})
window.onbeforeunload = (e) => {
this.#load()
e.returnValue = false
}
this.page = this.dataset.load
this.load(this.page).catch((err) => this.#error(err))
}
#error (err) {
try { this.panel.querySelector('slot').innerHTML = err.stack } catch (e) { console.error(err, e) }
}
load (page = 'readme.md', replace) {
if (replace) history.replaceState({ page }, page, page)
else history.pushState({ page }, page, page)
this.page = page
return this.#load()
}
async #load () {
this.panel.querySelector('slot').innerHTML = marked.parse(await (await fetch(this.page)).text(), {headerIds: false, mangle: false})
}
})