From 9d8be7e0fe8e611014470263b5bed0c35378c4a2 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Thu, 4 Jun 2026 20:33:26 -0400 Subject: [PATCH] =?UTF-8?q?feat(book):=20J4.c.1=20=E2=80=94=20threaded=20t?= =?UTF-8?q?ext=20shows=20in=20Pages=20overview=20tile=20thumbnails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/index.html | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/index.html b/src/index.html index 1f321ba..9c4fef7 100644 --- a/src/index.html +++ b/src/index.html @@ -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