You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
6.0 KiB
185 lines
6.0 KiB
4 years ago
|
'use strict';
|
||
|
|
||
|
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||
|
|
||
|
var postcss = _interopDefault(require('postcss'));
|
||
|
var parser = _interopDefault(require('postcss-values-parser'));
|
||
|
var convertColors = require('@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 = convertColors.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 [];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
module.exports = index;
|