blob: e37d76e029d4b12c77a9f98ba1099f3388ba27a0 [file] [log] [blame]
/* @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;
};