Skip to content

Commit 971abcd

Browse files
refactor: logic
1 parent 73e1c62 commit 971abcd

File tree

2 files changed

+120
-16
lines changed

2 files changed

+120
-16
lines changed

src/index.js

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ const IGNORE_MARKER = "cssmodules-pure-ignore";
99
const isSpacing = (node) => node.type === "combinator" && node.value === " ";
1010

1111
function getIgnoreComment(node) {
12-
const indexInParent = node.parent ? node.parent.index(node) : -1;
12+
if (!node.parent) {
13+
return;
14+
}
15+
16+
const indexInParent = node.parent.index(node);
17+
1318
for (let i = indexInParent - 1; i >= 0; i--) {
1419
const prevNode = node.parent.nodes[i];
1520
if (prevNode.type === "comment") {
@@ -529,7 +534,6 @@ module.exports = (options = {}) => {
529534
});
530535

531536
root.walkAtRules((atRule) => {
532-
const ignoreComment = getIgnoreComment(atRule);
533537
if (/keyframes$/i.test(atRule.name)) {
534538
const globalMatch = /^\s*:global\s*\((.+)\)\s*$/.exec(
535539
atRule.params
@@ -541,11 +545,18 @@ module.exports = (options = {}) => {
541545
let globalKeyframes = globalMode;
542546

543547
if (globalMatch) {
544-
if (pureMode && !ignoreComment) {
545-
throw atRule.error(
546-
"@keyframes :global(...) is not allowed in pure mode"
547-
);
548+
if (pureMode) {
549+
const ignoreComment = getIgnoreComment(atRule);
550+
551+
if (!ignoreComment) {
552+
throw atRule.error(
553+
"@keyframes :global(...) is not allowed in pure mode"
554+
);
555+
} else {
556+
ignoreComment.remove();
557+
}
548558
}
559+
549560
atRule.params = globalMatch[1];
550561
globalKeyframes = true;
551562
} else if (localMatch) {
@@ -568,6 +579,14 @@ module.exports = (options = {}) => {
568579
});
569580
} else if (/scope$/i.test(atRule.name)) {
570581
if (atRule.params) {
582+
const ignoreComment = pureMode
583+
? getIgnoreComment(atRule)
584+
: undefined;
585+
586+
if (ignoreComment) {
587+
ignoreComment.remove();
588+
}
589+
571590
atRule.params = atRule.params
572591
.split("to")
573592
.map((item) => {
@@ -581,7 +600,7 @@ module.exports = (options = {}) => {
581600
context.options = options;
582601
context.localAliasMap = localAliasMap;
583602

584-
if (pureMode && context.hasPureGlobals && ignoreComment) {
603+
if (pureMode && context.hasPureGlobals && !ignoreComment) {
585604
throw atRule.error(
586605
'Selector in at-rule"' +
587606
selector +
@@ -615,14 +634,9 @@ module.exports = (options = {}) => {
615634
}
616635
});
617636
}
618-
619-
if (ignoreComment) {
620-
ignoreComment.remove();
621-
}
622637
});
623638

624639
root.walkRules((rule) => {
625-
const ignoreComment = getIgnoreComment(rule);
626640
if (
627641
rule.parent &&
628642
rule.parent.type === "atrule" &&
@@ -637,13 +651,17 @@ module.exports = (options = {}) => {
637651
context.options = options;
638652
context.localAliasMap = localAliasMap;
639653

654+
const ignoreComment = pureMode ? getIgnoreComment(rule) : undefined;
655+
640656
if (pureMode && context.hasPureGlobals && !ignoreComment) {
641657
throw rule.error(
642658
'Selector "' +
643659
rule.selector +
644660
'" is not pure ' +
645661
"(pure selectors must contain at least one local class or id)"
646662
);
663+
} else if (ignoreComment) {
664+
ignoreComment.remove();
647665
}
648666

649667
rule.selector = context.selector;
@@ -654,10 +672,6 @@ module.exports = (options = {}) => {
654672
localizeDeclaration(declaration, context)
655673
);
656674
}
657-
658-
if (ignoreComment) {
659-
ignoreComment.remove();
660-
}
661675
});
662676
},
663677
};

test/index.test.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,57 @@ const tests = [
960960
expected: `/* another comment */
961961
.foo { color: blue; }`,
962962
},
963+
{
964+
name: "should suppress errors for global selectors after ignore comment #3",
965+
options: { mode: "pure" },
966+
input: `/* another comment */
967+
/* cssmodules-pure-ignore */
968+
:global(.foo) { color: blue; }`,
969+
expected: `/* another comment */
970+
.foo { color: blue; }`,
971+
},
972+
{
973+
name: "should suppress errors for global selectors after ignore comment #4",
974+
options: { mode: "pure" },
975+
input: `/* cssmodules-pure-ignore */ /* another comment */
976+
:global(.foo) { color: blue; }`,
977+
expected: `/* another comment */
978+
.foo { color: blue; }`,
979+
},
980+
{
981+
name: "should suppress errors for global selectors after ignore comment #5",
982+
options: { mode: "pure" },
983+
input: `/* another comment */ /* cssmodules-pure-ignore */
984+
:global(.foo) { color: blue; }`,
985+
expected: `/* another comment */
986+
.foo { color: blue; }`,
987+
},
988+
{
989+
name: "should suppress errors for global selectors after ignore comment #6",
990+
options: { mode: "pure" },
991+
input: `.foo { /* cssmodules-pure-ignore */ :global(.bar) { color: blue }; }`,
992+
expected: `:local(.foo) { .bar { color: blue }; }`,
993+
},
994+
{
995+
name: "should suppress errors for global selectors after ignore comment #7",
996+
options: { mode: "pure" },
997+
input: `/* cssmodules-pure-ignore */ :global(.foo) { /* cssmodules-pure-ignore */ :global(.bar) { color: blue } }`,
998+
expected: `.foo { .bar { color: blue } }`,
999+
},
1000+
{
1001+
name: "should suppress errors for global selectors after ignore comment #8",
1002+
options: { mode: "pure" },
1003+
input: `/* cssmodules-pure-ignore */ :global(.foo) { color: blue; }`,
1004+
expected: `.foo { color: blue; }`,
1005+
},
1006+
{
1007+
name: "should suppress errors for global selectors after ignore comment #9",
1008+
options: { mode: "pure" },
1009+
input: `/*
1010+
cssmodules-pure-ignore
1011+
*/ :global(.foo) { color: blue; }`,
1012+
expected: `.foo { color: blue; }`,
1013+
},
9631014
{
9641015
name: "should allow additional text in ignore comment",
9651016
options: { mode: "pure" },
@@ -1020,6 +1071,45 @@ const tests = [
10201071
to { opacity: 0; }
10211072
}`,
10221073
},
1074+
{
1075+
name: "should work with scope in ignored block",
1076+
options: { mode: "pure" },
1077+
input: `
1078+
/* cssmodules-pure-ignore */
1079+
@scope (:global(.foo)) to (:global(.bar)) {
1080+
.article-footer {
1081+
border: 5px solid black;
1082+
}
1083+
}
1084+
`,
1085+
expected: `
1086+
@scope (.foo) to (.bar) {
1087+
:local(.article-footer) {
1088+
border: 5px solid black;
1089+
}
1090+
}
1091+
`,
1092+
},
1093+
{
1094+
name: "should work with scope in ignored block #2",
1095+
options: { mode: "pure" },
1096+
input: `
1097+
/* cssmodules-pure-ignore */
1098+
@scope (:global(.foo))
1099+
to (:global(.bar)) {
1100+
.article-footer {
1101+
border: 5px solid black;
1102+
}
1103+
}
1104+
`,
1105+
expected: `
1106+
@scope (.foo) to (.bar) {
1107+
:local(.article-footer) {
1108+
border: 5px solid black;
1109+
}
1110+
}
1111+
`,
1112+
},
10231113
{
10241114
name: "should work in media queries",
10251115
options: { mode: "pure" },

0 commit comments

Comments
 (0)