index.cjs.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. 'use strict';
  2. function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  3. var postcss = _interopDefault(require('postcss'));
  4. var parser = _interopDefault(require('postcss-values-parser'));
  5. var convertColors = require('@csstools/convert-colors');
  6. function _slicedToArray(arr, i) {
  7. return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
  8. }
  9. function _arrayWithHoles(arr) {
  10. if (Array.isArray(arr)) return arr;
  11. }
  12. function _iterableToArrayLimit(arr, i) {
  13. var _arr = [];
  14. var _n = true;
  15. var _d = false;
  16. var _e = undefined;
  17. try {
  18. for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
  19. _arr.push(_s.value);
  20. if (i && _arr.length === i) break;
  21. }
  22. } catch (err) {
  23. _d = true;
  24. _e = err;
  25. } finally {
  26. try {
  27. if (!_n && _i["return"] != null) _i["return"]();
  28. } finally {
  29. if (_d) throw _e;
  30. }
  31. }
  32. return _arr;
  33. }
  34. function _nonIterableRest() {
  35. throw new TypeError("Invalid attempt to destructure non-iterable instance");
  36. }
  37. var index = postcss.plugin('postcss-color-gray', opts => root => {
  38. // walk all declarations likely containing a gray() function
  39. root.walkDecls(decl => {
  40. if (hasGrayFunction(decl)) {
  41. const originalValue = decl.value; // parse the declaration value
  42. const ast = parser(originalValue).parse(); // walk every node in the value that contains a gray() function
  43. ast.walk(node => {
  44. const _getFunctionGrayArgs = getFunctionGrayArgs(node),
  45. _getFunctionGrayArgs2 = _slicedToArray(_getFunctionGrayArgs, 2),
  46. lightness = _getFunctionGrayArgs2[0],
  47. alpha = _getFunctionGrayArgs2[1];
  48. if (lightness !== undefined) {
  49. // rename the gray() function to rgb()
  50. node.value = 'rgb'; // convert the lab gray lightness into rgb
  51. const _lab2rgb$map = convertColors.lab2rgb(lightness, 0, 0).map(channel => Math.max(Math.min(Math.round(channel * 2.55), 255), 0)),
  52. _lab2rgb$map2 = _slicedToArray(_lab2rgb$map, 3),
  53. r = _lab2rgb$map2[0],
  54. g = _lab2rgb$map2[1],
  55. b = _lab2rgb$map2[2]; // preserve the slash nodes within rgb()
  56. const openingSlash = node.first;
  57. const closingSlash = node.last;
  58. node.removeAll() // replace the contents of rgb with `(r,g,b`
  59. .append(openingSlash).append(parser.number({
  60. value: r
  61. })).append(parser.comma({
  62. value: ','
  63. })).append(parser.number({
  64. value: g
  65. })).append(parser.comma({
  66. value: ','
  67. })).append(parser.number({
  68. value: b
  69. })); // if an alpha channel was defined
  70. if (alpha < 1) {
  71. // rename the rgb() function to rgba()
  72. node.value += 'a';
  73. node // append the contents of rgba with `,a`
  74. .append(parser.comma({
  75. value: ','
  76. })).append(parser.number({
  77. value: alpha
  78. }));
  79. } // append the contents of rgb/rgba with `)`
  80. node.append(closingSlash);
  81. }
  82. });
  83. const modifiedValue = ast.toString(); // if the modified value has changed from the original value
  84. if (originalValue !== modifiedValue) {
  85. // if the original gray() color is to be preserved
  86. if (Object(opts).preserve) {
  87. // insert the declaration value with the fallback before the current declaration
  88. decl.cloneBefore({
  89. value: modifiedValue
  90. });
  91. } else {
  92. // otherwise, overwrite the declaration value with the fallback
  93. decl.value = modifiedValue;
  94. }
  95. }
  96. }
  97. });
  98. }); // return whether a string contains a gray() function
  99. const hasGrayFunctionRegExp = /(^|[^\w-])gray\(/i;
  100. const hasGrayFunction = decl => hasGrayFunctionRegExp.test(Object(decl).value); // return whether a node matches a specific type
  101. const isNumber = node => Object(node).type === 'number';
  102. const isOperator = node => Object(node).type === 'operator';
  103. const isFunction = node => Object(node).type === 'func';
  104. const isCalcRegExp = /^calc$/i;
  105. const isFunctionCalc = node => isFunction(node) && isCalcRegExp.test(node.value);
  106. const isGrayRegExp = /^gray$/i;
  107. const isFunctionGrayWithArgs = node => isFunction(node) && isGrayRegExp.test(node.value) && node.nodes && node.nodes.length;
  108. const isNumberPercentage = node => isNumber(node) && node.unit === '%';
  109. const isNumberUnitless = node => isNumber(node) && node.unit === '';
  110. const isOperatorSlash = node => isOperator(node) && node.value === '/'; // return valid values from a node, otherwise undefined
  111. const getNumberUnitless = node => isNumberUnitless(node) ? Number(node.value) : undefined;
  112. const getOperatorSlash = node => isOperatorSlash(node) ? null : undefined;
  113. 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
  114. const functionalGrayArgs = [getNumberUnitless, getOperatorSlash, getAlpha];
  115. const getFunctionGrayArgs = node => {
  116. const validArgs = []; // if the node is a gray() function with arguments
  117. if (isFunctionGrayWithArgs(node)) {
  118. // get all the gray() function arguments between `(` and `)`
  119. const nodes = node.nodes.slice(1, -1); // validate each argument
  120. for (const index in nodes) {
  121. const arg = typeof functionalGrayArgs[index] === 'function' ? functionalGrayArgs[index](nodes[index]) : undefined; // if the argument was validated
  122. if (arg !== undefined) {
  123. // push any non-null argument to the valid arguments array
  124. if (arg !== null) {
  125. validArgs.push(arg);
  126. }
  127. } else {
  128. // otherwise, return an empty array
  129. return [];
  130. }
  131. } // return the valid arguments array
  132. return validArgs;
  133. } else {
  134. // otherwise, return an empty array
  135. return [];
  136. }
  137. };
  138. module.exports = index;