Skip to content

Commit 04aae44

Browse files
authored
[7/16] refactor(painter): extract block/measure resolution helper (#2819)
* refactor(layout): lift page metadata into ResolvedPage * refactor(layout): lift fragment metadata into resolved paint items Add pmStart, pmEnd, continuesFromPrev, continuesOnNext, markerWidth, and metadata fields to resolved paint item types. Populate them in the resolvers and update the painter to prefer resolved item data over legacy Fragment reads with fallbacks. * refactor(layout): pre-compute SDT container keys in resolved layout * refactor(layout): pre-compute paragraph border data in resolved layout * refactor(layout): move change detection into resolved layout stage * refactor(layout): lift paragraph and list-item block/measure into resolved items * refactor(painter): extract block/measure resolution helper
1 parent 94d47f1 commit 04aae44

1 file changed

Lines changed: 69 additions & 54 deletions

File tree

packages/layout-engine/painters/dom/src/renderer.ts

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3058,22 +3058,16 @@ export class DomPainter {
30583058
throw new Error('DomPainter: document is not available');
30593059
}
30603060

3061-
// Prefer pre-extracted block/measure from the resolved item; fall back to blockLookup.
3062-
let block: ParagraphBlock;
3063-
let measure: ParagraphMeasure;
3064-
const resolvedBlock = resolvedItem?.block;
3065-
const resolvedMeasure = resolvedItem?.measure;
3066-
if (resolvedBlock?.kind === 'paragraph' && resolvedMeasure?.kind === 'paragraph') {
3067-
block = resolvedBlock as ParagraphBlock;
3068-
measure = resolvedMeasure as ParagraphMeasure;
3069-
} else {
3070-
const lookup = this.blockLookup.get(fragment.blockId);
3071-
if (!lookup || lookup.block.kind !== 'paragraph' || lookup.measure.kind !== 'paragraph') {
3072-
throw new Error(`DomPainter: missing block/measure for fragment ${fragment.blockId}`);
3073-
}
3074-
block = lookup.block as ParagraphBlock;
3075-
measure = lookup.measure as ParagraphMeasure;
3076-
}
3061+
// Prefer pre-extracted block/measure from the resolved item; fall back to blockLookup
3062+
// for header/footer fragments that don't have a resolved item.
3063+
const { block, measure } = this.resolveBlockAndMeasure<ParagraphBlock, ParagraphMeasure>(
3064+
fragment,
3065+
resolvedItem?.block,
3066+
resolvedItem?.measure,
3067+
'paragraph',
3068+
'paragraph',
3069+
'paragraph block/measure',
3070+
);
30773071
const wordLayout = isMinimalWordLayout(block.attrs?.wordLayout) ? block.attrs.wordLayout : undefined;
30783072
const content = resolvedItem?.content;
30793073

@@ -3609,22 +3603,16 @@ export class DomPainter {
36093603
throw new Error('DomPainter: document is not available');
36103604
}
36113605

3612-
// Prefer pre-extracted block/measure from the resolved item; fall back to blockLookup.
3613-
let block: ListBlock;
3614-
let measure: ListMeasure;
3615-
const resolvedBlock = resolvedItem?.block;
3616-
const resolvedMeasure = resolvedItem?.measure;
3617-
if (resolvedBlock?.kind === 'list' && resolvedMeasure?.kind === 'list') {
3618-
block = resolvedBlock as ListBlock;
3619-
measure = resolvedMeasure as ListMeasure;
3620-
} else {
3621-
const lookup = this.blockLookup.get(fragment.blockId);
3622-
if (!lookup || lookup.block.kind !== 'list' || lookup.measure.kind !== 'list') {
3623-
throw new Error(`DomPainter: missing list data for fragment ${fragment.blockId}`);
3624-
}
3625-
block = lookup.block as ListBlock;
3626-
measure = lookup.measure as ListMeasure;
3627-
}
3606+
// Prefer pre-extracted block/measure from the resolved item; fall back to blockLookup
3607+
// for header/footer fragments that don't have a resolved item.
3608+
const { block, measure } = this.resolveBlockAndMeasure<ListBlock, ListMeasure>(
3609+
fragment,
3610+
resolvedItem?.block,
3611+
resolvedItem?.measure,
3612+
'list',
3613+
'list',
3614+
'list block/measure',
3615+
);
36283616
const item = block.items.find((entry) => entry.id === fragment.itemId);
36293617
const itemMeasure = measure.items.find((entry) => entry.itemId === fragment.itemId);
36303618
if (!item || !itemMeasure) {
@@ -3759,17 +3747,9 @@ export class DomPainter {
37593747
resolvedItem?: ResolvedImageItem,
37603748
): HTMLElement {
37613749
try {
3762-
// Use pre-extracted block from resolved item; fall back to blockLookup when resolved item
3763-
// is a legacy ResolvedFragmentItem without the block field.
3764-
const block: ImageBlock =
3765-
resolvedItem?.block ??
3766-
(() => {
3767-
const lookup = this.blockLookup.get(fragment.blockId);
3768-
if (!lookup || lookup.block.kind !== 'image' || lookup.measure.kind !== 'image') {
3769-
throw new Error(`DomPainter: missing image block for fragment ${fragment.blockId}`);
3770-
}
3771-
return lookup.block as ImageBlock;
3772-
})();
3750+
// Prefer pre-extracted block from the resolved item; fall back to blockLookup
3751+
// for header/footer fragments that don't have a resolved item.
3752+
const block = this.resolveBlock<ImageBlock>(fragment, resolvedItem?.block, 'image', 'image block');
37733753

37743754
if (!this.doc) {
37753755
throw new Error('DomPainter: document is not available');
@@ -3967,17 +3947,9 @@ export class DomPainter {
39673947
resolvedItem?: ResolvedDrawingItem,
39683948
): HTMLElement {
39693949
try {
3970-
// Use pre-extracted block from resolved item; fall back to blockLookup when resolved item
3971-
// is a legacy ResolvedFragmentItem without the block field.
3972-
const block: DrawingBlock =
3973-
resolvedItem?.block ??
3974-
(() => {
3975-
const lookup = this.blockLookup.get(fragment.blockId);
3976-
if (!lookup || lookup.block.kind !== 'drawing' || lookup.measure.kind !== 'drawing') {
3977-
throw new Error(`DomPainter: missing drawing block for fragment ${fragment.blockId}`);
3978-
}
3979-
return lookup.block as DrawingBlock;
3980-
})();
3950+
// Prefer pre-extracted block from the resolved item; fall back to blockLookup
3951+
// for header/footer fragments that don't have a resolved item.
3952+
const block = this.resolveBlock<DrawingBlock>(fragment, resolvedItem?.block, 'drawing', 'drawing block');
39813953
if (!this.doc) {
39823954
throw new Error('DomPainter: document is not available');
39833955
}
@@ -7075,6 +7047,49 @@ export class DomPainter {
70757047
return 0;
70767048
}
70777049

7050+
/**
7051+
* Resolves the block + measure pair for a fragment. Body fragments get these from the
7052+
* ResolvedFragmentItem; header/footer fragments fall back to the blockLookup map.
7053+
*/
7054+
private resolveBlockAndMeasure<B extends FlowBlock, M extends Measure>(
7055+
fragment: { blockId: string },
7056+
resolvedBlock: FlowBlock | undefined,
7057+
resolvedMeasure: Measure | undefined,
7058+
blockKind: B['kind'],
7059+
measureKind: M['kind'],
7060+
errorLabel: string,
7061+
): { block: B; measure: M } {
7062+
if (resolvedBlock?.kind === blockKind && resolvedMeasure?.kind === measureKind) {
7063+
return { block: resolvedBlock as B, measure: resolvedMeasure as M };
7064+
}
7065+
const lookup = this.blockLookup.get(fragment.blockId);
7066+
if (!lookup || lookup.block.kind !== blockKind || lookup.measure.kind !== measureKind) {
7067+
throw new Error(`DomPainter: missing ${errorLabel} for fragment ${fragment.blockId}`);
7068+
}
7069+
return { block: lookup.block as B, measure: lookup.measure as M };
7070+
}
7071+
7072+
/**
7073+
* Resolves only the block for a fragment (image/drawing rendering doesn't consume the measure).
7074+
* Body fragments get this from the ResolvedImageItem/ResolvedDrawingItem; header/footer
7075+
* fragments fall back to the blockLookup map.
7076+
*/
7077+
private resolveBlock<B extends FlowBlock>(
7078+
fragment: { blockId: string },
7079+
resolvedBlock: B | undefined,
7080+
blockKind: B['kind'],
7081+
errorLabel: string,
7082+
): B {
7083+
if (resolvedBlock?.kind === blockKind) {
7084+
return resolvedBlock;
7085+
}
7086+
const lookup = this.blockLookup.get(fragment.blockId);
7087+
if (!lookup || lookup.block.kind !== blockKind) {
7088+
throw new Error(`DomPainter: missing ${errorLabel} for fragment ${fragment.blockId}`);
7089+
}
7090+
return lookup.block as B;
7091+
}
7092+
70787093
private buildBlockLookup(
70797094
blocks: FlowBlock[],
70807095
measures: Measure[],

0 commit comments

Comments
 (0)