refactor(painters/dom): unify drawing block rendering (SD-2838)#3334
Open
luccas-harbour wants to merge 119 commits into
Open
refactor(painters/dom): unify drawing block rendering (SD-2838)#3334luccas-harbour wants to merge 119 commits into
luccas-harbour wants to merge 119 commits into
Conversation
tupizz
reviewed
May 21, 2026
| @@ -570,7 +571,7 @@ type TableCellRenderDependencies = { | |||
| * The returned element will have width: 100% and height: 100% styles applied automatically. | |||
| * If undefined, a placeholder element with diagonal stripes pattern is rendered instead. | |||
Contributor
There was a problem hiding this comment.
This comment says the optional renderDrawingContent callback is for “vectorShapes and shapeGroups” and that if it is undefined, a placeholder is rendered. But image drawings can now go through that callback too and if the callback is undefined, the shared drawing renderer is used, not just a placeholder
Contributor
Author
There was a problem hiding this comment.
This was pointing at the same issue as Tadeu's comment. It's fixed now.
939ad72 to
fa548e5
Compare
0e2b687 to
a6958e5
Compare
fa548e5 to
191a5c0
Compare
a6958e5 to
7c9eedf
Compare
VladaHarbour
approved these changes
May 22, 2026
List rendering is now unified through the paragraph fragment path, so the list-item-specific renderer and its supporting helpers are no longer reachable. Removes: - `renderListItemFragment` and `applyResolvedListItemWrapperFrame` from `renderer.ts`, along with the `LIST_MARKER_GAP` constant and the `stripListIndent` helper. - list-item branches from `fragmentKey`, `deriveBlockVersion`, and the fragment-frame dispatch (now treats `list-item` as unsupported). - list-item handling in `computeBetweenBorderFlags` (border grouping now only pairs `para` fragments). - list-item fixtures and assertions from `between-borders.test.ts`, `renderer-dispatch.test.ts`, and `index.test.ts`. - the now-stale `renderer-known-divergences.test.ts`.
…le cells Extract the paragraph-rendering pipeline (block styles, decoration layers, list markers, indentation, line walking, drop caps) into a shared paragraph/renderParagraphContent module consumed by both the body-fragment path in renderer.ts and the table-cell path in renderTableCell.ts. The two sites had drifted into parallel ~500-line implementations; collapsing them removes ~1k lines net and gives both paths the same marker/indent/border behavior. Borders and shading now live on dedicated .superdoc-paragraph-border / .superdoc-paragraph-shading layers (already used by the body path) instead of being stamped onto the cell-paragraph wrapper, so renderTableCell tests were updated to assert against those layers.
Move `features/paragraph-borders/` to `paragraph/borders/` and fold `utils/marker-helpers.ts` into `paragraph/list-marker.ts` so all paragraph rendering pieces live under `paragraph/`. Update the feature registry and imports to match.
Pull line- and run-level rendering out of renderer.ts (~2500 lines) into a dedicated runs/ directory split by concern: text, image, math, tab, field annotation, links, SDT, tracked changes, formatting marks, and the top-level render-line/render-run orchestrators. Run hash helpers move from paragraph-hash-utils.ts to runs/hash.ts. Public re-exports (RenderedLineInfo, sanitizeUrl, linkMetrics, applyRunDataAttributes) now resolve through runs/index.ts. No behavior change — pure colocation of the run pipeline ahead of unifying body and table-cell paragraph rendering.
…dded table slices When an embedded table is split across page breaks, adjacent row slices within the same outer cell now account for the table's cellSpacingPx gap. Both the slice positions (sliceTop) and the visible-height total include the inter-slice spacing, mirroring how full table fragments are laid out, so partial-slice rendering no longer collapses the gap.
Extract the list rendering pipeline from numberingPlugin into a shared createListRenderingSync factory, and apply it in FootnotesBuilder so footnote paragraphs with numberingProperties get markerText, path, suffix, and justification populated before reaching toFlowBlocks. Previously only the main document body computed list markers, so numbered/bulleted footnotes rendered without markers. The helper is PM-agnostic (visitor + paragraph-property resolver) so the same code serves the editor plugin and the footnote builder.
…n flag Add a `resolveListRendering` option to `toFlowBlocks` that builds a numbering manager from `translatedNumbering` and lazily computes paragraph list marker metadata during PM JSON → FlowBlock conversion. The resolution flows through `computeParagraphAttrs` and the node handler context, so callers no longer have to pre-mutate node attrs with a `listRendering` field. FootnotesBuilder switches to the new flag and drops its local `applyFootnoteListRendering` helper, which traversed the footnote doc and mutated `attrs.listRendering` before handing it to the adapter. The new resolver runs against the original PM JSON without mutating it.
191a5c0 to
dabfe32
Compare
7c9eedf to
7c46785
Compare
refactor(painter-dom): consolidate rendering helpers and harden table edge cases (SD-2838)
…ox-shape-rendering refactor(painters/dom): unify textbox shape rendering (SD-2838)
…otes-endnotes-rendering refactor(painter-dom): unify footnote/endnote story detection (SD-2838)
…d-tables-rendering refactor: unify nested tables rendering (SD-2838)
Base automatically changed from
luccas/sd-2838-unify-image-block-rendering
to
luccas/sd-2838-unify-sdt-rendering
May 26, 2026 18:13
Base automatically changed from
luccas/sd-2838-unify-sdt-rendering
to
luccas/sd-2838-unify-paragraph-rendering
May 26, 2026 18:14
Base automatically changed from
luccas/sd-2838-unify-paragraph-rendering
to
luccas/sd-2851-remove-list-item-code-from-painter
May 26, 2026 18:14
Base automatically changed from
luccas/sd-2851-remove-list-item-code-from-painter
to
main
May 26, 2026 22:50
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Builds on the image-block unification (parent branch
luccas/sd-2838-unify-image-block-rendering) by collapsing the remaining drawing-rendering duplication betweenDomPainterandrenderTableCellonto a single implementation. Non-image drawings (vector shapes, shape groups, charts, shape text) now render through the same code path in body content and table cells, and the table-cell drawing wrapper is no longer reinvented for in-flow vs. anchored cases.What changed
New modules in
painters/dom/src/drawings/:renderDrawingContent.ts— extracts ~890 lines of vector-shape / chart / shape-group / shape-text rendering (preset + custom geometry, gradient/alpha fills, line ends, fallback styles, shape text layout) out ofDomPainterinto a pure function. Acceptsdoc,block, optionalgeometry, optionalclipContainer, and abuildImageHyperlinkAnchorcallback — no painter coupling.renderDrawingFragment.ts— movesrenderDrawingFragmentandisHeaderWordArtWatermarkout ofDomPainter; the painter now passes its frame/anchor helpers (applyResolvedFragmentFrame,applyFragmentFrame,applyFragmentWrapperZIndex,createErrorPlaceholder) in as parameters.tableDrawingFrame.ts— single helper that builds the table-cell drawing wrapper for bothposition: relative(in-flow) andposition: absolute(anchored) drawings, deduplicating the wrapper/inner/SDT-dataset scaffolding that previously existed twice inrenderTableCell.placeholder.ts— small shared factory for the diagonal-stripe drawing placeholder.renderer.tsshrinks by ~1000 lines. Drawing-related private methods (renderDrawingFragment,renderDrawingContent,createVectorShapeElement,createShapeGroupElement,createChartElement,createDrawingPlaceholder,isHeaderWordArtWatermark, plus their effect-extent / SVG / transform helpers) all delegate to the new modules. SVG/WordArt constants and local types (LineEnd,EffectExtent,VectorShapeDrawingWithEffects) move with them.renderTableCell.tsis slimmed by ~95 lines:renderTableDrawingFrameinstead of building the wrapper inline.renderDrawingContentcallback signature gains an optional{ clipContainer }so image clipping can flow through the shared path.renderDrawingContentdirectly withbuildSharedImageHyperlinkAnchor— non-image drawings in tables no longer disappear.images/drawing-image.ts—createDrawingImageElementaccepts an optionalclipContainerforwarded tocreateBlockImageContent, so the shared renderer can pipe the table cell's inner wrapper through for image clipping.Tests
renderDrawingContent.test.tscovers vector shapes, shape groups, charts, fallback placeholders, and image hyperlink/clip-container behavior through the shared path.renderTableCell.test.tsgains ~260 lines of new coverage: image drawings rendering through the shared renderer, placeholder for image without source, callback override behavior, fallback to the shared renderer when no callback is supplied, clip-container threading, and SDT metadata sourced fromattrs.sdt.