From df95960f8289a2232b9c3f6eaa83b936702d3c5d Mon Sep 17 00:00:00 2001 From: John Factotum <50942278+johnfactotum@users.noreply.github.com> Date: Thu, 17 Aug 2023 15:12:25 +0800 Subject: [PATCH] Expose relocation reason And fix history not updated when scrolling in scroll mode --- fixed-layout.js | 16 ++++++++-------- paginator.js | 8 ++++---- view.js | 15 ++++++--------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/fixed-layout.js b/fixed-layout.js index b359bc9..2d2da6e 100644 --- a/fixed-layout.js +++ b/fixed-layout.js @@ -221,9 +221,9 @@ export class FixedLayout extends HTMLElement { ? spread.left ?? spread.right : spread.right ?? spread.left) return this.book.sections.indexOf(section) } - #reportLocation() { + #reportLocation(reason) { this.dispatchEvent(new CustomEvent('relocate', { detail: - { range: null, index: this.index, fraction: 0, size: 1 } })) + { reason, range: null, index: this.index, fraction: 0, size: 1 } })) } getSpreadOf(section) { const spreads = this.#spreads @@ -234,7 +234,7 @@ export class FixedLayout extends HTMLElement { if (center === section) return { index, side: 'center' } } } - async goToSpread(index, side) { + async goToSpread(index, side, reason) { if (index < 0 || index > this.#spreads.length - 1) return if (index === this.#index) { this.#render(side) @@ -255,7 +255,7 @@ export class FixedLayout extends HTMLElement { const right = { index: indexR, src: srcR } await this.#showSpread({ left, right, side }) } - this.#reportLocation() + this.#reportLocation(reason) } async select(target) { await this.goTo(target) @@ -271,13 +271,13 @@ export class FixedLayout extends HTMLElement { } async next() { const s = this.rtl ? this.#goLeft() : this.#goRight() - if (s) this.#reportLocation() - else return this.goToSpread(this.#index + 1, this.rtl ? 'right' : 'left') + if (s) this.#reportLocation('page') + else return this.goToSpread(this.#index + 1, this.rtl ? 'right' : 'left', 'page') } async prev() { const s = this.rtl ? this.#goRight() : this.#goLeft() - if (s) this.#reportLocation() - else return this.goToSpread(this.#index - 1, this.rtl ? 'left' : 'right') + if (s) this.#reportLocation('page') + else return this.goToSpread(this.#index - 1, this.rtl ? 'left' : 'right', 'page') } getContents() { return Array.from(this.#root.querySelectorAll('iframe'), frame => ({ diff --git a/paginator.js b/paginator.js index 339177f..27744fa 100644 --- a/paginator.js +++ b/paginator.js @@ -664,7 +664,7 @@ export class Paginator extends HTMLElement { index: this.#adjacentIndex(dir), anchor: dir < 0 ? () => 1 : () => 0, }) - }).then(() => this.dispatchEvent(new Event('snapend'))) + }) } #onTouchStart(e) { const touch = e.changedTouches[0] @@ -807,7 +807,7 @@ export class Paginator extends HTMLElement { if (reason !== 'anchor') this.#anchor = range const index = this.#index - const detail = { range, index } + const detail = { reason, range, index } if (this.scrolled) detail.fraction = this.start / this.viewSize else if (this.pages > 0) { const { page, pages } = this @@ -881,7 +881,7 @@ export class Paginator extends HTMLElement { } if (this.atStart) return const page = this.page - 1 - return this.#scrollToPage(page, null, true).then(() => page <= 0) + return this.#scrollToPage(page, 'page', true).then(() => page <= 0) } #scrollNext(distance) { if (!this.#view) return true @@ -893,7 +893,7 @@ export class Paginator extends HTMLElement { if (this.atEnd) return const page = this.page + 1 const pages = this.pages - return this.#scrollToPage(page, null, true).then(() => page >= pages - 1) + return this.#scrollToPage(page, 'page', true).then(() => page >= pages - 1) } get atStart() { return this.#adjacentIndex(-1) == null && this.page <= 1 diff --git a/view.js b/view.js index cd7e2c0..789f099 100644 --- a/view.js +++ b/view.js @@ -126,8 +126,6 @@ export class View extends HTMLElement { this.renderer.setAttribute('exportparts', 'head,foot,filter') this.renderer.addEventListener('load', e => this.#onLoad(e.detail)) this.renderer.addEventListener('relocate', e => this.#onRelocate(e.detail)) - this.renderer.addEventListener('snapend', () => - this.history.replaceState(this.lastLocation.cfi)) this.renderer.addEventListener('create-overlayer', e => e.detail.attach(this.#createOverlayer(e.detail))) this.renderer.open(book) @@ -163,13 +161,14 @@ export class View extends HTMLElement { #emit(name, detail, cancelable) { return this.dispatchEvent(new CustomEvent(name, { detail, cancelable })) } - #onRelocate({ range, index, fraction, size }) { - if (!this.#sectionProgress) return - const progress = this.#sectionProgress.getProgress(index, fraction, size) - const tocItem = this.#tocProgress.getProgress(index, range) - const pageItem = this.#pageProgress.getProgress(index, range) + #onRelocate({ reason, range, index, fraction, size }) { + const progress = this.#sectionProgress?.getProgress(index, fraction, size) ?? {} + const tocItem = this.#tocProgress?.getProgress(index, range) + const pageItem = this.#pageProgress?.getProgress(index, range) const cfi = this.getCFI(index, range) this.lastLocation = { ...progress, tocItem, pageItem, cfi, range } + if (reason === 'snap' || reason === 'page' || reason === 'scroll') + this.history.replaceState(cfi) this.#emit('relocate', this.lastLocation) } #onLoad({ doc, index }) { @@ -337,11 +336,9 @@ export class View extends HTMLElement { } async prev(distance) { await this.renderer.prev(distance) - this.history.replaceState(this.lastLocation.cfi) } async next(distance) { await this.renderer.next(distance) - this.history.replaceState(this.lastLocation.cfi) } goLeft() { return this.book.dir === 'rtl' ? this.next() : this.prev()