functionArgumentsSearch.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. 'use strict';
  2. const balancedMatch = require('balanced-match');
  3. const valueParser = require('postcss-value-parser');
  4. const { assert, isString, isRegExp } = require('./validateTypes');
  5. /**
  6. * Search a CSS string for functions by name.
  7. * For every match, invoke the callback, passing the function's
  8. * "argument(s) string" (whatever is inside the parentheses)
  9. * as an argument.
  10. *
  11. * Callback will be called once for every matching function found,
  12. * with the function's "argument(s) string" and its starting index
  13. * as the arguments.
  14. *
  15. * @param {string} source
  16. * @param {string | RegExp} functionName
  17. * @param {(expression: string, expressionIndex: number) => void} callback
  18. * @returns {void}
  19. */
  20. module.exports = function functionArgumentsSearch(source, functionName, callback) {
  21. valueParser(source).walk((node) => {
  22. if (node.type !== 'function') return;
  23. const { value } = node;
  24. if (isString(functionName) && value !== functionName) return;
  25. if (isRegExp(functionName) && !functionName.test(node.value)) return;
  26. const parensMatch = balancedMatch('(', ')', source.slice(node.sourceIndex));
  27. assert(parensMatch);
  28. const expression = parensMatch.body;
  29. const parenLength = 1; // == '('
  30. const expressionIndex = node.sourceIndex + value.length + parenLength;
  31. callback(expression, expressionIndex);
  32. });
  33. };