parseFunction static method

List<CSSFunctionalNotation> parseFunction(
  1. String value
)

Implementation

static List<CSSFunctionalNotation> parseFunction(final String value) {
  if (_cachedParsedFunction.containsKey(value)) {
    return _cachedParsedFunction[value]!;
  }

  final int valueLength = value.length;
  final List<CSSFunctionalNotation> notations = [];

  int start = 0;
  int left = value.indexOf(_functionStart, start);

  // Function may contain function, should handle this situation.
  while (left != -1 && start < left) {
    String fn = value.substring(start, left);
    int argsBeginIndex = left + 1;
    List<String> argList = [];
    int argBeginIndex = argsBeginIndex;
    // Contain function count.
    int containLeftCount = 0;
    bool match = false;
    // Find all args in this function.
    while (argsBeginIndex < valueLength) {
      // url() function notation should not be split causing it only accept one URL.
      // https://drafts.csswg.org/css-values-3/#urls
      if (fn != _functionNotationUrl && value[argsBeginIndex] == FUNCTION_ARGS_SPLIT) {
        if (containLeftCount == 0 && argBeginIndex < argsBeginIndex) {
          argList.add(value.substring(argBeginIndex, argsBeginIndex));
          argBeginIndex = argsBeginIndex + 1;
        }
      } else if (value[argsBeginIndex] == _functionStart) {
        containLeftCount++;
      } else if (value[argsBeginIndex] == _functionEnd) {
        if (containLeftCount > 0) {
          containLeftCount--;
        } else {
          if (argBeginIndex < argsBeginIndex) {
            argList.add(value.substring(argBeginIndex, argsBeginIndex));
            argBeginIndex = argsBeginIndex + 1;
          }
          // Function parse success when find the matched right parenthesis.
          match = true;
          break;
        }
      }
      argsBeginIndex++;
    }
    if (match) {
      // Only add the right function.
      fn = fn.trim();
      if (fn.startsWith(FUNCTION_SPLIT)) {
        fn = fn
            .substring(
              1,
            )
            .trim();
      }
      notations.add(CSSFunctionalNotation(fn, argList));
    }
    start = argsBeginIndex + 1;
    if (start >= value.length) {
      break;
    }
    left = value.indexOf(_functionStart, start);
  }

  return _cachedParsedFunction[value] = notations;
}