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.

130 lines
2.9 KiB

4 years ago
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _postcss = require('postcss');
  6. function noop() {}
  7. function trimValue(value) {
  8. return value ? value.trim() : value;
  9. }
  10. function empty(node) {
  11. return !node.nodes.filter(child => child.type !== 'comment').length;
  12. }
  13. function equals(a, b) {
  14. if (a.type !== b.type) {
  15. return false;
  16. }
  17. if (a.important !== b.important) {
  18. return false;
  19. }
  20. if (a.raws && !b.raws || !a.raws && b.raws) {
  21. return false;
  22. }
  23. switch (a.type) {
  24. case 'rule':
  25. if (a.selector !== b.selector) {
  26. return false;
  27. }
  28. break;
  29. case 'atrule':
  30. if (a.name !== b.name || a.params !== b.params) {
  31. return false;
  32. }
  33. if (a.raws && trimValue(a.raws.before) !== trimValue(b.raws.before)) {
  34. return false;
  35. }
  36. if (a.raws && trimValue(a.raws.afterName) !== trimValue(b.raws.afterName)) {
  37. return false;
  38. }
  39. break;
  40. case 'decl':
  41. if (a.prop !== b.prop || a.value !== b.value) {
  42. return false;
  43. }
  44. if (a.raws && trimValue(a.raws.before) !== trimValue(b.raws.before)) {
  45. return false;
  46. }
  47. break;
  48. }
  49. if (a.nodes) {
  50. if (a.nodes.length !== b.nodes.length) {
  51. return false;
  52. }
  53. for (let i = 0; i < a.nodes.length; i++) {
  54. if (!equals(a.nodes[i], b.nodes[i])) {
  55. return false;
  56. }
  57. }
  58. }
  59. return true;
  60. }
  61. function dedupeRule(last, nodes) {
  62. let index = nodes.indexOf(last) - 1;
  63. while (index >= 0) {
  64. const node = nodes[index--];
  65. if (node && node.type === 'rule' && node.selector === last.selector) {
  66. last.each(child => {
  67. if (child.type === 'decl') {
  68. dedupeNode(child, node.nodes);
  69. }
  70. });
  71. if (empty(node)) {
  72. node.remove();
  73. }
  74. }
  75. }
  76. }
  77. function dedupeNode(last, nodes) {
  78. let index = !!~nodes.indexOf(last) ? nodes.indexOf(last) - 1 : nodes.length - 1;
  79. while (index >= 0) {
  80. const node = nodes[index--];
  81. if (node && equals(node, last)) {
  82. node.remove();
  83. }
  84. }
  85. }
  86. const handlers = {
  87. rule: dedupeRule,
  88. atrule: dedupeNode,
  89. decl: dedupeNode,
  90. comment: noop
  91. };
  92. function dedupe(root) {
  93. const { nodes } = root;
  94. if (!nodes) {
  95. return;
  96. }
  97. let index = nodes.length - 1;
  98. while (index >= 0) {
  99. let last = nodes[index--];
  100. if (!last || !last.parent) {
  101. continue;
  102. }
  103. dedupe(last);
  104. handlers[last.type](last, nodes);
  105. }
  106. }
  107. exports.default = (0, _postcss.plugin)('postcss-discard-duplicates', () => dedupe);
  108. module.exports = exports['default'];