mirror of
https://github.com/john-okeefe/foliate-js.git
synced 2026-09-09 11:29:14 -04:00
Foonotes: get note type
Also rename footnote.js -> footnotes.js
This commit is contained in:
+26
-11
@@ -1,17 +1,30 @@
|
|||||||
const refTypes = ['annoref', 'biblioref', 'glossref', 'noteref']
|
const getTypes = el => new Set(el?.getAttributeNS?.('http://www.idpf.org/2007/ops', 'type')?.split(' '))
|
||||||
|
const getRoles = el => new Set(el?.getAttribute?.('role')?.split(' '))
|
||||||
|
|
||||||
|
const refTypes = ['biblioref', 'glossref', 'noteref']
|
||||||
const refRoles = ['doc-biblioref', 'doc-glossref', 'doc-noteref']
|
const refRoles = ['doc-biblioref', 'doc-glossref', 'doc-noteref']
|
||||||
const isFootnote = a => {
|
const isFootnoteReference = a => {
|
||||||
const types = a.getAttributeNS('http://www.idpf.org/2007/ops', 'type')?.split(' ')
|
const types = getTypes(a)
|
||||||
const roles = a.getAttribute('role')?.split(' ')
|
const roles = getRoles(a)
|
||||||
return {
|
return {
|
||||||
yes: types?.some(t => refTypes.includes(t)) || roles?.some(r => refRoles.includes(r)),
|
yes: refRoles.some(r => roles.has(r)) || refTypes.some(t => types.has(t)),
|
||||||
maybe: () => !types?.includes('backlink') && !roles?.includes('doc-backlink')
|
maybe: () => !types.has('backlink') && !roles.has('doc-backlink')
|
||||||
&& (getComputedStyle(a).verticalAlign === 'super'
|
&& (getComputedStyle(a).verticalAlign === 'super'
|
||||||
|| a.children.length === 1 && getComputedStyle(a.children[0]).verticalAlign === 'super')
|
|| a.children.length === 1 && getComputedStyle(a.children[0]).verticalAlign === 'super')
|
||||||
|| getComputedStyle(a.parentElement).verticalAlign === 'super',
|
|| getComputedStyle(a.parentElement).verticalAlign === 'super',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getReferencedType = el => {
|
||||||
|
const types = getTypes(el)
|
||||||
|
const roles = getRoles(el)
|
||||||
|
return roles.has('doc-biblioentry') || types.has('biblioentry') ? 'biblioentry'
|
||||||
|
: roles.has('definition') || types.has('glossdef') ? 'definition'
|
||||||
|
: roles.has('doc-endnote') || types.has('endnote') || types.has('rearnote') ? 'endnote'
|
||||||
|
: roles.has('doc-footnote') || types.has('footnote') ? 'footnote'
|
||||||
|
: roles.has('note') || types.has('note') ? 'note' : null
|
||||||
|
}
|
||||||
|
|
||||||
const isInline = 'a, span, sup, sub, em, strong, i, b, small, big'
|
const isInline = 'a, span, sup, sub, em, strong, i, b, small, big'
|
||||||
const extractFootnote = (doc, anchor) => {
|
const extractFootnote = (doc, anchor) => {
|
||||||
let el = anchor(doc)
|
let el = anchor(doc)
|
||||||
@@ -25,11 +38,13 @@ const extractFootnote = (doc, anchor) => {
|
|||||||
|
|
||||||
export class FootnoteHandler extends EventTarget {
|
export class FootnoteHandler extends EventTarget {
|
||||||
detectFootnotes = true
|
detectFootnotes = true
|
||||||
#showFragment(book, { index, anchor }, getHref) {
|
#showFragment(book, { index, anchor }, href) {
|
||||||
const view = document.createElement('foliate-view')
|
const view = document.createElement('foliate-view')
|
||||||
view.addEventListener('load', e => {
|
view.addEventListener('load', e => {
|
||||||
const { doc } = e.detail
|
const { doc } = e.detail
|
||||||
const el = anchor(doc)
|
const el = anchor(doc)
|
||||||
|
const type = getReferencedType(el)
|
||||||
|
const hidden = el?.matches?.('aside') && type === 'footnote'
|
||||||
if (el) {
|
if (el) {
|
||||||
const range = el.startContainer ? el : doc.createRange()
|
const range = el.startContainer ? el : doc.createRange()
|
||||||
if (!el.startContainer) {
|
if (!el.startContainer) {
|
||||||
@@ -40,7 +55,7 @@ export class FootnoteHandler extends EventTarget {
|
|||||||
doc.body.replaceChildren()
|
doc.body.replaceChildren()
|
||||||
doc.body.appendChild(frag)
|
doc.body.appendChild(frag)
|
||||||
}
|
}
|
||||||
const detail = { view, href: getHref(el) }
|
const detail = { view, href, type, hidden, target: el }
|
||||||
this.dispatchEvent(new CustomEvent('render', { detail }))
|
this.dispatchEvent(new CustomEvent('render', { detail }))
|
||||||
})
|
})
|
||||||
view.open(book)
|
view.open(book)
|
||||||
@@ -49,17 +64,17 @@ export class FootnoteHandler extends EventTarget {
|
|||||||
}
|
}
|
||||||
handle(book, e) {
|
handle(book, e) {
|
||||||
const { a, href } = e.detail
|
const { a, href } = e.detail
|
||||||
const { yes, maybe } = isFootnote(a)
|
const { yes, maybe } = isFootnoteReference(a)
|
||||||
if (yes) {
|
if (yes) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
Promise.resolve(book.resolveHref(href)).then(target =>
|
Promise.resolve(book.resolveHref(href)).then(target =>
|
||||||
this.#showFragment(book, target, el => el?.matches?.('aside') ? null : href))
|
this.#showFragment(book, target, href))
|
||||||
}
|
}
|
||||||
else if (this.detectFootnotes && maybe()) {
|
else if (this.detectFootnotes && maybe()) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
Promise.resolve(book.resolveHref(href)).then(({ index, anchor }) => {
|
Promise.resolve(book.resolveHref(href)).then(({ index, anchor }) => {
|
||||||
const target = { index, anchor: doc => extractFootnote(doc, anchor) }
|
const target = { index, anchor: doc => extractFootnote(doc, anchor) }
|
||||||
this.#showFragment(book, target, () => href)
|
this.#showFragment(book, target, href)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user