diff --git a/src/dom/common/lib/range.ts b/src/dom/common/lib/range.ts index 171ccde9..85242958 100644 --- a/src/dom/common/lib/range.ts +++ b/src/dom/common/lib/range.ts @@ -22,6 +22,10 @@ export class PersistentRange { this.endOffset = range.endOffset; } + compareBoundaryPoints(how: number, other: Range | PersistentRange): number { + return this.toRange().compareBoundaryPoints(how, other instanceof PersistentRange ? other.toRange() : other); + } + toRange(): Range { let range = new Range(); range.setStart(this.startContainer, this.startOffset); diff --git a/src/dom/epub/epub-view.ts b/src/dom/epub/epub-view.ts index 1feddf19..c5e74658 100644 --- a/src/dom/epub/epub-view.ts +++ b/src/dom/epub/epub-view.ts @@ -87,6 +87,8 @@ class EPUBView extends DOMView { private readonly _rangeCache = new Map(); + private readonly _hrefTargetCache = new Map(); + private _pageMappingJSON!: string; constructor(options: DOMViewOptions) { @@ -688,6 +690,10 @@ class EPUBView extends DOMView { } protected _getHrefTarget(href: string): HTMLElement | null { + if (this._hrefTargetCache.has(href)) { + return this._hrefTargetCache.get(href)!; + } + let [pathname, hash] = this._splitHref(href); let section = this.book.spine.get(pathname); if (!section) { @@ -708,6 +714,7 @@ class EPUBView extends DOMView { console.warn('Unable to resolve hash', hashTarget); } } + this._hrefTargetCache.set(href, target); return target; } @@ -1290,7 +1297,7 @@ class EPUBView extends DOMView { return parseInt(elem.getAttribute('data-section-index')!); } - private static _compareSectionIndices(a: Range | Node, b: Range | Node): number { + private static _compareSectionIndices(a: Range | PersistentRange | Node, b: Range | PersistentRange | Node): number { let aSectionIndex = this.getContainingSectionIndex(a); if (aSectionIndex === null) { throw new Error('a is not inside a section'); @@ -1302,11 +1309,11 @@ class EPUBView extends DOMView { return aSectionIndex - bSectionIndex; } - static compareBoundaryPoints(how: number, a: Range, b: Range): number { + static compareBoundaryPoints(how: number, a: Range | PersistentRange, b: Range | PersistentRange): number { if (a.startContainer.getRootNode() !== b.startContainer.getRootNode()) { return this._compareSectionIndices(a, b) || -1; } - return a.compareBoundaryPoints(how, b); + return a.compareBoundaryPoints(how, b as Range); } static compareRangeToPoint(a: Range, b: Node, bOffset: number): number { diff --git a/src/dom/epub/lib/page-mapping.ts b/src/dom/epub/lib/page-mapping.ts index d98bb186..f92bc758 100644 --- a/src/dom/epub/lib/page-mapping.ts +++ b/src/dom/epub/lib/page-mapping.ts @@ -50,8 +50,8 @@ class PageMapping { readonly tree = new BTree( undefined, - (a, b) => EPUBView.compareBoundaryPoints(Range.START_TO_START, a.toRange(), b.toRange()) - || EPUBView.compareBoundaryPoints(Range.END_TO_END, a.toRange(), b.toRange()) + (a, b) => EPUBView.compareBoundaryPoints(Range.START_TO_START, a, b) + || EPUBView.compareBoundaryPoints(Range.END_TO_END, a, b) ); private _isPhysical = false;