Skip to content

Commit 25c4db4

Browse files
Antonio-Lagunaromainmenke
authored andcommitted
Switching to postcss-value-parser (postcss/postcss-custom-properties#260)
* Using new package * Using the new parser * Simplifying logic given how new parser works * Reworking the transforming logic to use the new parser * Whitespaces changes
1 parent d070b2f commit 25c4db4

11 files changed

+34
-77
lines changed

plugins/postcss-custom-properties/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"node": ">=12"
3737
},
3838
"dependencies": {
39-
"postcss-values-parser": "^6"
39+
"postcss-value-parser": "^4.2.0"
4040
},
4141
"peerDependencies": {
4242
"postcss": "^8.3"

plugins/postcss-custom-properties/src/lib/get-custom-properties-from-imports.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import fs from 'fs';
22
import path from 'path';
3-
import { parse as postcssParse } from 'postcss';
4-
import { parse } from 'postcss-values-parser';
3+
import { parse } from 'postcss';
4+
import valuesParser from 'postcss-value-parser';
55
import getCustomPropertiesFromRoot from './get-custom-properties-from-root';
66

77
/* Get Custom Properties from CSS File
88
/* ========================================================================== */
99

1010
async function getCustomPropertiesFromCSSFile(from) {
1111
const css = await readFile(from);
12-
const root = postcssParse(css, { from });
12+
const root = parse(css, { from });
1313

1414
return getCustomPropertiesFromRoot(root, { preserve: true });
1515
}
@@ -25,7 +25,7 @@ function getCustomPropertiesFromObject(object) {
2525
);
2626

2727
for (const key in customProperties) {
28-
customProperties[key] = parse(String(customProperties[key])).nodes;
28+
customProperties[key] = valuesParser(String(customProperties[key]));
2929
}
3030

3131
return customProperties;

plugins/postcss-custom-properties/src/lib/get-custom-properties-from-root.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { parse } from 'postcss-values-parser';
1+
import valuesParser from 'postcss-value-parser';
22
import { isBlockIgnored } from './is-ignored';
33

44
// return custom selectors from the css root, conditionally removing them
@@ -22,7 +22,7 @@ export default function getCustomPropertiesFromRoot(root, opts) {
2222
const { prop } = decl;
2323

2424
// write the parsed value to the custom property
25-
customPropertiesObject[prop] = parse(decl.value).nodes;
25+
customPropertiesObject[prop] = valuesParser(decl.value);
2626

2727
// conditionally remove the custom property declaration
2828
if (!opts.preserve) {

plugins/postcss-custom-properties/src/lib/transform-properties.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
import { parse } from 'postcss-values-parser';
1+
import valuesParser from 'postcss-value-parser';
22
import transformValueAST from './transform-value-ast';
33
import { isRuleIgnored } from './is-ignored';
44

55
// transform custom pseudo selectors with custom selectors
66
export default (decl, customProperties, opts) => {
77
if (isTransformableDecl(decl) && !isRuleIgnored(decl)) {
88
const originalValue = decl.value;
9-
const valueAST = parse(originalValue);
10-
let value = String(transformValueAST(valueAST, customProperties));
9+
const valueAST = valuesParser(originalValue);
10+
let value = transformValueAST(valueAST, customProperties);
1111

1212
// protect against circular references
1313
const valueSet = new Set();
1414

1515
while (customPropertiesRegExp.test(value) && !valueSet.has(value)) {
1616
valueSet.add(value);
17-
const parsedValueAST = parse(valueAST);
18-
value = String(transformValueAST(parsedValueAST, customProperties));
17+
const parsedValueAST = valuesParser(value);
18+
value = transformValueAST(parsedValueAST, customProperties);
1919
}
2020

2121
// conditionally transform values that have changed
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,37 @@
11
export default function transformValueAST(root, customProperties) {
22
if (root.nodes && root.nodes.length) {
3-
root.nodes.slice().forEach(child => {
3+
root.nodes.slice().forEach((child) => {
44
if (isVarFunction(child)) {
5-
// eslint-disable-next-line no-unused-vars
6-
const [propertyNode, comma, ...fallbacks] = child.nodes;
5+
const [propertyNode, ...fallbacks] = child.nodes.filter((node) => node.type !== 'div');
76
const { value: name } = propertyNode;
7+
const index = root.nodes.indexOf(child);
88

99
if (name in Object(customProperties)) {
10-
// conditionally replace a known custom property
11-
const nodes = asClonedArrayWithBeforeSpacing(customProperties[name], child.raws.before);
12-
13-
/**
14-
* https://github.com/postcss/postcss-custom-properties/issues/221
15-
* https://github.com/postcss/postcss-custom-properties/issues/218
16-
*
17-
* replaceWith loses node.raws values, so we need to save it and restore
18-
*/
19-
const raws = nodes.map(node => ({...node.raws}));
20-
21-
child.replaceWith(...nodes);
22-
23-
nodes.forEach((node, index) => {
24-
node.raws = raws[index];
25-
});
10+
// Direct match of a custom property to a parsed value
11+
const nodes = customProperties[name].nodes;
2612

13+
// Re-transform nested properties without given one to avoid circular from keeping this forever
2714
retransformValueAST({ nodes }, customProperties, name);
28-
} else if (fallbacks.length) {
29-
// conditionally replace a custom property with a fallback
30-
const index = root.nodes.indexOf(child);
3115

32-
if (index !== -1) {
33-
root.nodes.splice(index, 1, ...asClonedArrayWithBeforeSpacing(fallbacks, child.raws.before));
16+
if (index > -1) {
17+
root.nodes.splice(index, 1, ...nodes);
18+
}
19+
} else if (fallbacks.length) {
20+
// No match, but fallback available
21+
if (index > -1) {
22+
root.nodes.splice(index, 1, ...fallbacks);
3423
}
3524

3625
transformValueAST(root, customProperties);
3726
}
3827
} else {
28+
// Transform child nodes of current child
3929
transformValueAST(child, customProperties);
4030
}
4131
});
4232
}
4333

44-
return root;
34+
return root.toString();
4535
}
4636

4737
// retransform the current ast without a custom property (to prevent recursion)
@@ -57,35 +47,4 @@ function retransformValueAST(root, customProperties, withoutProperty) {
5747
const varRegExp = /^var$/i;
5848

5949
// whether the node is a var() function
60-
const isVarFunction = node => node.type === 'func' && varRegExp.test(node.name) && Object(node.nodes).length > 0;
61-
62-
// return an array with its nodes cloned, preserving the raw
63-
const asClonedArrayWithBeforeSpacing = (array, beforeSpacing) => {
64-
const clonedArray = asClonedArray(array, null);
65-
66-
if (clonedArray[0]) {
67-
clonedArray[0].raws.before = beforeSpacing;
68-
}
69-
70-
return clonedArray;
71-
};
72-
73-
// return an array with its nodes cloned
74-
const asClonedArray = (array, parent) => array.map(node => asClonedNode(node, parent));
75-
76-
// return a cloned node
77-
const asClonedNode = (node, parent) => {
78-
const cloneNode = new node.constructor(node);
79-
80-
for (const key in node) {
81-
if (key === 'parent') {
82-
cloneNode.parent = parent;
83-
} else if (Object(node[key]).constructor === Array) {
84-
cloneNode[key] = asClonedArray(node.nodes, cloneNode);
85-
} else if (Object(node[key]).constructor === Object) {
86-
cloneNode[key] = Object.assign({}, node[key]);
87-
}
88-
}
89-
90-
return cloneNode;
91-
};
50+
const isVarFunction = node => node.type === 'function' && varRegExp.test(node.value) && Object(node.nodes).length > 0;

plugins/postcss-custom-properties/src/lib/write-custom-properties-to-exports.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,7 @@ export default function writeCustomPropertiesToExports(customProperties, destina
130130
const defaultCustomPropertiesToJSON = customProperties => {
131131
return Object.keys(customProperties).reduce((customPropertiesJSON, key) => {
132132
const valueNodes = customProperties[key];
133-
customPropertiesJSON[key] = valueNodes.map((propertyObject) => {
134-
return propertyObject.toString();
135-
}).join(' ');
133+
customPropertiesJSON[key] = valueNodes.toString();
136134

137135
return customPropertiesJSON;
138136
}, {});

plugins/postcss-custom-properties/test/export-properties.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
--margin: 0 10px 20px 30px;
1111
--shadow-color: rgb(255,0,0);
1212
--shadow: 0 6px 14px 0 color(var(--shadow-color) a(.15));
13-
--font-family: "Open Sans" , sans-serif;
13+
--font-family: "Open Sans", sans-serif;
1414
--theme-color: #053;
1515
}

plugins/postcss-custom-properties/test/export-properties.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module.exports = {
1111
'--margin': '0 10px 20px 30px',
1212
'--shadow-color': 'rgb(255,0,0)',
1313
'--shadow': '0 6px 14px 0 color(var(--shadow-color) a(.15))',
14-
'--font-family': '"Open Sans" , sans-serif',
14+
'--font-family': '"Open Sans", sans-serif',
1515
'--theme-color': '#053'
1616
}
1717
};

plugins/postcss-custom-properties/test/export-properties.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"--margin": "0 10px 20px 30px",
1212
"--shadow-color": "rgb(255,0,0)",
1313
"--shadow": "0 6px 14px 0 color(var(--shadow-color) a(.15))",
14-
"--font-family": "\"Open Sans\" , sans-serif",
14+
"--font-family": "\"Open Sans\", sans-serif",
1515
"--theme-color": "#053"
1616
}
1717
}

plugins/postcss-custom-properties/test/export-properties.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ export const customProperties = {
1010
'--margin': '0 10px 20px 30px',
1111
'--shadow-color': 'rgb(255,0,0)',
1212
'--shadow': '0 6px 14px 0 color(var(--shadow-color) a(.15))',
13-
'--font-family': '"Open Sans" , sans-serif',
13+
'--font-family': '"Open Sans", sans-serif',
1414
'--theme-color': '#053'
1515
};

plugins/postcss-custom-properties/test/export-properties.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ $circular-2: var(--circular);
99
$margin: 0 10px 20px 30px;
1010
$shadow-color: rgb(255,0,0);
1111
$shadow: 0 6px 14px 0 color(var(--shadow-color) a(.15));
12-
$font-family: "Open Sans" , sans-serif;
12+
$font-family: "Open Sans", sans-serif;
1313
$theme-color: #053;

0 commit comments

Comments
 (0)