--- /dev/null
+/* @flow */
+"use strict";
+const _ = require("lodash");
+const balancedMatch = require("balanced-match");
+
+/**
+ * Replace all of the characters that are arguments to a certain
+ * CSS function with some innocuous character.
+ *
+ * This is useful if you need to use a RegExp to find a string
+ * but want to ignore matches in certain functions (e.g. `url()`,
+ * which might contain all kinds of false positives).
+ *
+ * For example:
+ * blurFunctionArguments("abc url(abc) abc", "url") === "abc url(```) abc"
+ *
+ * @param {string} source
+ * @param {string} functionName
+ * @param {[string]} blurChar="`"
+ * @return {string} - The result string, with the function arguments "blurred"
+ */
+module.exports = function(
+ source /*: string*/,
+ functionName /*: string*/
+) /*: string*/ {
+ const blurChar /*: string*/ =
+ arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "`";
+
+ const nameWithParen = `${functionName.toLowerCase()}(`;
+ const lowerCaseSource = source.toLowerCase();
+ if (!_.includes(lowerCaseSource, nameWithParen)) {
+ return source;
+ }
+
+ const functionNameLength /*: number*/ = functionName.length;
+
+ let result = source;
+ let searchStartIndex = 0;
+ while (lowerCaseSource.indexOf(nameWithParen, searchStartIndex) !== -1) {
+ const openingParenIndex =
+ lowerCaseSource.indexOf(nameWithParen, searchStartIndex) +
+ functionNameLength;
+ const closingParenIndex =
+ balancedMatch("(", ")", lowerCaseSource.slice(openingParenIndex)).end +
+ openingParenIndex;
+ const argumentsLength = closingParenIndex - openingParenIndex - 1;
+ result =
+ result.slice(0, openingParenIndex + 1) +
+ _.repeat(blurChar, argumentsLength) +
+ result.slice(closingParenIndex);
+ searchStartIndex = closingParenIndex;
+ }
+ return result;
+};