Skip to content

refactor(painter): remove legacy createDomPainter wrapper API#2853

Open
tupizz wants to merge 1 commit intotadeu/sd-2563-13-testing-cleanupfrom
tadeu/sd-2563-14-remove-legacy-wrapper
Open

refactor(painter): remove legacy createDomPainter wrapper API#2853
tupizz wants to merge 1 commit intotadeu/sd-2563-13-testing-cleanupfrom
tadeu/sd-2563-14-remove-legacy-wrapper

Conversation

@tupizz
Copy link
Copy Markdown
Contributor

@tupizz tupizz commented Apr 16, 2026

Summary

Closes SD-2563's remaining criterion: "Painter does not carry fallback or mixed-path logic that belongs in other stages."

The painter shipped a backward-compat API layer that existed only to smooth the migration to DomPainterInput. All known consumers now use the modern contract directly.

What's deleted from createDomPainter wrapper

  • blocks? and measures? fields on DomPainterOptions
  • setData(blocks, measures) method on DomPainterHandle
  • setResolvedLayout(resolvedLayout) method on DomPainterHandle
  • paint(input: DomPainterInput | Layout) union overload → paint(input: DomPainterInput) only
  • Internal helpers: LegacyDomPainterState, buildLegacyPaintInput, createEmptyResolvedLayout, isDomPainterInput, assertRequiredBlockMeasurePair

Net: -101 lines in index.ts.

What changed

  • index.ts — deleted all legacy paths. Painter wrapper is now a thin pass-through.
  • layout-bridge/benchmarks/index.ts — migrated to the modern API. Calls resolveLayout explicitly, passes {resolvedLayout, sourceLayout} to paint().
  • Test helper unified — extracted createTestPainter into packages/layout-engine/painters/dom/src/test-utils/test-painter.ts and switched 13 painter-dom test files to use it. Previously each file had inline or duplicated versions.

Testing rationale (applied /testing-excellence)

The previous tests violated Iron Law #2 ("never add methods to production only because a test needs it"): setData, setResolvedLayout, and the paint(Layout) overload existed in production largely to serve test ergonomics. Moving the legacy-shape translation into a shared test helper puts the responsibility in the test layer where it belongs — production code now exposes only its actual contract.

Verification

  • painter-dom build + 952/952 tests
  • layout-resolved 103/103 tests
  • layout-bridge 1162/1162 tests (benchmark compiles + runs)
  • super-editor build + 11350/11361 tests
  • pnpm layout:compare --input-root test-corpus → 0 changed / 407 unchanged (byte-identical rendering)

PR Stack (SD-2563: Dumb Painter Refactor)

# PR Title Status
1 #2810 Lift page metadata into ResolvedPage
2 #2811 Lift fragment metadata into resolved paint items
3 #2812 Pre-compute SDT container keys in resolved layout
4 #2813 Pre-compute paragraph border data in resolved layout
5 #2814 Move change detection into resolved layout stage
6 #2818 Lift paragraph/list block and measure into resolved items
7 #2819 Extract block/measure resolution helper
8 #2820 Remove body blocks/measures from DomPainterInput
9 #2826 Add resolveHeaderFooterLayout helper
10 #2827 Deliver resolved items to decoration provider callback
11 #2828 Remove blockLookup — painter reads only resolved data
12 #2829 Delete dead hash helpers after blockLookup removal
13 #2845 Testing cleanup + alignment tests
14 #2853 Remove legacy createDomPainter wrapper API 👈 this PR

The painter previously shipped a backward-compat API layer (setData,
setResolvedLayout, paint(Layout) overload, blocks/measures constructor
options, LegacyDomPainterState, buildLegacyPaintInput). This mixed-path
logic existed only to smooth the migration to DomPainterInput.

All production callers now use the modern contract directly. The
benchmark is updated to call resolveLayout explicitly. Test call sites
that still expressed fixtures as {blocks, measures} + raw Layout now
route through a shared createTestPainter helper in
painters/dom/src/test-utils/test-painter.ts, which wraps createDomPainter
and runs resolveLayout internally.

DomPainterOptions: blocks?/measures? removed
DomPainterHandle: setData/setResolvedLayout removed, paint() takes only DomPainterInput
Internal: LegacyDomPainterState, buildLegacyPaintInput, createEmptyResolvedLayout,
isDomPainterInput, assertRequiredBlockMeasurePair all deleted.

Closes SD-2563 criterion: painter does not carry mixed-path logic.
No rendering change (layout-compare 0/407 changed).
@linear
Copy link
Copy Markdown

linear bot commented Apr 16, 2026

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: 0277744abc

ℹ️ 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".

Comment on lines +127 to +128
paint(input: DomPainterInput, mount: HTMLElement, mapping?: PositionMapping) {
painter.paint(input, mount, mapping);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep legacy paint callers from crashing at runtime

This change forwards paint() input straight into DomPainter.paint without normalizing raw Layout inputs, but there are still in-repo legacy call sites that pass Layout directly (for example packages/layout-engine/pm-adapter/src/integration.test.ts still does createDomPainter({ blocks, measures }) + paint(layout, mount)). In that scenario DomPainter.paint reads input.sourceLayout, so a raw Layout makes layout undefined and throws at runtime; please migrate remaining callers in the same commit (or add an explicit runtime guard/error) to avoid this break.

Useful? React with 👍 / 👎.

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