11import { isIdentStart , isWhiteSpace , isIdent , isFunction } from '../parser/utils/syntax.js' ;
22import { PropertyList } from '../parser/declaration/list.js' ;
33import { eq } from '../parser/utils/eq.js' ;
4- import { render } from '../renderer/render.js' ;
5- import '../renderer/utils/color.js' ;
4+ import { render , renderToken } from '../renderer/render.js' ;
5+ import { parseString } from '../parser/parse.js' ;
6+ import { replaceCompound } from './expand.js' ;
7+ import { walkValues } from './walk.js' ;
68
79const combinators = [ '+' , '>' , '~' ] ;
810const notEndingWith = [ '(' , '[' ] . concat ( combinators ) ;
911const definedPropertySettings = { configurable : true , enumerable : false , writable : true } ;
10- function minify ( ast , options = { } , recursive = false , errors ) {
12+ function minify ( ast , options = { } , recursive = false , errors , nestingContent ) {
1113 function wrapNodes ( previous , node , match , ast , i , nodeIndex ) {
1214 // @ts -ignore
1315 let pSel = match . selector1 . reduce ( reducer , [ ] ) . join ( ',' ) ;
@@ -296,8 +298,28 @@ function minify(ast, options = {}, recursive = false, errors) {
296298 selector2
297299 } ;
298300 }
301+ function fixSelector ( node ) {
302+ // @ts -ignore
303+ if ( node . sel . includes ( '&' ) ) {
304+ const attributes = parseString ( node . sel ) ;
305+ for ( const attr of walkValues ( attributes ) ) {
306+ if ( attr . value . typ == 'Pseudo-class-func' && attr . value . val == ':is' ) {
307+ let i = attr . value . chi . length ;
308+ while ( i -- ) {
309+ if ( attr . value . chi [ i ] . typ == 'Literal' && attr . value . chi [ i ] . val == '&' ) {
310+ attr . value . chi . splice ( i , 1 ) ;
311+ }
312+ }
313+ }
314+ }
315+ node . sel = attributes . reduce ( ( acc , curr ) => acc + renderToken ( curr ) , '' ) ;
316+ }
317+ }
299318 // @ts -ignore
300319 if ( ( 'chi' in ast ) && ast . chi ?. length > 0 ) {
320+ if ( ! nestingContent ) {
321+ nestingContent = options . nestingRules && ast . typ == 'Rule' ;
322+ }
301323 let i = 0 ;
302324 let previous ;
303325 let node ;
@@ -312,7 +334,6 @@ function minify(ast, options = {}, recursive = false, errors) {
312334 node = ast . chi [ i ] ;
313335 // @ts -ignore
314336 if ( previous == node ) {
315- // console.error('idem!');
316337 // @ts -ignore
317338 ast . chi . splice ( i , 1 ) ;
318339 i -- ;
@@ -328,7 +349,6 @@ function minify(ast, options = {}, recursive = false, errors) {
328349 i -- ;
329350 continue ;
330351 }
331- // console.debug({previous, node});
332352 // @ts -ignore
333353 if ( previous ?. typ == 'AtRule' &&
334354 previous . nam == node . nam &&
@@ -348,7 +368,7 @@ function minify(ast, options = {}, recursive = false, errors) {
348368 minifyRule ( node ) ;
349369 }
350370 else {
351- minify ( node , options , recursive , errors ) ;
371+ minify ( node , options , recursive , errors , nestingContent ) ;
352372 }
353373 previous = node ;
354374 nodeIndex = i ;
@@ -402,7 +422,7 @@ function minify(ast, options = {}, recursive = false, errors) {
402422 nodeIndex = -- i ;
403423 // @ts -ignore
404424 previous = ast . chi [ nodeIndex ] ;
405- minify ( wrapper , options , recursive , errors ) ;
425+ minify ( wrapper , options , recursive , errors , nestingContent ) ;
406426 continue ;
407427 }
408428 // @ts -ignore
@@ -435,7 +455,7 @@ function minify(ast, options = {}, recursive = false, errors) {
435455 let wrap = true ;
436456 // @ts -ignore
437457 const selector = node . optimized . selector . reduce ( ( acc , curr ) => {
438- if ( curr [ 0 ] == '&' ) {
458+ if ( curr [ 0 ] == '&' && curr . length > 1 ) {
439459 if ( curr [ 1 ] == ' ' ) {
440460 curr . splice ( 0 , 2 ) ;
441461 }
@@ -459,15 +479,22 @@ function minify(ast, options = {}, recursive = false, errors) {
459479 if ( ! wrap ) {
460480 wrap = selector . some ( s => s [ 0 ] != '&' ) ;
461481 }
462- const rule = selector . map ( s => {
482+ let rule = selector . map ( s => {
463483 if ( s [ 0 ] == '&' ) {
464484 // @ts -ignore
465485 s [ 0 ] = node . optimized . optimized [ 0 ] ;
466486 }
467487 return s . join ( '' ) ;
468488 } ) . join ( ',' ) ;
469489 // @ts -ignore
470- node . sel = wrap ? node . optimized . optimized [ 0 ] + `:is(${ rule } )` : rule ;
490+ let sel = wrap ? node . optimized . optimized [ 0 ] + `:is(${ rule } )` : rule ;
491+ if ( rule . includes ( '&' ) ) {
492+ // @ts -ignore
493+ rule = replaceCompound ( rule , node . optimized . optimized [ 0 ] ) ;
494+ }
495+ if ( sel . length < node . sel . length ) {
496+ node . sel = sel ;
497+ }
471498 }
472499 }
473500 // @ts -ignore
@@ -503,7 +530,7 @@ function minify(ast, options = {}, recursive = false, errors) {
503530 minifyRule ( node ) ;
504531 }
505532 else {
506- minify ( node , options , recursive , errors ) ;
533+ minify ( node , options , recursive , errors , nestingContent ) ;
507534 }
508535 i -- ;
509536 previous = node ;
@@ -548,7 +575,7 @@ function minify(ast, options = {}, recursive = false, errors) {
548575 minifyRule ( previous ) ;
549576 }
550577 else {
551- minify ( previous , options , recursive , errors ) ;
578+ minify ( previous , options , recursive , errors , nestingContent ) ;
552579 }
553580 }
554581 }
@@ -560,11 +587,19 @@ function minify(ast, options = {}, recursive = false, errors) {
560587 minifyRule ( previous ) ;
561588 }
562589 else {
563- minify ( previous , options , recursive , errors ) ;
590+ minify ( previous , options , recursive , errors , nestingContent ) ;
564591 }
565592 }
566593 }
567594 }
595+ if ( ! nestingContent &&
596+ // @ts -ignore
597+ previous != null &&
598+ // previous.optimized != null &&
599+ previous . typ == 'Rule' &&
600+ previous . sel . includes ( '&' ) ) {
601+ fixSelector ( previous ) ;
602+ }
568603 previous = node ;
569604 nodeIndex = i ;
570605 }
@@ -577,10 +612,18 @@ function minify(ast, options = {}, recursive = false, errors) {
577612 else {
578613 // @ts -ignore
579614 if ( ! ( node . typ == 'AtRule' && node . nam != 'font-face' ) ) {
580- minify ( node , options , recursive , errors ) ;
615+ minify ( node , options , recursive , errors , nestingContent ) ;
581616 }
582617 }
583618 }
619+ if ( ! nestingContent &&
620+ // @ts -ignore
621+ node != null &&
622+ // previous.optimized != null &&
623+ node . typ == 'Rule' &&
624+ node . sel . includes ( '&' ) ) {
625+ fixSelector ( node ) ;
626+ }
584627 }
585628 return ast ;
586629}
@@ -819,7 +862,6 @@ function reduceRuleSelector(node) {
819862 Object . defineProperty ( node , 'raw' , { ...definedPropertySettings , value : raw } ) ;
820863 }
821864 }
822- // }
823865}
824866
825867export { combinators , hasDeclaration , minify , minifyRule , reduceSelector , splitRule } ;
0 commit comments