walk.js 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. 'use strict';
  2. var noop = function() {};
  3. function ensureFunction(value) {
  4. return typeof value === 'function' ? value : noop;
  5. }
  6. module.exports = function(node, fn, context) {
  7. function walk(node) {
  8. enter.call(context, node);
  9. switch (node.type) {
  10. case 'Group':
  11. node.terms.forEach(walk);
  12. break;
  13. case 'Function':
  14. case 'Parentheses':
  15. walk(node.children);
  16. break;
  17. case 'Keyword':
  18. case 'Type':
  19. case 'Property':
  20. case 'Combinator':
  21. case 'Comma':
  22. case 'Slash':
  23. case 'String':
  24. case 'Percent':
  25. break;
  26. default:
  27. throw new Error('Unknown type: ' + node.type);
  28. }
  29. leave.call(context, node);
  30. }
  31. var enter = noop;
  32. var leave = noop;
  33. if (typeof fn === 'function') {
  34. enter = fn;
  35. } else if (fn) {
  36. enter = ensureFunction(fn.enter);
  37. leave = ensureFunction(fn.leave);
  38. }
  39. if (enter === noop && leave === noop) {
  40. throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
  41. }
  42. walk(node, context);
  43. };