blurFunctionArguments.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. 'use strict';
  2. const balancedMatch = require('balanced-match');
  3. /**
  4. * Replace all of the characters that are arguments to a certain
  5. * CSS function with some innocuous character.
  6. *
  7. * This is useful if you need to use a RegExp to find a string
  8. * but want to ignore matches in certain functions (e.g. `url()`,
  9. * which might contain all kinds of false positives).
  10. *
  11. * For example:
  12. * blurFunctionArguments("abc url(abc) abc", "url") === "abc url(```) abc"
  13. *
  14. * @param {string} source
  15. * @param {string} functionName
  16. * @return {string} - The result string, with the function arguments "blurred"
  17. */
  18. module.exports = function blurFunctionArguments(source, functionName, blurChar = '`') {
  19. const nameWithParen = `${functionName.toLowerCase()}(`;
  20. const lowerCaseSource = source.toLowerCase();
  21. if (!lowerCaseSource.includes(nameWithParen)) {
  22. return source;
  23. }
  24. const functionNameLength = functionName.length;
  25. let result = source;
  26. let searchStartIndex = 0;
  27. while (lowerCaseSource.includes(nameWithParen, searchStartIndex)) {
  28. const openingParenIndex =
  29. lowerCaseSource.indexOf(nameWithParen, searchStartIndex) + functionNameLength;
  30. const parensMatch = balancedMatch('(', ')', lowerCaseSource.slice(openingParenIndex));
  31. if (!parensMatch) {
  32. throw new Error(`No parens match: "${source}"`);
  33. }
  34. const closingParenIndex = parensMatch.end + openingParenIndex;
  35. const argumentsLength = closingParenIndex - openingParenIndex - 1;
  36. result =
  37. result.slice(0, openingParenIndex + 1) +
  38. blurChar.repeat(argumentsLength) +
  39. result.slice(closingParenIndex);
  40. searchStartIndex = closingParenIndex;
  41. }
  42. return result;
  43. };