Wide or tall tables, code blocks and display equations overflowed the reading
column and a scroll gesture over them turned the page instead of scrolling the
content (#4400).
- Wrap tables and display equations in a horizontally/vertically scrollable
container; route touch + wheel along the box's scrollable axis so it scrolls
the box and never turns the page, even at the edge (both axes).
- A box that fits its column is marked fit (overflow:visible) so it never clips
or captures gestures; the fit decision is measured once after layout via a
self-disconnecting ResizeObserver, so it never relayerizes during a page turn.
- The scroll wrapper carries a new cfi-skip attribute that makes it transparent
to CFI: epubcfi.js hoists a cfi-skip node's children into its parent (unlike
cfi-inert which drops the subtree), and xcfi.ts mirrors this for CFI<->XPointer
so existing highlights, bookmarks and KOSync positions inside a wrapped table
or equation still resolve. The sanitizer whitelists cfi-skip.
- Bump foliate-js submodule (cfi-skip support + raf fallback for large sections).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add bidirectional annotation/highlight sync between KOReader and Readest:
- Add xpointer0/xpointer1 fields to BookNote and DBBookNote types for
KOReader XPointer positions alongside Readest's CFI format
- Extend transform layer to pass through xpointer fields to/from DB
- Convert CFI→XPointer on push and XPointer→CFI on pull in useNotesSync,
discarding notes that fail conversion
- Support KOReader's text()[K].N indexed text node format in xcfi.ts for
paragraphs with inline elements (e.g. <a> page anchors)
- Generate KOReader-compatible XPointers: text().N for single text nodes,
text()[K].N only when multiple direct text nodes exist
- Skip cfi-inert elements (injected by Readest at runtime) in XPointer
path building and resolution
- Map highlight colors between KOReader and Readest color systems
- Implement KOReader plugin annotation push/pull with deterministic IDs,
auto-sync on document open/close, and UIManager refresh on pull
- Refactor koplugin into focused modules: syncauth, syncconfig,
syncannotations, selfupdate
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(sync): implement KOReader progress synchronization
This commit introduces a comprehensive feature to synchronize reading progress with a KOReader sync server. It includes a compatibility layer to handle discrepancies between Readest's CFI-based progress and KOReader's XPointer/page-based progress, primarily using the `percentage` field as a common ground.
Key additions include:
- A new settings panel under "KOReader Sync" for server configuration, authentication, and sync strategy management (e.g., prompt on conflict, always use latest).
- A conflict resolution dialog that appears when remote progress differs significantly from local progress, allowing the user to choose which version to keep.
- A client-side `useKOSync` hook to manage the entire synchronization lifecycle, including API calls, state management, and conflict resolution logic.
- A new API endpoint `/api/kosync` that acts as a secure proxy to the user-configured KOReader sync server, handling authentication and forwarding requests.
- Logic to differentiate between paginated (PDF/CBZ) and reflowable (EPUB) formats, using page numbers for paginated files where possible and falling back to percentage for reliability.
- Spanish translations for all UI elements related to the KOReader sync feature.
- Addition of `uuid` package to generate a unique `device_id` for sync purposes.
Refactor:
- The `debounce` utility has been improved to include `flush` and `cancel` methods, allowing for more precise control over debounced function execution, which is now used in the sync hook.
* fix(kosync): add support for converting between XPointer and CFI in progress synchronization
* fix(kosync): update navigation method to use select instead of goTo for paginated formats
* fix(kosync): refactor synchronization settings and improve conflict resolution handling
* fix(kosync): add event dispatcher for flushing KOReader synchronization
* fix(sync): handle xpointer in a different section, fix styling
* i18n: update translations
---------
Co-authored-by: Huang Xin <chrox.huang@gmail.com>