mirror of
https://github.com/john-okeefe/foliate-js.git
synced 2026-09-09 11:29:14 -04:00
Footnotes: reject when failing to show footnote
Now `handle()` could return either undefined or a promise, which you can catch to handle the case where footnote fails to show. Also improve footnote extraction.
This commit is contained in:
+17
-3
@@ -32,11 +32,17 @@ const getReferencedType = el => {
|
|||||||
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)
|
||||||
|
const target = el
|
||||||
while (el.matches(isInline)) {
|
while (el.matches(isInline)) {
|
||||||
const parent = el.parentElement
|
const parent = el.parentElement
|
||||||
if (!parent) break
|
if (!parent) break
|
||||||
el = parent
|
el = parent
|
||||||
}
|
}
|
||||||
|
if (el === doc.body) {
|
||||||
|
const sibling = target.nextElementSibling
|
||||||
|
if (sibling && !sibling.matches(isInline)) return sibling
|
||||||
|
throw new Error('Failed to extract footnote')
|
||||||
|
}
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +50,9 @@ export class FootnoteHandler extends EventTarget {
|
|||||||
detectFootnotes = true
|
detectFootnotes = true
|
||||||
#showFragment(book, { index, anchor }, href) {
|
#showFragment(book, { index, anchor }, href) {
|
||||||
const view = document.createElement('foliate-view')
|
const view = document.createElement('foliate-view')
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
view.addEventListener('load', e => {
|
view.addEventListener('load', e => {
|
||||||
|
try {
|
||||||
const { doc } = e.detail
|
const { doc } = e.detail
|
||||||
const el = anchor(doc)
|
const el = anchor(doc)
|
||||||
const type = getReferencedType(el)
|
const type = getReferencedType(el)
|
||||||
@@ -61,24 +69,30 @@ export class FootnoteHandler extends EventTarget {
|
|||||||
}
|
}
|
||||||
const detail = { view, href, type, hidden, target: el }
|
const detail = { view, href, type, hidden, target: el }
|
||||||
this.dispatchEvent(new CustomEvent('render', { detail }))
|
this.dispatchEvent(new CustomEvent('render', { detail }))
|
||||||
|
resolve()
|
||||||
|
} catch (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
view.open(book)
|
view.open(book)
|
||||||
.then(() => this.dispatchEvent(new CustomEvent('before-render', { detail: { view } })))
|
.then(() => this.dispatchEvent(new CustomEvent('before-render', { detail: { view } })))
|
||||||
.then(() => view.goTo(index))
|
.then(() => view.goTo(index))
|
||||||
|
.catch(reject)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
handle(book, e) {
|
handle(book, e) {
|
||||||
const { a, href } = e.detail
|
const { a, href } = e.detail
|
||||||
const { yes, maybe } = isFootnoteReference(a)
|
const { yes, maybe } = isFootnoteReference(a)
|
||||||
if (yes) {
|
if (yes) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
Promise.resolve(book.resolveHref(href)).then(target =>
|
return Promise.resolve(book.resolveHref(href)).then(target =>
|
||||||
this.#showFragment(book, target, 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 }) => {
|
return 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)
|
return this.#showFragment(book, target, href)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user