Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/parser/html/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 80 kB image not shown  

Quellcode-Bibliothek nsHtml5Tokenizer.h

  Sprache: C
 

/*
 * Copyright (c) 2005-2007 Henri Sivonen
 * Copyright (c) 2007-2017 Mozilla Foundation
 * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
 * Foundation, and Opera Software ASA.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */


/*
 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
 * Please edit Tokenizer.java instead and regenerate.
 */


#ifndef nsHtml5Tokenizer_h
#define nsHtml5Tokenizer_h

#include "jArray.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsAtom.h"
#include "nsGkAtoms.h"
#include "nsHtml5ArrayCopy.h"
#include "nsHtml5AtomTable.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5Highlighter.h"
#include "nsHtml5Macros.h"
#include "nsHtml5NamedCharacters.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5String.h"
#include "nsHtml5TreeBuilder.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "mozilla/htmlaccel/htmlaccelEnabled.h"

class nsHtml5StreamParser;

class nsHtml5AttributeName;
class nsHtml5ElementName;
class nsHtml5TreeBuilder;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
class nsHtml5Portability;

class nsHtml5Tokenizer {
 private:
  static const int32_t DATA_AND_RCDATA_MASK = ~1;

 public:
  static const int32_t DATA = 0;

  static const int32_t RCDATA = 1;

  static const int32_t SCRIPT_DATA = 2;

  static const int32_t RAWTEXT = 3;

  static const int32_t SCRIPT_DATA_ESCAPED = 4;

  static const int32_t ATTRIBUTE_VALUE_DOUBLE_QUOTED = 5;

  static const int32_t ATTRIBUTE_VALUE_SINGLE_QUOTED = 6;

  static const int32_t ATTRIBUTE_VALUE_UNQUOTED = 7;

  static const int32_t PLAINTEXT = 8;

  static const int32_t TAG_OPEN = 9;

  static const int32_t CLOSE_TAG_OPEN = 10;

  static const int32_t TAG_NAME = 11;

  static const int32_t BEFORE_ATTRIBUTE_NAME = 12;

  static const int32_t ATTRIBUTE_NAME = 13;

  static const int32_t AFTER_ATTRIBUTE_NAME = 14;

  static const int32_t BEFORE_ATTRIBUTE_VALUE = 15;

  static const int32_t AFTER_ATTRIBUTE_VALUE_QUOTED = 16;

  static const int32_t BOGUS_COMMENT = 17;

  static const int32_t MARKUP_DECLARATION_OPEN = 18;

  static const int32_t DOCTYPE = 19;

  static const int32_t BEFORE_DOCTYPE_NAME = 20;

  static const int32_t DOCTYPE_NAME = 21;

  static const int32_t AFTER_DOCTYPE_NAME = 22;

  static const int32_t BEFORE_DOCTYPE_PUBLIC_IDENTIFIER = 23;

  static const int32_t DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED = 24;

  static const int32_t DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED = 25;

  static const int32_t AFTER_DOCTYPE_PUBLIC_IDENTIFIER = 26;

  static const int32_t BEFORE_DOCTYPE_SYSTEM_IDENTIFIER = 27;

  static const int32_t DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED = 28;

  static const int32_t DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED = 29;

  static const int32_t AFTER_DOCTYPE_SYSTEM_IDENTIFIER = 30;

  static const int32_t BOGUS_DOCTYPE = 31;

  static const int32_t COMMENT_START = 32;

  static const int32_t COMMENT_START_DASH = 33;

  static const int32_t COMMENT = 34;

  static const int32_t COMMENT_END_DASH = 35;

  static const int32_t COMMENT_END = 36;

  static const int32_t COMMENT_END_BANG = 37;

  static const int32_t NON_DATA_END_TAG_NAME = 38;

  static const int32_t MARKUP_DECLARATION_HYPHEN = 39;

  static const int32_t MARKUP_DECLARATION_OCTYPE = 40;

  static const int32_t DOCTYPE_UBLIC = 41;

  static const int32_t DOCTYPE_YSTEM = 42;

  static const int32_t AFTER_DOCTYPE_PUBLIC_KEYWORD = 43;

  static const int32_t BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS = 44;

  static const int32_t AFTER_DOCTYPE_SYSTEM_KEYWORD = 45;

  static const int32_t CONSUME_CHARACTER_REFERENCE = 46;

  static const int32_t CONSUME_NCR = 47;

  static const int32_t CHARACTER_REFERENCE_TAIL = 48;

  static const int32_t HEX_NCR_LOOP = 49;

  static const int32_t DECIMAL_NRC_LOOP = 50;

