document.addEventListener('click', (event) => {
if (!event.target.closest('[data-theme-toggle]')) return
const dark = document.documentElement.classList.toggle('dark')
localStorage.setItem('defter-dark', String(dark))
})
document.addEventListener('click', (event) => {
document.querySelectorAll('details[data-account-menu][open]').forEach((menu) => {
if (!menu.contains(event.target)) menu.open = false
})
})
document.addEventListener('keydown', (event) => {
if (event.key !== 'Escape') return
document.querySelectorAll('details[data-account-menu][open]').forEach((menu) => {
menu.open = false
menu.querySelector('summary').focus()
})
})
function syncFacetsToggle() {
const toggle = document.querySelector('[data-facets-toggle]')
if (!toggle) return
const open = [...document.querySelectorAll('details[data-facet]')].every((f) => f.open)
toggle.textContent = open ? toggle.dataset.closeLabel : toggle.dataset.openLabel
}
document.addEventListener('click', (event) => {
if (!event.target.closest('[data-facets-toggle]')) return
const facets = [...document.querySelectorAll('details[data-facet]')]
const open = !facets.every((f) => f.open)
facets.forEach((f) => { f.open = open })
})
document.addEventListener('toggle', syncFacetsToggle, true)
let openFacets = new Map()
let exportChoice = null
function syncExportStyle() {
const style = document.querySelector('[data-export-style]')
if (!style) return
style.hidden = document.querySelector('[data-export-format]').value !== 'citation'
}
document.addEventListener('change', (event) => {
if (event.target.matches('[data-export-format]')) syncExportStyle()
})
document.addEventListener('DOMContentLoaded', () => {
syncFacetsToggle()
syncExportStyle()
})
document.addEventListener('htmx:beforeSwap', () => {
openFacets = new Map(
[...document.querySelectorAll('details[data-facet]')].map((f) => [f.dataset.facet, f.open])
)
const format = document.querySelector('[data-export-format]')
const style = document.querySelector('[data-export-style]')
exportChoice = format && style ? [format.value, style.value] : null
})
document.addEventListener('htmx:afterSwap', () => {
document.querySelectorAll('details[data-facet]').forEach((f) => {
f.open = openFacets.get(f.dataset.facet) ?? f.open
})
const format = document.querySelector('[data-export-format]')
if (format && exportChoice) {
format.value = exportChoice[0]
document.querySelector('[data-export-style]').value = exportChoice[1]
}
syncFacetsToggle()
syncExportStyle()
})
function showCopied(button) {
const [copy, copied] = button.querySelectorAll('svg')
const label = button.querySelector('span')
const text = label?.textContent
copy.classList.add('hidden')
copied.classList.remove('hidden')
if (label) label.textContent = button.dataset.copiedLabel
setTimeout(() => {
copy.classList.remove('hidden')
copied.classList.add('hidden')
if (label) label.textContent = text
}, 2000)
}
async function copyFrom(url) {
const text = fetch(url).then((response) => {
if (!response.ok) throw new Error(`${url}: ${response.status}`)
return response.text()
})
if (typeof ClipboardItem !== 'undefined' && navigator.clipboard.write) {
const blob = text.then((value) => new Blob([value], { type: 'text/plain' }))
await navigator.clipboard.write([new ClipboardItem({ 'text/plain': blob })])
} else {
await navigator.clipboard.writeText(await text)
}
}
document.addEventListener('click', async (event) => {
const button = event.target.closest('[data-export-copy]')
if (!button) return
const form = button.closest('form')
const query = new URLSearchParams(new FormData(form))
await copyFrom(`${form.action}?${query}`)
showCopied(button)
})
document.addEventListener('click', async (event) => {
const button = event.target.closest('[data-copy-work]')
if (!button) return
const form = document.querySelector('[data-export]')
const picked = new FormData(form)
const query = new URLSearchParams({
key: button.dataset.copyWork,
format: picked.get('format'),
style: picked.get('style'),
lang: picked.get('lang'),
})
await copyFrom(`${form.action}?${query}`)
showCopied(button)
})
document.addEventListener('click', async (event) => {
const button = event.target.closest('[data-copy]')
if (!button) return
await navigator.clipboard.writeText(button.dataset.copy)
showCopied(button)
})
document.addEventListener('change', (event) => {
if (!event.target.matches('[data-language]')) return
if (event.target.matches('[data-language-submit]')) {
event.target.form.submit()
return
}
const url = new URL(window.location.href)
url.searchParams.set('lang', event.target.value)
window.location.href = url.href
})