4
0

nodeContextLookup.mjs 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. /**
  2. * Create a collection of Maps that serve to contextualize a given node.
  3. * This is useful to ensure that you only compare nodes that share a certain
  4. * context.
  5. *
  6. * All nodes are initially contextualized by their input source.
  7. * From there, you can contextualize them however you want.
  8. *
  9. * For a usage example, see `selector-no-descending-specificity`.
  10. */
  11. export default function nodeContextLookup() {
  12. const contextMap = new Map();
  13. return {
  14. /**
  15. * @param {import('postcss').Node} node
  16. * @param {any[]} subContexts
  17. * @returns {Map<any, any>}
  18. */
  19. getContext(node, ...subContexts) {
  20. if (!node.source) throw new Error('The node source must be present');
  21. const nodeSource = node.source.input.from;
  22. const baseContext = creativeGetMap(contextMap, nodeSource);
  23. return subContexts.reduce((result, context) => creativeGetMap(result, context), baseContext);
  24. },
  25. };
  26. }
  27. /**
  28. * @param {Map<any, any>} someMap
  29. * @param {any} someThing
  30. */
  31. function creativeGetMap(someMap, someThing) {
  32. if (!someMap.has(someThing)) {
  33. someMap.set(someThing, new Map());
  34. }
  35. return someMap.get(someThing);
  36. }