Skip to content

Commit 3811927

Browse files
fix: css nesting and pure mode
1 parent 582bd9e commit 3811927

File tree

2 files changed

+398
-2
lines changed

2 files changed

+398
-2
lines changed

src/index.js

+37-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ function normalizeNodeArray(nodes) {
4646
return array;
4747
}
4848

49+
const isPureSelectorSymbol = Symbol("is-pure-selector");
50+
4951
function localizeNode(rule, mode, localAliasMap) {
5052
const transform = (node, context) => {
5153
if (context.ignoreNextSpacing && !isSpacing(node)) {
@@ -253,7 +255,7 @@ function localizeNode(rule, mode, localAliasMap) {
253255
}
254256
case "nesting": {
255257
if (node.value === "&") {
256-
context.hasLocals = true;
258+
context.hasLocals = rule.parent[isPureSelectorSymbol];
257259
}
258260
}
259261
}
@@ -502,6 +504,30 @@ function localizeDeclaration(declaration, context) {
502504
}
503505
}
504506

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+
505531
module.exports = (options = {}) => {
506532
if (
507533
options &&
@@ -652,8 +678,13 @@ module.exports = (options = {}) => {
652678
context.localAliasMap = localAliasMap;
653679

654680
const ignoreComment = pureMode ? getIgnoreComment(rule) : undefined;
681+
const isNotPure = pureMode && !isPureSelector(context, rule);
655682

656-
if (pureMode && context.hasPureGlobals && !ignoreComment) {
683+
if (
684+
isNotPure &&
685+
isNodeWithoutDeclarations(rule) &&
686+
!ignoreComment
687+
) {
657688
throw rule.error(
658689
'Selector "' +
659690
rule.selector +
@@ -664,6 +695,10 @@ module.exports = (options = {}) => {
664695
ignoreComment.remove();
665696
}
666697

698+
if (pureMode) {
699+
rule[isPureSelectorSymbol] = !isNotPure;
700+
}
701+
667702
rule.selector = context.selector;
668703

669704
// Less-syntax mixins parse as rules with no nodes

0 commit comments

Comments
 (0)