dvMinifyCss function

String dvMinifyCss(
  1. String css
)

css without its comments or the whitespace that only made it readable.

The spaces that carry meaning stay: the one between nav and a that makes a descendant selector, the ones around the operators in calc(), and every character inside a string.

Implementation

String dvMinifyCss(String css) {
  final StringBuffer out = StringBuffer();
  int depth = 0;
  int parens = 0;
  bool space = false;
  // Nothing needs a space before it at the start of a file, and nothing needs
  // one after a brace, a semicolon or a comma.
  bool tightAfter = true;

  for (int i = 0; i < css.length; i++) {
    final String c = css[i];

    if (c == '/' && i + 1 < css.length && css[i + 1] == '*') {
      final int end = css.indexOf('*/', i + 2);
      i = end < 0 ? css.length : end + 1;
      // A comment separates two tokens exactly as whitespace does.
      space = true;
      continue;
    }
    if (_isSpace(c)) {
      space = true;
      continue;
    }

    // In a declaration or inside parentheses, `:` separates a property from
    // its value. In a selector it starts a pseudo-class, where the space in
    // `p :first-child` is a combinator and not decoration.
    final bool inValue = depth > 0 || parens > 0;
    final bool selector = depth == 0 && parens == 0;
    final bool combinator = selector && (c == '>' || c == '+' || c == '~');
    final bool tightBefore =
        c == '{' || c == '}' || c == ';' || c == ',' || c == ')' || (c == ':' && inValue) || combinator;
    final bool nowTightAfter =
        c == '{' || c == '}' || c == ';' || c == ',' || c == '(' || (c == ':' && inValue) || combinator;

    if (c == '}') {
      // The last declaration's semicolon closes nothing.
      final String written = out.toString();
      if (written.endsWith(';')) {
        out.clear();
        out.write(written.substring(0, written.length - 1));
      }
    }

    if (space && !tightBefore && !tightAfter && out.isNotEmpty) out.write(' ');
    space = false;

    if (c == '"' || c == "'") {
      final int end = _stringEnd(css, i, c);
      out.write(css.substring(i, end));
      i = end - 1;
      tightAfter = false;
      continue;
    }

    out.write(c);
    tightAfter = nowTightAfter;

    if (c == '{') depth++;
    if (c == '}' && depth > 0) depth--;
    if (c == '(') parens++;
    if (c == ')' && parens > 0) parens--;
  }
  return out.toString().trim();
}