normalizeSelector.cjs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // NOTICE: This file is generated by Rollup. To modify it,
  2. // please instead edit the ESM counterpart and rebuild with Rollup (npm run build).
  3. 'use strict';
  4. const parser = require('postcss-selector-parser');
  5. /** @import { Container, Node, Root, Selector } from 'postcss-selector-parser' */
  6. /**
  7. * Normalize a selector so that it can be more easily compared to other selectors.
  8. *
  9. * @template {Root | Selector} T
  10. * @param {T} node
  11. * @returns {T}
  12. */
  13. function normalizeSelector(node) {
  14. normalizeSelectorNodeWhitespaceAndComments(node);
  15. node.walk(normalizeSelectorNodeWhitespaceAndComments);
  16. normalizeSelectorNodesOrder(node);
  17. return node;
  18. }
  19. /**
  20. * @param {Node} node
  21. */
  22. function normalizeSelectorNodeWhitespaceAndComments(node) {
  23. if (parser.isComment(node)) {
  24. node.remove();
  25. return;
  26. }
  27. node.rawSpaceBefore = '';
  28. node.rawSpaceAfter = '';
  29. node.spaces.before = '';
  30. node.spaces.after = '';
  31. if (parser.isAttribute(node)) {
  32. delete node.spaces.insensitive;
  33. delete node.spaces.operator;
  34. delete node.spaces.attribute;
  35. delete node.spaces.value;
  36. delete node.raws.spaces;
  37. }
  38. }
  39. /**
  40. * @param {Node} node
  41. */
  42. function normalizeSelectorNodesOrder(node) {
  43. if (!parser.isContainer(node)) return;
  44. // Need to sort inside out, not outside in.
  45. // As the parents needs to sorted with their children already in the right order.
  46. node.each(normalizeSelectorNodesOrder);
  47. if (parser.isRoot(node) || parser.isPseudoClass(node) || parser.isPseudoElement(node)) {
  48. const nodes = node.nodes.map((childNode) => {
  49. // Make sure to only stringify the node once.
  50. return { node: childNode, string: childNode.toString() };
  51. });
  52. nodes.sort((a, b) => a.string.localeCompare(b.string));
  53. const uniqueNodes = new Set();
  54. const nodesIndices = new Map();
  55. nodes.forEach((x, i) => {
  56. if (uniqueNodes.has(x.string)) return;
  57. uniqueNodes.add(x.string);
  58. nodesIndices.set(x.node, i);
  59. });
  60. node.nodes = node.nodes
  61. .filter((childNode) => {
  62. return nodesIndices.has(childNode);
  63. })
  64. .sort((a, b) => {
  65. return nodesIndices.get(a) - nodesIndices.get(b);
  66. });
  67. }
  68. }
  69. module.exports = normalizeSelector;