  static const int32_t HANDLE_NCR_VALUE = 51;

  static const int32_t HANDLE_NCR_VALUE_RECONSUME = 52;

  static const int32_t CHARACTER_REFERENCE_HILO_LOOKUP = 53;

  static const int32_t SELF_CLOSING_START_TAG = 54;

  static const int32_t CDATA_START = 55;

  static const int32_t CDATA_SECTION = 56;

  static const int32_t CDATA_RSQB = 57;

  static const int32_t CDATA_RSQB_RSQB = 58;

  static const int32_t SCRIPT_DATA_LESS_THAN_SIGN = 59;

  static const int32_t SCRIPT_DATA_ESCAPE_START = 60;

  static const int32_t SCRIPT_DATA_ESCAPE_START_DASH = 61;

  static const int32_t SCRIPT_DATA_ESCAPED_DASH = 62;

  static const int32_t SCRIPT_DATA_ESCAPED_DASH_DASH = 63;

  static const int32_t BOGUS_COMMENT_HYPHEN = 64;

  static const int32_t RAWTEXT_RCDATA_LESS_THAN_SIGN = 65;

  static const int32_t SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN = 66;

  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPE_START = 67;

  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED = 68;

  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN = 69;

  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_DASH = 70;

  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH = 71;

  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPE_END = 72;

  static const int32_t PROCESSING_INSTRUCTION = 73;

  static const int32_t PROCESSING_INSTRUCTION_QUESTION_MARK = 74;

  static const int32_t COMMENT_LESSTHAN = 76;

  static const int32_t COMMENT_LESSTHAN_BANG = 77;

  static const int32_t COMMENT_LESSTHAN_BANG_DASH = 78;

  static const int32_t COMMENT_LESSTHAN_BANG_DASH_DASH = 79;

 private:
  static const int32_t LEAD_OFFSET = (0xD800 - (0x10000 >> 10));

  static char16_t LT_GT[];
  static char16_t LT_SOLIDUS[];
  static char16_t RSQB_RSQB[];
  static char16_t REPLACEMENT_CHARACTER[];
  static char16_t LF[];
  static char16_t CDATA_LSQB[];
  static char16_t OCTYPE[];
  static char16_t UBLIC[];
  static char16_t YSTEM[];
  static staticJArray<char16_t, int32_t> TITLE_ARR;
  static staticJArray<char16_t, int32_t> SCRIPT_ARR;
  static staticJArray<char16_t, int32_t> STYLE_ARR;
  static staticJArray<char16_t, int32_t> PLAINTEXT_ARR;
  static staticJArray<char16_t, int32_t> XMP_ARR;
  static staticJArray<char16_t, int32_t> TEXTAREA_ARR;
  static staticJArray<char16_t, int32_t> IFRAME_ARR;
  static staticJArray<char16_t, int32_t> NOEMBED_ARR;
  static staticJArray<char16_t, int32_t> NOSCRIPT_ARR;
  static staticJArray<char16_t, int32_t> NOFRAMES_ARR;

 protected:
  nsHtml5TreeBuilder* tokenHandler;
  nsHtml5StreamParser* encodingDeclarationHandler;
  bool lastCR;
  int32_t stateSave;

 private:
  int32_t returnStateSave;

 protected:
  int32_t index;

 private:
  bool forceQuirks;
  char16_t additional;
  int32_t entCol;
  int32_t firstCharKey;
  int32_t lo;
  int32_t hi;
  int32_t candidate;
  int32_t charRefBufMark;

 protected:
  int32_t value;

 private:
  bool seenDigits;
  bool suspendAfterCurrentNonTextToken;

 protected:
  int32_t cstart;

 private:
  nsHtml5String publicId;
  nsHtml5String systemId;
  autoJArray<char16_t, int32_t> strBuf;
  int32_t strBufLen;
  autoJArray<char16_t, int32_t> charRefBuf;
  int32_t charRefBufLen;
  autoJArray<char16_t, int32_t> bmpChar;
  autoJArray<char16_t, int32_t> astralChar;

 protected:
  nsHtml5ElementName* endTagExpectation;

 private:
  jArray<char16_t, int32_t> endTagExpectationAsArray;

 protected:
  bool endTag;

 private:
  bool containsHyphen;
  nsHtml5ElementName* tagName;
  nsHtml5ElementName* nonInternedTagName;

 protected:
  nsHtml5AttributeName* attributeName;

 private:
  nsHtml5AttributeName* nonInternedAttributeName;
  RefPtr<nsAtom> doctypeName;
  nsHtml5String publicIdentifier;
  nsHtml5String systemIdentifier;
  nsHtml5HtmlAttributes* attributes;
  bool newAttributesEachTime;
  bool shouldSuspend;
  bool keepBuffer;

