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.
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