@@ -11,7 +11,7 @@ import {
1111 type OoxmlResolverParams ,
1212} from './index.js' ;
1313
14- const emptyStyles = { docDefaults : { } , latentStyles : { } , styles : { } } ;
14+ const emptyStyles = { docDefaults : { } , latentStyles : { } , styles : [ ] } ;
1515const emptyNumbering = { abstracts : { } , definitions : { } } ;
1616
1717const buildParams = ( overrides ?: Partial < OoxmlResolverParams > ) : OoxmlResolverParams => ( {
@@ -31,9 +31,7 @@ describe('ooxml - resolveStyleChain', () => {
3131 const params = buildParams ( {
3232 translatedLinkedStyles : {
3333 ...emptyStyles ,
34- styles : {
35- Heading1 : { runProperties : { fontSize : 32 , bold : true } } ,
36- } ,
34+ styles : [ { styleId : 'Heading1' , runProperties : { fontSize : 32 , bold : true } } ] ,
3735 } ,
3836 } ) ;
3937 const result = resolveStyleChain ( 'runProperties' , params , 'Heading1' ) ;
@@ -44,16 +42,34 @@ describe('ooxml - resolveStyleChain', () => {
4442 const params = buildParams ( {
4543 translatedLinkedStyles : {
4644 ...emptyStyles ,
47- styles : {
48- BaseStyle : { runProperties : { fontSize : 22 , italic : true } } ,
49- DerivedStyle : { basedOn : 'BaseStyle' , runProperties : { fontSize : 24 , bold : true } } ,
50- } ,
45+ styles : [
46+ { styleId : 'BaseStyle' , runProperties : { fontSize : 22 , italic : true } } ,
47+ { styleId : 'DerivedStyle' , basedOn : 'BaseStyle' , runProperties : { fontSize : 24 , bold : true } } ,
48+ ] ,
5149 } ,
5250 } ) ;
5351 const result = resolveStyleChain ( 'runProperties' , params , 'DerivedStyle' ) ;
5452 expect ( result ) . toEqual ( { fontSize : 24 , bold : true , italic : true } ) ;
5553 } ) ;
5654
55+ it ( 'refreshes cached lookups after in-place styles mutations' , ( ) => {
56+ const styles = [ { styleId : 'Heading1' , runProperties : { fontSize : 32 , bold : true } } ] ;
57+ const params = buildParams ( {
58+ translatedLinkedStyles : {
59+ ...emptyStyles ,
60+ styles,
61+ } ,
62+ } ) ;
63+
64+ expect ( resolveStyleChain ( 'runProperties' , params , 'Heading1' ) ) . toEqual ( { fontSize : 32 , bold : true } ) ;
65+
66+ styles . push ( { styleId : 'Heading2' , runProperties : { italic : true } } ) ;
67+ expect ( resolveStyleChain ( 'runProperties' , params , 'Heading2' ) ) . toEqual ( { italic : true } ) ;
68+
69+ styles [ 0 ] . styleId = 'Heading1Renamed' ;
70+ expect ( resolveStyleChain ( 'runProperties' , params , 'Heading1Renamed' ) ) . toEqual ( { fontSize : 32 , bold : true } ) ;
71+ } ) ;
72+
5773 it ( 'returns empty object when styleId is missing from definitions' , ( ) => {
5874 const params = buildParams ( ) ;
5975 const result = resolveStyleChain ( 'runProperties' , params , 'MissingStyle' ) ;
@@ -151,9 +167,7 @@ describe('ooxml - resolveRunProperties', () => {
151167 translatedLinkedStyles : {
152168 ...emptyStyles ,
153169 docDefaults : { runProperties : { fontSize : 20 } } ,
154- styles : {
155- Normal : { default : true , runProperties : { fontSize : 22 } } ,
156- } ,
170+ styles : [ { styleId : 'Normal' , default : true , runProperties : { fontSize : 22 } } ] ,
157171 } ,
158172 } ) ;
159173 const result = resolveRunProperties ( params , null , null ) ;
@@ -165,9 +179,7 @@ describe('ooxml - resolveRunProperties', () => {
165179 translatedLinkedStyles : {
166180 ...emptyStyles ,
167181 docDefaults : { runProperties : { fontSize : 20 , color : { val : 'AAAAAA' } } } ,
168- styles : {
169- Normal : { default : false , runProperties : { fontSize : 22 , color : { val : 'BBBBBB' } } } ,
170- } ,
182+ styles : [ { styleId : 'Normal' , default : false , runProperties : { fontSize : 22 , color : { val : 'BBBBBB' } } } ] ,
171183 } ,
172184 } ) ;
173185 const result = resolveRunProperties ( params , null , null ) ;
@@ -178,10 +190,10 @@ describe('ooxml - resolveRunProperties', () => {
178190 const params = buildParams ( {
179191 translatedLinkedStyles : {
180192 ...emptyStyles ,
181- styles : {
182- TOC1 : { runProperties : { bold : true } } ,
183- Emphasis : { runProperties : { italic : true } } ,
184- } ,
193+ styles : [
194+ { styleId : 'TOC1' , runProperties : { bold : true } } ,
195+ { styleId : 'Emphasis' , runProperties : { italic : true } } ,
196+ ] ,
185197 } ,
186198 } ) ;
187199 const result = resolveRunProperties ( params , { styleId : 'Emphasis' , color : { val : 'FF0000' } } , { styleId : 'TOC1' } ) ;
@@ -220,8 +232,9 @@ describe('ooxml - resolveRunProperties', () => {
220232 const params = buildParams ( {
221233 translatedLinkedStyles : {
222234 ...emptyStyles ,
223- styles : {
224- TableStyle1 : {
235+ styles : [
236+ {
237+ styleId : 'TableStyle1' ,
225238 type : 'table' ,
226239 runProperties : { color : { val : 'AAAAAA' } } ,
227240 tableProperties : { tableStyleRowBandSize : 1 , tableStyleColBandSize : 1 } ,
@@ -234,7 +247,7 @@ describe('ooxml - resolveRunProperties', () => {
234247 nwCell : { runProperties : { fontSize : 15 } } ,
235248 } ,
236249 } ,
237- } ,
250+ ] ,
238251 } ,
239252 } ) ;
240253 const tableInfo = {
@@ -278,9 +291,7 @@ describe('ooxml - resolveParagraphProperties', () => {
278291 translatedLinkedStyles : {
279292 ...emptyStyles ,
280293 docDefaults : { paragraphProperties : { spacing : { before : 240 } } } ,
281- styles : {
282- Normal : { default : true , paragraphProperties : { spacing : { after : 120 } } } ,
283- } ,
294+ styles : [ { styleId : 'Normal' , default : true , paragraphProperties : { spacing : { after : 120 } } } ] ,
284295 } ,
285296 } ) ;
286297 const inlineProps = { spacing : { before : 480 } } ;
@@ -292,9 +303,7 @@ describe('ooxml - resolveParagraphProperties', () => {
292303 const params = buildParams ( {
293304 translatedLinkedStyles : {
294305 ...emptyStyles ,
295- styles : {
296- ListStyle : { paragraphProperties : { indent : { left : 1200 } } } ,
297- } ,
306+ styles : [ { styleId : 'ListStyle' , paragraphProperties : { indent : { left : 1200 } } } ] ,
298307 } ,
299308 translatedNumbering : {
300309 definitions : { '1' : { abstractNumId : 10 } } ,
@@ -318,13 +327,14 @@ describe('ooxml - resolveParagraphProperties', () => {
318327 const params = buildParams ( {
319328 translatedLinkedStyles : {
320329 ...emptyStyles ,
321- styles : {
322- BaseStyle : { paragraphProperties : { indent : { left : 2000 } } } ,
323- NumberedStyle : {
330+ styles : [
331+ { styleId : 'BaseStyle' , paragraphProperties : { indent : { left : 2000 } } } ,
332+ {
333+ styleId : 'NumberedStyle' ,
324334 basedOn : 'BaseStyle' ,
325335 paragraphProperties : { numberingProperties : { numId : 1 , ilvl : 0 } } ,
326336 } ,
327- } ,
337+ ] ,
328338 } ,
329339 translatedNumbering : {
330340 definitions : { '1' : { abstractNumId : 10 } } ,
@@ -347,9 +357,7 @@ describe('ooxml - resolveParagraphProperties', () => {
347357 translatedLinkedStyles : {
348358 ...emptyStyles ,
349359 docDefaults : { paragraphProperties : { tabStops : [ { pos : 720 } ] } } ,
350- styles : {
351- Normal : { default : true , paragraphProperties : { tabStops : [ { pos : 1440 } ] } } ,
352- } ,
360+ styles : [ { styleId : 'Normal' , default : true , paragraphProperties : { tabStops : [ { pos : 1440 } ] } } ] ,
353361 } ,
354362 } ) ;
355363 const result = resolveParagraphProperties ( params , { tabStops : [ { pos : 2160 } ] } ) ;
@@ -360,16 +368,17 @@ describe('ooxml - resolveParagraphProperties', () => {
360368 const params = buildParams ( {
361369 translatedLinkedStyles : {
362370 ...emptyStyles ,
363- styles : {
364- TableStyle1 : {
371+ styles : [
372+ {
373+ styleId : 'TableStyle1' ,
365374 type : 'table' ,
366375 paragraphProperties : { spacing : { before : 120 , after : 120 } , keepNext : true } ,
367376 tableProperties : { tableStyleRowBandSize : 1 , tableStyleColBandSize : 1 } ,
368377 tableStyleProperties : {
369378 firstRow : { paragraphProperties : { spacing : { after : 240 } } } ,
370379 } ,
371380 } ,
372- } ,
381+ ] ,
373382 } ,
374383 } ) ;
375384 const tableInfo = {
@@ -390,8 +399,9 @@ describe('ooxml - resolveCellStyles', () => {
390399 const params = buildParams ( {
391400 translatedLinkedStyles : {
392401 ...emptyStyles ,
393- styles : {
394- TableStyleBand : {
402+ styles : [
403+ {
404+ styleId : 'TableStyleBand' ,
395405 type : 'table' ,
396406 tableProperties : { tableStyleRowBandSize : 2 , tableStyleColBandSize : 3 } ,
397407 tableStyleProperties : {
@@ -402,7 +412,7 @@ describe('ooxml - resolveCellStyles', () => {
402412 band2Horz : { runProperties : { fontSize : 50 } } ,
403413 } ,
404414 } ,
405- } ,
415+ ] ,
406416 } ,
407417 } ) ;
408418 const tableInfo = {
@@ -420,9 +430,10 @@ describe('ooxml - resolveCellStyles', () => {
420430describe ( 'ooxml - resolveTableCellProperties' , ( ) => {
421431 const gridTable4Styles = {
422432 ...emptyStyles ,
423- styles : {
424- 'GridTable4-Accent1' : {
425- type : 'table' ,
433+ styles : [
434+ {
435+ styleId : 'GridTable4-Accent1' ,
436+ type : 'table' as const ,
426437 tableProperties : { tableStyleRowBandSize : 1 , tableStyleColBandSize : 1 } ,
427438 tableStyleProperties : {
428439 firstRow : {
@@ -443,7 +454,7 @@ describe('ooxml - resolveTableCellProperties', () => {
443454 } ,
444455 } ,
445456 } ,
446- } ,
457+ ] ,
447458 } ;
448459
449460 it ( 'resolves firstRow shading from table style' , ( ) => {
@@ -473,7 +484,6 @@ describe('ooxml - resolveTableCellProperties', () => {
473484 numCells : 4 ,
474485 } ;
475486 const result = resolveTableCellProperties ( null , tableInfo , gridTable4Styles ) ;
476- // band1Horz overrides wholeTable
477487 expect ( result . shading ) . toEqual ( { val : 'clear' , color : 'auto' , fill : 'C1E4F5' } ) ;
478488 } ) ;
479489
@@ -539,7 +549,6 @@ describe('ooxml - resolveTableCellProperties', () => {
539549 } ;
540550 const inlineProps = { borders : { bottom : { val : 'double' , color : '000000' , size : 8 } } } ;
541551 const result = resolveTableCellProperties ( inlineProps , tableInfo , gridTable4Styles ) ;
542- // firstRow style provides top border, inline provides bottom border - both should be present
543552 expect ( result . borders ?. top ) . toEqual ( { val : 'single' , color : '156082' , size : 4 } ) ;
544553 expect ( result . borders ?. bottom ) . toEqual ( { val : 'double' , color : '000000' , size : 8 } ) ;
545554 } ) ;
0 commit comments