dvMinifyHtml function

String dvMinifyHtml(
  1. String html
)

html without its comments, its indentation or the whitespace between its tags, with <pre> and <textarea> left exactly as they were written and inline <style> and <script> blocks minified as what they are.

Implementation

String dvMinifyHtml(String html) {
  final StringBuffer out = StringBuffer();
  // The tag last written, and the one coming, decide whether the whitespace
  // between them was a word break or an indent.
  String previousTag = '';
  int i = 0;

  while (i < html.length) {
    final String c = html[i];

    if (c == '<') {
      // A comment. Two kinds survive: `<!--[if IE]>`, which is markup a
      // browser acts on, and `<!-- dartvel:... -->`, which is where the
      // build and the server find the block they replace.
      //
      // Taking a Dartvel marker out is the quiet kind of wrong. The server
      // renders a route by replacing what is between the markers; with no
      // markers its regex matches nothing, so it adds a second block instead
      // of replacing the first, and every page ships the home page's words
      // underneath its own. The page renders and the crawler reads both.
      if (html.startsWith('<!--', i)) {
        final int end = html.indexOf('-->', i + 4);
        final int stop = end < 0 ? html.length : end + 3;
        final String comment = html.substring(i, stop);
        if (comment.startsWith('<!--[') || _isMarker(comment)) {
          out.write(comment);
        }
        i = stop;
        continue;
      }
      final int close = _tagEnd(html, i);
      final String tag = html.substring(i, close);
      final String name = _tagName(tag);
      out.write(tag);
      i = close;

      if (_verbatim.contains(name) && !tag.startsWith('</')) {
        final int end = _closingTag(html, name, i);
        out.write(html.substring(i, end));
        i = end;
        previousTag = name;
        continue;
      }
      if ((name == 'script' || name == 'style') && !tag.startsWith('</')) {
        final int end = _closingTag(html, name, i);
        final String body = html.substring(i, end == html.length ? end : _bodyEnd(html, name, i));
        final String minified = name == 'style'
            ? dvMinifyCss(body)
            : _isJsonScript(tag)
                ? _minifyJson(body)
                : dvMinifyJs(body);
        out.write(minified);
        i = i + body.length;
        previousTag = name;
        continue;
      }
      previousTag = name;
      continue;
    }

    // A text node, up to the next tag.
    final int next = html.indexOf('<', i);
    final int stop = next < 0 ? html.length : next;
    final String text = html.substring(i, stop);
    i = stop;
    final String collapsed = _collapse(text);
    if (collapsed.trim().isEmpty) {
      // Whitespace on its own. Keep one space only where both sides are
      // elements that sit in a line of text.
      final String nextTag = next < 0 ? '' : _tagName(html.substring(next, _tagEnd(html, next)));
      final bool between = _inline.contains(previousTag) && _inline.contains(nextTag);
      if (between && collapsed.isNotEmpty) out.write(' ');
      continue;
    }
    out.write(collapsed);
  }
  return out.toString();
}