Skip to content
This repository was archived by the owner on Jun 6, 2022. It is now read-only.

Commit acc8c99

Browse files
authored
change from global walk to AtRule (#66)
* change to using atrule * cleanup Co-authored-by: alexgagnon <[email protected]>
1 parent 24234a2 commit acc8c99

File tree

2 files changed

+31
-18
lines changed

2 files changed

+31
-18
lines changed

index.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,27 @@ const creator = opts => {
1414
const exportTo = [].concat(Object(opts).exportTo || []);
1515

1616
// promise any custom media are imported
17-
const customMediaPromise = getCustomMediaFromImports(importFrom);
17+
const customMediaImportsPromise = getCustomMediaFromImports(importFrom);
1818

1919
return {
2020
postcssPlugin: 'postcss-custom-media',
21-
Once: async root => {
22-
const customMedia = Object.assign(
23-
await customMediaPromise,
21+
Once: async (root, helpers) => {
22+
23+
// combine rules from root and from imports
24+
helpers.customMedia = Object.assign(
25+
await customMediaImportsPromise,
2426
getCustomMediaFromRoot(root, { preserve })
2527
);
2628

27-
await writeCustomMediaToExports(customMedia, exportTo);
28-
29-
transformAtrules(root, customMedia, { preserve });
29+
await writeCustomMediaToExports(helpers.customMedia, exportTo);
30+
},
31+
AtRule: {
32+
media: (atrule, helpers) => {
33+
transformAtrules(atrule, {preserve}, helpers)
34+
}
3035
}
3136
}
32-
};
37+
}
3338

3439
creator.postcss = true
3540

lib/transform-atrules.js

+18-10
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
1-
import transformMediaList from './transform-media-list';
2-
import mediaASTFromString from './media-ast-from-string';
1+
import transformMediaList from "./transform-media-list";
2+
import mediaASTFromString from "./media-ast-from-string";
33

44
// transform custom pseudo selectors with custom selectors
5-
export default (root, customMedia, opts) => {
6-
root.walkAtRules(mediaAtRuleRegExp, atrule => {
7-
if (customPseudoRegExp.test(atrule.params)) {
5+
export default (atrule, { preserve }, { customMedia }) => {
6+
if (customPseudoRegExp.test(atrule.params)) {
7+
// prevent infinite loops when using 'preserve' option
8+
if (!atrule[visitedFlag]) {
9+
atrule[visitedFlag] = true;
10+
811
const mediaAST = mediaASTFromString(atrule.params);
912
const params = String(transformMediaList(mediaAST, customMedia));
1013

11-
if (opts.preserve) {
12-
atrule.cloneBefore({ params });
13-
} else {
14+
if (preserve) {
15+
// keep an original copy
16+
const node = atrule.cloneAfter();
17+
node[visitedFlag] = true;
18+
}
19+
// replace the variable with the params from @custom-media rule
20+
// skip if the variable is undefined
21+
if (params != null) {
1422
atrule.params = params;
1523
}
1624
}
17-
});
25+
}
1826
};
1927

20-
const mediaAtRuleRegExp = /^media$/i;
28+
const visitedFlag = Symbol("customMediaVisited");
2129
const customPseudoRegExp = /\(--[A-z][\w-]*\)/;

0 commit comments

Comments
 (0)