@@ -46,6 +46,8 @@ function normalizeNodeArray(nodes) {
46
46
return array ;
47
47
}
48
48
49
+ const isPureSelectorSymbol = Symbol ( "is-pure-selector" ) ;
50
+
49
51
function localizeNode ( rule , mode , localAliasMap ) {
50
52
const transform = ( node , context ) => {
51
53
if ( context . ignoreNextSpacing && ! isSpacing ( node ) ) {
@@ -253,7 +255,7 @@ function localizeNode(rule, mode, localAliasMap) {
253
255
}
254
256
case "nesting" : {
255
257
if ( node . value === "&" ) {
256
- context . hasLocals = true ;
258
+ context . hasLocals = rule . parent [ isPureSelectorSymbol ] ;
257
259
}
258
260
}
259
261
}
@@ -502,6 +504,30 @@ function localizeDeclaration(declaration, context) {
502
504
}
503
505
}
504
506
507
+ const isPureSelector = ( context , rule ) => {
508
+ if ( ! rule . parent || rule . type === "root" ) {
509
+ return ! context . hasPureGlobals ;
510
+ }
511
+
512
+ if ( rule . type === "rule" && rule [ isPureSelectorSymbol ] ) {
513
+ return rule [ isPureSelectorSymbol ] || isPureSelector ( context , rule . parent ) ;
514
+ }
515
+
516
+ return ! context . hasPureGlobals || isPureSelector ( context , rule . parent ) ;
517
+ } ;
518
+
519
+ const isNodeWithoutDeclarations = ( rule ) => {
520
+ if ( rule . nodes . length > 0 ) {
521
+ return ! rule . nodes . every (
522
+ ( item ) =>
523
+ item . type === "rule" ||
524
+ ( item . type === "atrule" && ! isNodeWithoutDeclarations ( item ) )
525
+ ) ;
526
+ }
527
+
528
+ return true ;
529
+ } ;
530
+
505
531
module . exports = ( options = { } ) => {
506
532
if (
507
533
options &&
@@ -652,8 +678,13 @@ module.exports = (options = {}) => {
652
678
context . localAliasMap = localAliasMap ;
653
679
654
680
const ignoreComment = pureMode ? getIgnoreComment ( rule ) : undefined ;
681
+ const isNotPure = pureMode && ! isPureSelector ( context , rule ) ;
655
682
656
- if ( pureMode && context . hasPureGlobals && ! ignoreComment ) {
683
+ if (
684
+ isNotPure &&
685
+ isNodeWithoutDeclarations ( rule ) &&
686
+ ! ignoreComment
687
+ ) {
657
688
throw rule . error (
658
689
'Selector "' +
659
690
rule . selector +
@@ -664,6 +695,10 @@ module.exports = (options = {}) => {
664
695
ignoreComment . remove ( ) ;
665
696
}
666
697
698
+ if ( pureMode ) {
699
+ rule [ isPureSelectorSymbol ] = ! isNotPure ;
700
+ }
701
+
667
702
rule . selector = context . selector ;
668
703
669
704
// Less-syntax mixins parse as rules with no nodes
0 commit comments