[6a3a178] | 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
|
---|