scanHtml function

Iterable<Object> scanHtml(
  1. String html
)

Scans html sequentially, yielding HtmlTag and HtmlText tokens in document order. Comments, doctypes, and processing instructions are skipped. Malformed input degrades to text instead of throwing.

Implementation

Iterable<Object> scanHtml(String html) sync* {
  var i = 0;
  final length = html.length;
  while (i < length) {
    final lt = html.indexOf('<', i);
    if (lt == -1) {
      yield HtmlText(html.substring(i), i);
      return;
    }
    if (lt > i) yield HtmlText(html.substring(i, lt), i);
    // Not a tag start (a literal '<' in text): emit it as text and move on.
    if (!_isTagStartAt(html, lt)) {
      yield HtmlText('<', lt);
      i = lt + 1;
      continue;
    }
    final declarationEnd = _skipMarkupDeclaration(html, lt);
    if (declarationEnd != null) {
      i = declarationEnd;
      continue;
    }
    final gt = _findTagEnd(html, lt + 1);
    if (gt == -1) {
      // Unterminated tag at EOF: treat the rest as text.
      yield HtmlText(html.substring(lt), lt);
      return;
    }
    yield* _tagTokens(html, lt, gt);
    i = gt + 1;
  }
}