feat(book): J4.c.1 — threaded text shows in Pages overview tile thumbnails

After a designed-page tile is painted, walk its text-frame layers,
identify any that hold a placed chapter via their thread chain, and
paint each frame's paginated slice as an overlay at the frame's
position in the thumb canvas. Same _paintFrameBlocks helper the
editor uses, sized to the frame's bounding box.

The tile thumbnail now reflects the real text flow — author a
chapter, place it on a page-1 head frame, and the Pages overview
shows the first chunk of the chapter text in that frame; the
linked frame on page 2 shows the next chunk.

Still pending: PDF export and Reader Mode walk reflow entries the
old way (J4.c.2 / J4.c.3).

Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.7 committed 2026-06-04 20:33:26 -04:00
1 parent 282f5df4f3
commit 9d8be7e0fe
1 file changed
+67
+67
View File
@@ -10189,6 +10189,10 @@
},
layers: composed,
}, { compact: true });
// J4.c.1: paint threaded chapter text into any text-frame
// layers on this page that hold a placed chapter. Each
// frame gets its slice from the chain pagination.
_paintThreadedFramesOnThumb(thumb, pageLayers, book, trimW, trimH);
} catch (err) {
console.warn('book page thumb render failed', err);
}
@@ -22836,6 +22840,69 @@
};
}
// J4.c.1 — after a designed-page thumbnail is painted, overlay
// threaded chapter text into any text-frame layers that hold a
// placed chapter. The thumb's canvas div is the first child of
// `thumb` (per renderCustomArtPreviewDOM); we position absolute
// overlays inside it at each frame's coordinates.
//
// Note on geometry: the thumb canvas is sized at trim-only (no
// bleed). Layer coords are sheet-relative (include bleed). So we
// translate by subtracting `bleed` from x/y when computing the
// frame's percentage position. This matches what
// renderCustomArtPreviewDOM does for other layers — see how the
// current page-tile painter just hands its layers to the preview
// helper, which uses (layer.x / wIn) * 100% with wIn = trimW;
// the bleed offset is visible but consistent across all layers.
function _paintThreadedFramesOnThumb(thumb, pageLayers, book, trimW, trimH) {
if (!thumb || !book) return;
const canvas = thumb.firstChild;
if (!canvas) return;
const bleed = Number(book.spec?.bleed) || 0;
// The thumb canvas spans (0..trimW, 0..trimH) in inches.
// Sheet-coord origin is at (-bleed, -bleed) in that space.
for (const layer of pageLayers) {
if (layer.type !== 'shape' || layer.shape?.kind !== 'text-frame') continue;
const chain = _bookCollectThreadChain(layer);
const head = chain[0];
if (!head?.sourceChapter) continue;
const myIndex = chain.indexOf(layer);
let paginated;
try {
paginated = _paginateChapterIntoThread(head, book);
} catch (err) {
console.warn('thumb thread paginate failed', err);
continue;
}
const page = paginated.pages[myIndex];
if (!page || !page.blocks?.length) continue;
// Place an overlay sized to this frame's bounding box,
// expressed as a percentage of the trim-only thumb canvas.
const fx = (Number(layer.x) || 0) - bleed;
const fy = (Number(layer.y) || 0) - bleed;
const fw = Number(layer.w) || 0;
const fh = Number(layer.h) || 0;
if (fw <= 0 || fh <= 0) continue;
const overlay = document.createElement('div');
overlay.style.cssText = [
'position:absolute',
`left:${(fx / trimW) * 100}%`,
`top:${(fy / trimH) * 100}%`,
`width:${(fw / trimW) * 100}%`,
`height:${(fh / trimH) * 100}%`,
'pointer-events:none',
'overflow:hidden',
'z-index:6',
].join(';');
canvas.appendChild(overlay);
const padding = Number(layer.shape?.padding) || 0;
// _paintFrameBlocks expects to write into an element sized
// to the FRAME's inches (it computes padPct from the frame
// dimensions). overlay is sized to the frame, so it fits.
_paintFrameBlocks(overlay, page, fw, fh, padding);
}
}
// J4 — paint one paginated page's blocks directly into a
// freeLayer wrapper (the rendered text frame's own element).
// Coordinates are relative to the frame's own bounding box, NOT