 protected:
  bool confident;

 private:
  int32_t line;
  int32_t attributeLine;
  nsHtml5AtomTable* interner;
  bool viewingXmlSource;

 public:
  nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource);
  void setInterner(nsHtml5AtomTable* interner);
  void initLocation(nsHtml5String newPublicId, nsHtml5String newSystemId);
  bool isViewingXmlSource();
  void setKeepBuffer(bool keepBuffer);
  bool dropBufferIfLongerThan(int32_t length);
  void setState(int32_t specialTokenizerState);
  void setStateAndEndTagExpectation(int32_t specialTokenizerState,
                                    nsHtml5ElementName* endTagExpectation);

 private:
  void endTagExpectationToArray();

 public:
  void setLineNumber(int32_t line);
  inline int32_t getLineNumber() { return line; }

  inline nsHtml5HtmlAttributes* emptyAttributes() {
    return nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES;
  }

 private:
  void appendCharRefBuf(char16_t c);
  void emitOrAppendCharRefBuf(int32_t returnState);
  inline void clearStrBufAfterUse() { strBufLen = 0; }

  inline void clearStrBufBeforeUse() {
    MOZ_ASSERT(!strBufLen, "strBufLen not reset after previous use!");
    strBufLen = 0;
  }

  inline void clearStrBufAfterOneHyphen() {
    MOZ_ASSERT(strBufLen == 1"strBufLen length not one!");
    MOZ_ASSERT(strBuf[0] == '-'"strBuf does not start with a hyphen!");
    strBufLen = 0;
  }

  inline void appendStrBuf(char16_t c) {
    if (MOZ_UNLIKELY(strBufLen == strBuf.length)) {
      EnsureBufferSpaceShouldNeverHappen(1);
    }
    strBuf[strBufLen++] = c;
  }

 protected:
  inline nsHtml5String strBufToString() {
    nsHtml5String str = nsHtml5Portability::newStringFromBuffer(
        strBuf, 0, strBufLen, tokenHandler, nullptr);
    clearStrBufAfterUse();
    return str;
  }

  inline nsHtml5String strBufToAttributeValueString() {
    nsHtml5String digitAtom = TryAtomizeForSingleDigit();
    if (digitAtom) {
      return digitAtom;
    }
    nsHtml5String str = nsHtml5Portability::newStringFromBuffer(
        strBuf, 0, strBufLen, tokenHandler,
        attributeName->isUseAtom() ? interner : nullptr);
    clearStrBufAfterUse();
    return str;
  }

 private:
  inline void strBufToDoctypeName() {
    doctypeName =
        nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen, interner);
    clearStrBufAfterUse();
  }

  inline void emitStrBuf() {
    if (strBufLen > 0) {
      tokenHandler->characters(strBuf, 0, strBufLen);
      clearStrBufAfterUse();
    }
  }

  inline void appendSecondHyphenToBogusComment() { appendStrBuf('-'); }

  inline void adjustDoubleHyphenAndAppendToStrBufAndErr(
      char16_t c, bool reportedConsecutiveHyphens) {
    appendStrBuf(c);
  }

  inline void appendStrBuf(char16_t* buffer, int32_t offset, int32_t length) {
    int32_t newLen = strBufLen + length;
    if (MOZ_UNLIKELY(strBuf.length < newLen)) {
      EnsureBufferSpaceShouldNeverHappen(length);
    }
    nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length);
    strBufLen = newLen;
  }

  inline void appendCharRefBufToStrBuf() {
    appendStrBuf(charRefBuf, 0, charRefBufLen);
    charRefBufLen = 0;
  }

  void emitComment(int32_t provisionalHyphens, int32_t pos);

 protected:
  void flushChars(char16_t* buf, int32_t pos);

 private:
  void strBufToElementNameString();
  int32_t emitCurrentTagToken(bool selfClosing, int32_t pos);
  void attributeNameComplete();
  void addAttributeWithoutValue();
  void addAttributeWithValue();

 public:
  void start();
  bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer);

 private:
  template <class P>
  inline int32_t 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 {
              ++pos;
              pos += P::accelerateAdvancementData(this, buf, pos, endPos);
              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, 02);
                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, 01);
                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 {
              ++pos;
              pos += P::accelerateAdvancementAttributeValueDoubleQuoted(
                  this, buf, pos, endPos);
              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 (;;) {
            ++pos;
            pos += P::accelerateAdvancementComment(this, buf, pos, endPos);
            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 {
              ++pos;
              pos +=
                  P::accelerateAdvancementCdataSection(this, buf, pos, endPos);
              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, 01);
              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, 01);
                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, 02);
                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 {
              ++pos;
              pos += P::accelerateAdvancementAttributeValueSingleQuoted(
                  this, buf, pos, endPos);
              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 {
              ++pos;
              pos += P::accelerateAdvancementPlaintext(this, buf, pos, endPos);
              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 {
              ++pos;
              pos += P::accelerateAdvancementData(this, buf, pos, endPos);
              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 {
              ++pos;
              pos += P::accelerateAdvancementRawtext(this, buf, pos, endPos);
              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, 01);
                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, 02);
              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, 02);
                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, 02);
                  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 {
              ++pos;
              pos += P::accelerateAdvancementRawtext(this, buf, pos, endPos);
              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, 01);
                cstart = pos;
                state = P::transition(
                    mViewSource.get(),
                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START, reconsume, pos);
                NS_HTML5_BREAK(scriptdatalessthansignloop);
              }
              default: {
                tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 01);
                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 {
              ++pos;
              pos += P::accelerateAdvancementScriptDataEscaped(this, buf, pos,
                                                               endPos);
              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, 01);
                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, 01);
                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;
  }

  void initDoctypeFields();
  template <class P>
  inline void adjustDoubleHyphenAndAppendToStrBufCarriageReturn() {
    P::silentCarriageReturn(this);
    adjustDoubleHyphenAndAppendToStrBufAndErr('\n'false);
  }

  template <class P>
  inline void adjustDoubleHyphenAndAppendToStrBufLineFeed() {
    P::silentLineFeed(this);
    adjustDoubleHyphenAndAppendToStrBufAndErr('\n'false);
  }

  template <class P>
  inline void appendStrBufLineFeed() {
    P::silentLineFeed(this);
    appendStrBuf('\n');
  }

  template <class P>
  inline void appendStrBufCarriageReturn() {
    P::silentCarriageReturn(this);
    appendStrBuf('\n');
  }

  template <class P>
  inline void emitCarriageReturn(char16_t* buf, int32_t pos) {
    P::silentCarriageReturn(this);
    flushChars(buf, pos);
    tokenHandler->characters(nsHtml5Tokenizer::LF, 01);
    cstart = INT32_MAX;
  }

  void emitReplacementCharacter(char16_t* buf, int32_t pos);
  void maybeEmitReplacementCharacter(char16_t* buf, int32_t pos);
  void emitPlaintextReplacementCharacter(char16_t* buf, int32_t pos);
  inline void setAdditionalAndRememberAmpersandLocation(char16_t add) {
    additional = add;
  }

  void bogusDoctype();
  void bogusDoctypeWithoutQuirks();
  void handleNcrValue(int32_t returnState);

 public:
  void eof();

 private:
  void emitDoctypeToken(int32_t pos);
  inline void suspendIfRequestedAfterCurrentNonTextToken() {
    if (suspendAfterCurrentNonTextToken) {
      suspendAfterCurrentNonTextToken = false;
      shouldSuspend = true;
    }
  }

  void suspendAfterCurrentTokenIfNotInText();
  bool suspensionAfterCurrentNonTextTokenPending();

 public:
  bool internalEncodingDeclaration(nsHtml5String internalCharset);

 private:
  inline void emitOrAppendTwo(const char16_t* val, int32_t returnState) {
    if ((returnState & DATA_AND_RCDATA_MASK)) {
      appendStrBuf(val[0]);
      appendStrBuf(val[1]);
    } else {
      tokenHandler->characters(val, 02);
    }
  }

  inline void emitOrAppendOne(const char16_t* val, int32_t returnState) {
    if ((returnState & DATA_AND_RCDATA_MASK)) {
      appendStrBuf(val[0]);
    } else {
      tokenHandler->characters(val, 01);
    }
  }

 public:
  void end();
  inline void requestSuspension() { shouldSuspend = true; }

  inline bool isInDataState() { return (stateSave == DATA); }

  void resetToDataState();
  void loadState(nsHtml5Tokenizer* other);
  void initializeWithoutStarting();
  void setEncodingDeclarationHandler(
      nsHtml5StreamParser* encodingDeclarationHandler);
  ~nsHtml5Tokenizer();
  static void initializeStatics();
  static void releaseStatics();

#include "nsHtml5TokenizerHSupplement.h"
};

#endif

Messung V0.5 in Prozent
C=100 H=92 G=95

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.204Bemerkung:  (vorverarbeitet am  2026-08-25) ¤

*Bot Zugriff






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.