dvMinifyHtml function
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();
}