1
1
import {
2
+ Attribute ,
2
3
Block ,
3
4
Configuration as CSSBlocksConfiguration ,
4
5
Style ,
@@ -248,68 +249,59 @@ class HelperInvocationGenerator {
248
249
node . params = [ ] ;
249
250
node . hash = hash ( ) ;
250
251
node . params . push ( num ( HelperInvocationGenerator . HELPER_VERSION ) ) ;
251
- let { blocks, blockParams } = this . buildBlockParams ( sourceAnalysis ) ;
252
+
253
+ let stylesUsed = new Array < Style > ( ) ;
254
+ let blocksUsed = new Array < Block > ( ) ;
255
+ let staticParams = this . buildStaticParams ( sourceAnalysis , stylesUsed ) ;
256
+ let ternaryParams = this . buildTernaryParams ( sourceAnalysis , stylesUsed ) ;
257
+ let booleanParams = this . buildBooleanParams ( sourceAnalysis , stylesUsed ) ;
258
+ let switchParams = this . buildSwitchParams ( sourceAnalysis , blocksUsed ) ;
259
+ let styleParams = this . buildStyleParams ( sourceAnalysis , blocksUsed , stylesUsed ) ;
260
+ let blockParams = this . buildBlockParams ( blocksUsed ) ;
261
+
252
262
node . params . push ( ...blockParams ) ;
253
- let { styleIndices, styleParams } = this . buildStyleParams ( sourceAnalysis , blocks ) ;
254
263
node . params . push ( ...styleParams ) ;
255
- node . params . push ( ...this . buildStaticParams ( sourceAnalysis , styleIndices ) ) ;
256
- node . params . push ( ...this . buildTernaryParams ( sourceAnalysis , styleIndices ) ) ;
257
- node . params . push ( ...this . buildBooleanParams ( sourceAnalysis , styleIndices ) ) ;
258
- node . params . push ( ...this . buildSwitchParams ( sourceAnalysis , styleIndices ) ) ;
264
+ node . params . push ( ...staticParams ) ;
265
+ node . params . push ( ...ternaryParams ) ;
266
+ node . params . push ( ...booleanParams ) ;
267
+ node . params . push ( ...switchParams ) ;
259
268
return node ;
260
269
}
261
270
262
- indexOfBlock ( blocks : Array < Block > , style : Style ) {
263
- for ( let i = 0 ; i < blocks . length ; i ++ ) {
264
- if ( style . block === blocks [ i ] || style . block . isAncestorOf ( blocks [ i ] ) ) {
265
- return i ;
266
- }
267
- }
268
- throw new Error ( "[internal error] Block not found." ) ;
269
- }
270
-
271
- buildBlockParams ( sourceAnalysis : ElementSourceAnalysis ) : { blocks : Array < Block > ; blockParams : Array < AST . Expression > } {
271
+ buildBlockParams ( blocksUsed : Array < Block > ) : Array < AST . Expression > {
272
272
const { number : num , string : str , null : nullNode } = this . builders ;
273
- let blocks = [ ...sourceAnalysis . blocksFound ] ;
274
273
let blockParams = new Array < AST . Expression > ( ) ;
275
- blockParams . push ( num ( blocks . length ) ) ;
276
- for ( let block of blocks ) {
274
+ blockParams . push ( num ( blocksUsed . length ) ) ;
275
+ for ( let block of blocksUsed ) {
277
276
blockParams . push ( str ( block . guid ) ) ;
278
277
blockParams . push ( nullNode ( ) ) ; // this could be a block when we implement block passing
279
278
}
280
- return { blocks , blockParams} ;
279
+ return blockParams ;
281
280
}
282
281
283
- buildStyleParams ( sourceAnalysis : ElementSourceAnalysis , blocks : Array < Block > ) : { styleIndices : Map < Style , number > ; styleParams : Array < AST . Expression > } {
282
+ buildStyleParams ( sourceAnalysis : ElementSourceAnalysis , blocks : Array < Block > , stylesUsed : Array < Style > ) : Array < AST . Expression > {
284
283
const { number : num , string : str } = this . builders ;
285
- let styles = [ ...sourceAnalysis . stylesFound ] ;
286
284
let styleParams = new Array < AST . Expression > ( ) ;
287
- styleParams . push ( num ( styles . length ) ) ;
288
- let styleIndices = new Map < Style , number > ( ) ;
289
- let i = 0 ;
290
- for ( let style of styles ) {
291
- styleIndices . set ( style , i ++ ) ;
292
- styleParams . push ( num ( this . indexOfBlock ( blocks , style ) ) ) ;
285
+ styleParams . push ( num ( stylesUsed . length ) ) ;
286
+ for ( let style of stylesUsed ) {
287
+ styleParams . push ( num ( blockIndex ( blocks , style ) ) ) ;
293
288
styleParams . push ( str ( style . asSource ( ) ) ) ;
294
289
}
295
290
styleParams . push ( num ( sourceAnalysis . size ( ) ) ) ;
296
- return {
297
- styleIndices,
298
- styleParams,
299
- } ;
291
+ return styleParams ;
300
292
}
301
293
302
- buildStaticParams ( sourceAnalysis : ElementSourceAnalysis , styleIndices : Map < Style , number > ) : Array < AST . Expression > {
294
+ buildStaticParams ( sourceAnalysis : ElementSourceAnalysis , stylesUsed : Array < Style > ) : Array < AST . Expression > {
303
295
const { number : num } = this . builders ;
304
296
let params = new Array < AST . Expression > ( ) ;
305
297
for ( let style of sourceAnalysis . staticStyles ) {
306
298
params . push ( num ( StyleCondition . STATIC ) ) ;
307
- params . push ( num ( styleIndices . get ( style ) ! ) ) ;
299
+ params . push ( num ( styleIndex ( stylesUsed , style ) ) ) ;
308
300
}
309
301
return params ;
310
302
}
311
303
312
- buildTernaryParams ( sourceAnalysis : ElementSourceAnalysis , styleIndices : Map < Style , number > ) : Array < AST . Expression > {
304
+ buildTernaryParams ( sourceAnalysis : ElementSourceAnalysis , stylesUsed : Array < Style > ) : Array < AST . Expression > {
313
305
const { number : num } = this . builders ;
314
306
let params = new Array < AST . Expression > ( ) ;
315
307
for ( let ternaryClass of sourceAnalysis . ternaryStyles ) {
@@ -322,7 +314,7 @@ class HelperInvocationGenerator {
322
314
if ( isTrueCondition ( ternaryClass ) ) {
323
315
params . push ( num ( ternaryClass . whenTrue . length ) ) ;
324
316
for ( let cls of ternaryClass . whenTrue ) {
325
- params . push ( num ( styleIndices . get ( cls ) ! ) ) ;
317
+ params . push ( num ( styleIndex ( stylesUsed , cls ) ) ) ;
326
318
}
327
319
} else {
328
320
// there are no classes applied if true
@@ -331,7 +323,7 @@ class HelperInvocationGenerator {
331
323
if ( isFalseCondition ( ternaryClass ) ) {
332
324
params . push ( num ( ternaryClass . whenFalse . length ) ) ;
333
325
for ( let cls of ternaryClass . whenFalse ) {
334
- params . push ( num ( styleIndices . get ( cls ) ! ) ) ;
326
+ params . push ( num ( styleIndex ( stylesUsed , cls ) ) ) ;
335
327
}
336
328
} else {
337
329
// there are no classes applied if false
@@ -341,7 +333,7 @@ class HelperInvocationGenerator {
341
333
return params ;
342
334
}
343
335
344
- buildBooleanParams ( sourceAnalysis : ElementSourceAnalysis , styleIndices : Map < Style , number > ) : Array < AST . Expression > {
336
+ buildBooleanParams ( sourceAnalysis : ElementSourceAnalysis , stylesUsed : Array < Style > ) : Array < AST . Expression > {
345
337
const { number : num } = this . builders ;
346
338
let params = new Array < AST . Expression > ( ) ;
347
339
for ( let dynamicAttr of sourceAnalysis . booleanStyles ) {
@@ -353,13 +345,13 @@ class HelperInvocationGenerator {
353
345
}
354
346
params . push ( num ( dynamicAttr . value . size ) ) ;
355
347
for ( let attr of dynamicAttr . value ) {
356
- params . push ( num ( styleIndices . get ( attr ) ! ) ) ;
348
+ params . push ( num ( styleIndex ( stylesUsed , attr ) ) ) ;
357
349
}
358
350
}
359
351
return params ;
360
352
}
361
353
362
- buildSwitchParams ( sourceAnalysis : ElementSourceAnalysis , styleIndices : Map < Style , number > ) : Array < AST . Expression > {
354
+ buildSwitchParams ( sourceAnalysis : ElementSourceAnalysis , blocksUsed : Array < Block > ) : Array < AST . Expression > {
363
355
const { number : num , string : str } = this . builders ;
364
356
let params = new Array < AST . Expression > ( ) ;
365
357
@@ -371,24 +363,21 @@ class HelperInvocationGenerator {
371
363
} else {
372
364
params . push ( num ( FalsySwitchBehavior . unset ) ) ;
373
365
}
374
- params . push ( this . mustacheToStringExpression ( this . builders , switchStyle . stringExpression ! ) ) ;
375
- params . push ( num ( values . length ) ) ;
366
+ // We have to find the attribute that belongs to the most specific sub-block.
367
+ let attr : Attribute | undefined ;
376
368
for ( let value of values ) {
377
- let obj = switchStyle . group [ value ] ;
378
- params . push ( str ( value ) ) ;
379
- // If there are values provided for this conditional, they are meant to be
380
- // applied instead of the selected attribute group member.
381
- if ( switchStyle . value . size ) {
382
- params . push ( num ( switchStyle . value . size ) ) ;
383
- for ( let val of switchStyle . value ) {
384
- params . push ( num ( styleIndices . get ( val ) ! ) ) ;
369
+ let attrValue = switchStyle . group [ value ] ;
370
+ if ( ! attr ) {
371
+ attr = attrValue . attribute ;
372
+ } else {
373
+ if ( attr . block . isAncestorOf ( attrValue . block ) ) {
374
+ attr = attrValue . attribute ;
385
375
}
386
376
}
387
- else {
388
- params . push ( num ( 1 ) ) ;
389
- params . push ( num ( styleIndices . get ( obj ) ! ) ) ;
390
- }
391
377
}
378
+ params . push ( num ( blockIndex ( blocksUsed , attr ! ) ) ) ;
379
+ params . push ( str ( attr ! . asSource ( ) ) ) ;
380
+ params . push ( this . mustacheToStringExpression ( this . builders , switchStyle . stringExpression ! ) ) ;
392
381
}
393
382
return params ;
394
383
}
@@ -432,3 +421,23 @@ class HelperInvocationGenerator {
432
421
}
433
422
}
434
423
}
424
+
425
+ function styleIndex ( stylesUsed : Array < Style > , style : Style ) : number {
426
+ let index = stylesUsed . indexOf ( style ) ;
427
+ if ( index >= 0 ) { return index ; }
428
+ stylesUsed . push ( style ) ;
429
+ return stylesUsed . length - 1 ;
430
+ }
431
+
432
+ function blockIndex ( blocks : Array < Block > , style : Style | Attribute ) {
433
+ for ( let i = 0 ; i < blocks . length ; i ++ ) {
434
+ if ( style . block === blocks [ i ] || style . block . isAncestorOf ( blocks [ i ] ) ) {
435
+ return i ;
436
+ } else if ( blocks [ i ] . isAncestorOf ( style . block ) ) {
437
+ blocks [ i ] = style . block ;
438
+ return i ;
439
+ }
440
+ }
441
+ blocks . push ( style . block ) ;
442
+ return blocks . length - 1 ;
443
+ }
0 commit comments