index.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. var postcss = require('postcss');
  2. var valueParser = require('postcss-value-parser');
  3. var stringify = valueParser.stringify;
  4. var sort = require('alphanum-sort');
  5. var uniqs = require('uniqs');
  6. /**
  7. * Return the greatest common divisor
  8. * of two numbers.
  9. */
  10. function gcd(a, b) {
  11. return b ? gcd(b, a % b) : a;
  12. }
  13. function aspectRatio(a, b) {
  14. var divisor = gcd(a, b);
  15. return [a / divisor, b / divisor];
  16. }
  17. function split(nodes, div) {
  18. var result = [];
  19. var i, max, node;
  20. var last = '';
  21. for (i = 0, max = nodes.length; i < max; i += 1) {
  22. node = nodes[i];
  23. if (node.type === 'div' && node.value === div) {
  24. result.push(last);
  25. last = '';
  26. } else {
  27. last += stringify(node);
  28. }
  29. }
  30. result.push(last);
  31. return result;
  32. }
  33. function removeNode(node) {
  34. node.value = '';
  35. node.type = 'word';
  36. }
  37. module.exports = postcss.plugin('postcss-minify-params', function () {
  38. return function (css) {
  39. css.walkAtRules(function (rule) {
  40. if (!rule.params) {
  41. return;
  42. }
  43. var params = valueParser(rule.params);
  44. params.walk(function (node, index) {
  45. if (node.type === 'div' || node.type === 'function') {
  46. node.before = node.after = '';
  47. if (
  48. node.type === 'function' &&
  49. node.nodes[4] &&
  50. node.nodes[0].value.indexOf('-aspect-ratio') === 3
  51. ) {
  52. var ref = aspectRatio(
  53. node.nodes[2].value,
  54. node.nodes[4].value
  55. );
  56. var a = ref[0];
  57. var b = ref[1];
  58. node.nodes[2].value = a;
  59. node.nodes[4].value = b;
  60. }
  61. } else if (node.type === 'space') {
  62. node.value = ' ';
  63. } else if (node.type === 'word') {
  64. var prevWord = params.nodes[index - 2];
  65. if (
  66. node.value === 'all' &&
  67. rule.name === 'media' &&
  68. !prevWord
  69. ) {
  70. var nextSpace = params.nodes[index + 1];
  71. var nextWord = params.nodes[index + 2];
  72. var secondSpace = params.nodes[index + 3];
  73. if (nextWord && nextWord.value === 'and') {
  74. removeNode(nextWord);
  75. removeNode(nextSpace);
  76. if (secondSpace) {
  77. removeNode(secondSpace);
  78. }
  79. }
  80. removeNode(node);
  81. }
  82. }
  83. }, true);
  84. rule.params = sort(uniqs(split(params.nodes, ',')), {
  85. insensitive: true
  86. }).join();
  87. if (!rule.params.length) {
  88. rule.raws.afterName = '';
  89. }
  90. });
  91. };
  92. });