Refactor and fix prev/next at start/end of book

This commit is contained in:
John Factotum
2023-05-17 23:27:38 +08:00
parent 887138472b
commit ba4f58af4f
+40 -42
View File
@@ -714,41 +714,10 @@ export class Paginator extends HTMLElement {
? anchor(this.#view.document) : anchor) ?? 0
await this.#scrollToAnchor(select)
}
scrollPrev() {
if (!this.#view) return null
if (this.scrolled) {
if (this.start > 0)
return [true, this.#scrollTo(Math.max(0, this.start - this.size), '', true)]
else return null
}
const page = this.page - 1
return [page > 0, this.#scrollToPage(page, '', true)]
}
scrollNext() {
if (!this.#view) return null
if (this.scrolled) {
if (this.viewSize - this.end > 2)
return [true, this.#scrollTo(Math.min(this.viewSize, this.end), '', true)]
else return null
}
const page = this.page + 1
return [page < this.pages - 1, this.#scrollToPage(page, '', true)]
}
#canGoToIndex(index) {
return index >= 0 && index <= this.sections.length - 1
}
async #goTo(tryScroll, target, lock) {
if (this.#locked) return
if (lock) this.#locked = true
const scroll = tryScroll?.()
const shouldGo = !scroll?.[0]
if (scroll) await scroll[1]
if (shouldGo) {
const { index, anchor, select } = await target
if (!this.#canGoToIndex(index)) {
this.#locked = false
return null
}
async #goTo({ index, anchor, select}) {
if (index === this.#index) await this.#display({ index, anchor, select })
else {
const oldIndex = this.#index
@@ -765,25 +734,54 @@ export class Paginator extends HTMLElement {
}))
}
}
if (lock) {
await wait(100) // throttle by 100ms
this.#locked = false
}
}
async goTo(target) {
return this.#goTo(null, target)
if (this.#locked) return
const resolved = await target
if (this.#canGoToIndex(resolved.index)) return this.#goTo(resolved)
}
#scrollPrev() {
if (!this.#view) return
if (this.scrolled) {
if (this.start > 0)
return this.#scrollTo(Math.max(0, this.start - this.size), null, true)
return true
}
const page = this.page - 1
if (this.#index <= 0 && page <= 0) return
return this.#scrollToPage(page, null, true).then(() => page <= 0)
}
#scrollNext() {
if (!this.#view) return
if (this.scrolled) {
if (this.viewSize - this.end > 2)
return this.#scrollTo(Math.min(this.viewSize, this.end), null, true)
return true
}
const page = this.page + 1
const pages = this.pages
if (this.#index >= this.sections.length - 1 && page >= pages - 1) return
return this.#scrollToPage(page, null, true).then(() => page >= pages - 1)
}
#adjacentIndex(dir) {
for (let index = this.#index + dir; this.#canGoToIndex(index); index += dir)
if (this.sections[index]?.linear !== 'no') return index
}
async #turnPage(dir) {
this.#locked = true
const prev = dir === -1
const shouldGo = await (prev ? this.#scrollPrev() : this.#scrollNext())
if (shouldGo) await this.#goTo({
index: this.#adjacentIndex(dir),
anchor: prev ? () => 1 : () => 0,
})
if (shouldGo || !this.pageAnimation) await wait(100)
this.#locked = false
}
prev() {
const index = this.#adjacentIndex(-1)
return this.#goTo(() => this.scrollPrev(), { index, anchor: () => 1 }, true)
return this.#turnPage(-1)
}
next() {
const index = this.#adjacentIndex(1)
return this.#goTo(() => this.scrollNext(), { index }, true)
return this.#turnPage(1)
}
prevSection() {
return this.goTo({ index: this.#adjacentIndex(-1) })