* fix(reader): require a still-hold before instant-highlight on touch Instant Highlight (the highlighter quick action) engaged on every pointer-down over text, calling preventDefault, which swallowed the single tap / swipe that turns the page on Android. Tapping the side margins still worked only because they are not selectable text; the synthetic-click fallback was also dead on Android (native touchend calls handlePointerUp with no event). Gate engagement behind a 300ms still hold for touch/pen: a tap releases first and a swipe moves first, so both fall through to pagination, and only a deliberate still hold starts drag-to-highlight. Mouse input keeps engaging immediately (click vs. press-drag is already unambiguous). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(agent): update agent memories Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.4 KiB
name, description, metadata
| name | description | metadata | ||||||
|---|---|---|---|---|---|---|---|---|
| scrolled-header-title-center-4436 | Scrolled-mode header chapter title lagged because getVisibleRange picked the topmost sliver view, not the viewport-center section |
|
#4436 — In scrolled mode the reader header chapter title was wrong vs paginated
mode while transitioning between sections. Title comes from foliate tocItem = TOCProgress.getProgress(index, range); index/range come from the
paginator's relocate detail, ultimately from #getVisibleRange().
Root cause: the scrolled branch of #getVisibleRange (packages/foliate-js/paginator.js)
returned the FIRST overlapping view (lowest index = topmost in scroll order).
When the tail of section K is a thin text-bearing sliver at the very top of the
viewport but section K+1 occupies the centre/majority, it returned K's range →
title showed K while the reader was reading K+1. Paginated mode never shows this
because each page belongs to one section. (comparePoint end-boundary logic in
progress.js is shared by both modes and was NOT the divergence — the view
choice was.)
Fix: prefer the view whose visible band covers the viewport CENTRE
(center = #renderedStart + size/2; center >= off && center < off+vSize);
keep the first valid non-collapsed range as a fallback for when no loaded view
covers the centre (very top/bottom of book). Also fixed #afterScroll scrolled
fraction to size against this.#views.get(index) (the relocated view) instead of
#primaryView, since the relocated index can now differ from #primaryIndex.
#detectPrimaryView/#primaryIndex left UNCHANGED (drives preload/trim/bg;
guarded by #4112/#3987 tests) — only the relocate index/range moved to centre.
Accepted side effect: scrolled CFI/anchor now reflect the centre section (reopen lands at centre section top) — minor, arguably better.
Test: paginator-scrolled.browser.test.ts "should report the section
occupying the viewport centre…" — real paginator + sample-alice, two adjacent
tall linear sections, setAttribute('no-preload','') AFTER fill to freeze view
offsets (else backward-preload scroll-compensation shifts the absolute scrollTop
target), nudge-scroll (first debounced scroll only clears #justAnchored; need a
2nd to fire afterScroll('scroll')), assert relocate index == centre section.
See issue-4112-scroll-anchoring.