splitTopLevelComma function
Splits the arguments of a CSS function body on the first top-level comma.
Handles nested functions such as rgba(), color-mix() and var(), and
quoted strings — so light-dark(rgba(0, 0, 0, 0.1), #FFF) splits after the
closing ) of rgba, not at its first inner comma.
Returns null when there is no top-level comma.
Implementation
({String before, String after})? splitTopLevelComma(String input) {
var depth = 0;
String? quote;
var isEscaped = false;
for (var i = 0; i < input.length; i++) {
final char = input[i];
// Backslash escaping applies only inside a quoted string, as upstream has
// it. At the top level a backslash is an ordinary character.
if (quote != null) {
if (isEscaped) {
isEscaped = false;
} else if (char == r'\') {
isEscaped = true;
} else if (char == quote) {
quote = null;
}
continue;
}
if (char == '"' || char == "'") {
quote = char;
continue;
}
if (char == '(') {
depth++;
} else if (char == ')') {
// Clamped, so a stray closing paren cannot drive the depth negative and
// swallow every later top-level comma.
depth = math.max(0, depth - 1);
} else if (char == ',' && depth == 0) {
return (before: input.substring(0, i), after: input.substring(i + 1));
}
}
return null;
}