nodeContextLookup.js 1.1 KB

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