int32_t nsHtml5Tokenizer::stateLoop()

in parser/html/nsHtml5Tokenizer.cpp [473:4463]


int32_t nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos,
                                    char16_t* buf, bool reconsume,
                                    int32_t returnState, int32_t endPos) {
  bool reportedConsecutiveHyphens = false;
stateloop:
  for (;;) {
    switch (state) {
      case DATA: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '&': {
              flushChars(buf, pos);
              MOZ_ASSERT(!charRefBufLen,
                         "charRefBufLen not reset after previous use!");
              appendCharRefBuf(c);
              setAdditionalAndRememberAmpersandLocation('\0');
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '<': {
              flushChars(buf, pos);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::TAG_OPEN, reconsume, pos);
              NS_HTML5_BREAK(dataloop);
            }
            case '\0': {
              maybeEmitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      dataloop_end:;
        [[fallthrough]];
      }
      case TAG_OPEN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (c >= 'A' && c <= 'Z') {
            endTag = false;
            clearStrBufBeforeUse();
            appendStrBuf((char16_t)(c + 0x20));
            containsHyphen = false;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
                                  reconsume, pos);
            NS_HTML5_BREAK(tagopenloop);
          } else if (c >= 'a' && c <= 'z') {
            endTag = false;
            clearStrBufBeforeUse();
            appendStrBuf(c);
            containsHyphen = false;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
                                  reconsume, pos);
            NS_HTML5_BREAK(tagopenloop);
          }
          switch (c) {
            case '!': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::MARKUP_DECLARATION_OPEN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '/': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::CLOSE_TAG_OPEN, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\?': {
              if (viewingXmlSource) {
                state = P::transition(mViewSource.get(),
                                      nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
                                      reconsume, pos);
                NS_HTML5_CONTINUE(stateloop);
              }
              if (P::reportErrors) {
                errProcessingInstruction();
              }
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errLtGt();
              }
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
              cstart = pos + 1;
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              if (P::reportErrors) {
                errBadCharAfterLt(c);
              }
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
              cstart = pos;
              reconsume = true;
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      tagopenloop_end:;
        [[fallthrough]];
      }
      case TAG_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              strBufToElementNameString();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              strBufToElementNameString();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(tagnameloop);
            }
            case '/': {
              strBufToElementNameString();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              strBufToElementNameString();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              } else if (c == '-') {
                containsHyphen = true;
              }
              appendStrBuf(c);
              continue;
            }
          }
        }
      tagnameloop_end:;
        [[fallthrough]];
      }
      case BEFORE_ATTRIBUTE_NAME: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '/': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '\"':
            case '\'':
            case '<':
            case '=': {
              if (P::reportErrors) {
                errBadCharBeforeAttributeNameOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              }
              attributeLine = line;
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
                                    pos);
              NS_HTML5_BREAK(beforeattributenameloop);
            }
          }
        }
      beforeattributenameloop_end:;
        [[fallthrough]];
      }
      case ATTRIBUTE_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              attributeNameComplete();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              attributeNameComplete();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '/': {
              attributeNameComplete();
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '=': {
              attributeNameComplete();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
                                    reconsume, pos);
              NS_HTML5_BREAK(attributenameloop);
            }
            case '>': {
              attributeNameComplete();
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '\"':
            case '\'':
            case '<': {
              if (P::reportErrors) {
                errQuoteOrLtInAttributeNameOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              }
              appendStrBuf(c);
              continue;
            }
          }
        }
      attributenameloop_end:;
        [[fallthrough]];
      }
      case BEFORE_ATTRIBUTE_VALUE: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '\"': {
              attributeLine = line;
              clearStrBufBeforeUse();
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED,
                                reconsume, pos);
              NS_HTML5_BREAK(beforeattributevalueloop);
            }
            case '&': {
              attributeLine = line;
              clearStrBufBeforeUse();
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
                                    reconsume, pos);

              NS_HTML5_CONTINUE(stateloop);
            }
            case '\'': {
              attributeLine = line;
              clearStrBufBeforeUse();
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errAttributeValueMissing();
              }
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '<':
            case '=':
            case '`': {
              if (P::reportErrors) {
                errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              attributeLine = line;
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
                                    reconsume, pos);

              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      beforeattributevalueloop_end:;
        [[fallthrough]];
      }
      case ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\"': {
              addAttributeWithValue();
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
                                reconsume, pos);
              NS_HTML5_BREAK(attributevaluedoublequotedloop);
            }
            case '&': {
              MOZ_ASSERT(!charRefBufLen,
                         "charRefBufLen not reset after previous use!");
              appendCharRefBuf(c);
              setAdditionalAndRememberAmpersandLocation('\"');
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      attributevaluedoublequotedloop_end:;
        [[fallthrough]];
      }
      case AFTER_ATTRIBUTE_VALUE_QUOTED: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '/': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_BREAK(afterattributevaluequotedloop);
            }
            case '>': {
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              if (P::reportErrors) {
                errNoSpaceBetweenAttributes();
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      afterattributevaluequotedloop_end:;
        [[fallthrough]];
      }
      case SELF_CLOSING_START_TAG: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '>': {
            state =
                P::transition(mViewSource.get(), emitCurrentTagToken(true, pos),
                              reconsume, pos);
            if (shouldSuspend) {
              NS_HTML5_BREAK(stateloop);
            }
            NS_HTML5_CONTINUE(stateloop);
          }
          default: {
            if (P::reportErrors) {
              errSlashNotFollowedByGt();
            }
            reconsume = true;
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
      }
      case ATTRIBUTE_VALUE_UNQUOTED: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              addAttributeWithValue();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              addAttributeWithValue();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '&': {
              MOZ_ASSERT(!charRefBufLen,
                         "charRefBufLen not reset after previous use!");
              appendCharRefBuf(c);
              setAdditionalAndRememberAmpersandLocation('>');
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              addAttributeWithValue();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '<':
            case '\"':
            case '\'':
            case '=':
            case '`': {
              if (P::reportErrors) {
                errUnquotedAttributeValOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      }
      case AFTER_ATTRIBUTE_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '/': {
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '=': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '\"':
            case '\'':
            case '<': {
              if (P::reportErrors) {
                errQuoteOrLtInAttributeNameOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              addAttributeWithoutValue();
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              }
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case MARKUP_DECLARATION_OPEN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::MARKUP_DECLARATION_HYPHEN,
                                    reconsume, pos);
              NS_HTML5_BREAK(markupdeclarationopenloop);
            }
            case 'd':
            case 'D': {
              clearStrBufBeforeUse();
              appendStrBuf(c);
              index = 0;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::MARKUP_DECLARATION_OCTYPE,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '[': {
              if (tokenHandler->cdataSectionAllowed()) {
                clearStrBufBeforeUse();
                appendStrBuf(c);
                index = 0;
                state = P::transition(mViewSource.get(),
                                      nsHtml5Tokenizer::CDATA_START, reconsume,
                                      pos);
                NS_HTML5_CONTINUE(stateloop);
              }
              [[fallthrough]];
            }
            default: {
              if (P::reportErrors) {
                errBogusComment();
              }
              clearStrBufBeforeUse();
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      markupdeclarationopenloop_end:;
        [[fallthrough]];
      }
      case MARKUP_DECLARATION_HYPHEN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              clearStrBufAfterOneHyphen();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_START, reconsume,
                                    pos);
              NS_HTML5_BREAK(markupdeclarationhyphenloop);
            }
            default: {
              if (P::reportErrors) {
                errBogusComment();
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      markupdeclarationhyphenloop_end:;
        [[fallthrough]];
      }
      case COMMENT_START: {
        reportedConsecutiveHyphens = false;
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_START_DASH,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errPrematureEndOfComment();
              }
              emitComment(0, pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(commentstartloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(commentstartloop);
            }
          }
        }
      commentstartloop_end:;
        [[fallthrough]];
      }
      case COMMENT: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_END_DASH,
                                    reconsume, pos);
              NS_HTML5_BREAK(commentloop);
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      commentloop_end:;
        [[fallthrough]];
      }
      case COMMENT_END_DASH: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              appendStrBuf(c);
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::COMMENT_END, reconsume, pos);
              NS_HTML5_BREAK(commentenddashloop);
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      commentenddashloop_end:;
        [[fallthrough]];
      }
      case COMMENT_END: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '>': {
              emitComment(2, pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '-': {
              adjustDoubleHyphenAndAppendToStrBufAndErr(
                  c, reportedConsecutiveHyphens);
              reportedConsecutiveHyphens = true;
              continue;
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              adjustDoubleHyphenAndAppendToStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              adjustDoubleHyphenAndAppendToStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '!': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_END_BANG,
                                    reconsume, pos);
              NS_HTML5_BREAK(commentendloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              adjustDoubleHyphenAndAppendToStrBufAndErr(
                  c, reportedConsecutiveHyphens);
              reportedConsecutiveHyphens = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      commentendloop_end:;
        [[fallthrough]];
      }
      case COMMENT_END_BANG: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '>': {
              emitComment(3, pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_END_DASH,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case COMMENT_LESSTHAN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '!': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG,
                                    reconsume, pos);
              NS_HTML5_BREAK(commentlessthanloop);
            }
            case '<': {
              appendStrBuf(c);
              continue;
            }
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_END_DASH,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      commentlessthanloop_end:;
        [[fallthrough]];
      }
      case COMMENT_LESSTHAN_BANG: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              appendStrBuf(c);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH, reconsume, pos);
              NS_HTML5_BREAK(commentlessthanbangloop);
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      commentlessthanbangloop_end:;
        [[fallthrough]];
      }
      case COMMENT_LESSTHAN_BANG_DASH: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '-': {
            appendStrBuf(c);
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH,
                              reconsume, pos);
            break;
          }
          case '<': {
            appendStrBuf(c);
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
                                  pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\r': {
            appendStrBufCarriageReturn<P>();
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_BREAK(stateloop);
          }
          case '\n': {
            appendStrBufLineFeed<P>();
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\0': {
            c = 0xfffd;
            [[fallthrough]];
          }
          default: {
            appendStrBuf(c);
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
        [[fallthrough]];
      }
      case COMMENT_LESSTHAN_BANG_DASH_DASH: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '>': {
            appendStrBuf(c);
            emitComment(3, pos);
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                  reconsume, pos);
            if (shouldSuspend) {
              NS_HTML5_BREAK(stateloop);
            }
            NS_HTML5_CONTINUE(stateloop);
          }
          case '-': {
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state =
                P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
                              reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\r': {
            c = '\n';
            P::silentCarriageReturn(this);
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_BREAK(stateloop);
          }
          case '\n': {
            P::silentLineFeed(this);
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '!': {
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::COMMENT_END_BANG, reconsume,
                                  pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\0': {
            c = 0xfffd;
            [[fallthrough]];
          }
          default: {
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
      }
      case COMMENT_START_DASH: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '-': {
            appendStrBuf(c);
            state =
                P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
                              reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '>': {
            if (P::reportErrors) {
              errPrematureEndOfComment();
            }
            emitComment(1, pos);
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                  reconsume, pos);
            if (shouldSuspend) {
              NS_HTML5_BREAK(stateloop);
            }
            NS_HTML5_CONTINUE(stateloop);
          }
          case '<': {
            appendStrBuf(c);
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
                                  pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\r': {
            appendStrBufCarriageReturn<P>();
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_BREAK(stateloop);
          }
          case '\n': {
            appendStrBufLineFeed<P>();
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\0': {
            c = 0xfffd;
            [[fallthrough]];
          }
          default: {
            appendStrBuf(c);
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
      }
      case CDATA_START: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (index < 6) {
            if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
              appendStrBuf(c);
            } else {
              if (P::reportErrors) {
                errBogusComment();
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            index++;
            continue;
          } else {
            clearStrBufAfterUse();
            cstart = pos;
            reconsume = true;
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
            break;
          }
        }
        [[fallthrough]];
      }
      case CDATA_SECTION: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case ']': {
              flushChars(buf, pos);
              state =
                  P::transition(mViewSource.get(), nsHtml5Tokenizer::CDATA_RSQB,
                                reconsume, pos);
              NS_HTML5_BREAK(cdatasectionloop);
            }
            case '\0': {
              maybeEmitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      cdatasectionloop_end:;
        [[fallthrough]];
      }
      case CDATA_RSQB: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case ']': {
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::CDATA_RSQB_RSQB, reconsume,
                                  pos);
            break;
          }
          default: {
            tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
            cstart = pos;
            reconsume = true;
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
        [[fallthrough]];
      }
      case CDATA_RSQB_RSQB: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case ']': {
              tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
              continue;
            }
            case '>': {
              cstart = pos + 1;
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              suspendIfRequestedAfterCurrentNonTextToken();
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
              cstart = pos;
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::CDATA_SECTION, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case ATTRIBUTE_VALUE_SINGLE_QUOTED: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\'': {
              addAttributeWithValue();
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '&': {
              MOZ_ASSERT(!charRefBufLen,
                         "charRefBufLen not reset after previous use!");
              appendCharRefBuf(c);
              setAdditionalAndRememberAmpersandLocation('\'');
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
                                reconsume, pos);
              NS_HTML5_BREAK(attributevaluesinglequotedloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      attributevaluesinglequotedloop_end:;
        [[fallthrough]];
      }
      case CONSUME_CHARACTER_REFERENCE: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case ' ':
          case '\t':
          case '\n':
          case '\r':
          case '\f':
          case '<':
          case '&':
          case '\0':
          case ';': {
            emitOrAppendCharRefBuf(returnState);
            if (!(returnState & DATA_AND_RCDATA_MASK)) {
              cstart = pos;
            }
            reconsume = true;
            state =
                P::transition(mViewSource.get(), returnState, reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '#': {
            appendCharRefBuf('#');
            state =
                P::transition(mViewSource.get(), nsHtml5Tokenizer::CONSUME_NCR,
                              reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          default: {
            if (c == additional) {
              emitOrAppendCharRefBuf(returnState);
              reconsume = true;
              state =
                  P::transition(mViewSource.get(), returnState, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            if (c >= 'a' && c <= 'z') {
              firstCharKey = c - 'a' + 26;
            } else if (c >= 'A' && c <= 'Z') {
              firstCharKey = c - 'A';
            } else {
              if (c == ';') {
                if (P::reportErrors) {
                  errNoNamedCharacterMatch();
                }
              }
              emitOrAppendCharRefBuf(returnState);
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos;
              }
              reconsume = true;
              state =
                  P::transition(mViewSource.get(), returnState, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            appendCharRefBuf(c);
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP,
                              reconsume, pos);
            break;
          }
        }
        [[fallthrough]];
      }
      case CHARACTER_REFERENCE_HILO_LOOKUP: {
        {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          int32_t hilo = 0;
          if (c <= 'z') {
            const int32_t* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c];
            if (row) {
              hilo = row[firstCharKey];
            }
          }
          if (!hilo) {
            if (c == ';') {
              if (P::reportErrors) {
                errNoNamedCharacterMatch();
              }
            }
            emitOrAppendCharRefBuf(returnState);
            if (!(returnState & DATA_AND_RCDATA_MASK)) {
              cstart = pos;
            }
            reconsume = true;
            state =
                P::transition(mViewSource.get(), returnState, reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          appendCharRefBuf(c);
          lo = hilo & 0xFFFF;
          hi = hilo >> 16;
          entCol = -1;
          candidate = -1;
          charRefBufMark = 0;
          state = P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL,
                                reconsume, pos);
        }
        [[fallthrough]];
      }
      case CHARACTER_REFERENCE_TAIL: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          entCol++;
          for (;;) {
            if (hi < lo) {
              NS_HTML5_BREAK(outer);
            }
            if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
              candidate = lo;
              charRefBufMark = charRefBufLen;
              lo++;
            } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
              NS_HTML5_BREAK(outer);
            } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
              lo++;
            } else {
              NS_HTML5_BREAK(loloop);
            }
          }
        loloop_end:;
          for (;;) {
            if (hi < lo) {
              NS_HTML5_BREAK(outer);
            }
            if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
              NS_HTML5_BREAK(hiloop);
            }
            if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
              NS_HTML5_BREAK(outer);
            } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
              hi--;
            } else {
              NS_HTML5_BREAK(hiloop);
            }
          }
        hiloop_end:;
          if (c == ';') {
            if (entCol + 1 == nsHtml5NamedCharacters::NAMES[lo].length()) {
              candidate = lo;
              charRefBufMark = charRefBufLen;
            }
            NS_HTML5_BREAK(outer);
          }
          if (hi < lo) {
            NS_HTML5_BREAK(outer);
          }
          appendCharRefBuf(c);
          continue;
        }
      outer_end:;
        if (candidate == -1) {
          if (c == ';') {
            if (P::reportErrors) {
              errNoNamedCharacterMatch();
            }
          }
          emitOrAppendCharRefBuf(returnState);
          if (!(returnState & DATA_AND_RCDATA_MASK)) {
            cstart = pos;
          }
          reconsume = true;
          state = P::transition(mViewSource.get(), returnState, reconsume, pos);
          NS_HTML5_CONTINUE(stateloop);
        } else {
          const nsHtml5CharacterName& candidateName =
              nsHtml5NamedCharacters::NAMES[candidate];
          if (!candidateName.length() ||
              candidateName.charAt(candidateName.length() - 1) != ';') {
            if ((returnState & DATA_AND_RCDATA_MASK)) {
              char16_t ch;
              if (charRefBufMark == charRefBufLen) {
                ch = c;
              } else {
                ch = charRefBuf[charRefBufMark];
              }
              if (ch == '=' || (ch >= '0' && ch <= '9') ||
                  (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
                if (c == ';') {
                  if (P::reportErrors) {
                    errNoNamedCharacterMatch();
                  }
                }
                appendCharRefBufToStrBuf();
                reconsume = true;
                state = P::transition(mViewSource.get(), returnState, reconsume,
                                      pos);
                NS_HTML5_CONTINUE(stateloop);
              }
            }
            if ((returnState & DATA_AND_RCDATA_MASK)) {
              if (P::reportErrors) {
                errUnescapedAmpersandInterpretedAsCharacterReference();
              }
            } else {
              if (P::reportErrors) {
                errNotSemicolonTerminated();
              }
            }
          }
          P::completedNamedCharacterReference(mViewSource.get());
          const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
          if (!val[1]) {
            emitOrAppendOne(val, returnState);
          } else {
            emitOrAppendTwo(val, returnState);
          }
          if (charRefBufMark < charRefBufLen) {
            if ((returnState & DATA_AND_RCDATA_MASK)) {
              appendStrBuf(charRefBuf, charRefBufMark,
                           charRefBufLen - charRefBufMark);
            } else {
              tokenHandler->characters(charRefBuf, charRefBufMark,
                                       charRefBufLen - charRefBufMark);
            }
          }
          bool earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
          charRefBufLen = 0;
          if (!(returnState & DATA_AND_RCDATA_MASK)) {
            cstart = earlyBreak ? pos + 1 : pos;
          }
          reconsume = !earlyBreak;
          state = P::transition(mViewSource.get(), returnState, reconsume, pos);
          NS_HTML5_CONTINUE(stateloop);
        }
      }
      case CONSUME_NCR: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        value = 0;
        seenDigits = false;
        switch (c) {
          case 'x':
          case 'X': {
            appendCharRefBuf(c);
            state =
                P::transition(mViewSource.get(), nsHtml5Tokenizer::HEX_NCR_LOOP,
                              reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          default: {
            reconsume = true;
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::DECIMAL_NRC_LOOP, reconsume,
                                  pos);
            break;
          }
        }
        [[fallthrough]];
      }
      case DECIMAL_NRC_LOOP: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          MOZ_ASSERT(value >= 0, "value must not become negative.");
          if (c >= '0' && c <= '9') {
            seenDigits = true;
            if (value <= 0x10FFFF) {
              value *= 10;
              value += c - '0';
            }
            continue;
          } else if (c == ';') {
            if (seenDigits) {
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos + 1;
              }
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::HANDLE_NCR_VALUE,
                                    reconsume, pos);
              NS_HTML5_BREAK(decimalloop);
            } else {
              if (P::reportErrors) {
                errNoDigitsInNCR();
              }
              appendCharRefBuf(';');
              emitOrAppendCharRefBuf(returnState);
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos + 1;
              }
              state =
                  P::transition(mViewSource.get(), returnState, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          } else {
            if (!seenDigits) {
              if (P::reportErrors) {
                errNoDigitsInNCR();
              }
              emitOrAppendCharRefBuf(returnState);
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos;
              }
              reconsume = true;
              state =
                  P::transition(mViewSource.get(), returnState, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            } else {
              if (P::reportErrors) {
                errCharRefLacksSemicolon();
              }
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos;
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::HANDLE_NCR_VALUE,
                                    reconsume, pos);
              NS_HTML5_BREAK(decimalloop);
            }
          }
        }
      decimalloop_end:;
        [[fallthrough]];
      }
      case HANDLE_NCR_VALUE: {
        charRefBufLen = 0;
        handleNcrValue(returnState);
        state = P::transition(mViewSource.get(), returnState, reconsume, pos);
        NS_HTML5_CONTINUE(stateloop);
      }
      case HEX_NCR_LOOP: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          MOZ_ASSERT(value >= 0, "value must not become negative.");
          if (c >= '0' && c <= '9') {
            seenDigits = true;
            if (value <= 0x10FFFF) {
              value *= 16;
              value += c - '0';
            }
            continue;
          } else if (c >= 'A' && c <= 'F') {
            seenDigits = true;
            if (value <= 0x10FFFF) {
              value *= 16;
              value += c - 'A' + 10;
            }
            continue;
          } else if (c >= 'a' && c <= 'f') {
            seenDigits = true;
            if (value <= 0x10FFFF) {
              value *= 16;
              value += c - 'a' + 10;
            }
            continue;
          } else if (c == ';') {
            if (seenDigits) {
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos + 1;
              }
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::HANDLE_NCR_VALUE,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            } else {
              if (P::reportErrors) {
                errNoDigitsInNCR();
              }
              appendCharRefBuf(';');
              emitOrAppendCharRefBuf(returnState);
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos + 1;
              }
              state =
                  P::transition(mViewSource.get(), returnState, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          } else {
            if (!seenDigits) {
              if (P::reportErrors) {
                errNoDigitsInNCR();
              }
              emitOrAppendCharRefBuf(returnState);
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos;
              }
              reconsume = true;
              state =
                  P::transition(mViewSource.get(), returnState, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            } else {
              if (P::reportErrors) {
                errCharRefLacksSemicolon();
              }
              if (!(returnState & DATA_AND_RCDATA_MASK)) {
                cstart = pos;
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::HANDLE_NCR_VALUE,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case PLAINTEXT: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\0': {
              emitPlaintextReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      }
      case CLOSE_TAG_OPEN: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '>': {
            if (P::reportErrors) {
              errLtSlashGt();
            }
            cstart = pos + 1;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\r': {
            P::silentCarriageReturn(this);
            if (P::reportErrors) {
              errGarbageAfterLtSlash();
            }
            clearStrBufBeforeUse();
            appendStrBuf('\n');
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
            NS_HTML5_BREAK(stateloop);
          }
          case '\n': {
            P::silentLineFeed(this);
            if (P::reportErrors) {
              errGarbageAfterLtSlash();
            }
            clearStrBufBeforeUse();
            appendStrBuf(c);
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\0': {
            c = 0xfffd;
            [[fallthrough]];
          }
          default: {
            if (c >= 'A' && c <= 'Z') {
              c += 0x20;
            }
            if (c >= 'a' && c <= 'z') {
              endTag = true;
              clearStrBufBeforeUse();
              appendStrBuf(c);
              containsHyphen = false;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::TAG_NAME, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            } else {
              if (P::reportErrors) {
                errGarbageAfterLtSlash();
              }
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case RCDATA: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '&': {
              flushChars(buf, pos);
              MOZ_ASSERT(!charRefBufLen,
                         "charRefBufLen not reset after previous use!");
              appendCharRefBuf(c);
              setAdditionalAndRememberAmpersandLocation('\0');
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '<': {
              flushChars(buf, pos);
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      }
      case RAWTEXT: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '<': {
              flushChars(buf, pos);
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
                                reconsume, pos);
              NS_HTML5_BREAK(rawtextloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      rawtextloop_end:;
        [[fallthrough]];
      }
      case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '/': {
              index = 0;
              clearStrBufBeforeUse();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(rawtextrcdatalessthansignloop);
            }
            default: {
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
              cstart = pos;
              reconsume = true;
              state =
                  P::transition(mViewSource.get(), returnState, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      rawtextrcdatalessthansignloop_end:;
        [[fallthrough]];
      }
      case NON_DATA_END_TAG_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (!endTagExpectationAsArray) {
            tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
            cstart = pos;
            reconsume = true;
            state =
                P::transition(mViewSource.get(), returnState, reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          } else if (index < endTagExpectationAsArray.length) {
            char16_t e = endTagExpectationAsArray[index];
            char16_t folded = c;
            if (c >= 'A' && c <= 'Z') {
              folded += 0x20;
            }
            if (folded != e) {
              tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
              emitStrBuf();
              cstart = pos;
              reconsume = true;
              state =
                  P::transition(mViewSource.get(), returnState, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            appendStrBuf(c);
            index++;
            continue;
          } else {
            endTag = true;
            tagName = endTagExpectation;
            switch (c) {
              case '\r': {
                P::silentCarriageReturn(this);
                clearStrBufAfterUse();
                state = P::transition(mViewSource.get(),
                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                      reconsume, pos);
                NS_HTML5_BREAK(stateloop);
              }
              case '\n': {
                P::silentLineFeed(this);
                [[fallthrough]];
              }
              case ' ':
              case '\t':
              case '\f': {
                clearStrBufAfterUse();
                state = P::transition(mViewSource.get(),
                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                      reconsume, pos);
                NS_HTML5_CONTINUE(stateloop);
              }
              case '/': {
                clearStrBufAfterUse();
                state = P::transition(mViewSource.get(),
                                      nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                      reconsume, pos);
                NS_HTML5_CONTINUE(stateloop);
              }
              case '>': {
                clearStrBufAfterUse();
                state = P::transition(mViewSource.get(),
                                      emitCurrentTagToken(false, pos),
                                      reconsume, pos);
                if (shouldSuspend) {
                  NS_HTML5_BREAK(stateloop);
                }
                NS_HTML5_CONTINUE(stateloop);
              }
              default: {
                tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
                emitStrBuf();
                cstart = pos;
                reconsume = true;
                state = P::transition(mViewSource.get(), returnState, reconsume,
                                      pos);
                NS_HTML5_CONTINUE(stateloop);
              }
            }
          }
        }
      }
      case BOGUS_COMMENT: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '>': {
              emitComment(0, pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN,
                                    reconsume, pos);
              NS_HTML5_BREAK(boguscommentloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      boguscommentloop_end:;
        [[fallthrough]];
      }
      case BOGUS_COMMENT_HYPHEN: {
      boguscommenthyphenloop:
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '>': {
              emitComment(0, pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '-': {
              appendSecondHyphenToBogusComment();
              NS_HTML5_CONTINUE(boguscommenthyphenloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case SCRIPT_DATA: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '<': {
              flushChars(buf, pos);
              returnState = state;
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos);
              NS_HTML5_BREAK(scriptdataloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      scriptdataloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_LESS_THAN_SIGN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '/': {
              index = 0;
              clearStrBufBeforeUse();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '!': {
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
              cstart = pos;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START,
                                    reconsume, pos);
              NS_HTML5_BREAK(scriptdatalessthansignloop);
            }
            default: {
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
              cstart = pos;
              reconsume = true;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdatalessthansignloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_ESCAPE_START: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START_DASH,
                                reconsume, pos);
              NS_HTML5_BREAK(scriptdataescapestartloop);
            }
            default: {
              reconsume = true;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdataescapestartloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_ESCAPE_START_DASH: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
                                reconsume, pos);
              NS_HTML5_BREAK(scriptdataescapestartdashloop);
            }
            default: {
              reconsume = true;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdataescapestartdashloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_ESCAPED_DASH_DASH: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              continue;
            }
            case '<': {
              flushChars(buf, pos);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_BREAK(scriptdataescapeddashdashloop);
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_BREAK(scriptdataescapeddashdashloop);
            }
          }
        }
      scriptdataescapeddashdashloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_ESCAPED: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '-': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH,
                                    reconsume, pos);
              NS_HTML5_BREAK(scriptdataescapedloop);
            }
            case '<': {
              flushChars(buf, pos);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      scriptdataescapedloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_ESCAPED_DASH: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '<': {
              flushChars(buf, pos);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
                  reconsume, pos);
              NS_HTML5_BREAK(scriptdataescapeddashloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdataescapeddashloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '/': {
              index = 0;
              clearStrBufBeforeUse();
              returnState = nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case 'S':
            case 's': {
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
              cstart = pos;
              index = 1;
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume,
                  pos);
              NS_HTML5_BREAK(scriptdataescapedlessthanloop);
            }
            default: {
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
              cstart = pos;
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdataescapedlessthanloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_DOUBLE_ESCAPE_START: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          MOZ_ASSERT(index > 0);
          if (index < 6) {
            char16_t folded = c;
            if (c >= 'A' && c <= 'Z') {
              folded += 0x20;
            }
            if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            index++;
            continue;
          }
          switch (c) {
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f':
            case '/':
            case '>': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_BREAK(scriptdatadoubleescapestartloop);
            }
            default: {
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdatadoubleescapestartloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_DOUBLE_ESCAPED: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '-': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume,
                  pos);
              NS_HTML5_BREAK(scriptdatadoubleescapedloop);
            }
            case '<': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      scriptdatadoubleescapedloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH,
                  reconsume, pos);
              NS_HTML5_BREAK(scriptdatadoubleescapeddashloop);
            }
            case '<': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdatadoubleescapeddashloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              continue;
            }
            case '<': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
                  reconsume, pos);
              NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop);
            }
            case '>': {
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              emitReplacementCharacter(buf, pos);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdatadoubleescapeddashdashloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '/': {
              index = 0;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_END,
                                reconsume, pos);
              NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop);
            }
            default: {
              reconsume = true;
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      scriptdatadoubleescapedlessthanloop_end:;
        [[fallthrough]];
      }
      case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (index < 6) {
            char16_t folded = c;
            if (c >= 'A' && c <= 'Z') {
              folded += 0x20;
            }
            if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
              reconsume = true;
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            index++;
            continue;
          }
          switch (c) {
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f':
            case '/':
            case '>': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              reconsume = true;
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case MARKUP_DECLARATION_OCTYPE: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (index < 6) {
            char16_t folded = c;
            if (c >= 'A' && c <= 'Z') {
              folded += 0x20;
            }
            if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
              appendStrBuf(c);
            } else {
              if (P::reportErrors) {
                errBogusComment();
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            index++;
            continue;
          } else {
            reconsume = true;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DOCTYPE,
                                  reconsume, pos);
            NS_HTML5_BREAK(markupdeclarationdoctypeloop);
          }
        }
      markupdeclarationdoctypeloop_end:;
        [[fallthrough]];
      }
      case DOCTYPE: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          initDoctypeFields();
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(doctypeloop);
            }
            default: {
              if (P::reportErrors) {
                errMissingSpaceBeforeDoctypeName();
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(doctypeloop);
            }
          }
        }
      doctypeloop_end:;
        [[fallthrough]];
      }
      case BEFORE_DOCTYPE_NAME: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '>': {
              if (P::reportErrors) {
                errNamelessDoctype();
              }
              forceQuirks = true;
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              }
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::DOCTYPE_NAME, reconsume, pos);
              NS_HTML5_BREAK(beforedoctypenameloop);
            }
          }
        }
      beforedoctypenameloop_end:;
        [[fallthrough]];
      }
      case DOCTYPE_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              strBufToDoctypeName();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              strBufToDoctypeName();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(doctypenameloop);
            }
            case '>': {
              strBufToDoctypeName();
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              if (c >= 'A' && c <= 'Z') {
                c += 0x0020;
              }
              appendStrBuf(c);
              continue;
            }
          }
        }
      doctypenameloop_end:;
        [[fallthrough]];
      }
      case AFTER_DOCTYPE_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '>': {
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case 'p':
            case 'P': {
              index = 0;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::DOCTYPE_UBLIC, reconsume,
                                    pos);
              NS_HTML5_BREAK(afterdoctypenameloop);
            }
            case 's':
            case 'S': {
              index = 0;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::DOCTYPE_YSTEM, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              bogusDoctype();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      afterdoctypenameloop_end:;
        [[fallthrough]];
      }
      case DOCTYPE_UBLIC: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (index < 5) {
            char16_t folded = c;
            if (c >= 'A' && c <= 'Z') {
              folded += 0x20;
            }
            if (folded != nsHtml5Tokenizer::UBLIC[index]) {
              bogusDoctype();
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            index++;
            continue;
          } else {
            reconsume = true;
            state = P::transition(
                mViewSource.get(),
                nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
            NS_HTML5_BREAK(doctypeublicloop);
          }
        }
      doctypeublicloop_end:;
        [[fallthrough]];
      }
      case AFTER_DOCTYPE_PUBLIC_KEYWORD: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
                  pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
                  pos);
              NS_HTML5_BREAK(afterdoctypepublickeywordloop);
            }
            case '\"': {
              if (P::reportErrors) {
                errNoSpaceBetweenDoctypePublicKeywordAndQuote();
              }
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\'': {
              if (P::reportErrors) {
                errNoSpaceBetweenDoctypePublicKeywordAndQuote();
              }
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errExpectedPublicId();
              }
              forceQuirks = true;
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              bogusDoctype();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      afterdoctypepublickeywordloop_end:;
        [[fallthrough]];
      }
      case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '\"': {
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
            }
            case '\'': {
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errExpectedPublicId();
              }
              forceQuirks = true;
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              bogusDoctype();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      beforedoctypepublicidentifierloop_end:;
        [[fallthrough]];
      }
      case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\"': {
              publicIdentifier = strBufToString();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
                  pos);
              NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
            }
            case '>': {
              if (P::reportErrors) {
                errGtInPublicId();
              }
              forceQuirks = true;
              publicIdentifier = strBufToString();
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      doctypepublicidentifierdoublequotedloop_end:;
        [[fallthrough]];
      }
      case AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::
                      BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
                  reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::
                      BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
                  reconsume, pos);
              NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
            }
            case '>': {
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\"': {
              if (P::reportErrors) {
                errNoSpaceBetweenPublicAndSystemIds();
              }
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\'': {
              if (P::reportErrors) {
                errNoSpaceBetweenPublicAndSystemIds();
              }
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              bogusDoctype();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      afterdoctypepublicidentifierloop_end:;
        [[fallthrough]];
      }
      case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '>': {
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\"': {
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop);
            }
            case '\'': {
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              bogusDoctype();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      betweendoctypepublicandsystemidentifiersloop_end:;
        [[fallthrough]];
      }
      case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\"': {
              systemIdentifier = strBufToString();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
                  pos);
              NS_HTML5_BREAK(doctypesystemidentifierdoublequotedloop);
            }
            case '>': {
              if (P::reportErrors) {
                errGtInSystemId();
              }
              forceQuirks = true;
              systemIdentifier = strBufToString();
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      doctypesystemidentifierdoublequotedloop_end:;
        [[fallthrough]];
      }
      case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '>': {
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              bogusDoctypeWithoutQuirks();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_BREAK(afterdoctypesystemidentifierloop);
            }
          }
        }
      afterdoctypesystemidentifierloop_end:;
        [[fallthrough]];
      }
      case BOGUS_DOCTYPE: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '>': {
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      }
      case DOCTYPE_YSTEM: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (index < 5) {
            char16_t folded = c;
            if (c >= 'A' && c <= 'Z') {
              folded += 0x20;
            }
            if (folded != nsHtml5Tokenizer::YSTEM[index]) {
              bogusDoctype();
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            index++;
            NS_HTML5_CONTINUE(stateloop);
          } else {
            reconsume = true;
            state = P::transition(
                mViewSource.get(),
                nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
            NS_HTML5_BREAK(doctypeystemloop);
          }
        }
      doctypeystemloop_end:;
        [[fallthrough]];
      }
      case AFTER_DOCTYPE_SYSTEM_KEYWORD: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
                  pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
                  pos);
              NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
            }
            case '\"': {
              if (P::reportErrors) {
                errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
              }
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\'': {
              if (P::reportErrors) {
                errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
              }
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errExpectedPublicId();
              }
              forceQuirks = true;
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              bogusDoctype();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      afterdoctypesystemkeywordloop_end:;
        [[fallthrough]];
      }
      case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '\"': {
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\'': {
              clearStrBufBeforeUse();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
                  reconsume, pos);
              NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
            }
            case '>': {
              if (P::reportErrors) {
                errExpectedSystemId();
              }
              forceQuirks = true;
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              bogusDoctype();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      beforedoctypesystemidentifierloop_end:;
        [[fallthrough]];
      }
      case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\'': {
              systemIdentifier = strBufToString();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
                  pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errGtInSystemId();
              }
              forceQuirks = true;
              systemIdentifier = strBufToString();
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      }
      case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\'': {
              publicIdentifier = strBufToString();
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
                  pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errGtInPublicId();
              }
              forceQuirks = true;
              publicIdentifier = strBufToString();
              emitDoctypeToken(pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      }
      case PROCESSING_INSTRUCTION: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\?': {
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK,
                  reconsume, pos);
              NS_HTML5_BREAK(processinginstructionloop);
            }
            default: {
              continue;
            }
          }
        }
      processinginstructionloop_end:;
        [[fallthrough]];
      }
      case PROCESSING_INSTRUCTION_QUESTION_MARK: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '>': {
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                  reconsume, pos);
            suspendIfRequestedAfterCurrentNonTextToken();
            if (shouldSuspend) {
              NS_HTML5_BREAK(stateloop);
            }
            NS_HTML5_CONTINUE(stateloop);
          }
          default: {
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
      }
    }
  }
stateloop_end:;
  flushChars(buf, pos);
  stateSave = state;
  returnStateSave = returnState;
  return pos;
}