123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- import postcss from 'postcss';
- import parser from 'postcss-values-parser';
- import { lab2rgb } from '@csstools/convert-colors';
- function _slicedToArray(arr, i) {
- return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
- }
- function _arrayWithHoles(arr) {
- if (Array.isArray(arr)) return arr;
- }
- function _iterableToArrayLimit(arr, i) {
- var _arr = [];
- var _n = true;
- var _d = false;
- var _e = undefined;
- try {
- for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
- _arr.push(_s.value);
- if (i && _arr.length === i) break;
- }
- } catch (err) {
- _d = true;
- _e = err;
- } finally {
- try {
- if (!_n && _i["return"] != null) _i["return"]();
- } finally {
- if (_d) throw _e;
- }
- }
- return _arr;
- }
- function _nonIterableRest() {
- throw new TypeError("Invalid attempt to destructure non-iterable instance");
- }
- var index = postcss.plugin('postcss-color-gray', opts => root => {
- // walk all declarations likely containing a gray() function
- root.walkDecls(decl => {
- if (hasGrayFunction(decl)) {
- const originalValue = decl.value; // parse the declaration value
- const ast = parser(originalValue).parse(); // walk every node in the value that contains a gray() function
- ast.walk(node => {
- const _getFunctionGrayArgs = getFunctionGrayArgs(node),
- _getFunctionGrayArgs2 = _slicedToArray(_getFunctionGrayArgs, 2),
- lightness = _getFunctionGrayArgs2[0],
- alpha = _getFunctionGrayArgs2[1];
- if (lightness !== undefined) {
- // rename the gray() function to rgb()
- node.value = 'rgb'; // convert the lab gray lightness into rgb
- const _lab2rgb$map = lab2rgb(lightness, 0, 0).map(channel => Math.max(Math.min(Math.round(channel * 2.55), 255), 0)),
- _lab2rgb$map2 = _slicedToArray(_lab2rgb$map, 3),
- r = _lab2rgb$map2[0],
- g = _lab2rgb$map2[1],
- b = _lab2rgb$map2[2]; // preserve the slash nodes within rgb()
- const openingSlash = node.first;
- const closingSlash = node.last;
- node.removeAll() // replace the contents of rgb with `(r,g,b`
- .append(openingSlash).append(parser.number({
- value: r
- })).append(parser.comma({
- value: ','
- })).append(parser.number({
- value: g
- })).append(parser.comma({
- value: ','
- })).append(parser.number({
- value: b
- })); // if an alpha channel was defined
- if (alpha < 1) {
- // rename the rgb() function to rgba()
- node.value += 'a';
- node // append the contents of rgba with `,a`
- .append(parser.comma({
- value: ','
- })).append(parser.number({
- value: alpha
- }));
- } // append the contents of rgb/rgba with `)`
- node.append(closingSlash);
- }
- });
- const modifiedValue = ast.toString(); // if the modified value has changed from the original value
- if (originalValue !== modifiedValue) {
- // if the original gray() color is to be preserved
- if (Object(opts).preserve) {
- // insert the declaration value with the fallback before the current declaration
- decl.cloneBefore({
- value: modifiedValue
- });
- } else {
- // otherwise, overwrite the declaration value with the fallback
- decl.value = modifiedValue;
- }
- }
- }
- });
- }); // return whether a string contains a gray() function
- const hasGrayFunctionRegExp = /(^|[^\w-])gray\(/i;
- const hasGrayFunction = decl => hasGrayFunctionRegExp.test(Object(decl).value); // return whether a node matches a specific type
- const isNumber = node => Object(node).type === 'number';
- const isOperator = node => Object(node).type === 'operator';
- const isFunction = node => Object(node).type === 'func';
- const isCalcRegExp = /^calc$/i;
- const isFunctionCalc = node => isFunction(node) && isCalcRegExp.test(node.value);
- const isGrayRegExp = /^gray$/i;
- const isFunctionGrayWithArgs = node => isFunction(node) && isGrayRegExp.test(node.value) && node.nodes && node.nodes.length;
- const isNumberPercentage = node => isNumber(node) && node.unit === '%';
- const isNumberUnitless = node => isNumber(node) && node.unit === '';
- const isOperatorSlash = node => isOperator(node) && node.value === '/'; // return valid values from a node, otherwise undefined
- const getNumberUnitless = node => isNumberUnitless(node) ? Number(node.value) : undefined;
- const getOperatorSlash = node => isOperatorSlash(node) ? null : undefined;
- const getAlpha = node => isFunctionCalc(node) ? String(node) : isNumberUnitless(node) ? Number(node.value) : isNumberPercentage(node) ? Number(node.value) / 100 : undefined; // return valid arguments from a gray() function
- const functionalGrayArgs = [getNumberUnitless, getOperatorSlash, getAlpha];
- const getFunctionGrayArgs = node => {
- const validArgs = []; // if the node is a gray() function with arguments
- if (isFunctionGrayWithArgs(node)) {
- // get all the gray() function arguments between `(` and `)`
- const nodes = node.nodes.slice(1, -1); // validate each argument
- for (const index in nodes) {
- const arg = typeof functionalGrayArgs[index] === 'function' ? functionalGrayArgs[index](nodes[index]) : undefined; // if the argument was validated
- if (arg !== undefined) {
- // push any non-null argument to the valid arguments array
- if (arg !== null) {
- validArgs.push(arg);
- }
- } else {
- // otherwise, return an empty array
- return [];
- }
- } // return the valid arguments array
- return validArgs;
- } else {
- // otherwise, return an empty array
- return [];
- }
- };
- export default index;
|