Skip to content

Luccas/sd 2838 unify nested tables rendering#3367

Open
luccas-harbour wants to merge 11 commits into
luccas/sd-2838-unify-drawing-block-renderingfrom
luccas/sd-2838-unify-nested-tables-rendering
Open

Luccas/sd 2838 unify nested tables rendering#3367
luccas-harbour wants to merge 11 commits into
luccas/sd-2838-unify-drawing-block-renderingfrom
luccas/sd-2838-unify-nested-tables-rendering

Conversation

@luccas-harbour
Copy link
Copy Markdown
Contributor

Summary

Continuation of the SD-2838 unification effort, focused on nested table rendering. The painter and the layout engine had grown two parallel implementations of cell-segment expansion, partial-row pricing, and table fragment height math — slightly out of sync, and both living inside large renderer.ts / layout-table.ts files. This PR collapses them onto a single source of truth in @superdoc/contracts and breaks the painter's table branch out into co-located modules.

Shared cell-slice + fragment-height helpers (contracts/)

  • New table-cell-slice.ts (moved from layout-engine/): owns getCellLines, getEmbeddedRowLines, describeCellRenderBlocks, createCellSliceCursor, computeFullCellContentHeight, and computeCellSliceContentHeight. Exposed via the contracts barrel and marked internal in JSDoc.
  • New table-fragment-height.ts: computeTableFragmentHeight() is the single formula for adding header rows + body rows (with partial-row substitution) + cell-spacing gutters + outer borders when border-collapse: separate.
  • layout-table.ts and the DOM painter both call into these helpers; the painter's even-split height approximation for embedded rows is gone — slice heights now come from the same recursive walk the layout engine uses.

DomPainter.renderFragment (table branch) decomposition

Carved out of renderer.ts into painters/dom/src/table/:

  • renderResolvedTableFragment.ts — the former renderTableFragment method plus its resolveTableRenderData helper. Takes renderLine, snapshot capture, frame application, and SDT helpers as injected deps.
  • fragmentKey.tstableFragmentKey() with the partial-row-aware cache key.
  • snapshot.tsgetTableSnapshotFlags() for the inTableFragment / inTableParagraph .closest() checks used during paint-snapshot capture.
  • embeddedTableFragment.tscreateEmbeddedTableFragment, mapEmbeddedTableRowSlice, computeRenderedTableFragmentHeight, and getEmbeddedTableSegmentCount, replacing the duplicated segment counters, visible-height loops, and partial-row computation inside renderTableCell.

Each new module has a co-located test. renderer.ts shrinks by ~150 lines and no longer carries table-specific helper closures.

Bug fixes uncovered along the way

  • fix(layout-engine): price embedded table slice height — partial embedded table slices now report their actual visible height instead of the full table height when computing whether they fit on the page.
  • fix(layout-engine): price partial embedded table slices — pricing now uses the shared cell-slice cursor so deeply nested partial rows are sized consistently with the splitter's decisions.
  • Removed a redundant table-cell-slice.ts shim in layout-engine/ now that contracts/ owns the implementation.

Tests

  • New unit tests in contracts/: table-cell-slice.test.ts (132 lines), table-fragment-height.test.ts (51 lines).
  • New painter tests: renderResolvedTableFragment.test.ts, embeddedTableFragment.test.ts, fragmentKey.test.ts, snapshot.test.ts.
  • Expanded renderTableCell.test.ts covers embedded-row slice mapping.
  • renderer-dispatch.test.ts updated for the new dispatch path.

…ntracts

Move getCellLines, getEmbeddedRowLines, describeCellRenderBlocks, and the
cell-slice cursor/height utilities into @superdoc/contracts so the DOM
painter and layout engine share a single source of truth for nested table
rendering. Replace the painter's duplicated segment counters and even-split
height approximations with calls into the shared module, and extract
embedded table fragment assembly into a dedicated embeddedTableFragment
helper.
Pull the table branch of DomPainter.renderFragment out of renderer.ts into
dedicated modules under painters/dom/src/table/:

- renderResolvedTableFragment: the former renderTableFragment method plus
  its resolveTableRenderData helper, taking renderLine, snapshot capture,
  frame application, and SDT helpers as dependencies
- fragmentKey: tableFragmentKey() with the partial-row-aware cache key
- snapshot: getTableSnapshotFlags() for the inTableFragment/inTableParagraph
  closest() checks used during paint-snapshot capture

Each extraction has a co-located test. DomPainter now dispatches table
fragments through renderResolvedTableFragment and delegates fragmentKey /
snapshot-flag work to the new helpers, shrinking renderer.ts by ~150 lines.
@luccas-harbour luccas-harbour requested a review from a team as a code owner May 18, 2026 17:46
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 18, 2026

SD-2838

@luccas-harbour luccas-harbour changed the base branch from main to luccas/sd-2838-unify-drawing-block-rendering May 18, 2026 17:50
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fa69af7b08

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@luccas-harbour
Copy link
Copy Markdown
Contributor Author

I deleted codex' comment as it related to the removal of rendering of list-item fragments, which was handled in another PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant