@@ -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