Allow processing hrefs in TOC asynchronously

This commit is contained in:
John Factotum
2023-10-08 20:42:47 +08:00
parent 819106c71f
commit 27a290ff59
3 changed files with 6 additions and 4 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ Processors for each book format return an object that implements the following i
- `.isExternal(href)`: returns a boolean. If `true`, the link should be opened externally. - `.isExternal(href)`: returns a boolean. If `true`, the link should be opened externally.
The following methods are consumed by `progress.js`, for getting the correct TOC and page list item when navigating: The following methods are consumed by `progress.js`, for getting the correct TOC and page list item when navigating:
- `.splitTOCHref(href)`: given an href string (from the TOC), returns an array, the first element of which is the `id` of the section (see above), and the second element is the fragment identifier (can be any type; see below) - `.splitTOCHref(href)`: given an href string (from the TOC), returns an array, the first element of which is the `id` of the section (see above), and the second element is the fragment identifier (can be any type; see below). May be async.
- `.getTOCFragment(doc, id)`: given a `Document` object and a fragment identifier (the one provided by `.splitTOCHref()`; see above), returns a `Node` representing the target linked by the TOC item - `.getTOCFragment(doc, id)`: given a `Document` object and a fragment identifier (the one provided by `.splitTOCHref()`; see above), returns a `Node` representing the target linked by the TOC item
Almost all of the properties and methods are optional. At minimum it needs `.sections` and the `.load()` method for the sections, as otherwise there won't be anything to render. Almost all of the properties and methods are optional. At minimum it needs `.sections` and the `.load()` method for the sections, as otherwise there won't be anything to render.
+3 -2
View File
@@ -16,12 +16,12 @@ const flatten = items => items
.flat() .flat()
export class TOCProgress { export class TOCProgress {
constructor({ toc, ids, splitHref, getFragment }) { async init({ toc, ids, splitHref, getFragment }) {
assignIDs(toc) assignIDs(toc)
const items = flatten(toc) const items = flatten(toc)
const grouped = new Map() const grouped = new Map()
for (const [i, item] of items.entries()) { for (const [i, item] of items.entries()) {
const [id, fragment] = splitHref(item?.href) ?? [] const [id, fragment] = await splitHref(item?.href) ?? []
const value = { fragment, item } const value = { fragment, item }
if (grouped.has(id)) grouped.get(id).items.push(value) if (grouped.has(id)) grouped.get(id).items.push(value)
else grouped.set(id, { prev: items[i - 1], items: [value] }) else grouped.set(id, { prev: items[i - 1], items: [value] })
@@ -36,6 +36,7 @@ export class TOCProgress {
this.getFragment = getFragment this.getFragment = getFragment
} }
getProgress(index, range) { getProgress(index, range) {
if (!this.ids) return
const id = this.ids[index] const id = this.ids[index]
const obj = this.map.get(id) const obj = this.map.get(id)
if (!obj) return null if (!obj) return null
+2 -1
View File
@@ -91,7 +91,8 @@ export class View extends HTMLElement {
this.#sectionProgress = new SectionProgress(book.sections, 1500, 1600) this.#sectionProgress = new SectionProgress(book.sections, 1500, 1600)
const splitHref = book.splitTOCHref.bind(book) const splitHref = book.splitTOCHref.bind(book)
const getFragment = book.getTOCFragment.bind(book) const getFragment = book.getTOCFragment.bind(book)
this.#tocProgress = new TOCProgress({ this.#tocProgress = new TOCProgress()
await this.#tocProgress.init({
toc: book.toc ?? [], ids, splitHref, getFragment }) toc: book.toc ?? [], ids, splitHref, getFragment })
this.#pageProgress = new TOCProgress({ this.#pageProgress = new TOCProgress({
toc: book.pageList ?? [], ids, splitHref, getFragment }) toc: book.pageList ?? [], ids, splitHref, getFragment })