@@ -10,7 +10,7 @@ import {
1010 type OoxmlResolverParams ,
1111} from './index.js' ;
1212
13- const emptyStyles = { docDefaults : { } , latentStyles : { } , styles : { } } ;
13+ const emptyStyles = { docDefaults : { } , latentStyles : { } , styles : [ ] } ;
1414const emptyNumbering = { abstracts : { } , definitions : { } } ;
1515
1616const buildParams = ( overrides ?: Partial < OoxmlResolverParams > ) : OoxmlResolverParams => ( {
@@ -30,9 +30,7 @@ describe('ooxml - resolveStyleChain', () => {
3030 const params = buildParams ( {
3131 translatedLinkedStyles : {
3232 ...emptyStyles ,
33- styles : {
34- Heading1 : { runProperties : { fontSize : 32 , bold : true } } ,
35- } ,
33+ styles : [ { styleId : 'Heading1' , runProperties : { fontSize : 32 , bold : true } } ] ,
3634 } ,
3735 } ) ;
3836 const result = resolveStyleChain ( 'runProperties' , params , 'Heading1' ) ;
@@ -43,16 +41,34 @@ describe('ooxml - resolveStyleChain', () => {
4341 const params = buildParams ( {
4442 translatedLinkedStyles : {
4543 ...emptyStyles ,
46- styles : {
47- BaseStyle : { runProperties : { fontSize : 22 , italic : true } } ,
48- DerivedStyle : { basedOn : 'BaseStyle' , runProperties : { fontSize : 24 , bold : true } } ,
49- } ,
44+ styles : [
45+ { styleId : 'BaseStyle' , runProperties : { fontSize : 22 , italic : true } } ,
46+ { styleId : 'DerivedStyle' , basedOn : 'BaseStyle' , runProperties : { fontSize : 24 , bold : true } } ,
47+ ] ,
5048 } ,
5149 } ) ;
5250 const result = resolveStyleChain ( 'runProperties' , params , 'DerivedStyle' ) ;
5351 expect ( result ) . toEqual ( { fontSize : 24 , bold : true , italic : true } ) ;
5452 } ) ;
5553
54+ it ( 'refreshes cached lookups after in-place styles mutations' , ( ) => {
55+ const styles = [ { styleId : 'Heading1' , runProperties : { fontSize : 32 , bold : true } } ] ;
56+ const params = buildParams ( {
57+ translatedLinkedStyles : {
58+ ...emptyStyles ,
59+ styles,
60+ } ,
61+ } ) ;
62+
63+ expect ( resolveStyleChain ( 'runProperties' , params , 'Heading1' ) ) . toEqual ( { fontSize : 32 , bold : true } ) ;
64+
65+ styles . push ( { styleId : 'Heading2' , runProperties : { italic : true } } ) ;
66+ expect ( resolveStyleChain ( 'runProperties' , params , 'Heading2' ) ) . toEqual ( { italic : true } ) ;
67+
68+ styles [ 0 ] . styleId = 'Heading1Renamed' ;
69+ expect ( resolveStyleChain ( 'runProperties' , params , 'Heading1Renamed' ) ) . toEqual ( { fontSize : 32 , bold : true } ) ;
70+ } ) ;
71+
5672 it ( 'returns empty object when styleId is missing from definitions' , ( ) => {
5773 const params = buildParams ( ) ;
5874 const result = resolveStyleChain ( 'runProperties' , params , 'MissingStyle' ) ;
@@ -150,9 +166,7 @@ describe('ooxml - resolveRunProperties', () => {
150166 translatedLinkedStyles : {
151167 ...emptyStyles ,
152168 docDefaults : { runProperties : { fontSize : 20 } } ,
153- styles : {
154- Normal : { default : true , runProperties : { fontSize : 22 } } ,
155- } ,
169+ styles : [ { styleId : 'Normal' , default : true , runProperties : { fontSize : 22 } } ] ,
156170 } ,
157171 } ) ;
158172 const result = resolveRunProperties ( params , null , null ) ;
@@ -164,9 +178,7 @@ describe('ooxml - resolveRunProperties', () => {
164178 translatedLinkedStyles : {
165179 ...emptyStyles ,
166180 docDefaults : { runProperties : { fontSize : 20 , color : { val : 'AAAAAA' } } } ,
167- styles : {
168- Normal : { default : false , runProperties : { fontSize : 22 , color : { val : 'BBBBBB' } } } ,
169- } ,
181+ styles : [ { styleId : 'Normal' , default : false , runProperties : { fontSize : 22 , color : { val : 'BBBBBB' } } } ] ,
170182 } ,
171183 } ) ;
172184 const result = resolveRunProperties ( params , null , null ) ;
@@ -177,10 +189,10 @@ describe('ooxml - resolveRunProperties', () => {
177189 const params = buildParams ( {
178190 translatedLinkedStyles : {
179191 ...emptyStyles ,
180- styles : {
181- TOC1 : { runProperties : { bold : true } } ,
182- Emphasis : { runProperties : { italic : true } } ,
183- } ,
192+ styles : [
193+ { styleId : 'TOC1' , runProperties : { bold : true } } ,
194+ { styleId : 'Emphasis' , runProperties : { italic : true } } ,
195+ ] ,
184196 } ,
185197 } ) ;
186198 const result = resolveRunProperties ( params , { styleId : 'Emphasis' , color : { val : 'FF0000' } } , { styleId : 'TOC1' } ) ;
@@ -219,8 +231,9 @@ describe('ooxml - resolveRunProperties', () => {
219231 const params = buildParams ( {
220232 translatedLinkedStyles : {
221233 ...emptyStyles ,
222- styles : {
223- TableStyle1 : {
234+ styles : [
235+ {
236+ styleId : 'TableStyle1' ,
224237 type : 'table' ,
225238 runProperties : { color : { val : 'AAAAAA' } } ,
226239 tableProperties : { tableStyleRowBandSize : 1 , tableStyleColBandSize : 1 } ,
@@ -233,7 +246,7 @@ describe('ooxml - resolveRunProperties', () => {
233246 nwCell : { runProperties : { fontSize : 15 } } ,
234247 } ,
235248 } ,
236- } ,
249+ ] ,
237250 } ,
238251 } ) ;
239252 const tableInfo = {
@@ -277,9 +290,7 @@ describe('ooxml - resolveParagraphProperties', () => {
277290 translatedLinkedStyles : {
278291 ...emptyStyles ,
279292 docDefaults : { paragraphProperties : { spacing : { before : 240 } } } ,
280- styles : {
281- Normal : { default : true , paragraphProperties : { spacing : { after : 120 } } } ,
282- } ,
293+ styles : [ { styleId : 'Normal' , default : true , paragraphProperties : { spacing : { after : 120 } } } ] ,
283294 } ,
284295 } ) ;
285296 const inlineProps = { spacing : { before : 480 } } ;
@@ -291,9 +302,7 @@ describe('ooxml - resolveParagraphProperties', () => {
291302 const params = buildParams ( {
292303 translatedLinkedStyles : {
293304 ...emptyStyles ,
294- styles : {
295- ListStyle : { paragraphProperties : { indent : { left : 1200 } } } ,
296- } ,
305+ styles : [ { styleId : 'ListStyle' , paragraphProperties : { indent : { left : 1200 } } } ] ,
297306 } ,
298307 translatedNumbering : {
299308 definitions : { '1' : { abstractNumId : 10 } } ,
@@ -317,13 +326,14 @@ describe('ooxml - resolveParagraphProperties', () => {
317326 const params = buildParams ( {
318327 translatedLinkedStyles : {
319328 ...emptyStyles ,
320- styles : {
321- BaseStyle : { paragraphProperties : { indent : { left : 2000 } } } ,
322- NumberedStyle : {
329+ styles : [
330+ { styleId : 'BaseStyle' , paragraphProperties : { indent : { left : 2000 } } } ,
331+ {
332+ styleId : 'NumberedStyle' ,
323333 basedOn : 'BaseStyle' ,
324334 paragraphProperties : { numberingProperties : { numId : 1 , ilvl : 0 } } ,
325335 } ,
326- } ,
336+ ] ,
327337 } ,
328338 translatedNumbering : {
329339 definitions : { '1' : { abstractNumId : 10 } } ,
@@ -346,9 +356,7 @@ describe('ooxml - resolveParagraphProperties', () => {
346356 translatedLinkedStyles : {
347357 ...emptyStyles ,
348358 docDefaults : { paragraphProperties : { tabStops : [ { pos : 720 } ] } } ,
349- styles : {
350- Normal : { default : true , paragraphProperties : { tabStops : [ { pos : 1440 } ] } } ,
351- } ,
359+ styles : [ { styleId : 'Normal' , default : true , paragraphProperties : { tabStops : [ { pos : 1440 } ] } } ] ,
352360 } ,
353361 } ) ;
354362 const result = resolveParagraphProperties ( params , { tabStops : [ { pos : 2160 } ] } ) ;
@@ -359,16 +367,17 @@ describe('ooxml - resolveParagraphProperties', () => {
359367 const params = buildParams ( {
360368 translatedLinkedStyles : {
361369 ...emptyStyles ,
362- styles : {
363- TableStyle1 : {
370+ styles : [
371+ {
372+ styleId : 'TableStyle1' ,
364373 type : 'table' ,
365374 paragraphProperties : { spacing : { before : 120 , after : 120 } , keepNext : true } ,
366375 tableProperties : { tableStyleRowBandSize : 1 , tableStyleColBandSize : 1 } ,
367376 tableStyleProperties : {
368377 firstRow : { paragraphProperties : { spacing : { after : 240 } } } ,
369378 } ,
370379 } ,
371- } ,
380+ ] ,
372381 } ,
373382 } ) ;
374383 const tableInfo = {
@@ -389,8 +398,9 @@ describe('ooxml - resolveCellStyles', () => {
389398 const params = buildParams ( {
390399 translatedLinkedStyles : {
391400 ...emptyStyles ,
392- styles : {
393- TableStyleBand : {
401+ styles : [
402+ {
403+ styleId : 'TableStyleBand' ,
394404 type : 'table' ,
395405 tableProperties : { tableStyleRowBandSize : 2 , tableStyleColBandSize : 3 } ,
396406 tableStyleProperties : {
@@ -401,7 +411,7 @@ describe('ooxml - resolveCellStyles', () => {
401411 band2Horz : { runProperties : { fontSize : 50 } } ,
402412 } ,
403413 } ,
404- } ,
414+ ] ,
405415 } ,
406416 } ) ;
407417 const tableInfo = {
@@ -419,9 +429,10 @@ describe('ooxml - resolveCellStyles', () => {
419429describe ( 'ooxml - resolveTableCellProperties' , ( ) => {
420430 const gridTable4Styles = {
421431 ...emptyStyles ,
422- styles : {
423- 'GridTable4-Accent1' : {
424- type : 'table' ,
432+ styles : [
433+ {
434+ styleId : 'GridTable4-Accent1' ,
435+ type : 'table' as const ,
425436 tableProperties : { tableStyleRowBandSize : 1 , tableStyleColBandSize : 1 } ,
426437 tableStyleProperties : {
427438 firstRow : {
@@ -442,7 +453,7 @@ describe('ooxml - resolveTableCellProperties', () => {
442453 } ,
443454 } ,
444455 } ,
445- } ,
456+ ] ,
446457 } ;
447458
448459 it ( 'resolves firstRow shading from table style' , ( ) => {
@@ -472,7 +483,6 @@ describe('ooxml - resolveTableCellProperties', () => {
472483 numCells : 4 ,
473484 } ;
474485 const result = resolveTableCellProperties ( null , tableInfo , gridTable4Styles ) ;
475- // band1Horz overrides wholeTable
476486 expect ( result . shading ) . toEqual ( { val : 'clear' , color : 'auto' , fill : 'C1E4F5' } ) ;
477487 } ) ;
478488
@@ -538,7 +548,6 @@ describe('ooxml - resolveTableCellProperties', () => {
538548 } ;
539549 const inlineProps = { borders : { bottom : { val : 'double' , color : '000000' , size : 8 } } } ;
540550 const result = resolveTableCellProperties ( inlineProps , tableInfo , gridTable4Styles ) ;
541- // firstRow style provides top border, inline provides bottom border - both should be present
542551 expect ( result . borders ?. top ) . toEqual ( { val : 'single' , color : '156082' , size : 4 } ) ;
543552 expect ( result . borders ?. bottom ) . toEqual ( { val : 'double' , color : '000000' , size : 8 } ) ;
544553 } ) ;
0 commit comments