elm-spa/docs/public/main.js

102 lines
2.8 KiB
JavaScript
Raw Normal View History

2021-01-16 06:39:37 +03:00
const app = Elm.Main.init({ flags: window.__FLAGS__ })
// Handle smoothly scrolling to links
const scrollToHash = () => {
const element = window.location.hash && document.querySelector(window.location.hash)
if (element) {
element.scrollIntoView({ behavior: 'smooth' })
} else {
window.scroll({ behavior: 'smooth', top: 0 })
}
}
app.ports.onUrlChange.subscribe(_ => setTimeout(scrollToHash, 400))
setTimeout(scrollToHash, 200)
// Quick search shortcut (/)
window.addEventListener('keypress', (e) => {
if (e.key === '/') {
const el = document.getElementById('quick-search')
if (el && el !== document.activeElement) {
el.focus()
el.select()
e.preventDefault()
}
}
return false
})
// HighlightJS custom element
customElements.define('highlight-js', class HighlightJS extends HTMLElement {
constructor () { super() }
connectedCallback () {
const pre = document.createElement('pre')
const code = document.createElement('code')
pre.className = `language-elm`
code.innerText = this.body
pre.appendChild(code)
this.appendChild(pre)
window.hljs.highlightBlock(pre)
}
})
// Dropdown arrow key support
customElements.define('dropdown-arrow-keys', class DropdownArrowKeys extends HTMLElement {
constructor () {
super()
}
connectedCallback () {
const component = this
const arrows = { ArrowUp: -1, ArrowDown: 1 }
const interactiveChildren = () => component.querySelectorAll('input, a, button')
const onBlur = (e) => window.requestAnimationFrame(_ => {
const active = document.activeElement
const siblings = interactiveChildren()
let foundFocusedSibling = false
e.target.removeEventListener('blur', onBlur)
siblings.forEach(sibling => {
if (sibling === active) {
sibling.addEventListener('blur', onBlur)
foundFocusedSibling = true
}
})
if (foundFocusedSibling === false) {
component.dispatchEvent(new CustomEvent('clearDropdown'))
siblings.forEach(el => el.addEventListener('focus', _ => el.addEventListener('blur', onBlur)))
}
})
interactiveChildren().forEach(el => el.addEventListener('blur', onBlur))
component.addEventListener('keydown', (e) => {
const delta = arrows[e.key]
if (delta) {
e.preventDefault()
const interactive = interactiveChildren()
const count = interactive.length
const active = document.activeElement
if (count < 2) return
interactive.forEach((el, i) => {
if (active == el) {
const next = interactive[(i + delta + count) % count]
next.focus()
}
})
}
})
}
})
window.addEventListener('keyup', (e) => {
const el = document.getElementById('quick-search')
if (e.key === 'Escape' && el === document.activeElement) {
if (el) el.blur()
}
})