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>
1.3 KiB
name, description, metadata
| name | description | metadata | ||||||
|---|---|---|---|---|---|---|---|---|
| iframe-cross-realm-instanceof | App-bundle code handling foliate iframe DOM must not use `instanceof Element/HTMLElement` — cross-realm, always false |
|
Reader content lives in foliate iframes, each with its own JS realm. App-bundle
code (e.g. src/utils/style.ts, iframeEventHandlers.ts) runs in the top window
realm, so its Element/HTMLElement constructors differ from the iframe's.
someIframeEl instanceof Element (top-realm Element) is always false — verified:
Element === iframeWin.Element is false. So any guard like if (!(target instanceof Element)) return
silently drops every real iframe element. Functions still pass jsdom unit tests (single realm)
yet are dead in the running app.
Use duck-typing instead: if (!target || !('closest' in target)) return; then
(target as Element).closest(...). For node-type checks use node.nodeType === Node.ELEMENT_NODE
(numeric constant, realm-safe) or check classList/closest presence.
Seen in PR #4391 (wide-table horizontal scroll): the touch findWrapper and applyTableStyle's
re-entrancy guard both used instanceof, so the touch routing never fired and the dedupe guard
never tripped. Related: foliate-touch-listener-capture-phase.