1 | import { lab2rgb, lch2rgb } from '@csstools/convert-colors';
|
---|
2 | import postcss from 'postcss';
|
---|
3 | import parser from 'postcss-values-parser';
|
---|
4 |
|
---|
5 | var index = postcss.plugin('postcss-lab-function', opts => {
|
---|
6 | const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false;
|
---|
7 | return root => {
|
---|
8 | root.walkDecls(decl => {
|
---|
9 | const value = decl.value;
|
---|
10 |
|
---|
11 | if (colorAnyRegExp.test(value)) {
|
---|
12 | const ast = parser(value).parse();
|
---|
13 | ast.walkType('func', node => {
|
---|
14 | if (colorRegExp.test(node.value)) {
|
---|
15 | const children = node.nodes.slice(1, -1);
|
---|
16 | const isLab = labRegExp.test(node.value);
|
---|
17 | const isGray = grayRegExp.test(node.value);
|
---|
18 | const isFunctionalLAB = !isGray && matchFunctionalLAB(children);
|
---|
19 | const isFunctionalLCH = !isGray && matchFunctionalLCH(children);
|
---|
20 | const isFunctionalGray = isGray && matchFunctionalGray(children);
|
---|
21 |
|
---|
22 | if (isFunctionalLAB || isFunctionalLCH) {
|
---|
23 | node.value = 'rgb';
|
---|
24 | const slashNode = children[3];
|
---|
25 | const alphaNode = children[4];
|
---|
26 |
|
---|
27 | if (alphaNode) {
|
---|
28 | if (isPercentage(alphaNode) && !isCalc(alphaNode)) {
|
---|
29 | alphaNode.unit = '';
|
---|
30 | alphaNode.value = String(alphaNode.value / 100);
|
---|
31 | }
|
---|
32 |
|
---|
33 | if (alphaNode.value === '1') {
|
---|
34 | slashNode.remove();
|
---|
35 | alphaNode.remove();
|
---|
36 | } else {
|
---|
37 | node.value += 'a';
|
---|
38 | }
|
---|
39 | }
|
---|
40 |
|
---|
41 | if (slashNode && isSlash(slashNode)) {
|
---|
42 | slashNode.replaceWith(newComma());
|
---|
43 | }
|
---|
44 |
|
---|
45 | const converter = isLab ? lab2rgb : lch2rgb;
|
---|
46 | const rgbValues = converter(...[children[0].value, children[1].value, children[2].value].map(number => parseFloat(number))).map(sourceValue => Math.max(Math.min(parseInt(sourceValue * 2.55), 255), 0));
|
---|
47 | children[0].value = String(rgbValues[0]);
|
---|
48 | children[1].value = String(rgbValues[1]);
|
---|
49 | children[2].value = String(rgbValues[2]);
|
---|
50 | node.nodes.splice(3, 0, [newComma()]);
|
---|
51 | node.nodes.splice(2, 0, [newComma()]);
|
---|
52 | } else if (isFunctionalGray) {
|
---|
53 | node.value = 'rgb';
|
---|
54 | const alphaNode = children[2];
|
---|
55 | const rgbValues = lab2rgb(...[children[0].value, 0, 0].map(number => parseFloat(number))).map(sourceValue => Math.max(Math.min(parseInt(sourceValue * 2.55), 255), 0));
|
---|
56 | node.removeAll().append(newParen('(')).append(newNumber(rgbValues[0])).append(newComma()).append(newNumber(rgbValues[1])).append(newComma()).append(newNumber(rgbValues[2])).append(newParen(')'));
|
---|
57 |
|
---|
58 | if (alphaNode) {
|
---|
59 | if (isPercentage(alphaNode) && !isCalc(alphaNode)) {
|
---|
60 | alphaNode.unit = '';
|
---|
61 | alphaNode.value = String(alphaNode.value / 100);
|
---|
62 | }
|
---|
63 |
|
---|
64 | if (alphaNode.value !== '1') {
|
---|
65 | node.value += 'a';
|
---|
66 | node.insertBefore(node.last, newComma()).insertBefore(node.last, alphaNode);
|
---|
67 | }
|
---|
68 | }
|
---|
69 | }
|
---|
70 | }
|
---|
71 | });
|
---|
72 | const newValue = String(ast);
|
---|
73 |
|
---|
74 | if (preserve) {
|
---|
75 | decl.cloneBefore({
|
---|
76 | value: newValue
|
---|
77 | });
|
---|
78 | } else {
|
---|
79 | decl.value = newValue;
|
---|
80 | }
|
---|
81 | }
|
---|
82 | });
|
---|
83 | };
|
---|
84 | });
|
---|
85 | const colorAnyRegExp = /(^|[^\w-])(lab|lch|gray)\(/i;
|
---|
86 | const colorRegExp = /^(lab|lch|gray)$/i;
|
---|
87 | const labRegExp = /^lab$/i;
|
---|
88 | const grayRegExp = /^gray$/i;
|
---|
89 | const alphaUnitMatch = /^%?$/i;
|
---|
90 | const calcFuncMatch = /^calc$/i;
|
---|
91 | const hueUnitMatch = /^(deg|grad|rad|turn)?$/i;
|
---|
92 |
|
---|
93 | const isAlphaValue = node => isCalc(node) || node.type === 'number' && alphaUnitMatch.test(node.unit);
|
---|
94 |
|
---|
95 | const isCalc = node => node.type === 'func' && calcFuncMatch.test(node.value);
|
---|
96 |
|
---|
97 | const isHue = node => isCalc(node) || node.type === 'number' && hueUnitMatch.test(node.unit);
|
---|
98 |
|
---|
99 | const isNumber = node => isCalc(node) || node.type === 'number' && node.unit === '';
|
---|
100 |
|
---|
101 | const isPercentage = node => isCalc(node) || node.type === 'number' && node.unit === '%';
|
---|
102 |
|
---|
103 | const isSlash = node => node.type === 'operator' && node.value === '/';
|
---|
104 |
|
---|
105 | const functionalLABMatch = [isNumber, isNumber, isNumber, isSlash, isAlphaValue];
|
---|
106 | const functionalLCHMatch = [isNumber, isNumber, isHue, isSlash, isAlphaValue];
|
---|
107 | const functionalGrayMatch = [isNumber, isSlash, isAlphaValue];
|
---|
108 |
|
---|
109 | const matchFunctionalLAB = children => children.every((child, index) => typeof functionalLABMatch[index] === 'function' && functionalLABMatch[index](child));
|
---|
110 |
|
---|
111 | const matchFunctionalLCH = children => children.every((child, index) => typeof functionalLCHMatch[index] === 'function' && functionalLCHMatch[index](child));
|
---|
112 |
|
---|
113 | const matchFunctionalGray = children => children.every((child, index) => typeof functionalGrayMatch[index] === 'function' && functionalGrayMatch[index](child));
|
---|
114 |
|
---|
115 | const newComma = () => parser.comma({
|
---|
116 | value: ','
|
---|
117 | });
|
---|
118 |
|
---|
119 | const newNumber = value => parser.number({
|
---|
120 | value
|
---|
121 | });
|
---|
122 |
|
---|
123 | const newParen = value => parser.paren({
|
---|
124 | value
|
---|
125 | });
|
---|
126 |
|
---|
127 | export default index;
|
---|
128 | //# sourceMappingURL=index.es.mjs.map
|
---|