Skip to content

Commit bbdb44d

Browse files
authored
feat: upgrade to PostCSS 8 (#18)
1 parent 6e6cb37 commit bbdb44d

7 files changed

+101
-128
lines changed

.gitignore

-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
node_modules
2-
index.*.js
32
package-lock.json
43
*.log*
54
*.result.css
65
.*
76
!.editorconfig
87
!.gitignore
9-
!.rollup.js
108
!.tape.js
119
!.travis.yml

.rollup.js

-16
This file was deleted.

.tape.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
module.exports = {
2-
'postcss-color-gray': {
3-
'basic': {
4-
message: 'supports basic usage'
5-
},
6-
'basic:preserve': {
7-
message: 'supports { preserve: true } usage',
8-
options: {
9-
preserve: true
10-
}
2+
'basic': {
3+
message: 'supports basic usage'
4+
},
5+
'basic:preserve': {
6+
message: 'supports { preserve: true } usage',
7+
options: {
8+
preserve: true
119
}
1210
}
1311
};

.travis.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
language: node_js
44

55
node_js:
6-
- 6
6+
- 10
7+
- 12
78

89
install:
910
- npm install --ignore-scripts

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ body {
2828
Add [PostCSS Gray] to your project:
2929

3030
```bash
31-
npm install postcss-color-gray --save-dev
31+
npm install postcss postcss-color-gray --save-dev
3232
```
3333

3434
Use [PostCSS Gray] to process your CSS:

index.js

+80-77
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,90 @@
1-
import postcss from 'postcss';
2-
import parser from 'postcss-values-parser';
3-
import { lab2rgb } from '@csstools/convert-colors';
4-
5-
export default postcss.plugin('postcss-color-gray', opts => root => {
6-
// walk all declarations likely containing a gray() function
7-
root.walkDecls(decl => {
8-
if (hasGrayFunction(decl)) {
9-
const { value: originalValue } = decl;
10-
11-
// parse the declaration value
12-
const ast = parser(originalValue).parse();
13-
14-
// walk every node in the value that contains a gray() function
15-
ast.walk(node => {
16-
const [lightness, alpha] = getFunctionGrayArgs(node);
17-
18-
if (lightness !== undefined) {
19-
// rename the gray() function to rgb()
20-
node.value = 'rgb';
21-
22-
// convert the lab gray lightness into rgb
23-
const [r, g, b] = lab2rgb(lightness, 0, 0).map(
24-
channel => Math.max(Math.min(Math.round(channel * 2.55), 255), 0)
25-
);
26-
27-
// preserve the slash nodes within rgb()
28-
const openingSlash = node.first;
29-
const closingSlash = node.last;
30-
31-
node.removeAll()
32-
// replace the contents of rgb with `(r,g,b`
33-
.append(openingSlash)
34-
.append(parser.number({ value: r }))
35-
.append(parser.comma({ value: ',' }))
36-
.append(parser.number({ value: g }))
37-
.append(parser.comma({ value: ',' }))
38-
.append(parser.number({ value: b }))
39-
40-
// if an alpha channel was defined
41-
if (alpha < 1) {
42-
// rename the rgb() function to rgba()
43-
node.value += 'a';
44-
45-
node
46-
// append the contents of rgba with `,a`
47-
.append(parser.comma({ value: ',' }))
48-
.append(parser.number({ value: alpha }));
1+
const {parse} = require("postcss-values-parser");
2+
const {lab2rgb} = require("@csstools/convert-colors");
3+
const Numeric = require("postcss-values-parser/lib/nodes/Numeric");
4+
const Punctuation = require("postcss-values-parser/lib/nodes/Punctuation");
5+
6+
/**
7+
* @param {{preserve?: boolean}} opts
8+
* @returns {import('postcss').Plugin}
9+
*/
10+
module.exports = function creator(opts) {
11+
const preserve = Boolean(Object(opts).preserve);
12+
13+
return {
14+
postcssPlugin: 'postcss-color-gray',
15+
// walk all declarations likely containing a gray() function
16+
Declaration(decl) {
17+
if (hasGrayFunction(decl)) {
18+
const { value: originalValue } = decl;
19+
20+
// parse the declaration value
21+
const ast = parse(originalValue);
22+
23+
// walk every node in the value that contains a gray() function
24+
ast.walkFuncs(node => {
25+
const [lightness, alpha] = getFunctionGrayArgs(node);
26+
27+
if (lightness !== undefined) {
28+
// rename the gray() function to rgb()
29+
node.name = 'rgb';
30+
31+
// convert the lab gray lightness into rgb
32+
const [r, g, b] = lab2rgb(lightness, 0, 0).map(
33+
channel => Math.max(Math.min(Math.round(channel * 2.55), 255), 0)
34+
);
35+
36+
node.removeAll()
37+
// replace the contents of rgb with `r,g,b`
38+
.append(new Numeric({ value: r }))
39+
.append(new Punctuation({ value: ',' }))
40+
.append(new Numeric({ value: g }))
41+
.append(new Punctuation({ value: ',' }))
42+
.append(new Numeric({ value: b }))
43+
44+
// if an alpha channel was defined
45+
if (alpha < 1) {
46+
// rename the rgb() function to rgba()
47+
node.name += 'a';
48+
49+
node
50+
// append the contents of rgba with `,a`
51+
.append(new Punctuation({ value: ',' }))
52+
.append(new Numeric({ value: alpha }));
53+
}
54+
}
55+
});
56+
57+
const modifiedValue = ast.toString();
58+
59+
// if the modified value has changed from the original value
60+
if (originalValue !== modifiedValue) {
61+
// if the original gray() color is to be preserved
62+
if (preserve) {
63+
// insert the declaration value with the fallback before the current declaration
64+
decl.cloneBefore({
65+
value: modifiedValue
66+
});
67+
} else {
68+
// otherwise, overwrite the declaration value with the fallback
69+
decl.value = modifiedValue;
4970
}
50-
51-
// append the contents of rgb/rgba with `)`
52-
node.append(closingSlash);
53-
}
54-
});
55-
56-
const modifiedValue = ast.toString();
57-
58-
// if the modified value has changed from the original value
59-
if (originalValue !== modifiedValue) {
60-
// if the original gray() color is to be preserved
61-
if (Object(opts).preserve) {
62-
// insert the declaration value with the fallback before the current declaration
63-
decl.cloneBefore({
64-
value: modifiedValue
65-
});
66-
} else {
67-
// otherwise, overwrite the declaration value with the fallback
68-
decl.value = modifiedValue;
6971
}
7072
}
7173
}
72-
});
73-
});
74+
}
75+
}
76+
77+
module.exports.postcss = true;
7478

7579
// return whether a string contains a gray() function
7680
const hasGrayFunctionRegExp = /(^|[^\w-])gray\(/i;
7781
const hasGrayFunction = decl => hasGrayFunctionRegExp.test(Object(decl).value);
7882

7983
// return whether a node matches a specific type
80-
const isNumber = node => Object(node).type === 'number';
84+
const isNumber = node => Object(node).type === 'numeric';
8185
const isOperator = node => Object(node).type === 'operator';
8286
const isFunction = node => Object(node).type === 'func';
83-
const isCalcRegExp = /^calc$/i;
84-
const isFunctionCalc = node => isFunction(node) && isCalcRegExp.test(node.value);
85-
const isGrayRegExp = /^gray$/i;
86-
const isFunctionGrayWithArgs = node => isFunction(node) && isGrayRegExp.test(node.value) && node.nodes && node.nodes.length;
87+
const isFunctionCalc = node => isFunction(node) && node.name === 'calc';
8788
const isNumberPercentage = node => isNumber(node) && node.unit === '%';
8889
const isNumberUnitless = node => isNumber(node) && node.unit === '';
8990
const isOperatorSlash = node => isOperator(node) && node.value === '/';
@@ -105,13 +106,15 @@ const getFunctionGrayArgs = node => {
105106
const validArgs = [];
106107

107108
// if the node is a gray() function with arguments
108-
if (isFunctionGrayWithArgs(node)) {
109+
if (node.name === 'gray' && node.nodes && node.nodes.length) {
109110
// get all the gray() function arguments between `(` and `)`
110-
const nodes = node.nodes.slice(1, -1);
111+
const nodes = node.nodes;
111112

112113
// validate each argument
113114
for (const index in nodes) {
114-
const arg = typeof functionalGrayArgs[index] === 'function' ? functionalGrayArgs[index](nodes[index]) : undefined;
115+
const arg = typeof functionalGrayArgs[index] === 'function'
116+
? functionalGrayArgs[index](nodes[index])
117+
: undefined;
115118

116119
// if the argument was validated
117120
if (arg !== undefined) {

package.json

+11-22
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,31 @@
77
"repository": "postcss/postcss-color-gray",
88
"homepage": "https://github.com/postcss/postcss-color-gray#readme",
99
"bugs": "https://github.com/postcss/postcss-color-gray/issues",
10-
"main": "index.cjs.js",
11-
"module": "index.es.js",
12-
"files": [
13-
"index.cjs.js",
14-
"index.es.js"
15-
],
10+
"main": "index.js",
1611
"scripts": {
1712
"prepublishOnly": "npm test",
18-
"pretest": "rollup -c .rollup.js --silent",
1913
"test": "echo 'Running tests...'; npm run test:js && npm run test:tape",
20-
"test:ec": "echint --ignore index.*.js test",
2114
"test:js": "eslint *.js --cache --ignore-path .gitignore --quiet",
2215
"test:tape": "postcss-tape"
2316
},
2417
"engines": {
25-
"node": ">=6.0.0"
18+
"node": ">=10.0.0"
2619
},
2720
"dependencies": {
28-
"@csstools/convert-colors": "^1.4.0",
29-
"postcss": "^7.0.5",
30-
"postcss-values-parser": "^2.0.0"
21+
"@csstools/convert-colors": "^2.0.0",
22+
"postcss-values-parser": "^5.0.0"
23+
},
24+
"peerDependencies": {
25+
"postcss": "^8.0.0"
3126
},
3227
"devDependencies": {
33-
"@babel/core": "^7.0.0",
34-
"@babel/preset-env": "^7.0.0",
35-
"babel-eslint": "^10.0.1",
36-
"eslint": "^5.6.1",
28+
"postcss": "^8.2.8",
29+
"eslint": "^7.22.0",
3730
"eslint-config-dev": "^2.0.0",
38-
"postcss-tape": "^2.2.0",
39-
"pre-commit": "^1.2.2",
40-
"rollup": "^0.66.5",
41-
"rollup-plugin-babel": "^4.0.1"
31+
"postcss-tape": "^6.0.0"
4232
},
4333
"eslintConfig": {
44-
"extends": "dev",
45-
"parser": "babel-eslint"
34+
"extends": "dev"
4635
},
4736
"keywords": [
4837
"postcss",

0 commit comments

Comments
 (0)