Auto-follow is now decided by the reader's own settled scrolling: once the sentence being read is scrolled out of view, sentence changes no longer scroll back; following resumes via 回到播放位置 or by scrolling back to it. Wheel/touch/key input overrides one of our smooth scrolls in progress. Follow and 回到播放位置 scroll the sentence itself instead of its parent block (a TXT block holds 32 KiB, so the old scroll landed far from the sentence). Adds a regression test.
fix(reader): highlight and follow speech on unrendered PDF pages
When the clip being read is on a page or section that is not rendered yet, the adapter navigates there, waits for its text layer and the clip is highlighted once. Auto-follow no longer turns itself off after its own smooth scroll, and HTML frame offsets are included. Adds a sparse 30-page PDF regression test. Previously: playback starts once one batch plus its planning context (1,800 chars) is loaded instead of the full 2,400-char lookahead; slow searches through pages without text show page progress; stop cancels a pending text load. PDF pages already rendered use their text layer.
fix(reader): start reading sooner on sparse/scanned PDFs
Playback starts once one batch plus its planning context (1,800 chars) is loaded instead of the full 2,400-char lookahead; slow searches through pages without text show page progress; stop cancels a pending text load. PDF pages already rendered use their text layer.
feat(reader): native reading for every text-bearing Reader format
Adds the shared tts-client.js player (Hitokoto CPU TTS) to the Reader. reader-speech.mjs supplies a growing-text adapter per format: TXT/Markdown/HTML rendered text, Foliate EPUB/MOBI/FB2 sections, chapter bundles, native PDF text layers and pdf-pages/v3 OCR text layers. Highlights use the CSS Custom Highlight API in the owning realm; DOM text is never modified. Images/media/pages without text get no button. CSP adds the Hitokoto origin to connect-src and Hitokoto plus blob: to media-src. Inventory, components and release gate list the new files on both sites.
fix(search): multi-token AND across tokenizer boundaries, exact term splitting
vomebook
ba5a2f5
Ordinary multi-token queries now union each term's jieba/fuzzy postings with
a literal substring scan before intersecting, so matches that cross a jieba
token boundary are retained. Exact mode splits on whitespace and matches each
term independently; punctuation-bearing terms stay literal, preserving the
documented "手。机" and wildcard behaviour.
The bootstrap payload now reports the same string generation as search and
initial payloads, GET search routes return 405, unknown API paths return a
JSON 404, and the SVG manifest icon declares sizes "any".
Bump HF search semantics to v4 so cached orders and snapshots are invalidated.
Native PDFs: PDF.js parses non-linearized files from the end, demanding
the trailer and cross-reference chunks one round trip at a time. Fetch the
last two aligned chunks once alongside startup and serve those demands from
it. Paired production A/B (24 cold opens): first canvas 680 ms faster at
the median, 22/24 pairs faster, one fewer range request, same bytes.
v3 PDFs: fetch the opening preview partition alongside the page map; it
depends only on the validated reading manifest. Paired A/B (58 cold opens):
229 ms faster at the median, 39/58 pairs faster, no duplicate requests.
Selection: a focus on a separator text node (line ends, inter-block gaps)
or on a page whose text layer had not loaded was moved to the last run in
the document, scrolling to a distant retained page. Separator focus is now
left in place, and other focuses are clamped to the nearest run.
fix: accept fractional SVG preview sizes and requeue visible PDF pages
The pipeline records math.ceil() of a vector preview's intrinsic size while
browsers round naturalWidth, so A4 (595.3pt) and 16:9 slide SVGs failed the
exact-size check with PDF_V3_PREVIEW_GEOMETRY_MISMATCH. The first page showed
"page load failed, retrying" until PDF.js replaced it. SVG previews now allow
a 1px rounding difference; raster previews and the aspect check are unchanged.
Visible pages whose speculative render was cancelled are requeued on slot
release and scroll, and PDF page reads enter the render queue before getPage.
Preview cancellation no longer writes a page failure state.
8 days ago
feat: consume unified Reader snapshots and vector previews