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.
184 lines
6.0 KiB
184 lines
6.0 KiB
'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;
|
|
|