index.es.mjs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import postcss from 'postcss';
  2. import valueParser from 'postcss-values-parser';
  3. var index = postcss.plugin('postcss-color-hex-alpha', opts => {
  4. // whether to preserve the original hexa
  5. const preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false;
  6. return root => {
  7. // for each declaration with a hexa
  8. root.walkDecls(decl => {
  9. if (hasAlphaHex(decl)) {
  10. // replace instances of hexa with rgba()
  11. const ast = valueParser(decl.value).parse();
  12. walk(ast, node => {
  13. if (isAlphaHex(node)) {
  14. node.replaceWith(hexa2rgba(node));
  15. }
  16. }); // conditionally update the declaration
  17. const modifiedValue = String(ast);
  18. if (decl.value !== modifiedValue) {
  19. if (preserve) {
  20. decl.cloneBefore({
  21. value: modifiedValue
  22. });
  23. } else {
  24. decl.value = modifiedValue;
  25. }
  26. }
  27. }
  28. });
  29. };
  30. }); // match any hexa
  31. const alphaHexRegExp = /#([0-9A-Fa-f]{4}(?:[0-9A-Fa-f]{4})?)\b/; // whether a node has a hexa
  32. const hasAlphaHex = node => alphaHexRegExp.test(node.value); // match an exact hexa
  33. const alphaHexValueRegExp = /^#([0-9A-Fa-f]{4}(?:[0-9A-Fa-f]{4})?)$/; // walk all nodes in a value
  34. const walk = (node, fn) => {
  35. if (Object(node.nodes).length) {
  36. node.nodes.slice().forEach(child => {
  37. fn(child);
  38. walk(child, fn);
  39. });
  40. }
  41. }; // decimal precision
  42. const alphaDecimalPrecision = 100000; // match a hexa node
  43. const isAlphaHex = node => node.type === 'word' && alphaHexValueRegExp.test(node.value);
  44. const hexa2rgba = node => {
  45. // hex is the node value
  46. const hex = node.value; // conditionally expand a hex
  47. const hex8 = `0x${hex.length === 5 ? hex.slice(1).replace(/[0-9A-f]/g, '$&$&') : hex.slice(1)}`; // extract the red, blue, green, and alpha values from the hex
  48. const _ref = [parseInt(hex8.slice(2, 4), 16), parseInt(hex8.slice(4, 6), 16), parseInt(hex8.slice(6, 8), 16), Math.round(parseInt(hex8.slice(8, 10), 16) / 255 * alphaDecimalPrecision) / alphaDecimalPrecision],
  49. r = _ref[0],
  50. g = _ref[1],
  51. b = _ref[2],
  52. a = _ref[3]; // return a new rgba function, preserving the whitespace of the original node
  53. const rgbaFunc = valueParser.func({
  54. value: 'rgba',
  55. raws: Object.assign({}, node.raws)
  56. });
  57. rgbaFunc.append(valueParser.paren({
  58. value: '('
  59. }));
  60. rgbaFunc.append(valueParser.number({
  61. value: r
  62. }));
  63. rgbaFunc.append(valueParser.comma({
  64. value: ','
  65. }));
  66. rgbaFunc.append(valueParser.number({
  67. value: g
  68. }));
  69. rgbaFunc.append(valueParser.comma({
  70. value: ','
  71. }));
  72. rgbaFunc.append(valueParser.number({
  73. value: b
  74. }));
  75. rgbaFunc.append(valueParser.comma({
  76. value: ','
  77. }));
  78. rgbaFunc.append(valueParser.number({
  79. value: a
  80. }));
  81. rgbaFunc.append(valueParser.paren({
  82. value: ')'
  83. }));
  84. return rgbaFunc;
  85. };
  86. export default index;
  87. //# sourceMappingURL=index.es.mjs.map