Skip to content

Commit

Permalink
add pure ignore comment for css modules
Browse files Browse the repository at this point in the history
  • Loading branch information
jantimon committed Oct 31, 2024
1 parent f1c05a5 commit bd8f968
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 2 deletions.
36 changes: 34 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const selectorParser = require("postcss-selector-parser");
const valueParser = require("postcss-value-parser");
const { extractICSS } = require("icss-utils");

const IGNORE_MARKER = "cssmodules-pure-ignore";

const isSpacing = (node) => node.type === "combinator" && node.value === " ";

function normalizeNodeArray(nodes) {
Expand All @@ -26,6 +28,8 @@ function normalizeNodeArray(nodes) {
}

function localizeNode(rule, mode, localAliasMap) {
const isIgnored = hasIgnoreComment(rule);

const transform = (node, context) => {
if (context.ignoreNextSpacing && !isSpacing(node)) {
throw new Error("Missing whitespace after " + context.ignoreNextSpacing);
Expand Down Expand Up @@ -212,6 +216,10 @@ function localizeNode(rule, mode, localAliasMap) {
break;
}

if (isIgnored) {
break;
}

const isImportedValue = localAliasMap.has(node.value);
const isImportedWithExplicitScope = isImportedValue && context.explicit;

Expand Down Expand Up @@ -348,6 +356,10 @@ function localizeDeclarationValues(localize, declaration, context) {
}

function localizeDeclaration(declaration, context) {
if (hasIgnoreComment(declaration)) {
return;
}

const isAnimation = /animation$/i.test(declaration.prop);

if (isAnimation) {
Expand Down Expand Up @@ -471,6 +483,22 @@ function localizeDeclaration(declaration, context) {
}
}

function hasIgnoreComment(node) {
if (!node.parent) {
return false;
}
const indexInParent = node.parent.index(node);
for (let i = indexInParent - 1; i >= 0; i--) {
const prevNode = node.parent.nodes[i];
if (prevNode.type === "comment") {
return prevNode.text.trimStart().startsWith(IGNORE_MARKER)
} else {
break;
}
}
return false;
}

module.exports = (options = {}) => {
if (
options &&
Expand Down Expand Up @@ -554,7 +582,11 @@ module.exports = (options = {}) => {
context.options = options;
context.localAliasMap = localAliasMap;

if (pureMode && context.hasPureGlobals) {
if (
pureMode &&
context.hasPureGlobals &&
!hasIgnoreComment(selector)
) {
throw atRule.error(
'Selector in at-rule"' +
selector +
Expand Down Expand Up @@ -605,7 +637,7 @@ module.exports = (options = {}) => {
context.options = options;
context.localAliasMap = localAliasMap;

if (pureMode && context.hasPureGlobals) {
if (pureMode && context.hasPureGlobals && !hasIgnoreComment(rule)) {
throw rule.error(
'Selector "' +
rule.selector +
Expand Down
62 changes: 62 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,68 @@ const tests = [
options: { mode: "pure" },
expected: ":export { foo: __foo; }",
},
{
name: "global selectors after an ignore comments should be pure",
options: { mode: "pure" },
input: `/* cssmodules-pure-ignore */
.global { a_value: some-value; }`,
expected: `/* cssmodules-pure-ignore */
.global { a_value: some-value; }`,
},
{
name: "global selectors after an ignore comments with postfix stays pure",
options: { mode: "pure" },
input: `/* cssmodules-pure-ignore With additional explanation */
.global { a_value: some-value; }`,
expected: `/* cssmodules-pure-ignore With additional explanation */
.global { a_value: some-value; }`,
},
{
name: "global selector after an ignore comments should still localize its properties",
options: { mode: "pure" },
input: `/* cssmodules-pure-ignore */
.global {
animation: fadeOut;
}`,
expected: `/* cssmodules-pure-ignore */
.global {
animation: :local(fadeOut);
}`,
},
{
name: "global selector after an ignore comments should still localize its child selectors",
options: { mode: "pure" },
input: `/* cssmodules-pure-ignore */
.outer {
.inner { a_value: some-value; }
}`,
expected: `/* cssmodules-pure-ignore */
.outer {
:local(.inner) { a_value: some-value; }
}`,
},
{
name: "global animation after an ignore comments should be pure",
options: { mode: "pure" },
input: `.foo { /* cssmodules-pure-ignore */
animation: fadeOut; }`,
expected: `:local(.foo) { /* cssmodules-pure-ignore */
animation: fadeOut; }`,
},
{
name: "global follow up properties after an ignore comments should be localized",
options: { mode: "pure" },
input: `.foo {
/* cssmodules-pure-ignore */
animation: fadeOut;
&:disabled { animation-name: localAnimation; }
}`,
expected: `:local(.foo) {
/* cssmodules-pure-ignore */
animation: fadeOut;
&:disabled { animation-name: :local(localAnimation); }
}`,
},
{
name: "handle negative animation-delay in animation shorthand",
input: ".foo { animation: 1s -500ms; }",
Expand Down

0 comments on commit bd8f968

Please sign in to comment.