tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsHtml5Tokenizer.h (160149B)


      1 /*
      2 * Copyright (c) 2005-2007 Henri Sivonen
      3 * Copyright (c) 2007-2017 Mozilla Foundation
      4 * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
      5 * Foundation, and Opera Software ASA.
      6 *
      7 * Permission is hereby granted, free of charge, to any person obtaining a
      8 * copy of this software and associated documentation files (the "Software"),
      9 * to deal in the Software without restriction, including without limitation
     10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11 * and/or sell copies of the Software, and to permit persons to whom the
     12 * Software is furnished to do so, subject to the following conditions:
     13 *
     14 * The above copyright notice and this permission notice shall be included in
     15 * all copies or substantial portions of the Software.
     16 *
     17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     23 * DEALINGS IN THE SOFTWARE.
     24 */
     25 
     26 /*
     27 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
     28 * Please edit Tokenizer.java instead and regenerate.
     29 */
     30 
     31 #ifndef nsHtml5Tokenizer_h
     32 #define nsHtml5Tokenizer_h
     33 
     34 #include "jArray.h"
     35 #include "nsAHtml5TreeBuilderState.h"
     36 #include "nsAtom.h"
     37 #include "nsGkAtoms.h"
     38 #include "nsHtml5ArrayCopy.h"
     39 #include "nsHtml5AtomTable.h"
     40 #include "nsHtml5DocumentMode.h"
     41 #include "nsHtml5Highlighter.h"
     42 #include "nsHtml5Macros.h"
     43 #include "nsHtml5NamedCharacters.h"
     44 #include "nsHtml5NamedCharactersAccel.h"
     45 #include "nsHtml5String.h"
     46 #include "nsHtml5TreeBuilder.h"
     47 #include "nsIContent.h"
     48 #include "nsTraceRefcnt.h"
     49 #include "mozilla/htmlaccel/htmlaccelEnabled.h"
     50 
     51 class nsHtml5StreamParser;
     52 
     53 class nsHtml5AttributeName;
     54 class nsHtml5ElementName;
     55 class nsHtml5TreeBuilder;
     56 class nsHtml5UTF16Buffer;
     57 class nsHtml5StateSnapshot;
     58 class nsHtml5Portability;
     59 
     60 class nsHtml5Tokenizer {
     61 private:
     62  static const int32_t DATA_AND_RCDATA_MASK = ~1;
     63 
     64 public:
     65  static const int32_t DATA = 0;
     66 
     67  static const int32_t RCDATA = 1;
     68 
     69  static const int32_t SCRIPT_DATA = 2;
     70 
     71  static const int32_t RAWTEXT = 3;
     72 
     73  static const int32_t SCRIPT_DATA_ESCAPED = 4;
     74 
     75  static const int32_t ATTRIBUTE_VALUE_DOUBLE_QUOTED = 5;
     76 
     77  static const int32_t ATTRIBUTE_VALUE_SINGLE_QUOTED = 6;
     78 
     79  static const int32_t ATTRIBUTE_VALUE_UNQUOTED = 7;
     80 
     81  static const int32_t PLAINTEXT = 8;
     82 
     83  static const int32_t TAG_OPEN = 9;
     84 
     85  static const int32_t CLOSE_TAG_OPEN = 10;
     86 
     87  static const int32_t TAG_NAME = 11;
     88 
     89  static const int32_t BEFORE_ATTRIBUTE_NAME = 12;
     90 
     91  static const int32_t ATTRIBUTE_NAME = 13;
     92 
     93  static const int32_t AFTER_ATTRIBUTE_NAME = 14;
     94 
     95  static const int32_t BEFORE_ATTRIBUTE_VALUE = 15;
     96 
     97  static const int32_t AFTER_ATTRIBUTE_VALUE_QUOTED = 16;
     98 
     99  static const int32_t BOGUS_COMMENT = 17;
    100 
    101  static const int32_t MARKUP_DECLARATION_OPEN = 18;
    102 
    103  static const int32_t DOCTYPE = 19;
    104 
    105  static const int32_t BEFORE_DOCTYPE_NAME = 20;
    106 
    107  static const int32_t DOCTYPE_NAME = 21;
    108 
    109  static const int32_t AFTER_DOCTYPE_NAME = 22;
    110 
    111  static const int32_t BEFORE_DOCTYPE_PUBLIC_IDENTIFIER = 23;
    112 
    113  static const int32_t DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED = 24;
    114 
    115  static const int32_t DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED = 25;
    116 
    117  static const int32_t AFTER_DOCTYPE_PUBLIC_IDENTIFIER = 26;
    118 
    119  static const int32_t BEFORE_DOCTYPE_SYSTEM_IDENTIFIER = 27;
    120 
    121  static const int32_t DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED = 28;
    122 
    123  static const int32_t DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED = 29;
    124 
    125  static const int32_t AFTER_DOCTYPE_SYSTEM_IDENTIFIER = 30;
    126 
    127  static const int32_t BOGUS_DOCTYPE = 31;
    128 
    129  static const int32_t COMMENT_START = 32;
    130 
    131  static const int32_t COMMENT_START_DASH = 33;
    132 
    133  static const int32_t COMMENT = 34;
    134 
    135  static const int32_t COMMENT_END_DASH = 35;
    136 
    137  static const int32_t COMMENT_END = 36;
    138 
    139  static const int32_t COMMENT_END_BANG = 37;
    140 
    141  static const int32_t NON_DATA_END_TAG_NAME = 38;
    142 
    143  static const int32_t MARKUP_DECLARATION_HYPHEN = 39;
    144 
    145  static const int32_t MARKUP_DECLARATION_OCTYPE = 40;
    146 
    147  static const int32_t DOCTYPE_UBLIC = 41;
    148 
    149  static const int32_t DOCTYPE_YSTEM = 42;
    150 
    151  static const int32_t AFTER_DOCTYPE_PUBLIC_KEYWORD = 43;
    152 
    153  static const int32_t BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS = 44;
    154 
    155  static const int32_t AFTER_DOCTYPE_SYSTEM_KEYWORD = 45;
    156 
    157  static const int32_t CONSUME_CHARACTER_REFERENCE = 46;
    158 
    159  static const int32_t CONSUME_NCR = 47;
    160 
    161  static const int32_t CHARACTER_REFERENCE_TAIL = 48;
    162 
    163  static const int32_t HEX_NCR_LOOP = 49;
    164 
    165  static const int32_t DECIMAL_NRC_LOOP = 50;
    166 
    167  static const int32_t HANDLE_NCR_VALUE = 51;
    168 
    169  static const int32_t HANDLE_NCR_VALUE_RECONSUME = 52;
    170 
    171  static const int32_t CHARACTER_REFERENCE_HILO_LOOKUP = 53;
    172 
    173  static const int32_t SELF_CLOSING_START_TAG = 54;
    174 
    175  static const int32_t CDATA_START = 55;
    176 
    177  static const int32_t CDATA_SECTION = 56;
    178 
    179  static const int32_t CDATA_RSQB = 57;
    180 
    181  static const int32_t CDATA_RSQB_RSQB = 58;
    182 
    183  static const int32_t SCRIPT_DATA_LESS_THAN_SIGN = 59;
    184 
    185  static const int32_t SCRIPT_DATA_ESCAPE_START = 60;
    186 
    187  static const int32_t SCRIPT_DATA_ESCAPE_START_DASH = 61;
    188 
    189  static const int32_t SCRIPT_DATA_ESCAPED_DASH = 62;
    190 
    191  static const int32_t SCRIPT_DATA_ESCAPED_DASH_DASH = 63;
    192 
    193  static const int32_t BOGUS_COMMENT_HYPHEN = 64;
    194 
    195  static const int32_t RAWTEXT_RCDATA_LESS_THAN_SIGN = 65;
    196 
    197  static const int32_t SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN = 66;
    198 
    199  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPE_START = 67;
    200 
    201  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED = 68;
    202 
    203  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN = 69;
    204 
    205  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_DASH = 70;
    206 
    207  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH = 71;
    208 
    209  static const int32_t SCRIPT_DATA_DOUBLE_ESCAPE_END = 72;
    210 
    211  static const int32_t PROCESSING_INSTRUCTION = 73;
    212 
    213  static const int32_t PROCESSING_INSTRUCTION_QUESTION_MARK = 74;
    214 
    215  static const int32_t COMMENT_LESSTHAN = 76;
    216 
    217  static const int32_t COMMENT_LESSTHAN_BANG = 77;
    218 
    219  static const int32_t COMMENT_LESSTHAN_BANG_DASH = 78;
    220 
    221  static const int32_t COMMENT_LESSTHAN_BANG_DASH_DASH = 79;
    222 
    223 private:
    224  static const int32_t LEAD_OFFSET = (0xD800 - (0x10000 >> 10));
    225 
    226  static char16_t LT_GT[];
    227  static char16_t LT_SOLIDUS[];
    228  static char16_t RSQB_RSQB[];
    229  static char16_t REPLACEMENT_CHARACTER[];
    230  static char16_t LF[];
    231  static char16_t CDATA_LSQB[];
    232  static char16_t OCTYPE[];
    233  static char16_t UBLIC[];
    234  static char16_t YSTEM[];
    235  static staticJArray<char16_t, int32_t> TITLE_ARR;
    236  static staticJArray<char16_t, int32_t> SCRIPT_ARR;
    237  static staticJArray<char16_t, int32_t> STYLE_ARR;
    238  static staticJArray<char16_t, int32_t> PLAINTEXT_ARR;
    239  static staticJArray<char16_t, int32_t> XMP_ARR;
    240  static staticJArray<char16_t, int32_t> TEXTAREA_ARR;
    241  static staticJArray<char16_t, int32_t> IFRAME_ARR;
    242  static staticJArray<char16_t, int32_t> NOEMBED_ARR;
    243  static staticJArray<char16_t, int32_t> NOSCRIPT_ARR;
    244  static staticJArray<char16_t, int32_t> NOFRAMES_ARR;
    245 
    246 protected:
    247  nsHtml5TreeBuilder* tokenHandler;
    248  nsHtml5StreamParser* encodingDeclarationHandler;
    249  bool lastCR;
    250  int32_t stateSave;
    251 
    252 private:
    253  int32_t returnStateSave;
    254 
    255 protected:
    256  int32_t index;
    257 
    258 private:
    259  bool forceQuirks;
    260  char16_t additional;
    261  int32_t entCol;
    262  int32_t firstCharKey;
    263  int32_t lo;
    264  int32_t hi;
    265  int32_t candidate;
    266  int32_t charRefBufMark;
    267 
    268 protected:
    269  int32_t value;
    270 
    271 private:
    272  bool seenDigits;
    273  bool suspendAfterCurrentNonTextToken;
    274 
    275 protected:
    276  int32_t cstart;
    277 
    278 private:
    279  nsHtml5String publicId;
    280  nsHtml5String systemId;
    281  autoJArray<char16_t, int32_t> strBuf;
    282  int32_t strBufLen;
    283  autoJArray<char16_t, int32_t> charRefBuf;
    284  int32_t charRefBufLen;
    285  autoJArray<char16_t, int32_t> bmpChar;
    286  autoJArray<char16_t, int32_t> astralChar;
    287 
    288 protected:
    289  nsHtml5ElementName* endTagExpectation;
    290 
    291 private:
    292  jArray<char16_t, int32_t> endTagExpectationAsArray;
    293 
    294 protected:
    295  bool endTag;
    296 
    297 private:
    298  bool containsHyphen;
    299  nsHtml5ElementName* tagName;
    300  nsHtml5ElementName* nonInternedTagName;
    301 
    302 protected:
    303  nsHtml5AttributeName* attributeName;
    304 
    305 private:
    306  nsHtml5AttributeName* nonInternedAttributeName;
    307  RefPtr<nsAtom> doctypeName;
    308  nsHtml5String publicIdentifier;
    309  nsHtml5String systemIdentifier;
    310  nsHtml5HtmlAttributes* attributes;
    311  bool newAttributesEachTime;
    312  bool shouldSuspend;
    313  bool keepBuffer;
    314 
    315 protected:
    316  bool confident;
    317 
    318 private:
    319  int32_t line;
    320  int32_t attributeLine;
    321  nsHtml5AtomTable* interner;
    322  bool viewingXmlSource;
    323 
    324 public:
    325  nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource);
    326  void setInterner(nsHtml5AtomTable* interner);
    327  void initLocation(nsHtml5String newPublicId, nsHtml5String newSystemId);
    328  bool isViewingXmlSource();
    329  void setKeepBuffer(bool keepBuffer);
    330  bool dropBufferIfLongerThan(int32_t length);
    331  void setState(int32_t specialTokenizerState);
    332  void setStateAndEndTagExpectation(int32_t specialTokenizerState,
    333                                    nsHtml5ElementName* endTagExpectation);
    334 
    335 private:
    336  void endTagExpectationToArray();
    337 
    338 public:
    339  void setLineNumber(int32_t line);
    340  inline int32_t getLineNumber() { return line; }
    341 
    342  inline nsHtml5HtmlAttributes* emptyAttributes() {
    343    return nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES;
    344  }
    345 
    346 private:
    347  void appendCharRefBuf(char16_t c);
    348  void emitOrAppendCharRefBuf(int32_t returnState);
    349  inline void clearStrBufAfterUse() { strBufLen = 0; }
    350 
    351  inline void clearStrBufBeforeUse() {
    352    MOZ_ASSERT(!strBufLen, "strBufLen not reset after previous use!");
    353    strBufLen = 0;
    354  }
    355 
    356  inline void clearStrBufAfterOneHyphen() {
    357    MOZ_ASSERT(strBufLen == 1, "strBufLen length not one!");
    358    MOZ_ASSERT(strBuf[0] == '-', "strBuf does not start with a hyphen!");
    359    strBufLen = 0;
    360  }
    361 
    362  inline void appendStrBuf(char16_t c) {
    363    if (MOZ_UNLIKELY(strBufLen == strBuf.length)) {
    364      EnsureBufferSpaceShouldNeverHappen(1);
    365    }
    366    strBuf[strBufLen++] = c;
    367  }
    368 
    369 protected:
    370  inline nsHtml5String strBufToString() {
    371    nsHtml5String digitAtom = TryAtomizeForSingleDigit();
    372    if (digitAtom) {
    373      return digitAtom;
    374    }
    375    bool maybeAtomize = false;
    376    if (!newAttributesEachTime) {
    377      if (attributeName == nsHtml5AttributeName::ATTR_CLASS ||
    378          attributeName == nsHtml5AttributeName::ATTR_TYPE) {
    379        maybeAtomize = true;
    380      }
    381    }
    382    nsHtml5String str = nsHtml5Portability::newStringFromBuffer(
    383        strBuf, 0, strBufLen, tokenHandler, maybeAtomize);
    384    clearStrBufAfterUse();
    385    return str;
    386  }
    387 
    388 private:
    389  inline void strBufToDoctypeName() {
    390    doctypeName =
    391        nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen, interner);
    392    clearStrBufAfterUse();
    393  }
    394 
    395  inline void emitStrBuf() {
    396    if (strBufLen > 0) {
    397      tokenHandler->characters(strBuf, 0, strBufLen);
    398      clearStrBufAfterUse();
    399    }
    400  }
    401 
    402  inline void appendSecondHyphenToBogusComment() { appendStrBuf('-'); }
    403 
    404  inline void adjustDoubleHyphenAndAppendToStrBufAndErr(
    405      char16_t c, bool reportedConsecutiveHyphens) {
    406    appendStrBuf(c);
    407  }
    408 
    409  inline void appendStrBuf(char16_t* buffer, int32_t offset, int32_t length) {
    410    int32_t newLen = strBufLen + length;
    411    if (MOZ_UNLIKELY(strBuf.length < newLen)) {
    412      EnsureBufferSpaceShouldNeverHappen(length);
    413    }
    414    nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length);
    415    strBufLen = newLen;
    416  }
    417 
    418  inline void appendCharRefBufToStrBuf() {
    419    appendStrBuf(charRefBuf, 0, charRefBufLen);
    420    charRefBufLen = 0;
    421  }
    422 
    423  void emitComment(int32_t provisionalHyphens, int32_t pos);
    424 
    425 protected:
    426  void flushChars(char16_t* buf, int32_t pos);
    427 
    428 private:
    429  void strBufToElementNameString();
    430  int32_t emitCurrentTagToken(bool selfClosing, int32_t pos);
    431  void attributeNameComplete();
    432  void addAttributeWithoutValue();
    433  void addAttributeWithValue();
    434 
    435 public:
    436  void start();
    437  bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer);
    438 
    439 private:
    440  template <class P>
    441  inline int32_t stateLoop(int32_t state, char16_t c, int32_t pos,
    442                           char16_t* buf, bool reconsume, int32_t returnState,
    443                           int32_t endPos) {
    444    bool reportedConsecutiveHyphens = false;
    445  stateloop:
    446    for (;;) {
    447      switch (state) {
    448        case DATA: {
    449          for (;;) {
    450            if (reconsume) {
    451              reconsume = false;
    452            } else {
    453              ++pos;
    454              pos += P::accelerateAdvancementData(this, buf, pos, endPos);
    455              if (pos == endPos) {
    456                NS_HTML5_BREAK(stateloop);
    457              }
    458              c = P::checkChar(this, buf, pos);
    459            }
    460            switch (c) {
    461              case '&': {
    462                flushChars(buf, pos);
    463                MOZ_ASSERT(!charRefBufLen,
    464                           "charRefBufLen not reset after previous use!");
    465                appendCharRefBuf(c);
    466                setAdditionalAndRememberAmpersandLocation('\0');
    467                returnState = state;
    468                state =
    469                    P::transition(mViewSource.get(),
    470                                  nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
    471                                  reconsume, pos);
    472                NS_HTML5_CONTINUE(stateloop);
    473              }
    474              case '<': {
    475                flushChars(buf, pos);
    476                state =
    477                    P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_OPEN,
    478                                  reconsume, pos);
    479                NS_HTML5_BREAK(dataloop);
    480              }
    481              case '\0': {
    482                maybeEmitReplacementCharacter(buf, pos);
    483                continue;
    484              }
    485              case '\r': {
    486                emitCarriageReturn<P>(buf, pos);
    487                NS_HTML5_BREAK(stateloop);
    488              }
    489              case '\n': {
    490                P::silentLineFeed(this);
    491                [[fallthrough]];
    492              }
    493              default: {
    494                continue;
    495              }
    496            }
    497          }
    498        dataloop_end:;
    499          [[fallthrough]];
    500        }
    501        case TAG_OPEN: {
    502          for (;;) {
    503            if (++pos == endPos) {
    504              NS_HTML5_BREAK(stateloop);
    505            }
    506            c = P::checkChar(this, buf, pos);
    507            if (c >= 'A' && c <= 'Z') {
    508              endTag = false;
    509              clearStrBufBeforeUse();
    510              appendStrBuf((char16_t)(c + 0x20));
    511              containsHyphen = false;
    512              state = P::transition(mViewSource.get(),
    513                                    nsHtml5Tokenizer::TAG_NAME, reconsume, pos);
    514              NS_HTML5_BREAK(tagopenloop);
    515            } else if (c >= 'a' && c <= 'z') {
    516              endTag = false;
    517              clearStrBufBeforeUse();
    518              appendStrBuf(c);
    519              containsHyphen = false;
    520              state = P::transition(mViewSource.get(),
    521                                    nsHtml5Tokenizer::TAG_NAME, reconsume, pos);
    522              NS_HTML5_BREAK(tagopenloop);
    523            }
    524            switch (c) {
    525              case '!': {
    526                state = P::transition(mViewSource.get(),
    527                                      nsHtml5Tokenizer::MARKUP_DECLARATION_OPEN,
    528                                      reconsume, pos);
    529                NS_HTML5_CONTINUE(stateloop);
    530              }
    531              case '/': {
    532                state = P::transition(mViewSource.get(),
    533                                      nsHtml5Tokenizer::CLOSE_TAG_OPEN,
    534                                      reconsume, pos);
    535                NS_HTML5_CONTINUE(stateloop);
    536              }
    537              case '\?': {
    538                if (viewingXmlSource) {
    539                  state = P::transition(
    540                      mViewSource.get(),
    541                      nsHtml5Tokenizer::PROCESSING_INSTRUCTION, reconsume, pos);
    542                  NS_HTML5_CONTINUE(stateloop);
    543                }
    544                if (P::reportErrors) {
    545                  errProcessingInstruction();
    546                }
    547                clearStrBufBeforeUse();
    548                appendStrBuf(c);
    549                state = P::transition(mViewSource.get(),
    550                                      nsHtml5Tokenizer::BOGUS_COMMENT,
    551                                      reconsume, pos);
    552                NS_HTML5_CONTINUE(stateloop);
    553              }
    554              case '>': {
    555                if (P::reportErrors) {
    556                  errLtGt();
    557                }
    558                tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
    559                cstart = pos + 1;
    560                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
    561                                      reconsume, pos);
    562                NS_HTML5_CONTINUE(stateloop);
    563              }
    564              default: {
    565                if (P::reportErrors) {
    566                  errBadCharAfterLt(c);
    567                }
    568                tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
    569                cstart = pos;
    570                reconsume = true;
    571                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
    572                                      reconsume, pos);
    573                NS_HTML5_CONTINUE(stateloop);
    574              }
    575            }
    576          }
    577        tagopenloop_end:;
    578          [[fallthrough]];
    579        }
    580        case TAG_NAME: {
    581          for (;;) {
    582            if (++pos == endPos) {
    583              NS_HTML5_BREAK(stateloop);
    584            }
    585            c = P::checkChar(this, buf, pos);
    586            switch (c) {
    587              case '\r': {
    588                P::silentCarriageReturn(this);
    589                strBufToElementNameString();
    590                state = P::transition(mViewSource.get(),
    591                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
    592                                      reconsume, pos);
    593                NS_HTML5_BREAK(stateloop);
    594              }
    595              case '\n': {
    596                P::silentLineFeed(this);
    597                [[fallthrough]];
    598              }
    599              case ' ':
    600              case '\t':
    601              case '\f': {
    602                strBufToElementNameString();
    603                state = P::transition(mViewSource.get(),
    604                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
    605                                      reconsume, pos);
    606                NS_HTML5_BREAK(tagnameloop);
    607              }
    608              case '/': {
    609                strBufToElementNameString();
    610                state = P::transition(mViewSource.get(),
    611                                      nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
    612                                      reconsume, pos);
    613                NS_HTML5_CONTINUE(stateloop);
    614              }
    615              case '>': {
    616                strBufToElementNameString();
    617                state = P::transition(mViewSource.get(),
    618                                      emitCurrentTagToken(false, pos),
    619                                      reconsume, pos);
    620                if (shouldSuspend) {
    621                  NS_HTML5_BREAK(stateloop);
    622                }
    623                NS_HTML5_CONTINUE(stateloop);
    624              }
    625              case '\0': {
    626                c = 0xfffd;
    627                [[fallthrough]];
    628              }
    629              default: {
    630                if (c >= 'A' && c <= 'Z') {
    631                  c += 0x20;
    632                } else if (c == '-') {
    633                  containsHyphen = true;
    634                }
    635                appendStrBuf(c);
    636                continue;
    637              }
    638            }
    639          }
    640        tagnameloop_end:;
    641          [[fallthrough]];
    642        }
    643        case BEFORE_ATTRIBUTE_NAME: {
    644          for (;;) {
    645            if (reconsume) {
    646              reconsume = false;
    647            } else {
    648              if (++pos == endPos) {
    649                NS_HTML5_BREAK(stateloop);
    650              }
    651              c = P::checkChar(this, buf, pos);
    652            }
    653            switch (c) {
    654              case '\r': {
    655                P::silentCarriageReturn(this);
    656                NS_HTML5_BREAK(stateloop);
    657              }
    658              case '\n': {
    659                P::silentLineFeed(this);
    660                [[fallthrough]];
    661              }
    662              case ' ':
    663              case '\t':
    664              case '\f': {
    665                continue;
    666              }
    667              case '/': {
    668                state = P::transition(mViewSource.get(),
    669                                      nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
    670                                      reconsume, pos);
    671                NS_HTML5_CONTINUE(stateloop);
    672              }
    673              case '>': {
    674                state = P::transition(mViewSource.get(),
    675                                      emitCurrentTagToken(false, pos),
    676                                      reconsume, pos);
    677                if (shouldSuspend) {
    678                  NS_HTML5_BREAK(stateloop);
    679                }
    680                NS_HTML5_CONTINUE(stateloop);
    681              }
    682              case '\0': {
    683                c = 0xfffd;
    684                [[fallthrough]];
    685              }
    686              case '\"':
    687              case '\'':
    688              case '<':
    689              case '=': {
    690                if (P::reportErrors) {
    691                  errBadCharBeforeAttributeNameOrNull(c);
    692                }
    693                [[fallthrough]];
    694              }
    695              default: {
    696                if (c >= 'A' && c <= 'Z') {
    697                  c += 0x20;
    698                }
    699                attributeLine = line;
    700                clearStrBufBeforeUse();
    701                appendStrBuf(c);
    702                state = P::transition(mViewSource.get(),
    703                                      nsHtml5Tokenizer::ATTRIBUTE_NAME,
    704                                      reconsume, pos);
    705                NS_HTML5_BREAK(beforeattributenameloop);
    706              }
    707            }
    708          }
    709        beforeattributenameloop_end:;
    710          [[fallthrough]];
    711        }
    712        case ATTRIBUTE_NAME: {
    713          for (;;) {
    714            if (++pos == endPos) {
    715              NS_HTML5_BREAK(stateloop);
    716            }
    717            c = P::checkChar(this, buf, pos);
    718            switch (c) {
    719              case '\r': {
    720                P::silentCarriageReturn(this);
    721                attributeNameComplete();
    722                state = P::transition(mViewSource.get(),
    723                                      nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
    724                                      reconsume, pos);
    725                NS_HTML5_BREAK(stateloop);
    726              }
    727              case '\n': {
    728                P::silentLineFeed(this);
    729                [[fallthrough]];
    730              }
    731              case ' ':
    732              case '\t':
    733              case '\f': {
    734                attributeNameComplete();
    735                state = P::transition(mViewSource.get(),
    736                                      nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
    737                                      reconsume, pos);
    738                NS_HTML5_CONTINUE(stateloop);
    739              }
    740              case '/': {
    741                attributeNameComplete();
    742                addAttributeWithoutValue();
    743                state = P::transition(mViewSource.get(),
    744                                      nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
    745                                      reconsume, pos);
    746                NS_HTML5_CONTINUE(stateloop);
    747              }
    748              case '=': {
    749                attributeNameComplete();
    750                state = P::transition(mViewSource.get(),
    751                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
    752                                      reconsume, pos);
    753                NS_HTML5_BREAK(attributenameloop);
    754              }
    755              case '>': {
    756                attributeNameComplete();
    757                addAttributeWithoutValue();
    758                state = P::transition(mViewSource.get(),
    759                                      emitCurrentTagToken(false, pos),
    760                                      reconsume, pos);
    761                if (shouldSuspend) {
    762                  NS_HTML5_BREAK(stateloop);
    763                }
    764                NS_HTML5_CONTINUE(stateloop);
    765              }
    766              case '\0': {
    767                c = 0xfffd;
    768                [[fallthrough]];
    769              }
    770              case '\"':
    771              case '\'':
    772              case '<': {
    773                if (P::reportErrors) {
    774                  errQuoteOrLtInAttributeNameOrNull(c);
    775                }
    776                [[fallthrough]];
    777              }
    778              default: {
    779                if (c >= 'A' && c <= 'Z') {
    780                  c += 0x20;
    781                }
    782                appendStrBuf(c);
    783                continue;
    784              }
    785            }
    786          }
    787        attributenameloop_end:;
    788          [[fallthrough]];
    789        }
    790        case BEFORE_ATTRIBUTE_VALUE: {
    791          for (;;) {
    792            if (++pos == endPos) {
    793              NS_HTML5_BREAK(stateloop);
    794            }
    795            c = P::checkChar(this, buf, pos);
    796            switch (c) {
    797              case '\r': {
    798                P::silentCarriageReturn(this);
    799                NS_HTML5_BREAK(stateloop);
    800              }
    801              case '\n': {
    802                P::silentLineFeed(this);
    803                [[fallthrough]];
    804              }
    805              case ' ':
    806              case '\t':
    807              case '\f': {
    808                continue;
    809              }
    810              case '\"': {
    811                attributeLine = line;
    812                clearStrBufBeforeUse();
    813                state = P::transition(
    814                    mViewSource.get(),
    815                    nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED, reconsume,
    816                    pos);
    817                NS_HTML5_BREAK(beforeattributevalueloop);
    818              }
    819              case '&': {
    820                attributeLine = line;
    821                clearStrBufBeforeUse();
    822                reconsume = true;
    823                state = P::transition(
    824                    mViewSource.get(),
    825                    nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
    826 
    827                NS_HTML5_CONTINUE(stateloop);
    828              }
    829              case '\'': {
    830                attributeLine = line;
    831                clearStrBufBeforeUse();
    832                state = P::transition(
    833                    mViewSource.get(),
    834                    nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED, reconsume,
    835                    pos);
    836                NS_HTML5_CONTINUE(stateloop);
    837              }
    838              case '>': {
    839                if (P::reportErrors) {
    840                  errAttributeValueMissing();
    841                }
    842                addAttributeWithoutValue();
    843                state = P::transition(mViewSource.get(),
    844                                      emitCurrentTagToken(false, pos),
    845                                      reconsume, pos);
    846                if (shouldSuspend) {
    847                  NS_HTML5_BREAK(stateloop);
    848                }
    849                NS_HTML5_CONTINUE(stateloop);
    850              }
    851              case '\0': {
    852                c = 0xfffd;
    853                [[fallthrough]];
    854              }
    855              case '<':
    856              case '=':
    857              case '`': {
    858                if (P::reportErrors) {
    859                  errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
    860                }
    861                [[fallthrough]];
    862              }
    863              default: {
    864                attributeLine = line;
    865                clearStrBufBeforeUse();
    866                appendStrBuf(c);
    867                state = P::transition(
    868                    mViewSource.get(),
    869                    nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
    870 
    871                NS_HTML5_CONTINUE(stateloop);
    872              }
    873            }
    874          }
    875        beforeattributevalueloop_end:;
    876          [[fallthrough]];
    877        }
    878        case ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
    879          for (;;) {
    880            if (reconsume) {
    881              reconsume = false;
    882            } else {
    883              ++pos;
    884              pos += P::accelerateAdvancementAttributeValueDoubleQuoted(
    885                  this, buf, pos, endPos);
    886              if (pos == endPos) {
    887                NS_HTML5_BREAK(stateloop);
    888              }
    889              c = P::checkChar(this, buf, pos);
    890            }
    891            switch (c) {
    892              case '\"': {
    893                addAttributeWithValue();
    894                state = P::transition(
    895                    mViewSource.get(),
    896                    nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume,
    897                    pos);
    898                NS_HTML5_BREAK(attributevaluedoublequotedloop);
    899              }
    900              case '&': {
    901                MOZ_ASSERT(!charRefBufLen,
    902                           "charRefBufLen not reset after previous use!");
    903                appendCharRefBuf(c);
    904                setAdditionalAndRememberAmpersandLocation('\"');
    905                returnState = state;
    906                state =
    907                    P::transition(mViewSource.get(),
    908                                  nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
    909                                  reconsume, pos);
    910                NS_HTML5_CONTINUE(stateloop);
    911              }
    912              case '\r': {
    913                appendStrBufCarriageReturn<P>();
    914                NS_HTML5_BREAK(stateloop);
    915              }
    916              case '\n': {
    917                appendStrBufLineFeed<P>();
    918                continue;
    919              }
    920              case '\0': {
    921                c = 0xfffd;
    922                [[fallthrough]];
    923              }
    924              default: {
    925                appendStrBuf(c);
    926                continue;
    927              }
    928            }
    929          }
    930        attributevaluedoublequotedloop_end:;
    931          [[fallthrough]];
    932        }
    933        case AFTER_ATTRIBUTE_VALUE_QUOTED: {
    934          for (;;) {
    935            if (++pos == endPos) {
    936              NS_HTML5_BREAK(stateloop);
    937            }
    938            c = P::checkChar(this, buf, pos);
    939            switch (c) {
    940              case '\r': {
    941                P::silentCarriageReturn(this);
    942                state = P::transition(mViewSource.get(),
    943                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
    944                                      reconsume, pos);
    945                NS_HTML5_BREAK(stateloop);
    946              }
    947              case '\n': {
    948                P::silentLineFeed(this);
    949                [[fallthrough]];
    950              }
    951              case ' ':
    952              case '\t':
    953              case '\f': {
    954                state = P::transition(mViewSource.get(),
    955                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
    956                                      reconsume, pos);
    957                NS_HTML5_CONTINUE(stateloop);
    958              }
    959              case '/': {
    960                state = P::transition(mViewSource.get(),
    961                                      nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
    962                                      reconsume, pos);
    963                NS_HTML5_BREAK(afterattributevaluequotedloop);
    964              }
    965              case '>': {
    966                state = P::transition(mViewSource.get(),
    967                                      emitCurrentTagToken(false, pos),
    968                                      reconsume, pos);
    969                if (shouldSuspend) {
    970                  NS_HTML5_BREAK(stateloop);
    971                }
    972                NS_HTML5_CONTINUE(stateloop);
    973              }
    974              default: {
    975                if (P::reportErrors) {
    976                  errNoSpaceBetweenAttributes();
    977                }
    978                reconsume = true;
    979                state = P::transition(mViewSource.get(),
    980                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
    981                                      reconsume, pos);
    982                NS_HTML5_CONTINUE(stateloop);
    983              }
    984            }
    985          }
    986        afterattributevaluequotedloop_end:;
    987          [[fallthrough]];
    988        }
    989        case SELF_CLOSING_START_TAG: {
    990          if (++pos == endPos) {
    991            NS_HTML5_BREAK(stateloop);
    992          }
    993          c = P::checkChar(this, buf, pos);
    994          switch (c) {
    995            case '>': {
    996              state =
    997                  P::transition(mViewSource.get(),
    998                                emitCurrentTagToken(true, pos), reconsume, pos);
    999              if (shouldSuspend) {
   1000                NS_HTML5_BREAK(stateloop);
   1001              }
   1002              NS_HTML5_CONTINUE(stateloop);
   1003            }
   1004            default: {
   1005              if (P::reportErrors) {
   1006                errSlashNotFollowedByGt();
   1007              }
   1008              reconsume = true;
   1009              state = P::transition(mViewSource.get(),
   1010                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
   1011                                    reconsume, pos);
   1012              NS_HTML5_CONTINUE(stateloop);
   1013            }
   1014          }
   1015        }
   1016        case ATTRIBUTE_VALUE_UNQUOTED: {
   1017          for (;;) {
   1018            if (reconsume) {
   1019              reconsume = false;
   1020            } else {
   1021              if (++pos == endPos) {
   1022                NS_HTML5_BREAK(stateloop);
   1023              }
   1024              c = P::checkChar(this, buf, pos);
   1025            }
   1026            switch (c) {
   1027              case '\r': {
   1028                P::silentCarriageReturn(this);
   1029                addAttributeWithValue();
   1030                state = P::transition(mViewSource.get(),
   1031                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
   1032                                      reconsume, pos);
   1033                NS_HTML5_BREAK(stateloop);
   1034              }
   1035              case '\n': {
   1036                P::silentLineFeed(this);
   1037                [[fallthrough]];
   1038              }
   1039              case ' ':
   1040              case '\t':
   1041              case '\f': {
   1042                addAttributeWithValue();
   1043                state = P::transition(mViewSource.get(),
   1044                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
   1045                                      reconsume, pos);
   1046                NS_HTML5_CONTINUE(stateloop);
   1047              }
   1048              case '&': {
   1049                MOZ_ASSERT(!charRefBufLen,
   1050                           "charRefBufLen not reset after previous use!");
   1051                appendCharRefBuf(c);
   1052                setAdditionalAndRememberAmpersandLocation('>');
   1053                returnState = state;
   1054                state =
   1055                    P::transition(mViewSource.get(),
   1056                                  nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
   1057                                  reconsume, pos);
   1058                NS_HTML5_CONTINUE(stateloop);
   1059              }
   1060              case '>': {
   1061                addAttributeWithValue();
   1062                state = P::transition(mViewSource.get(),
   1063                                      emitCurrentTagToken(false, pos),
   1064                                      reconsume, pos);
   1065                if (shouldSuspend) {
   1066                  NS_HTML5_BREAK(stateloop);
   1067                }
   1068                NS_HTML5_CONTINUE(stateloop);
   1069              }
   1070              case '\0': {
   1071                c = 0xfffd;
   1072                [[fallthrough]];
   1073              }
   1074              case '<':
   1075              case '\"':
   1076              case '\'':
   1077              case '=':
   1078              case '`': {
   1079                if (P::reportErrors) {
   1080                  errUnquotedAttributeValOrNull(c);
   1081                }
   1082                [[fallthrough]];
   1083              }
   1084              default: {
   1085                appendStrBuf(c);
   1086                continue;
   1087              }
   1088            }
   1089          }
   1090        }
   1091        case AFTER_ATTRIBUTE_NAME: {
   1092          for (;;) {
   1093            if (++pos == endPos) {
   1094              NS_HTML5_BREAK(stateloop);
   1095            }
   1096            c = P::checkChar(this, buf, pos);
   1097            switch (c) {
   1098              case '\r': {
   1099                P::silentCarriageReturn(this);
   1100                NS_HTML5_BREAK(stateloop);
   1101              }
   1102              case '\n': {
   1103                P::silentLineFeed(this);
   1104                [[fallthrough]];
   1105              }
   1106              case ' ':
   1107              case '\t':
   1108              case '\f': {
   1109                continue;
   1110              }
   1111              case '/': {
   1112                addAttributeWithoutValue();
   1113                state = P::transition(mViewSource.get(),
   1114                                      nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
   1115                                      reconsume, pos);
   1116                NS_HTML5_CONTINUE(stateloop);
   1117              }
   1118              case '=': {
   1119                state = P::transition(mViewSource.get(),
   1120                                      nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
   1121                                      reconsume, pos);
   1122                NS_HTML5_CONTINUE(stateloop);
   1123              }
   1124              case '>': {
   1125                addAttributeWithoutValue();
   1126                state = P::transition(mViewSource.get(),
   1127                                      emitCurrentTagToken(false, pos),
   1128                                      reconsume, pos);
   1129                if (shouldSuspend) {
   1130                  NS_HTML5_BREAK(stateloop);
   1131                }
   1132                NS_HTML5_CONTINUE(stateloop);
   1133              }
   1134              case '\0': {
   1135                c = 0xfffd;
   1136                [[fallthrough]];
   1137              }
   1138              case '\"':
   1139              case '\'':
   1140              case '<': {
   1141                if (P::reportErrors) {
   1142                  errQuoteOrLtInAttributeNameOrNull(c);
   1143                }
   1144                [[fallthrough]];
   1145              }
   1146              default: {
   1147                addAttributeWithoutValue();
   1148                if (c >= 'A' && c <= 'Z') {
   1149                  c += 0x20;
   1150                }
   1151                clearStrBufBeforeUse();
   1152                appendStrBuf(c);
   1153                state = P::transition(mViewSource.get(),
   1154                                      nsHtml5Tokenizer::ATTRIBUTE_NAME,
   1155                                      reconsume, pos);
   1156                NS_HTML5_CONTINUE(stateloop);
   1157              }
   1158            }
   1159          }
   1160        }
   1161        case MARKUP_DECLARATION_OPEN: {
   1162          for (;;) {
   1163            if (++pos == endPos) {
   1164              NS_HTML5_BREAK(stateloop);
   1165            }
   1166            c = P::checkChar(this, buf, pos);
   1167            switch (c) {
   1168              case '-': {
   1169                clearStrBufBeforeUse();
   1170                appendStrBuf(c);
   1171                state =
   1172                    P::transition(mViewSource.get(),
   1173                                  nsHtml5Tokenizer::MARKUP_DECLARATION_HYPHEN,
   1174                                  reconsume, pos);
   1175                NS_HTML5_BREAK(markupdeclarationopenloop);
   1176              }
   1177              case 'd':
   1178              case 'D': {
   1179                clearStrBufBeforeUse();
   1180                appendStrBuf(c);
   1181                index = 0;
   1182                state =
   1183                    P::transition(mViewSource.get(),
   1184                                  nsHtml5Tokenizer::MARKUP_DECLARATION_OCTYPE,
   1185                                  reconsume, pos);
   1186                NS_HTML5_CONTINUE(stateloop);
   1187              }
   1188              case '[': {
   1189                if (tokenHandler->cdataSectionAllowed()) {
   1190                  clearStrBufBeforeUse();
   1191                  appendStrBuf(c);
   1192                  index = 0;
   1193                  state = P::transition(mViewSource.get(),
   1194                                        nsHtml5Tokenizer::CDATA_START,
   1195                                        reconsume, pos);
   1196                  NS_HTML5_CONTINUE(stateloop);
   1197                }
   1198                [[fallthrough]];
   1199              }
   1200              default: {
   1201                if (P::reportErrors) {
   1202                  errBogusComment();
   1203                }
   1204                clearStrBufBeforeUse();
   1205                reconsume = true;
   1206                state = P::transition(mViewSource.get(),
   1207                                      nsHtml5Tokenizer::BOGUS_COMMENT,
   1208                                      reconsume, pos);
   1209                NS_HTML5_CONTINUE(stateloop);
   1210              }
   1211            }
   1212          }
   1213        markupdeclarationopenloop_end:;
   1214          [[fallthrough]];
   1215        }
   1216        case MARKUP_DECLARATION_HYPHEN: {
   1217          for (;;) {
   1218            if (++pos == endPos) {
   1219              NS_HTML5_BREAK(stateloop);
   1220            }
   1221            c = P::checkChar(this, buf, pos);
   1222            switch (c) {
   1223              case '-': {
   1224                clearStrBufAfterOneHyphen();
   1225                state = P::transition(mViewSource.get(),
   1226                                      nsHtml5Tokenizer::COMMENT_START,
   1227                                      reconsume, pos);
   1228                NS_HTML5_BREAK(markupdeclarationhyphenloop);
   1229              }
   1230              default: {
   1231                if (P::reportErrors) {
   1232                  errBogusComment();
   1233                }
   1234                reconsume = true;
   1235                state = P::transition(mViewSource.get(),
   1236                                      nsHtml5Tokenizer::BOGUS_COMMENT,
   1237                                      reconsume, pos);
   1238                NS_HTML5_CONTINUE(stateloop);
   1239              }
   1240            }
   1241          }
   1242        markupdeclarationhyphenloop_end:;
   1243          [[fallthrough]];
   1244        }
   1245        case COMMENT_START: {
   1246          reportedConsecutiveHyphens = false;
   1247          for (;;) {
   1248            if (++pos == endPos) {
   1249              NS_HTML5_BREAK(stateloop);
   1250            }
   1251            c = P::checkChar(this, buf, pos);
   1252            switch (c) {
   1253              case '-': {
   1254                appendStrBuf(c);
   1255                state = P::transition(mViewSource.get(),
   1256                                      nsHtml5Tokenizer::COMMENT_START_DASH,
   1257                                      reconsume, pos);
   1258                NS_HTML5_CONTINUE(stateloop);
   1259              }
   1260              case '>': {
   1261                if (P::reportErrors) {
   1262                  errPrematureEndOfComment();
   1263                }
   1264                emitComment(0, pos);
   1265                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   1266                                      reconsume, pos);
   1267                if (shouldSuspend) {
   1268                  NS_HTML5_BREAK(stateloop);
   1269                }
   1270                NS_HTML5_CONTINUE(stateloop);
   1271              }
   1272              case '<': {
   1273                appendStrBuf(c);
   1274                state = P::transition(mViewSource.get(),
   1275                                      nsHtml5Tokenizer::COMMENT_LESSTHAN,
   1276                                      reconsume, pos);
   1277                NS_HTML5_CONTINUE(stateloop);
   1278              }
   1279              case '\r': {
   1280                appendStrBufCarriageReturn<P>();
   1281                state =
   1282                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1283                                  reconsume, pos);
   1284                NS_HTML5_BREAK(stateloop);
   1285              }
   1286              case '\n': {
   1287                appendStrBufLineFeed<P>();
   1288                state =
   1289                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1290                                  reconsume, pos);
   1291                NS_HTML5_BREAK(commentstartloop);
   1292              }
   1293              case '\0': {
   1294                c = 0xfffd;
   1295                [[fallthrough]];
   1296              }
   1297              default: {
   1298                appendStrBuf(c);
   1299                state =
   1300                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1301                                  reconsume, pos);
   1302                NS_HTML5_BREAK(commentstartloop);
   1303              }
   1304            }
   1305          }
   1306        commentstartloop_end:;
   1307          [[fallthrough]];
   1308        }
   1309        case COMMENT: {
   1310          for (;;) {
   1311            ++pos;
   1312            pos += P::accelerateAdvancementComment(this, buf, pos, endPos);
   1313            if (pos == endPos) {
   1314              NS_HTML5_BREAK(stateloop);
   1315            }
   1316            c = P::checkChar(this, buf, pos);
   1317            switch (c) {
   1318              case '-': {
   1319                appendStrBuf(c);
   1320                state = P::transition(mViewSource.get(),
   1321                                      nsHtml5Tokenizer::COMMENT_END_DASH,
   1322                                      reconsume, pos);
   1323                NS_HTML5_BREAK(commentloop);
   1324              }
   1325              case '<': {
   1326                appendStrBuf(c);
   1327                state = P::transition(mViewSource.get(),
   1328                                      nsHtml5Tokenizer::COMMENT_LESSTHAN,
   1329                                      reconsume, pos);
   1330                NS_HTML5_CONTINUE(stateloop);
   1331              }
   1332              case '\r': {
   1333                appendStrBufCarriageReturn<P>();
   1334                NS_HTML5_BREAK(stateloop);
   1335              }
   1336              case '\n': {
   1337                appendStrBufLineFeed<P>();
   1338                continue;
   1339              }
   1340              case '\0': {
   1341                c = 0xfffd;
   1342                [[fallthrough]];
   1343              }
   1344              default: {
   1345                appendStrBuf(c);
   1346                continue;
   1347              }
   1348            }
   1349          }
   1350        commentloop_end:;
   1351          [[fallthrough]];
   1352        }
   1353        case COMMENT_END_DASH: {
   1354          for (;;) {
   1355            if (++pos == endPos) {
   1356              NS_HTML5_BREAK(stateloop);
   1357            }
   1358            c = P::checkChar(this, buf, pos);
   1359            switch (c) {
   1360              case '-': {
   1361                appendStrBuf(c);
   1362                state = P::transition(mViewSource.get(),
   1363                                      nsHtml5Tokenizer::COMMENT_END, reconsume,
   1364                                      pos);
   1365                NS_HTML5_BREAK(commentenddashloop);
   1366              }
   1367              case '<': {
   1368                appendStrBuf(c);
   1369                state = P::transition(mViewSource.get(),
   1370                                      nsHtml5Tokenizer::COMMENT_LESSTHAN,
   1371                                      reconsume, pos);
   1372                NS_HTML5_CONTINUE(stateloop);
   1373              }
   1374              case '\r': {
   1375                appendStrBufCarriageReturn<P>();
   1376                state =
   1377                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1378                                  reconsume, pos);
   1379                NS_HTML5_BREAK(stateloop);
   1380              }
   1381              case '\n': {
   1382                appendStrBufLineFeed<P>();
   1383                state =
   1384                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1385                                  reconsume, pos);
   1386                NS_HTML5_CONTINUE(stateloop);
   1387              }
   1388              case '\0': {
   1389                c = 0xfffd;
   1390                [[fallthrough]];
   1391              }
   1392              default: {
   1393                appendStrBuf(c);
   1394                state =
   1395                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1396                                  reconsume, pos);
   1397                NS_HTML5_CONTINUE(stateloop);
   1398              }
   1399            }
   1400          }
   1401        commentenddashloop_end:;
   1402          [[fallthrough]];
   1403        }
   1404        case COMMENT_END: {
   1405          for (;;) {
   1406            if (++pos == endPos) {
   1407              NS_HTML5_BREAK(stateloop);
   1408            }
   1409            c = P::checkChar(this, buf, pos);
   1410            switch (c) {
   1411              case '>': {
   1412                emitComment(2, pos);
   1413                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   1414                                      reconsume, pos);
   1415                if (shouldSuspend) {
   1416                  NS_HTML5_BREAK(stateloop);
   1417                }
   1418                NS_HTML5_CONTINUE(stateloop);
   1419              }
   1420              case '-': {
   1421                adjustDoubleHyphenAndAppendToStrBufAndErr(
   1422                    c, reportedConsecutiveHyphens);
   1423                reportedConsecutiveHyphens = true;
   1424                continue;
   1425              }
   1426              case '<': {
   1427                appendStrBuf(c);
   1428                state = P::transition(mViewSource.get(),
   1429                                      nsHtml5Tokenizer::COMMENT_LESSTHAN,
   1430                                      reconsume, pos);
   1431                NS_HTML5_CONTINUE(stateloop);
   1432              }
   1433              case '\r': {
   1434                adjustDoubleHyphenAndAppendToStrBufCarriageReturn<P>();
   1435                state =
   1436                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1437                                  reconsume, pos);
   1438                NS_HTML5_BREAK(stateloop);
   1439              }
   1440              case '\n': {
   1441                adjustDoubleHyphenAndAppendToStrBufLineFeed<P>();
   1442                state =
   1443                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1444                                  reconsume, pos);
   1445                NS_HTML5_CONTINUE(stateloop);
   1446              }
   1447              case '!': {
   1448                appendStrBuf(c);
   1449                state = P::transition(mViewSource.get(),
   1450                                      nsHtml5Tokenizer::COMMENT_END_BANG,
   1451                                      reconsume, pos);
   1452                NS_HTML5_BREAK(commentendloop);
   1453              }
   1454              case '\0': {
   1455                c = 0xfffd;
   1456                [[fallthrough]];
   1457              }
   1458              default: {
   1459                adjustDoubleHyphenAndAppendToStrBufAndErr(
   1460                    c, reportedConsecutiveHyphens);
   1461                reportedConsecutiveHyphens = true;
   1462                state =
   1463                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1464                                  reconsume, pos);
   1465                NS_HTML5_CONTINUE(stateloop);
   1466              }
   1467            }
   1468          }
   1469        commentendloop_end:;
   1470          [[fallthrough]];
   1471        }
   1472        case COMMENT_END_BANG: {
   1473          for (;;) {
   1474            if (++pos == endPos) {
   1475              NS_HTML5_BREAK(stateloop);
   1476            }
   1477            c = P::checkChar(this, buf, pos);
   1478            switch (c) {
   1479              case '>': {
   1480                emitComment(3, pos);
   1481                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   1482                                      reconsume, pos);
   1483                if (shouldSuspend) {
   1484                  NS_HTML5_BREAK(stateloop);
   1485                }
   1486                NS_HTML5_CONTINUE(stateloop);
   1487              }
   1488              case '-': {
   1489                appendStrBuf(c);
   1490                state = P::transition(mViewSource.get(),
   1491                                      nsHtml5Tokenizer::COMMENT_END_DASH,
   1492                                      reconsume, pos);
   1493                NS_HTML5_CONTINUE(stateloop);
   1494              }
   1495              case '\r': {
   1496                appendStrBufCarriageReturn<P>();
   1497                state =
   1498                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1499                                  reconsume, pos);
   1500                NS_HTML5_BREAK(stateloop);
   1501              }
   1502              case '\n': {
   1503                appendStrBufLineFeed<P>();
   1504                state =
   1505                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1506                                  reconsume, pos);
   1507                NS_HTML5_CONTINUE(stateloop);
   1508              }
   1509              case '\0': {
   1510                c = 0xfffd;
   1511                [[fallthrough]];
   1512              }
   1513              default: {
   1514                appendStrBuf(c);
   1515                state =
   1516                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1517                                  reconsume, pos);
   1518                NS_HTML5_CONTINUE(stateloop);
   1519              }
   1520            }
   1521          }
   1522        }
   1523        case COMMENT_LESSTHAN: {
   1524          for (;;) {
   1525            if (++pos == endPos) {
   1526              NS_HTML5_BREAK(stateloop);
   1527            }
   1528            c = P::checkChar(this, buf, pos);
   1529            switch (c) {
   1530              case '!': {
   1531                appendStrBuf(c);
   1532                state = P::transition(mViewSource.get(),
   1533                                      nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG,
   1534                                      reconsume, pos);
   1535                NS_HTML5_BREAK(commentlessthanloop);
   1536              }
   1537              case '<': {
   1538                appendStrBuf(c);
   1539                continue;
   1540              }
   1541              case '-': {
   1542                appendStrBuf(c);
   1543                state = P::transition(mViewSource.get(),
   1544                                      nsHtml5Tokenizer::COMMENT_END_DASH,
   1545                                      reconsume, pos);
   1546                NS_HTML5_CONTINUE(stateloop);
   1547              }
   1548              case '\r': {
   1549                appendStrBufCarriageReturn<P>();
   1550                state =
   1551                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1552                                  reconsume, pos);
   1553                NS_HTML5_BREAK(stateloop);
   1554              }
   1555              case '\n': {
   1556                appendStrBufLineFeed<P>();
   1557                state =
   1558                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1559                                  reconsume, pos);
   1560                NS_HTML5_CONTINUE(stateloop);
   1561              }
   1562              case '\0': {
   1563                c = 0xfffd;
   1564                [[fallthrough]];
   1565              }
   1566              default: {
   1567                appendStrBuf(c);
   1568                state =
   1569                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1570                                  reconsume, pos);
   1571                NS_HTML5_CONTINUE(stateloop);
   1572              }
   1573            }
   1574          }
   1575        commentlessthanloop_end:;
   1576          [[fallthrough]];
   1577        }
   1578        case COMMENT_LESSTHAN_BANG: {
   1579          for (;;) {
   1580            if (++pos == endPos) {
   1581              NS_HTML5_BREAK(stateloop);
   1582            }
   1583            c = P::checkChar(this, buf, pos);
   1584            switch (c) {
   1585              case '-': {
   1586                appendStrBuf(c);
   1587                state =
   1588                    P::transition(mViewSource.get(),
   1589                                  nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH,
   1590                                  reconsume, pos);
   1591                NS_HTML5_BREAK(commentlessthanbangloop);
   1592              }
   1593              case '<': {
   1594                appendStrBuf(c);
   1595                state = P::transition(mViewSource.get(),
   1596                                      nsHtml5Tokenizer::COMMENT_LESSTHAN,
   1597                                      reconsume, pos);
   1598                NS_HTML5_CONTINUE(stateloop);
   1599              }
   1600              case '\r': {
   1601                appendStrBufCarriageReturn<P>();
   1602                state =
   1603                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1604                                  reconsume, pos);
   1605                NS_HTML5_BREAK(stateloop);
   1606              }
   1607              case '\n': {
   1608                appendStrBufLineFeed<P>();
   1609                state =
   1610                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1611                                  reconsume, pos);
   1612                NS_HTML5_CONTINUE(stateloop);
   1613              }
   1614              case '\0': {
   1615                c = 0xfffd;
   1616                [[fallthrough]];
   1617              }
   1618              default: {
   1619                appendStrBuf(c);
   1620                state =
   1621                    P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
   1622                                  reconsume, pos);
   1623                NS_HTML5_CONTINUE(stateloop);
   1624              }
   1625            }
   1626          }
   1627        commentlessthanbangloop_end:;
   1628          [[fallthrough]];
   1629        }
   1630        case COMMENT_LESSTHAN_BANG_DASH: {
   1631          if (++pos == endPos) {
   1632            NS_HTML5_BREAK(stateloop);
   1633          }
   1634          c = P::checkChar(this, buf, pos);
   1635          switch (c) {
   1636            case '-': {
   1637              appendStrBuf(c);
   1638              state = P::transition(
   1639                  mViewSource.get(),
   1640                  nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH, reconsume,
   1641                  pos);
   1642              break;
   1643            }
   1644            case '<': {
   1645              appendStrBuf(c);
   1646              state = P::transition(mViewSource.get(),
   1647                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
   1648                                    reconsume, pos);
   1649              NS_HTML5_CONTINUE(stateloop);
   1650            }
   1651            case '\r': {
   1652              appendStrBufCarriageReturn<P>();
   1653              state = P::transition(mViewSource.get(),
   1654                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1655              NS_HTML5_BREAK(stateloop);
   1656            }
   1657            case '\n': {
   1658              appendStrBufLineFeed<P>();
   1659              state = P::transition(mViewSource.get(),
   1660                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1661              NS_HTML5_CONTINUE(stateloop);
   1662            }
   1663            case '\0': {
   1664              c = 0xfffd;
   1665              [[fallthrough]];
   1666            }
   1667            default: {
   1668              appendStrBuf(c);
   1669              state = P::transition(mViewSource.get(),
   1670                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1671              NS_HTML5_CONTINUE(stateloop);
   1672            }
   1673          }
   1674          [[fallthrough]];
   1675        }
   1676        case COMMENT_LESSTHAN_BANG_DASH_DASH: {
   1677          if (++pos == endPos) {
   1678            NS_HTML5_BREAK(stateloop);
   1679          }
   1680          c = P::checkChar(this, buf, pos);
   1681          switch (c) {
   1682            case '>': {
   1683              appendStrBuf(c);
   1684              emitComment(3, pos);
   1685              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   1686                                    reconsume, pos);
   1687              if (shouldSuspend) {
   1688                NS_HTML5_BREAK(stateloop);
   1689              }
   1690              NS_HTML5_CONTINUE(stateloop);
   1691            }
   1692            case '-': {
   1693              if (P::reportErrors) {
   1694                errNestedComment();
   1695              }
   1696              adjustDoubleHyphenAndAppendToStrBufAndErr(
   1697                  c, reportedConsecutiveHyphens);
   1698              reportedConsecutiveHyphens = true;
   1699              state =
   1700                  P::transition(mViewSource.get(),
   1701                                nsHtml5Tokenizer::COMMENT_END, reconsume, pos);
   1702              NS_HTML5_CONTINUE(stateloop);
   1703            }
   1704            case '\r': {
   1705              c = '\n';
   1706              P::silentCarriageReturn(this);
   1707              if (P::reportErrors) {
   1708                errNestedComment();
   1709              }
   1710              adjustDoubleHyphenAndAppendToStrBufAndErr(
   1711                  c, reportedConsecutiveHyphens);
   1712              reportedConsecutiveHyphens = true;
   1713              state = P::transition(mViewSource.get(),
   1714                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1715              NS_HTML5_BREAK(stateloop);
   1716            }
   1717            case '\n': {
   1718              P::silentLineFeed(this);
   1719              if (P::reportErrors) {
   1720                errNestedComment();
   1721              }
   1722              adjustDoubleHyphenAndAppendToStrBufAndErr(
   1723                  c, reportedConsecutiveHyphens);
   1724              reportedConsecutiveHyphens = true;
   1725              state = P::transition(mViewSource.get(),
   1726                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1727              NS_HTML5_CONTINUE(stateloop);
   1728            }
   1729            case '!': {
   1730              if (P::reportErrors) {
   1731                errNestedComment();
   1732              }
   1733              adjustDoubleHyphenAndAppendToStrBufAndErr(
   1734                  c, reportedConsecutiveHyphens);
   1735              reportedConsecutiveHyphens = true;
   1736              state = P::transition(mViewSource.get(),
   1737                                    nsHtml5Tokenizer::COMMENT_END_BANG,
   1738                                    reconsume, pos);
   1739              NS_HTML5_CONTINUE(stateloop);
   1740            }
   1741            case '\0': {
   1742              c = 0xfffd;
   1743              [[fallthrough]];
   1744            }
   1745            default: {
   1746              if (P::reportErrors) {
   1747                errNestedComment();
   1748              }
   1749              adjustDoubleHyphenAndAppendToStrBufAndErr(
   1750                  c, reportedConsecutiveHyphens);
   1751              reportedConsecutiveHyphens = true;
   1752              state = P::transition(mViewSource.get(),
   1753                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1754              NS_HTML5_CONTINUE(stateloop);
   1755            }
   1756          }
   1757        }
   1758        case COMMENT_START_DASH: {
   1759          if (++pos == endPos) {
   1760            NS_HTML5_BREAK(stateloop);
   1761          }
   1762          c = P::checkChar(this, buf, pos);
   1763          switch (c) {
   1764            case '-': {
   1765              appendStrBuf(c);
   1766              state =
   1767                  P::transition(mViewSource.get(),
   1768                                nsHtml5Tokenizer::COMMENT_END, reconsume, pos);
   1769              NS_HTML5_CONTINUE(stateloop);
   1770            }
   1771            case '>': {
   1772              if (P::reportErrors) {
   1773                errPrematureEndOfComment();
   1774              }
   1775              emitComment(1, pos);
   1776              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   1777                                    reconsume, pos);
   1778              if (shouldSuspend) {
   1779                NS_HTML5_BREAK(stateloop);
   1780              }
   1781              NS_HTML5_CONTINUE(stateloop);
   1782            }
   1783            case '<': {
   1784              appendStrBuf(c);
   1785              state = P::transition(mViewSource.get(),
   1786                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
   1787                                    reconsume, pos);
   1788              NS_HTML5_CONTINUE(stateloop);
   1789            }
   1790            case '\r': {
   1791              appendStrBufCarriageReturn<P>();
   1792              state = P::transition(mViewSource.get(),
   1793                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1794              NS_HTML5_BREAK(stateloop);
   1795            }
   1796            case '\n': {
   1797              appendStrBufLineFeed<P>();
   1798              state = P::transition(mViewSource.get(),
   1799                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1800              NS_HTML5_CONTINUE(stateloop);
   1801            }
   1802            case '\0': {
   1803              c = 0xfffd;
   1804              [[fallthrough]];
   1805            }
   1806            default: {
   1807              appendStrBuf(c);
   1808              state = P::transition(mViewSource.get(),
   1809                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
   1810              NS_HTML5_CONTINUE(stateloop);
   1811            }
   1812          }
   1813        }
   1814        case CDATA_START: {
   1815          for (;;) {
   1816            if (++pos == endPos) {
   1817              NS_HTML5_BREAK(stateloop);
   1818            }
   1819            c = P::checkChar(this, buf, pos);
   1820            if (index < 6) {
   1821              if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
   1822                appendStrBuf(c);
   1823              } else {
   1824                if (P::reportErrors) {
   1825                  errBogusComment();
   1826                }
   1827                reconsume = true;
   1828                state = P::transition(mViewSource.get(),
   1829                                      nsHtml5Tokenizer::BOGUS_COMMENT,
   1830                                      reconsume, pos);
   1831                NS_HTML5_CONTINUE(stateloop);
   1832              }
   1833              index++;
   1834              continue;
   1835            } else {
   1836              clearStrBufAfterUse();
   1837              cstart = pos;
   1838              reconsume = true;
   1839              state = P::transition(mViewSource.get(),
   1840                                    nsHtml5Tokenizer::CDATA_SECTION, reconsume,
   1841                                    pos);
   1842              break;
   1843            }
   1844          }
   1845          [[fallthrough]];
   1846        }
   1847        case CDATA_SECTION: {
   1848          for (;;) {
   1849            if (reconsume) {
   1850              reconsume = false;
   1851            } else {
   1852              ++pos;
   1853              pos +=
   1854                  P::accelerateAdvancementCdataSection(this, buf, pos, endPos);
   1855              if (pos == endPos) {
   1856                NS_HTML5_BREAK(stateloop);
   1857              }
   1858              c = P::checkChar(this, buf, pos);
   1859            }
   1860            switch (c) {
   1861              case ']': {
   1862                flushChars(buf, pos);
   1863                state =
   1864                    P::transition(mViewSource.get(),
   1865                                  nsHtml5Tokenizer::CDATA_RSQB, reconsume, pos);
   1866                NS_HTML5_BREAK(cdatasectionloop);
   1867              }
   1868              case '\0': {
   1869                maybeEmitReplacementCharacter(buf, pos);
   1870                continue;
   1871              }
   1872              case '\r': {
   1873                emitCarriageReturn<P>(buf, pos);
   1874                NS_HTML5_BREAK(stateloop);
   1875              }
   1876              case '\n': {
   1877                P::silentLineFeed(this);
   1878                [[fallthrough]];
   1879              }
   1880              default: {
   1881                continue;
   1882              }
   1883            }
   1884          }
   1885        cdatasectionloop_end:;
   1886          [[fallthrough]];
   1887        }
   1888        case CDATA_RSQB: {
   1889          if (++pos == endPos) {
   1890            NS_HTML5_BREAK(stateloop);
   1891          }
   1892          c = P::checkChar(this, buf, pos);
   1893          switch (c) {
   1894            case ']': {
   1895              state = P::transition(mViewSource.get(),
   1896                                    nsHtml5Tokenizer::CDATA_RSQB_RSQB,
   1897                                    reconsume, pos);
   1898              break;
   1899            }
   1900            default: {
   1901              tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
   1902              cstart = pos;
   1903              reconsume = true;
   1904              state = P::transition(mViewSource.get(),
   1905                                    nsHtml5Tokenizer::CDATA_SECTION, reconsume,
   1906                                    pos);
   1907              NS_HTML5_CONTINUE(stateloop);
   1908            }
   1909          }
   1910          [[fallthrough]];
   1911        }
   1912        case CDATA_RSQB_RSQB: {
   1913          for (;;) {
   1914            if (++pos == endPos) {
   1915              NS_HTML5_BREAK(stateloop);
   1916            }
   1917            c = P::checkChar(this, buf, pos);
   1918            switch (c) {
   1919              case ']': {
   1920                tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
   1921                continue;
   1922              }
   1923              case '>': {
   1924                cstart = pos + 1;
   1925                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   1926                                      reconsume, pos);
   1927                suspendIfRequestedAfterCurrentNonTextToken();
   1928                if (shouldSuspend) {
   1929                  NS_HTML5_BREAK(stateloop);
   1930                }
   1931                NS_HTML5_CONTINUE(stateloop);
   1932              }
   1933              default: {
   1934                tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
   1935                cstart = pos;
   1936                reconsume = true;
   1937                state = P::transition(mViewSource.get(),
   1938                                      nsHtml5Tokenizer::CDATA_SECTION,
   1939                                      reconsume, pos);
   1940                NS_HTML5_CONTINUE(stateloop);
   1941              }
   1942            }
   1943          }
   1944        }
   1945        case ATTRIBUTE_VALUE_SINGLE_QUOTED: {
   1946          for (;;) {
   1947            if (reconsume) {
   1948              reconsume = false;
   1949            } else {
   1950              ++pos;
   1951              pos += P::accelerateAdvancementAttributeValueSingleQuoted(
   1952                  this, buf, pos, endPos);
   1953              if (pos == endPos) {
   1954                NS_HTML5_BREAK(stateloop);
   1955              }
   1956              c = P::checkChar(this, buf, pos);
   1957            }
   1958            switch (c) {
   1959              case '\'': {
   1960                addAttributeWithValue();
   1961                state = P::transition(
   1962                    mViewSource.get(),
   1963                    nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED, reconsume,
   1964                    pos);
   1965                NS_HTML5_CONTINUE(stateloop);
   1966              }
   1967              case '&': {
   1968                MOZ_ASSERT(!charRefBufLen,
   1969                           "charRefBufLen not reset after previous use!");
   1970                appendCharRefBuf(c);
   1971                setAdditionalAndRememberAmpersandLocation('\'');
   1972                returnState = state;
   1973                state =
   1974                    P::transition(mViewSource.get(),
   1975                                  nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
   1976                                  reconsume, pos);
   1977                NS_HTML5_BREAK(attributevaluesinglequotedloop);
   1978              }
   1979              case '\r': {
   1980                appendStrBufCarriageReturn<P>();
   1981                NS_HTML5_BREAK(stateloop);
   1982              }
   1983              case '\n': {
   1984                appendStrBufLineFeed<P>();
   1985                continue;
   1986              }
   1987              case '\0': {
   1988                c = 0xfffd;
   1989                [[fallthrough]];
   1990              }
   1991              default: {
   1992                appendStrBuf(c);
   1993                continue;
   1994              }
   1995            }
   1996          }
   1997        attributevaluesinglequotedloop_end:;
   1998          [[fallthrough]];
   1999        }
   2000        case CONSUME_CHARACTER_REFERENCE: {
   2001          if (++pos == endPos) {
   2002            NS_HTML5_BREAK(stateloop);
   2003          }
   2004          c = P::checkChar(this, buf, pos);
   2005          switch (c) {
   2006            case ' ':
   2007            case '\t':
   2008            case '\n':
   2009            case '\r':
   2010            case '\f':
   2011            case '<':
   2012            case '&':
   2013            case '\0':
   2014            case ';': {
   2015              emitOrAppendCharRefBuf(returnState);
   2016              if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2017                cstart = pos;
   2018              }
   2019              reconsume = true;
   2020              state =
   2021                  P::transition(mViewSource.get(), returnState, reconsume, pos);
   2022              NS_HTML5_CONTINUE(stateloop);
   2023            }
   2024            case '#': {
   2025              appendCharRefBuf('#');
   2026              state =
   2027                  P::transition(mViewSource.get(),
   2028                                nsHtml5Tokenizer::CONSUME_NCR, reconsume, pos);
   2029              NS_HTML5_CONTINUE(stateloop);
   2030            }
   2031            default: {
   2032              if (c == additional) {
   2033                emitOrAppendCharRefBuf(returnState);
   2034                reconsume = true;
   2035                state = P::transition(mViewSource.get(), returnState, reconsume,
   2036                                      pos);
   2037                NS_HTML5_CONTINUE(stateloop);
   2038              }
   2039              if (c >= 'a' && c <= 'z') {
   2040                firstCharKey = c - 'a' + 26;
   2041              } else if (c >= 'A' && c <= 'Z') {
   2042                firstCharKey = c - 'A';
   2043              } else {
   2044                if (c == ';') {
   2045                  if (P::reportErrors) {
   2046                    errNoNamedCharacterMatch();
   2047                  }
   2048                }
   2049                emitOrAppendCharRefBuf(returnState);
   2050                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2051                  cstart = pos;
   2052                }
   2053                reconsume = true;
   2054                state = P::transition(mViewSource.get(), returnState, reconsume,
   2055                                      pos);
   2056                NS_HTML5_CONTINUE(stateloop);
   2057              }
   2058              appendCharRefBuf(c);
   2059              state = P::transition(
   2060                  mViewSource.get(),
   2061                  nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP, reconsume,
   2062                  pos);
   2063              break;
   2064            }
   2065          }
   2066          [[fallthrough]];
   2067        }
   2068        case CHARACTER_REFERENCE_HILO_LOOKUP: {
   2069          {
   2070            if (++pos == endPos) {
   2071              NS_HTML5_BREAK(stateloop);
   2072            }
   2073            c = P::checkChar(this, buf, pos);
   2074            int32_t hilo = 0;
   2075            if (c <= 'z') {
   2076              const int32_t* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c];
   2077              if (row) {
   2078                hilo = row[firstCharKey];
   2079              }
   2080            }
   2081            if (!hilo) {
   2082              if (c == ';') {
   2083                if (P::reportErrors) {
   2084                  errNoNamedCharacterMatch();
   2085                }
   2086              }
   2087              emitOrAppendCharRefBuf(returnState);
   2088              if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2089                cstart = pos;
   2090              }
   2091              reconsume = true;
   2092              state =
   2093                  P::transition(mViewSource.get(), returnState, reconsume, pos);
   2094              NS_HTML5_CONTINUE(stateloop);
   2095            }
   2096            appendCharRefBuf(c);
   2097            lo = hilo & 0xFFFF;
   2098            hi = hilo >> 16;
   2099            entCol = -1;
   2100            candidate = -1;
   2101            charRefBufMark = 0;
   2102            state = P::transition(mViewSource.get(),
   2103                                  nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL,
   2104                                  reconsume, pos);
   2105          }
   2106          [[fallthrough]];
   2107        }
   2108        case CHARACTER_REFERENCE_TAIL: {
   2109          for (;;) {
   2110            if (++pos == endPos) {
   2111              NS_HTML5_BREAK(stateloop);
   2112            }
   2113            c = P::checkChar(this, buf, pos);
   2114            entCol++;
   2115            for (;;) {
   2116              if (hi < lo) {
   2117                NS_HTML5_BREAK(outer);
   2118              }
   2119              if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
   2120                candidate = lo;
   2121                charRefBufMark = charRefBufLen;
   2122                lo++;
   2123              } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
   2124                NS_HTML5_BREAK(outer);
   2125              } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
   2126                lo++;
   2127              } else {
   2128                NS_HTML5_BREAK(loloop);
   2129              }
   2130            }
   2131          loloop_end:;
   2132            for (;;) {
   2133              if (hi < lo) {
   2134                NS_HTML5_BREAK(outer);
   2135              }
   2136              if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
   2137                NS_HTML5_BREAK(hiloop);
   2138              }
   2139              if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
   2140                NS_HTML5_BREAK(outer);
   2141              } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
   2142                hi--;
   2143              } else {
   2144                NS_HTML5_BREAK(hiloop);
   2145              }
   2146            }
   2147          hiloop_end:;
   2148            if (c == ';') {
   2149              if (entCol + 1 == nsHtml5NamedCharacters::NAMES[lo].length()) {
   2150                candidate = lo;
   2151                charRefBufMark = charRefBufLen;
   2152              }
   2153              NS_HTML5_BREAK(outer);
   2154            }
   2155            if (hi < lo) {
   2156              NS_HTML5_BREAK(outer);
   2157            }
   2158            appendCharRefBuf(c);
   2159            continue;
   2160          }
   2161        outer_end:;
   2162          if (candidate == -1) {
   2163            if (c == ';') {
   2164              if (P::reportErrors) {
   2165                errNoNamedCharacterMatch();
   2166              }
   2167            }
   2168            emitOrAppendCharRefBuf(returnState);
   2169            if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2170              cstart = pos;
   2171            }
   2172            reconsume = true;
   2173            state =
   2174                P::transition(mViewSource.get(), returnState, reconsume, pos);
   2175            NS_HTML5_CONTINUE(stateloop);
   2176          } else {
   2177            const nsHtml5CharacterName& candidateName =
   2178                nsHtml5NamedCharacters::NAMES[candidate];
   2179            if (!candidateName.length() ||
   2180                candidateName.charAt(candidateName.length() - 1) != ';') {
   2181              if ((returnState & DATA_AND_RCDATA_MASK)) {
   2182                char16_t ch;
   2183                if (charRefBufMark == charRefBufLen) {
   2184                  ch = c;
   2185                } else {
   2186                  ch = charRefBuf[charRefBufMark];
   2187                }
   2188                if (ch == '=' || (ch >= '0' && ch <= '9') ||
   2189                    (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
   2190                  if (c == ';') {
   2191                    if (P::reportErrors) {
   2192                      errNoNamedCharacterMatch();
   2193                    }
   2194                  }
   2195                  appendCharRefBufToStrBuf();
   2196                  reconsume = true;
   2197                  state = P::transition(mViewSource.get(), returnState,
   2198                                        reconsume, pos);
   2199                  NS_HTML5_CONTINUE(stateloop);
   2200                }
   2201              }
   2202              if ((returnState & DATA_AND_RCDATA_MASK)) {
   2203                if (P::reportErrors) {
   2204                  errUnescapedAmpersandInterpretedAsCharacterReference();
   2205                }
   2206              } else {
   2207                if (P::reportErrors) {
   2208                  errNotSemicolonTerminated();
   2209                }
   2210              }
   2211            }
   2212            P::completedNamedCharacterReference(mViewSource.get());
   2213            const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
   2214            if (!val[1]) {
   2215              emitOrAppendOne(val, returnState);
   2216            } else {
   2217              emitOrAppendTwo(val, returnState);
   2218            }
   2219            if (charRefBufMark < charRefBufLen) {
   2220              if ((returnState & DATA_AND_RCDATA_MASK)) {
   2221                appendStrBuf(charRefBuf, charRefBufMark,
   2222                             charRefBufLen - charRefBufMark);
   2223              } else {
   2224                tokenHandler->characters(charRefBuf, charRefBufMark,
   2225                                         charRefBufLen - charRefBufMark);
   2226              }
   2227            }
   2228            bool earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
   2229            charRefBufLen = 0;
   2230            if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2231              cstart = earlyBreak ? pos + 1 : pos;
   2232            }
   2233            reconsume = !earlyBreak;
   2234            state =
   2235                P::transition(mViewSource.get(), returnState, reconsume, pos);
   2236            NS_HTML5_CONTINUE(stateloop);
   2237          }
   2238        }
   2239        case CONSUME_NCR: {
   2240          if (++pos == endPos) {
   2241            NS_HTML5_BREAK(stateloop);
   2242          }
   2243          c = P::checkChar(this, buf, pos);
   2244          value = 0;
   2245          seenDigits = false;
   2246          switch (c) {
   2247            case 'x':
   2248            case 'X': {
   2249              appendCharRefBuf(c);
   2250              state =
   2251                  P::transition(mViewSource.get(),
   2252                                nsHtml5Tokenizer::HEX_NCR_LOOP, reconsume, pos);
   2253              NS_HTML5_CONTINUE(stateloop);
   2254            }
   2255            default: {
   2256              reconsume = true;
   2257              state = P::transition(mViewSource.get(),
   2258                                    nsHtml5Tokenizer::DECIMAL_NRC_LOOP,
   2259                                    reconsume, pos);
   2260              break;
   2261            }
   2262          }
   2263          [[fallthrough]];
   2264        }
   2265        case DECIMAL_NRC_LOOP: {
   2266          for (;;) {
   2267            if (reconsume) {
   2268              reconsume = false;
   2269            } else {
   2270              if (++pos == endPos) {
   2271                NS_HTML5_BREAK(stateloop);
   2272              }
   2273              c = P::checkChar(this, buf, pos);
   2274            }
   2275            MOZ_ASSERT(value >= 0, "value must not become negative.");
   2276            if (c >= '0' && c <= '9') {
   2277              seenDigits = true;
   2278              if (value <= 0x10FFFF) {
   2279                value *= 10;
   2280                value += c - '0';
   2281              }
   2282              continue;
   2283            } else if (c == ';') {
   2284              if (seenDigits) {
   2285                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2286                  cstart = pos + 1;
   2287                }
   2288                state = P::transition(mViewSource.get(),
   2289                                      nsHtml5Tokenizer::HANDLE_NCR_VALUE,
   2290                                      reconsume, pos);
   2291                NS_HTML5_BREAK(decimalloop);
   2292              } else {
   2293                if (P::reportErrors) {
   2294                  errNoDigitsInNCR();
   2295                }
   2296                appendCharRefBuf(';');
   2297                emitOrAppendCharRefBuf(returnState);
   2298                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2299                  cstart = pos + 1;
   2300                }
   2301                state = P::transition(mViewSource.get(), returnState, reconsume,
   2302                                      pos);
   2303                NS_HTML5_CONTINUE(stateloop);
   2304              }
   2305            } else {
   2306              if (!seenDigits) {
   2307                if (P::reportErrors) {
   2308                  errNoDigitsInNCR();
   2309                }
   2310                emitOrAppendCharRefBuf(returnState);
   2311                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2312                  cstart = pos;
   2313                }
   2314                reconsume = true;
   2315                state = P::transition(mViewSource.get(), returnState, reconsume,
   2316                                      pos);
   2317                NS_HTML5_CONTINUE(stateloop);
   2318              } else {
   2319                if (P::reportErrors) {
   2320                  errCharRefLacksSemicolon();
   2321                }
   2322                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2323                  cstart = pos;
   2324                }
   2325                reconsume = true;
   2326                state = P::transition(mViewSource.get(),
   2327                                      nsHtml5Tokenizer::HANDLE_NCR_VALUE,
   2328                                      reconsume, pos);
   2329                NS_HTML5_BREAK(decimalloop);
   2330              }
   2331            }
   2332          }
   2333        decimalloop_end:;
   2334          [[fallthrough]];
   2335        }
   2336        case HANDLE_NCR_VALUE: {
   2337          charRefBufLen = 0;
   2338          handleNcrValue(returnState);
   2339          state = P::transition(mViewSource.get(), returnState, reconsume, pos);
   2340          NS_HTML5_CONTINUE(stateloop);
   2341        }
   2342        case HEX_NCR_LOOP: {
   2343          for (;;) {
   2344            if (++pos == endPos) {
   2345              NS_HTML5_BREAK(stateloop);
   2346            }
   2347            c = P::checkChar(this, buf, pos);
   2348            MOZ_ASSERT(value >= 0, "value must not become negative.");
   2349            if (c >= '0' && c <= '9') {
   2350              seenDigits = true;
   2351              if (value <= 0x10FFFF) {
   2352                value *= 16;
   2353                value += c - '0';
   2354              }
   2355              continue;
   2356            } else if (c >= 'A' && c <= 'F') {
   2357              seenDigits = true;
   2358              if (value <= 0x10FFFF) {
   2359                value *= 16;
   2360                value += c - 'A' + 10;
   2361              }
   2362              continue;
   2363            } else if (c >= 'a' && c <= 'f') {
   2364              seenDigits = true;
   2365              if (value <= 0x10FFFF) {
   2366                value *= 16;
   2367                value += c - 'a' + 10;
   2368              }
   2369              continue;
   2370            } else if (c == ';') {
   2371              if (seenDigits) {
   2372                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2373                  cstart = pos + 1;
   2374                }
   2375                state = P::transition(mViewSource.get(),
   2376                                      nsHtml5Tokenizer::HANDLE_NCR_VALUE,
   2377                                      reconsume, pos);
   2378                NS_HTML5_CONTINUE(stateloop);
   2379              } else {
   2380                if (P::reportErrors) {
   2381                  errNoDigitsInNCR();
   2382                }
   2383                appendCharRefBuf(';');
   2384                emitOrAppendCharRefBuf(returnState);
   2385                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2386                  cstart = pos + 1;
   2387                }
   2388                state = P::transition(mViewSource.get(), returnState, reconsume,
   2389                                      pos);
   2390                NS_HTML5_CONTINUE(stateloop);
   2391              }
   2392            } else {
   2393              if (!seenDigits) {
   2394                if (P::reportErrors) {
   2395                  errNoDigitsInNCR();
   2396                }
   2397                emitOrAppendCharRefBuf(returnState);
   2398                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2399                  cstart = pos;
   2400                }
   2401                reconsume = true;
   2402                state = P::transition(mViewSource.get(), returnState, reconsume,
   2403                                      pos);
   2404                NS_HTML5_CONTINUE(stateloop);
   2405              } else {
   2406                if (P::reportErrors) {
   2407                  errCharRefLacksSemicolon();
   2408                }
   2409                if (!(returnState & DATA_AND_RCDATA_MASK)) {
   2410                  cstart = pos;
   2411                }
   2412                reconsume = true;
   2413                state = P::transition(mViewSource.get(),
   2414                                      nsHtml5Tokenizer::HANDLE_NCR_VALUE,
   2415                                      reconsume, pos);
   2416                NS_HTML5_CONTINUE(stateloop);
   2417              }
   2418            }
   2419          }
   2420        }
   2421        case PLAINTEXT: {
   2422          for (;;) {
   2423            if (reconsume) {
   2424              reconsume = false;
   2425            } else {
   2426              ++pos;
   2427              pos += P::accelerateAdvancementPlaintext(this, buf, pos, endPos);
   2428              if (pos == endPos) {
   2429                NS_HTML5_BREAK(stateloop);
   2430              }
   2431              c = P::checkChar(this, buf, pos);
   2432            }
   2433            switch (c) {
   2434              case '\0': {
   2435                emitPlaintextReplacementCharacter(buf, pos);
   2436                continue;
   2437              }
   2438              case '\r': {
   2439                emitCarriageReturn<P>(buf, pos);
   2440                NS_HTML5_BREAK(stateloop);
   2441              }
   2442              case '\n': {
   2443                P::silentLineFeed(this);
   2444                [[fallthrough]];
   2445              }
   2446              default: {
   2447                continue;
   2448              }
   2449            }
   2450          }
   2451        }
   2452        case CLOSE_TAG_OPEN: {
   2453          if (++pos == endPos) {
   2454            NS_HTML5_BREAK(stateloop);
   2455          }
   2456          c = P::checkChar(this, buf, pos);
   2457          switch (c) {
   2458            case '>': {
   2459              if (P::reportErrors) {
   2460                errLtSlashGt();
   2461              }
   2462              cstart = pos + 1;
   2463              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   2464                                    reconsume, pos);
   2465              NS_HTML5_CONTINUE(stateloop);
   2466            }
   2467            case '\r': {
   2468              P::silentCarriageReturn(this);
   2469              if (P::reportErrors) {
   2470                errGarbageAfterLtSlash();
   2471              }
   2472              clearStrBufBeforeUse();
   2473              appendStrBuf('\n');
   2474              state = P::transition(mViewSource.get(),
   2475                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
   2476                                    pos);
   2477              NS_HTML5_BREAK(stateloop);
   2478            }
   2479            case '\n': {
   2480              P::silentLineFeed(this);
   2481              if (P::reportErrors) {
   2482                errGarbageAfterLtSlash();
   2483              }
   2484              clearStrBufBeforeUse();
   2485              appendStrBuf(c);
   2486              state = P::transition(mViewSource.get(),
   2487                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
   2488                                    pos);
   2489              NS_HTML5_CONTINUE(stateloop);
   2490            }
   2491            case '\0': {
   2492              c = 0xfffd;
   2493              [[fallthrough]];
   2494            }
   2495            default: {
   2496              if (c >= 'A' && c <= 'Z') {
   2497                c += 0x20;
   2498              }
   2499              if (c >= 'a' && c <= 'z') {
   2500                endTag = true;
   2501                clearStrBufBeforeUse();
   2502                appendStrBuf(c);
   2503                containsHyphen = false;
   2504                state =
   2505                    P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
   2506                                  reconsume, pos);
   2507                NS_HTML5_CONTINUE(stateloop);
   2508              } else {
   2509                if (P::reportErrors) {
   2510                  errGarbageAfterLtSlash();
   2511                }
   2512                clearStrBufBeforeUse();
   2513                appendStrBuf(c);
   2514                state = P::transition(mViewSource.get(),
   2515                                      nsHtml5Tokenizer::BOGUS_COMMENT,
   2516                                      reconsume, pos);
   2517                NS_HTML5_CONTINUE(stateloop);
   2518              }
   2519            }
   2520          }
   2521        }
   2522        case RCDATA: {
   2523          for (;;) {
   2524            if (reconsume) {
   2525              reconsume = false;
   2526            } else {
   2527              ++pos;
   2528              pos += P::accelerateAdvancementData(this, buf, pos, endPos);
   2529              if (pos == endPos) {
   2530                NS_HTML5_BREAK(stateloop);
   2531              }
   2532              c = P::checkChar(this, buf, pos);
   2533            }
   2534            switch (c) {
   2535              case '&': {
   2536                flushChars(buf, pos);
   2537                MOZ_ASSERT(!charRefBufLen,
   2538                           "charRefBufLen not reset after previous use!");
   2539                appendCharRefBuf(c);
   2540                setAdditionalAndRememberAmpersandLocation('\0');
   2541                returnState = state;
   2542                state =
   2543                    P::transition(mViewSource.get(),
   2544                                  nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
   2545                                  reconsume, pos);
   2546                NS_HTML5_CONTINUE(stateloop);
   2547              }
   2548              case '<': {
   2549                flushChars(buf, pos);
   2550                returnState = state;
   2551                state = P::transition(
   2552                    mViewSource.get(),
   2553                    nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume,
   2554                    pos);
   2555                NS_HTML5_CONTINUE(stateloop);
   2556              }
   2557              case '\0': {
   2558                emitReplacementCharacter(buf, pos);
   2559                continue;
   2560              }
   2561              case '\r': {
   2562                emitCarriageReturn<P>(buf, pos);
   2563                NS_HTML5_BREAK(stateloop);
   2564              }
   2565              case '\n': {
   2566                P::silentLineFeed(this);
   2567                [[fallthrough]];
   2568              }
   2569              default: {
   2570                continue;
   2571              }
   2572            }
   2573          }
   2574        }
   2575        case RAWTEXT: {
   2576          for (;;) {
   2577            if (reconsume) {
   2578              reconsume = false;
   2579            } else {
   2580              ++pos;
   2581              pos += P::accelerateAdvancementRawtext(this, buf, pos, endPos);
   2582              if (pos == endPos) {
   2583                NS_HTML5_BREAK(stateloop);
   2584              }
   2585              c = P::checkChar(this, buf, pos);
   2586            }
   2587            switch (c) {
   2588              case '<': {
   2589                flushChars(buf, pos);
   2590                returnState = state;
   2591                state = P::transition(
   2592                    mViewSource.get(),
   2593                    nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN, reconsume,
   2594                    pos);
   2595                NS_HTML5_BREAK(rawtextloop);
   2596              }
   2597              case '\0': {
   2598                emitReplacementCharacter(buf, pos);
   2599                continue;
   2600              }
   2601              case '\r': {
   2602                emitCarriageReturn<P>(buf, pos);
   2603                NS_HTML5_BREAK(stateloop);
   2604              }
   2605              case '\n': {
   2606                P::silentLineFeed(this);
   2607                [[fallthrough]];
   2608              }
   2609              default: {
   2610                continue;
   2611              }
   2612            }
   2613          }
   2614        rawtextloop_end:;
   2615          [[fallthrough]];
   2616        }
   2617        case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
   2618          for (;;) {
   2619            if (++pos == endPos) {
   2620              NS_HTML5_BREAK(stateloop);
   2621            }
   2622            c = P::checkChar(this, buf, pos);
   2623            switch (c) {
   2624              case '/': {
   2625                index = 0;
   2626                clearStrBufBeforeUse();
   2627                state = P::transition(mViewSource.get(),
   2628                                      nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
   2629                                      reconsume, pos);
   2630                NS_HTML5_BREAK(rawtextrcdatalessthansignloop);
   2631              }
   2632              default: {
   2633                tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
   2634                cstart = pos;
   2635                reconsume = true;
   2636                state = P::transition(mViewSource.get(), returnState, reconsume,
   2637                                      pos);
   2638                NS_HTML5_CONTINUE(stateloop);
   2639              }
   2640            }
   2641          }
   2642        rawtextrcdatalessthansignloop_end:;
   2643          [[fallthrough]];
   2644        }
   2645        case NON_DATA_END_TAG_NAME: {
   2646          for (;;) {
   2647            if (++pos == endPos) {
   2648              NS_HTML5_BREAK(stateloop);
   2649            }
   2650            c = P::checkChar(this, buf, pos);
   2651            if (!endTagExpectationAsArray) {
   2652              tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
   2653              cstart = pos;
   2654              reconsume = true;
   2655              state =
   2656                  P::transition(mViewSource.get(), returnState, reconsume, pos);
   2657              NS_HTML5_CONTINUE(stateloop);
   2658            } else if (index < endTagExpectationAsArray.length) {
   2659              char16_t e = endTagExpectationAsArray[index];
   2660              char16_t folded = c;
   2661              if (c >= 'A' && c <= 'Z') {
   2662                folded += 0x20;
   2663              }
   2664              if (folded != e) {
   2665                tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
   2666                emitStrBuf();
   2667                cstart = pos;
   2668                reconsume = true;
   2669                state = P::transition(mViewSource.get(), returnState, reconsume,
   2670                                      pos);
   2671                NS_HTML5_CONTINUE(stateloop);
   2672              }
   2673              appendStrBuf(c);
   2674              index++;
   2675              continue;
   2676            } else {
   2677              endTag = true;
   2678              tagName = endTagExpectation;
   2679              switch (c) {
   2680                case '\r': {
   2681                  P::silentCarriageReturn(this);
   2682                  clearStrBufAfterUse();
   2683                  state = P::transition(mViewSource.get(),
   2684                                        nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
   2685                                        reconsume, pos);
   2686                  NS_HTML5_BREAK(stateloop);
   2687                }
   2688                case '\n': {
   2689                  P::silentLineFeed(this);
   2690                  [[fallthrough]];
   2691                }
   2692                case ' ':
   2693                case '\t':
   2694                case '\f': {
   2695                  clearStrBufAfterUse();
   2696                  state = P::transition(mViewSource.get(),
   2697                                        nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
   2698                                        reconsume, pos);
   2699                  NS_HTML5_CONTINUE(stateloop);
   2700                }
   2701                case '/': {
   2702                  clearStrBufAfterUse();
   2703                  state = P::transition(
   2704                      mViewSource.get(),
   2705                      nsHtml5Tokenizer::SELF_CLOSING_START_TAG, reconsume, pos);
   2706                  NS_HTML5_CONTINUE(stateloop);
   2707                }
   2708                case '>': {
   2709                  clearStrBufAfterUse();
   2710                  state = P::transition(mViewSource.get(),
   2711                                        emitCurrentTagToken(false, pos),
   2712                                        reconsume, pos);
   2713                  if (shouldSuspend) {
   2714                    NS_HTML5_BREAK(stateloop);
   2715                  }
   2716                  NS_HTML5_CONTINUE(stateloop);
   2717                }
   2718                default: {
   2719                  tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
   2720                  emitStrBuf();
   2721                  cstart = pos;
   2722                  reconsume = true;
   2723                  state = P::transition(mViewSource.get(), returnState,
   2724                                        reconsume, pos);
   2725                  NS_HTML5_CONTINUE(stateloop);
   2726                }
   2727              }
   2728            }
   2729          }
   2730        }
   2731        case BOGUS_COMMENT: {
   2732          for (;;) {
   2733            if (reconsume) {
   2734              reconsume = false;
   2735            } else {
   2736              if (++pos == endPos) {
   2737                NS_HTML5_BREAK(stateloop);
   2738              }
   2739              c = P::checkChar(this, buf, pos);
   2740            }
   2741            switch (c) {
   2742              case '>': {
   2743                emitComment(0, pos);
   2744                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   2745                                      reconsume, pos);
   2746                if (shouldSuspend) {
   2747                  NS_HTML5_BREAK(stateloop);
   2748                }
   2749                NS_HTML5_CONTINUE(stateloop);
   2750              }
   2751              case '-': {
   2752                appendStrBuf(c);
   2753                state = P::transition(mViewSource.get(),
   2754                                      nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN,
   2755                                      reconsume, pos);
   2756                NS_HTML5_BREAK(boguscommentloop);
   2757              }
   2758              case '\r': {
   2759                appendStrBufCarriageReturn<P>();
   2760                NS_HTML5_BREAK(stateloop);
   2761              }
   2762              case '\n': {
   2763                appendStrBufLineFeed<P>();
   2764                continue;
   2765              }
   2766              case '\0': {
   2767                c = 0xfffd;
   2768                [[fallthrough]];
   2769              }
   2770              default: {
   2771                appendStrBuf(c);
   2772                continue;
   2773              }
   2774            }
   2775          }
   2776        boguscommentloop_end:;
   2777          [[fallthrough]];
   2778        }
   2779        case BOGUS_COMMENT_HYPHEN: {
   2780        boguscommenthyphenloop:
   2781          for (;;) {
   2782            if (++pos == endPos) {
   2783              NS_HTML5_BREAK(stateloop);
   2784            }
   2785            c = P::checkChar(this, buf, pos);
   2786            switch (c) {
   2787              case '>': {
   2788                emitComment(0, pos);
   2789                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   2790                                      reconsume, pos);
   2791                if (shouldSuspend) {
   2792                  NS_HTML5_BREAK(stateloop);
   2793                }
   2794                NS_HTML5_CONTINUE(stateloop);
   2795              }
   2796              case '-': {
   2797                appendSecondHyphenToBogusComment();
   2798                NS_HTML5_CONTINUE(boguscommenthyphenloop);
   2799              }
   2800              case '\r': {
   2801                appendStrBufCarriageReturn<P>();
   2802                state = P::transition(mViewSource.get(),
   2803                                      nsHtml5Tokenizer::BOGUS_COMMENT,
   2804                                      reconsume, pos);
   2805                NS_HTML5_BREAK(stateloop);
   2806              }
   2807              case '\n': {
   2808                appendStrBufLineFeed<P>();
   2809                state = P::transition(mViewSource.get(),
   2810                                      nsHtml5Tokenizer::BOGUS_COMMENT,
   2811                                      reconsume, pos);
   2812                NS_HTML5_CONTINUE(stateloop);
   2813              }
   2814              case '\0': {
   2815                c = 0xfffd;
   2816                [[fallthrough]];
   2817              }
   2818              default: {
   2819                appendStrBuf(c);
   2820                state = P::transition(mViewSource.get(),
   2821                                      nsHtml5Tokenizer::BOGUS_COMMENT,
   2822                                      reconsume, pos);
   2823                NS_HTML5_CONTINUE(stateloop);
   2824              }
   2825            }
   2826          }
   2827        }
   2828        case SCRIPT_DATA: {
   2829          for (;;) {
   2830            if (reconsume) {
   2831              reconsume = false;
   2832            } else {
   2833              ++pos;
   2834              pos += P::accelerateAdvancementRawtext(this, buf, pos, endPos);
   2835              if (pos == endPos) {
   2836                NS_HTML5_BREAK(stateloop);
   2837              }
   2838              c = P::checkChar(this, buf, pos);
   2839            }
   2840            switch (c) {
   2841              case '<': {
   2842                flushChars(buf, pos);
   2843                returnState = state;
   2844                state =
   2845                    P::transition(mViewSource.get(),
   2846                                  nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN,
   2847                                  reconsume, pos);
   2848                NS_HTML5_BREAK(scriptdataloop);
   2849              }
   2850              case '\0': {
   2851                emitReplacementCharacter(buf, pos);
   2852                continue;
   2853              }
   2854              case '\r': {
   2855                emitCarriageReturn<P>(buf, pos);
   2856                NS_HTML5_BREAK(stateloop);
   2857              }
   2858              case '\n': {
   2859                P::silentLineFeed(this);
   2860                [[fallthrough]];
   2861              }
   2862              default: {
   2863                continue;
   2864              }
   2865            }
   2866          }
   2867        scriptdataloop_end:;
   2868          [[fallthrough]];
   2869        }
   2870        case SCRIPT_DATA_LESS_THAN_SIGN: {
   2871          for (;;) {
   2872            if (++pos == endPos) {
   2873              NS_HTML5_BREAK(stateloop);
   2874            }
   2875            c = P::checkChar(this, buf, pos);
   2876            switch (c) {
   2877              case '/': {
   2878                index = 0;
   2879                clearStrBufBeforeUse();
   2880                state = P::transition(mViewSource.get(),
   2881                                      nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
   2882                                      reconsume, pos);
   2883                NS_HTML5_CONTINUE(stateloop);
   2884              }
   2885              case '!': {
   2886                tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
   2887                cstart = pos;
   2888                state = P::transition(
   2889                    mViewSource.get(),
   2890                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START, reconsume, pos);
   2891                NS_HTML5_BREAK(scriptdatalessthansignloop);
   2892              }
   2893              default: {
   2894                tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
   2895                cstart = pos;
   2896                reconsume = true;
   2897                state = P::transition(mViewSource.get(),
   2898                                      nsHtml5Tokenizer::SCRIPT_DATA, reconsume,
   2899                                      pos);
   2900                NS_HTML5_CONTINUE(stateloop);
   2901              }
   2902            }
   2903          }
   2904        scriptdatalessthansignloop_end:;
   2905          [[fallthrough]];
   2906        }
   2907        case SCRIPT_DATA_ESCAPE_START: {
   2908          for (;;) {
   2909            if (++pos == endPos) {
   2910              NS_HTML5_BREAK(stateloop);
   2911            }
   2912            c = P::checkChar(this, buf, pos);
   2913            switch (c) {
   2914              case '-': {
   2915                state = P::transition(
   2916                    mViewSource.get(),
   2917                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START_DASH, reconsume,
   2918                    pos);
   2919                NS_HTML5_BREAK(scriptdataescapestartloop);
   2920              }
   2921              default: {
   2922                reconsume = true;
   2923                state = P::transition(mViewSource.get(),
   2924                                      nsHtml5Tokenizer::SCRIPT_DATA, reconsume,
   2925                                      pos);
   2926                NS_HTML5_CONTINUE(stateloop);
   2927              }
   2928            }
   2929          }
   2930        scriptdataescapestartloop_end:;
   2931          [[fallthrough]];
   2932        }
   2933        case SCRIPT_DATA_ESCAPE_START_DASH: {
   2934          for (;;) {
   2935            if (++pos == endPos) {
   2936              NS_HTML5_BREAK(stateloop);
   2937            }
   2938            c = P::checkChar(this, buf, pos);
   2939            switch (c) {
   2940              case '-': {
   2941                state = P::transition(
   2942                    mViewSource.get(),
   2943                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume,
   2944                    pos);
   2945                NS_HTML5_BREAK(scriptdataescapestartdashloop);
   2946              }
   2947              default: {
   2948                reconsume = true;
   2949                state = P::transition(mViewSource.get(),
   2950                                      nsHtml5Tokenizer::SCRIPT_DATA, reconsume,
   2951                                      pos);
   2952                NS_HTML5_CONTINUE(stateloop);
   2953              }
   2954            }
   2955          }
   2956        scriptdataescapestartdashloop_end:;
   2957          [[fallthrough]];
   2958        }
   2959        case SCRIPT_DATA_ESCAPED_DASH_DASH: {
   2960          for (;;) {
   2961            if (++pos == endPos) {
   2962              NS_HTML5_BREAK(stateloop);
   2963            }
   2964            c = P::checkChar(this, buf, pos);
   2965            switch (c) {
   2966              case '-': {
   2967                continue;
   2968              }
   2969              case '<': {
   2970                flushChars(buf, pos);
   2971                state = P::transition(
   2972                    mViewSource.get(),
   2973                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
   2974                    reconsume, pos);
   2975                NS_HTML5_CONTINUE(stateloop);
   2976              }
   2977              case '>': {
   2978                state = P::transition(mViewSource.get(),
   2979                                      nsHtml5Tokenizer::SCRIPT_DATA, reconsume,
   2980                                      pos);
   2981                NS_HTML5_CONTINUE(stateloop);
   2982              }
   2983              case '\0': {
   2984                emitReplacementCharacter(buf, pos);
   2985                state = P::transition(mViewSource.get(),
   2986                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   2987                                      reconsume, pos);
   2988                NS_HTML5_BREAK(scriptdataescapeddashdashloop);
   2989              }
   2990              case '\r': {
   2991                emitCarriageReturn<P>(buf, pos);
   2992                state = P::transition(mViewSource.get(),
   2993                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   2994                                      reconsume, pos);
   2995                NS_HTML5_BREAK(stateloop);
   2996              }
   2997              case '\n': {
   2998                P::silentLineFeed(this);
   2999                [[fallthrough]];
   3000              }
   3001              default: {
   3002                state = P::transition(mViewSource.get(),
   3003                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3004                                      reconsume, pos);
   3005                NS_HTML5_BREAK(scriptdataescapeddashdashloop);
   3006              }
   3007            }
   3008          }
   3009        scriptdataescapeddashdashloop_end:;
   3010          [[fallthrough]];
   3011        }
   3012        case SCRIPT_DATA_ESCAPED: {
   3013          for (;;) {
   3014            if (reconsume) {
   3015              reconsume = false;
   3016            } else {
   3017              ++pos;
   3018              pos += P::accelerateAdvancementScriptDataEscaped(this, buf, pos,
   3019                                                               endPos);
   3020              if (pos == endPos) {
   3021                NS_HTML5_BREAK(stateloop);
   3022              }
   3023              c = P::checkChar(this, buf, pos);
   3024            }
   3025            switch (c) {
   3026              case '-': {
   3027                state = P::transition(
   3028                    mViewSource.get(),
   3029                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH, reconsume, pos);
   3030                NS_HTML5_BREAK(scriptdataescapedloop);
   3031              }
   3032              case '<': {
   3033                flushChars(buf, pos);
   3034                state = P::transition(
   3035                    mViewSource.get(),
   3036                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
   3037                    reconsume, pos);
   3038                NS_HTML5_CONTINUE(stateloop);
   3039              }
   3040              case '\0': {
   3041                emitReplacementCharacter(buf, pos);
   3042                continue;
   3043              }
   3044              case '\r': {
   3045                emitCarriageReturn<P>(buf, pos);
   3046                NS_HTML5_BREAK(stateloop);
   3047              }
   3048              case '\n': {
   3049                P::silentLineFeed(this);
   3050                [[fallthrough]];
   3051              }
   3052              default: {
   3053                continue;
   3054              }
   3055            }
   3056          }
   3057        scriptdataescapedloop_end:;
   3058          [[fallthrough]];
   3059        }
   3060        case SCRIPT_DATA_ESCAPED_DASH: {
   3061          for (;;) {
   3062            if (++pos == endPos) {
   3063              NS_HTML5_BREAK(stateloop);
   3064            }
   3065            c = P::checkChar(this, buf, pos);
   3066            switch (c) {
   3067              case '-': {
   3068                state = P::transition(
   3069                    mViewSource.get(),
   3070                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH, reconsume,
   3071                    pos);
   3072                NS_HTML5_CONTINUE(stateloop);
   3073              }
   3074              case '<': {
   3075                flushChars(buf, pos);
   3076                state = P::transition(
   3077                    mViewSource.get(),
   3078                    nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
   3079                    reconsume, pos);
   3080                NS_HTML5_BREAK(scriptdataescapeddashloop);
   3081              }
   3082              case '\0': {
   3083                emitReplacementCharacter(buf, pos);
   3084                state = P::transition(mViewSource.get(),
   3085                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3086                                      reconsume, pos);
   3087                NS_HTML5_CONTINUE(stateloop);
   3088              }
   3089              case '\r': {
   3090                emitCarriageReturn<P>(buf, pos);
   3091                state = P::transition(mViewSource.get(),
   3092                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3093                                      reconsume, pos);
   3094                NS_HTML5_BREAK(stateloop);
   3095              }
   3096              case '\n': {
   3097                P::silentLineFeed(this);
   3098                [[fallthrough]];
   3099              }
   3100              default: {
   3101                state = P::transition(mViewSource.get(),
   3102                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3103                                      reconsume, pos);
   3104                NS_HTML5_CONTINUE(stateloop);
   3105              }
   3106            }
   3107          }
   3108        scriptdataescapeddashloop_end:;
   3109          [[fallthrough]];
   3110        }
   3111        case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
   3112          for (;;) {
   3113            if (++pos == endPos) {
   3114              NS_HTML5_BREAK(stateloop);
   3115            }
   3116            c = P::checkChar(this, buf, pos);
   3117            switch (c) {
   3118              case '/': {
   3119                index = 0;
   3120                clearStrBufBeforeUse();
   3121                returnState = nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED;
   3122                state = P::transition(mViewSource.get(),
   3123                                      nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
   3124                                      reconsume, pos);
   3125                NS_HTML5_CONTINUE(stateloop);
   3126              }
   3127              case 'S':
   3128              case 's': {
   3129                tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
   3130                cstart = pos;
   3131                index = 1;
   3132                state = P::transition(
   3133                    mViewSource.get(),
   3134                    nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_START,
   3135                    reconsume, pos);
   3136                NS_HTML5_BREAK(scriptdataescapedlessthanloop);
   3137              }
   3138              default: {
   3139                tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
   3140                cstart = pos;
   3141                reconsume = true;
   3142                state = P::transition(mViewSource.get(),
   3143                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3144                                      reconsume, pos);
   3145                NS_HTML5_CONTINUE(stateloop);
   3146              }
   3147            }
   3148          }
   3149        scriptdataescapedlessthanloop_end:;
   3150          [[fallthrough]];
   3151        }
   3152        case SCRIPT_DATA_DOUBLE_ESCAPE_START: {
   3153          for (;;) {
   3154            if (++pos == endPos) {
   3155              NS_HTML5_BREAK(stateloop);
   3156            }
   3157            c = P::checkChar(this, buf, pos);
   3158            MOZ_ASSERT(index > 0);
   3159            if (index < 6) {
   3160              char16_t folded = c;
   3161              if (c >= 'A' && c <= 'Z') {
   3162                folded += 0x20;
   3163              }
   3164              if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
   3165                reconsume = true;
   3166                state = P::transition(mViewSource.get(),
   3167                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3168                                      reconsume, pos);
   3169                NS_HTML5_CONTINUE(stateloop);
   3170              }
   3171              index++;
   3172              continue;
   3173            }
   3174            switch (c) {
   3175              case '\r': {
   3176                emitCarriageReturn<P>(buf, pos);
   3177                state =
   3178                    P::transition(mViewSource.get(),
   3179                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3180                                  reconsume, pos);
   3181                NS_HTML5_BREAK(stateloop);
   3182              }
   3183              case '\n': {
   3184                P::silentLineFeed(this);
   3185                [[fallthrough]];
   3186              }
   3187              case ' ':
   3188              case '\t':
   3189              case '\f':
   3190              case '/':
   3191              case '>': {
   3192                state =
   3193                    P::transition(mViewSource.get(),
   3194                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3195                                  reconsume, pos);
   3196                NS_HTML5_BREAK(scriptdatadoubleescapestartloop);
   3197              }
   3198              default: {
   3199                reconsume = true;
   3200                state = P::transition(mViewSource.get(),
   3201                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3202                                      reconsume, pos);
   3203                NS_HTML5_CONTINUE(stateloop);
   3204              }
   3205            }
   3206          }
   3207        scriptdatadoubleescapestartloop_end:;
   3208          [[fallthrough]];
   3209        }
   3210        case SCRIPT_DATA_DOUBLE_ESCAPED: {
   3211          for (;;) {
   3212            if (reconsume) {
   3213              reconsume = false;
   3214            } else {
   3215              if (++pos == endPos) {
   3216                NS_HTML5_BREAK(stateloop);
   3217              }
   3218              c = P::checkChar(this, buf, pos);
   3219            }
   3220            switch (c) {
   3221              case '-': {
   3222                state = P::transition(
   3223                    mViewSource.get(),
   3224                    nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH,
   3225                    reconsume, pos);
   3226                NS_HTML5_BREAK(scriptdatadoubleescapedloop);
   3227              }
   3228              case '<': {
   3229                state = P::transition(
   3230                    mViewSource.get(),
   3231                    nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
   3232                    reconsume, pos);
   3233                NS_HTML5_CONTINUE(stateloop);
   3234              }
   3235              case '\0': {
   3236                emitReplacementCharacter(buf, pos);
   3237                continue;
   3238              }
   3239              case '\r': {
   3240                emitCarriageReturn<P>(buf, pos);
   3241                NS_HTML5_BREAK(stateloop);
   3242              }
   3243              case '\n': {
   3244                P::silentLineFeed(this);
   3245                [[fallthrough]];
   3246              }
   3247              default: {
   3248                continue;
   3249              }
   3250            }
   3251          }
   3252        scriptdatadoubleescapedloop_end:;
   3253          [[fallthrough]];
   3254        }
   3255        case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
   3256          for (;;) {
   3257            if (++pos == endPos) {
   3258              NS_HTML5_BREAK(stateloop);
   3259            }
   3260            c = P::checkChar(this, buf, pos);
   3261            switch (c) {
   3262              case '-': {
   3263                state = P::transition(
   3264                    mViewSource.get(),
   3265                    nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH,
   3266                    reconsume, pos);
   3267                NS_HTML5_BREAK(scriptdatadoubleescapeddashloop);
   3268              }
   3269              case '<': {
   3270                state = P::transition(
   3271                    mViewSource.get(),
   3272                    nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
   3273                    reconsume, pos);
   3274                NS_HTML5_CONTINUE(stateloop);
   3275              }
   3276              case '\0': {
   3277                emitReplacementCharacter(buf, pos);
   3278                state =
   3279                    P::transition(mViewSource.get(),
   3280                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3281                                  reconsume, pos);
   3282                NS_HTML5_CONTINUE(stateloop);
   3283              }
   3284              case '\r': {
   3285                emitCarriageReturn<P>(buf, pos);
   3286                state =
   3287                    P::transition(mViewSource.get(),
   3288                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3289                                  reconsume, pos);
   3290                NS_HTML5_BREAK(stateloop);
   3291              }
   3292              case '\n': {
   3293                P::silentLineFeed(this);
   3294                [[fallthrough]];
   3295              }
   3296              default: {
   3297                state =
   3298                    P::transition(mViewSource.get(),
   3299                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3300                                  reconsume, pos);
   3301                NS_HTML5_CONTINUE(stateloop);
   3302              }
   3303            }
   3304          }
   3305        scriptdatadoubleescapeddashloop_end:;
   3306          [[fallthrough]];
   3307        }
   3308        case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
   3309          for (;;) {
   3310            if (++pos == endPos) {
   3311              NS_HTML5_BREAK(stateloop);
   3312            }
   3313            c = P::checkChar(this, buf, pos);
   3314            switch (c) {
   3315              case '-': {
   3316                continue;
   3317              }
   3318              case '<': {
   3319                state = P::transition(
   3320                    mViewSource.get(),
   3321                    nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
   3322                    reconsume, pos);
   3323                NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop);
   3324              }
   3325              case '>': {
   3326                state = P::transition(mViewSource.get(),
   3327                                      nsHtml5Tokenizer::SCRIPT_DATA, reconsume,
   3328                                      pos);
   3329                NS_HTML5_CONTINUE(stateloop);
   3330              }
   3331              case '\0': {
   3332                emitReplacementCharacter(buf, pos);
   3333                state =
   3334                    P::transition(mViewSource.get(),
   3335                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3336                                  reconsume, pos);
   3337                NS_HTML5_CONTINUE(stateloop);
   3338              }
   3339              case '\r': {
   3340                emitCarriageReturn<P>(buf, pos);
   3341                state =
   3342                    P::transition(mViewSource.get(),
   3343                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3344                                  reconsume, pos);
   3345                NS_HTML5_BREAK(stateloop);
   3346              }
   3347              case '\n': {
   3348                P::silentLineFeed(this);
   3349                [[fallthrough]];
   3350              }
   3351              default: {
   3352                state =
   3353                    P::transition(mViewSource.get(),
   3354                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3355                                  reconsume, pos);
   3356                NS_HTML5_CONTINUE(stateloop);
   3357              }
   3358            }
   3359          }
   3360        scriptdatadoubleescapeddashdashloop_end:;
   3361          [[fallthrough]];
   3362        }
   3363        case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
   3364          for (;;) {
   3365            if (++pos == endPos) {
   3366              NS_HTML5_BREAK(stateloop);
   3367            }
   3368            c = P::checkChar(this, buf, pos);
   3369            switch (c) {
   3370              case '/': {
   3371                index = 0;
   3372                state = P::transition(
   3373                    mViewSource.get(),
   3374                    nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_END, reconsume,
   3375                    pos);
   3376                NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop);
   3377              }
   3378              default: {
   3379                reconsume = true;
   3380                state =
   3381                    P::transition(mViewSource.get(),
   3382                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3383                                  reconsume, pos);
   3384                NS_HTML5_CONTINUE(stateloop);
   3385              }
   3386            }
   3387          }
   3388        scriptdatadoubleescapedlessthanloop_end:;
   3389          [[fallthrough]];
   3390        }
   3391        case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
   3392          for (;;) {
   3393            if (++pos == endPos) {
   3394              NS_HTML5_BREAK(stateloop);
   3395            }
   3396            c = P::checkChar(this, buf, pos);
   3397            if (index < 6) {
   3398              char16_t folded = c;
   3399              if (c >= 'A' && c <= 'Z') {
   3400                folded += 0x20;
   3401              }
   3402              if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
   3403                reconsume = true;
   3404                state =
   3405                    P::transition(mViewSource.get(),
   3406                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3407                                  reconsume, pos);
   3408                NS_HTML5_CONTINUE(stateloop);
   3409              }
   3410              index++;
   3411              continue;
   3412            }
   3413            switch (c) {
   3414              case '\r': {
   3415                emitCarriageReturn<P>(buf, pos);
   3416                state = P::transition(mViewSource.get(),
   3417                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3418                                      reconsume, pos);
   3419                NS_HTML5_BREAK(stateloop);
   3420              }
   3421              case '\n': {
   3422                P::silentLineFeed(this);
   3423                [[fallthrough]];
   3424              }
   3425              case ' ':
   3426              case '\t':
   3427              case '\f':
   3428              case '/':
   3429              case '>': {
   3430                state = P::transition(mViewSource.get(),
   3431                                      nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
   3432                                      reconsume, pos);
   3433                NS_HTML5_CONTINUE(stateloop);
   3434              }
   3435              default: {
   3436                reconsume = true;
   3437                state =
   3438                    P::transition(mViewSource.get(),
   3439                                  nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED,
   3440                                  reconsume, pos);
   3441                NS_HTML5_CONTINUE(stateloop);
   3442              }
   3443            }
   3444          }
   3445        }
   3446        case MARKUP_DECLARATION_OCTYPE: {
   3447          for (;;) {
   3448            if (++pos == endPos) {
   3449              NS_HTML5_BREAK(stateloop);
   3450            }
   3451            c = P::checkChar(this, buf, pos);
   3452            if (index < 6) {
   3453              char16_t folded = c;
   3454              if (c >= 'A' && c <= 'Z') {
   3455                folded += 0x20;
   3456              }
   3457              if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
   3458                appendStrBuf(c);
   3459              } else {
   3460                if (P::reportErrors) {
   3461                  errBogusComment();
   3462                }
   3463                reconsume = true;
   3464                state = P::transition(mViewSource.get(),
   3465                                      nsHtml5Tokenizer::BOGUS_COMMENT,
   3466                                      reconsume, pos);
   3467                NS_HTML5_CONTINUE(stateloop);
   3468              }
   3469              index++;
   3470              continue;
   3471            } else {
   3472              reconsume = true;
   3473              state = P::transition(mViewSource.get(),
   3474                                    nsHtml5Tokenizer::DOCTYPE, reconsume, pos);
   3475              NS_HTML5_BREAK(markupdeclarationdoctypeloop);
   3476            }
   3477          }
   3478        markupdeclarationdoctypeloop_end:;
   3479          [[fallthrough]];
   3480        }
   3481        case DOCTYPE: {
   3482          for (;;) {
   3483            if (reconsume) {
   3484              reconsume = false;
   3485            } else {
   3486              if (++pos == endPos) {
   3487                NS_HTML5_BREAK(stateloop);
   3488              }
   3489              c = P::checkChar(this, buf, pos);
   3490            }
   3491            initDoctypeFields();
   3492            switch (c) {
   3493              case '\r': {
   3494                P::silentCarriageReturn(this);
   3495                state = P::transition(mViewSource.get(),
   3496                                      nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
   3497                                      reconsume, pos);
   3498                NS_HTML5_BREAK(stateloop);
   3499              }
   3500              case '\n': {
   3501                P::silentLineFeed(this);
   3502                [[fallthrough]];
   3503              }
   3504              case ' ':
   3505              case '\t':
   3506              case '\f': {
   3507                state = P::transition(mViewSource.get(),
   3508                                      nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
   3509                                      reconsume, pos);
   3510                NS_HTML5_BREAK(doctypeloop);
   3511              }
   3512              default: {
   3513                if (P::reportErrors) {
   3514                  errMissingSpaceBeforeDoctypeName();
   3515                }
   3516                reconsume = true;
   3517                state = P::transition(mViewSource.get(),
   3518                                      nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
   3519                                      reconsume, pos);
   3520                NS_HTML5_BREAK(doctypeloop);
   3521              }
   3522            }
   3523          }
   3524        doctypeloop_end:;
   3525          [[fallthrough]];
   3526        }
   3527        case BEFORE_DOCTYPE_NAME: {
   3528          for (;;) {
   3529            if (reconsume) {
   3530              reconsume = false;
   3531            } else {
   3532              if (++pos == endPos) {
   3533                NS_HTML5_BREAK(stateloop);
   3534              }
   3535              c = P::checkChar(this, buf, pos);
   3536            }
   3537            switch (c) {
   3538              case '\r': {
   3539                P::silentCarriageReturn(this);
   3540                NS_HTML5_BREAK(stateloop);
   3541              }
   3542              case '\n': {
   3543                P::silentLineFeed(this);
   3544                [[fallthrough]];
   3545              }
   3546              case ' ':
   3547              case '\t':
   3548              case '\f': {
   3549                continue;
   3550              }
   3551              case '>': {
   3552                if (P::reportErrors) {
   3553                  errNamelessDoctype();
   3554                }
   3555                forceQuirks = true;
   3556                emitDoctypeToken(pos);
   3557                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   3558                                      reconsume, pos);
   3559                if (shouldSuspend) {
   3560                  NS_HTML5_BREAK(stateloop);
   3561                }
   3562                NS_HTML5_CONTINUE(stateloop);
   3563              }
   3564              case '\0': {
   3565                c = 0xfffd;
   3566                [[fallthrough]];
   3567              }
   3568              default: {
   3569                if (c >= 'A' && c <= 'Z') {
   3570                  c += 0x20;
   3571                }
   3572                clearStrBufBeforeUse();
   3573                appendStrBuf(c);
   3574                state = P::transition(mViewSource.get(),
   3575                                      nsHtml5Tokenizer::DOCTYPE_NAME, reconsume,
   3576                                      pos);
   3577                NS_HTML5_BREAK(beforedoctypenameloop);
   3578              }
   3579            }
   3580          }
   3581        beforedoctypenameloop_end:;
   3582          [[fallthrough]];
   3583        }
   3584        case DOCTYPE_NAME: {
   3585          for (;;) {
   3586            if (++pos == endPos) {
   3587              NS_HTML5_BREAK(stateloop);
   3588            }
   3589            c = P::checkChar(this, buf, pos);
   3590            switch (c) {
   3591              case '\r': {
   3592                P::silentCarriageReturn(this);
   3593                strBufToDoctypeName();
   3594                state = P::transition(mViewSource.get(),
   3595                                      nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
   3596                                      reconsume, pos);
   3597                NS_HTML5_BREAK(stateloop);
   3598              }
   3599              case '\n': {
   3600                P::silentLineFeed(this);
   3601                [[fallthrough]];
   3602              }
   3603              case ' ':
   3604              case '\t':
   3605              case '\f': {
   3606                strBufToDoctypeName();
   3607                state = P::transition(mViewSource.get(),
   3608                                      nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
   3609                                      reconsume, pos);
   3610                NS_HTML5_BREAK(doctypenameloop);
   3611              }
   3612              case '>': {
   3613                strBufToDoctypeName();
   3614                emitDoctypeToken(pos);
   3615                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   3616                                      reconsume, pos);
   3617                if (shouldSuspend) {
   3618                  NS_HTML5_BREAK(stateloop);
   3619                }
   3620                NS_HTML5_CONTINUE(stateloop);
   3621              }
   3622              case '\0': {
   3623                c = 0xfffd;
   3624                [[fallthrough]];
   3625              }
   3626              default: {
   3627                if (c >= 'A' && c <= 'Z') {
   3628                  c += 0x0020;
   3629                }
   3630                appendStrBuf(c);
   3631                continue;
   3632              }
   3633            }
   3634          }
   3635        doctypenameloop_end:;
   3636          [[fallthrough]];
   3637        }
   3638        case AFTER_DOCTYPE_NAME: {
   3639          for (;;) {
   3640            if (++pos == endPos) {
   3641              NS_HTML5_BREAK(stateloop);
   3642            }
   3643            c = P::checkChar(this, buf, pos);
   3644            switch (c) {
   3645              case '\r': {
   3646                P::silentCarriageReturn(this);
   3647                NS_HTML5_BREAK(stateloop);
   3648              }
   3649              case '\n': {
   3650                P::silentLineFeed(this);
   3651                [[fallthrough]];
   3652              }
   3653              case ' ':
   3654              case '\t':
   3655              case '\f': {
   3656                continue;
   3657              }
   3658              case '>': {
   3659                emitDoctypeToken(pos);
   3660                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   3661                                      reconsume, pos);
   3662                if (shouldSuspend) {
   3663                  NS_HTML5_BREAK(stateloop);
   3664                }
   3665                NS_HTML5_CONTINUE(stateloop);
   3666              }
   3667              case 'p':
   3668              case 'P': {
   3669                index = 0;
   3670                state = P::transition(mViewSource.get(),
   3671                                      nsHtml5Tokenizer::DOCTYPE_UBLIC,
   3672                                      reconsume, pos);
   3673                NS_HTML5_BREAK(afterdoctypenameloop);
   3674              }
   3675              case 's':
   3676              case 'S': {
   3677                index = 0;
   3678                state = P::transition(mViewSource.get(),
   3679                                      nsHtml5Tokenizer::DOCTYPE_YSTEM,
   3680                                      reconsume, pos);
   3681                NS_HTML5_CONTINUE(stateloop);
   3682              }
   3683              default: {
   3684                bogusDoctype();
   3685                state = P::transition(mViewSource.get(),
   3686                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   3687                                      reconsume, pos);
   3688                NS_HTML5_CONTINUE(stateloop);
   3689              }
   3690            }
   3691          }
   3692        afterdoctypenameloop_end:;
   3693          [[fallthrough]];
   3694        }
   3695        case DOCTYPE_UBLIC: {
   3696          for (;;) {
   3697            if (++pos == endPos) {
   3698              NS_HTML5_BREAK(stateloop);
   3699            }
   3700            c = P::checkChar(this, buf, pos);
   3701            if (index < 5) {
   3702              char16_t folded = c;
   3703              if (c >= 'A' && c <= 'Z') {
   3704                folded += 0x20;
   3705              }
   3706              if (folded != nsHtml5Tokenizer::UBLIC[index]) {
   3707                bogusDoctype();
   3708                reconsume = true;
   3709                state = P::transition(mViewSource.get(),
   3710                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   3711                                      reconsume, pos);
   3712                NS_HTML5_CONTINUE(stateloop);
   3713              }
   3714              index++;
   3715              continue;
   3716            } else {
   3717              reconsume = true;
   3718              state =
   3719                  P::transition(mViewSource.get(),
   3720                                nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD,
   3721                                reconsume, pos);
   3722              NS_HTML5_BREAK(doctypeublicloop);
   3723            }
   3724          }
   3725        doctypeublicloop_end:;
   3726          [[fallthrough]];
   3727        }
   3728        case AFTER_DOCTYPE_PUBLIC_KEYWORD: {
   3729          for (;;) {
   3730            if (reconsume) {
   3731              reconsume = false;
   3732            } else {
   3733              if (++pos == endPos) {
   3734                NS_HTML5_BREAK(stateloop);
   3735              }
   3736              c = P::checkChar(this, buf, pos);
   3737            }
   3738            switch (c) {
   3739              case '\r': {
   3740                P::silentCarriageReturn(this);
   3741                state = P::transition(
   3742                    mViewSource.get(),
   3743                    nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER,
   3744                    reconsume, pos);
   3745                NS_HTML5_BREAK(stateloop);
   3746              }
   3747              case '\n': {
   3748                P::silentLineFeed(this);
   3749                [[fallthrough]];
   3750              }
   3751              case ' ':
   3752              case '\t':
   3753              case '\f': {
   3754                state = P::transition(
   3755                    mViewSource.get(),
   3756                    nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER,
   3757                    reconsume, pos);
   3758                NS_HTML5_BREAK(afterdoctypepublickeywordloop);
   3759              }
   3760              case '\"': {
   3761                if (P::reportErrors) {
   3762                  errNoSpaceBetweenDoctypePublicKeywordAndQuote();
   3763                }
   3764                clearStrBufBeforeUse();
   3765                state = P::transition(
   3766                    mViewSource.get(),
   3767                    nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
   3768                    reconsume, pos);
   3769                NS_HTML5_CONTINUE(stateloop);
   3770              }
   3771              case '\'': {
   3772                if (P::reportErrors) {
   3773                  errNoSpaceBetweenDoctypePublicKeywordAndQuote();
   3774                }
   3775                clearStrBufBeforeUse();
   3776                state = P::transition(
   3777                    mViewSource.get(),
   3778                    nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
   3779                    reconsume, pos);
   3780                NS_HTML5_CONTINUE(stateloop);
   3781              }
   3782              case '>': {
   3783                if (P::reportErrors) {
   3784                  errExpectedPublicId();
   3785                }
   3786                forceQuirks = true;
   3787                emitDoctypeToken(pos);
   3788                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   3789                                      reconsume, pos);
   3790                if (shouldSuspend) {
   3791                  NS_HTML5_BREAK(stateloop);
   3792                }
   3793                NS_HTML5_CONTINUE(stateloop);
   3794              }
   3795              default: {
   3796                bogusDoctype();
   3797                state = P::transition(mViewSource.get(),
   3798                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   3799                                      reconsume, pos);
   3800                NS_HTML5_CONTINUE(stateloop);
   3801              }
   3802            }
   3803          }
   3804        afterdoctypepublickeywordloop_end:;
   3805          [[fallthrough]];
   3806        }
   3807        case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
   3808          for (;;) {
   3809            if (++pos == endPos) {
   3810              NS_HTML5_BREAK(stateloop);
   3811            }
   3812            c = P::checkChar(this, buf, pos);
   3813            switch (c) {
   3814              case '\r': {
   3815                P::silentCarriageReturn(this);
   3816                NS_HTML5_BREAK(stateloop);
   3817              }
   3818              case '\n': {
   3819                P::silentLineFeed(this);
   3820                [[fallthrough]];
   3821              }
   3822              case ' ':
   3823              case '\t':
   3824              case '\f': {
   3825                continue;
   3826              }
   3827              case '\"': {
   3828                clearStrBufBeforeUse();
   3829                state = P::transition(
   3830                    mViewSource.get(),
   3831                    nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
   3832                    reconsume, pos);
   3833                NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
   3834              }
   3835              case '\'': {
   3836                clearStrBufBeforeUse();
   3837                state = P::transition(
   3838                    mViewSource.get(),
   3839                    nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
   3840                    reconsume, pos);
   3841                NS_HTML5_CONTINUE(stateloop);
   3842              }
   3843              case '>': {
   3844                if (P::reportErrors) {
   3845                  errExpectedPublicId();
   3846                }
   3847                forceQuirks = true;
   3848                emitDoctypeToken(pos);
   3849                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   3850                                      reconsume, pos);
   3851                if (shouldSuspend) {
   3852                  NS_HTML5_BREAK(stateloop);
   3853                }
   3854                NS_HTML5_CONTINUE(stateloop);
   3855              }
   3856              default: {
   3857                bogusDoctype();
   3858                state = P::transition(mViewSource.get(),
   3859                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   3860                                      reconsume, pos);
   3861                NS_HTML5_CONTINUE(stateloop);
   3862              }
   3863            }
   3864          }
   3865        beforedoctypepublicidentifierloop_end:;
   3866          [[fallthrough]];
   3867        }
   3868        case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
   3869          for (;;) {
   3870            if (++pos == endPos) {
   3871              NS_HTML5_BREAK(stateloop);
   3872            }
   3873            c = P::checkChar(this, buf, pos);
   3874            switch (c) {
   3875              case '\"': {
   3876                publicIdentifier = strBufToString();
   3877                state = P::transition(
   3878                    mViewSource.get(),
   3879                    nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER,
   3880                    reconsume, pos);
   3881                NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
   3882              }
   3883              case '>': {
   3884                if (P::reportErrors) {
   3885                  errGtInPublicId();
   3886                }
   3887                forceQuirks = true;
   3888                publicIdentifier = strBufToString();
   3889                emitDoctypeToken(pos);
   3890                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   3891                                      reconsume, pos);
   3892                if (shouldSuspend) {
   3893                  NS_HTML5_BREAK(stateloop);
   3894                }
   3895                NS_HTML5_CONTINUE(stateloop);
   3896              }
   3897              case '\r': {
   3898                appendStrBufCarriageReturn<P>();
   3899                NS_HTML5_BREAK(stateloop);
   3900              }
   3901              case '\n': {
   3902                appendStrBufLineFeed<P>();
   3903                continue;
   3904              }
   3905              case '\0': {
   3906                c = 0xfffd;
   3907                [[fallthrough]];
   3908              }
   3909              default: {
   3910                appendStrBuf(c);
   3911                continue;
   3912              }
   3913            }
   3914          }
   3915        doctypepublicidentifierdoublequotedloop_end:;
   3916          [[fallthrough]];
   3917        }
   3918        case AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
   3919          for (;;) {
   3920            if (++pos == endPos) {
   3921              NS_HTML5_BREAK(stateloop);
   3922            }
   3923            c = P::checkChar(this, buf, pos);
   3924            switch (c) {
   3925              case '\r': {
   3926                P::silentCarriageReturn(this);
   3927                state = P::transition(
   3928                    mViewSource.get(),
   3929                    nsHtml5Tokenizer::
   3930                        BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
   3931                    reconsume, pos);
   3932                NS_HTML5_BREAK(stateloop);
   3933              }
   3934              case '\n': {
   3935                P::silentLineFeed(this);
   3936                [[fallthrough]];
   3937              }
   3938              case ' ':
   3939              case '\t':
   3940              case '\f': {
   3941                state = P::transition(
   3942                    mViewSource.get(),
   3943                    nsHtml5Tokenizer::
   3944                        BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
   3945                    reconsume, pos);
   3946                NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
   3947              }
   3948              case '>': {
   3949                emitDoctypeToken(pos);
   3950                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   3951                                      reconsume, pos);
   3952                if (shouldSuspend) {
   3953                  NS_HTML5_BREAK(stateloop);
   3954                }
   3955                NS_HTML5_CONTINUE(stateloop);
   3956              }
   3957              case '\"': {
   3958                if (P::reportErrors) {
   3959                  errNoSpaceBetweenPublicAndSystemIds();
   3960                }
   3961                clearStrBufBeforeUse();
   3962                state = P::transition(
   3963                    mViewSource.get(),
   3964                    nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
   3965                    reconsume, pos);
   3966                NS_HTML5_CONTINUE(stateloop);
   3967              }
   3968              case '\'': {
   3969                if (P::reportErrors) {
   3970                  errNoSpaceBetweenPublicAndSystemIds();
   3971                }
   3972                clearStrBufBeforeUse();
   3973                state = P::transition(
   3974                    mViewSource.get(),
   3975                    nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
   3976                    reconsume, pos);
   3977                NS_HTML5_CONTINUE(stateloop);
   3978              }
   3979              default: {
   3980                bogusDoctype();
   3981                state = P::transition(mViewSource.get(),
   3982                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   3983                                      reconsume, pos);
   3984                NS_HTML5_CONTINUE(stateloop);
   3985              }
   3986            }
   3987          }
   3988        afterdoctypepublicidentifierloop_end:;
   3989          [[fallthrough]];
   3990        }
   3991        case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
   3992          for (;;) {
   3993            if (++pos == endPos) {
   3994              NS_HTML5_BREAK(stateloop);
   3995            }
   3996            c = P::checkChar(this, buf, pos);
   3997            switch (c) {
   3998              case '\r': {
   3999                P::silentCarriageReturn(this);
   4000                NS_HTML5_BREAK(stateloop);
   4001              }
   4002              case '\n': {
   4003                P::silentLineFeed(this);
   4004                [[fallthrough]];
   4005              }
   4006              case ' ':
   4007              case '\t':
   4008              case '\f': {
   4009                continue;
   4010              }
   4011              case '>': {
   4012                emitDoctypeToken(pos);
   4013                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4014                                      reconsume, pos);
   4015                if (shouldSuspend) {
   4016                  NS_HTML5_BREAK(stateloop);
   4017                }
   4018                NS_HTML5_CONTINUE(stateloop);
   4019              }
   4020              case '\"': {
   4021                clearStrBufBeforeUse();
   4022                state = P::transition(
   4023                    mViewSource.get(),
   4024                    nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
   4025                    reconsume, pos);
   4026                NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop);
   4027              }
   4028              case '\'': {
   4029                clearStrBufBeforeUse();
   4030                state = P::transition(
   4031                    mViewSource.get(),
   4032                    nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
   4033                    reconsume, pos);
   4034                NS_HTML5_CONTINUE(stateloop);
   4035              }
   4036              default: {
   4037                bogusDoctype();
   4038                state = P::transition(mViewSource.get(),
   4039                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   4040                                      reconsume, pos);
   4041                NS_HTML5_CONTINUE(stateloop);
   4042              }
   4043            }
   4044          }
   4045        betweendoctypepublicandsystemidentifiersloop_end:;
   4046          [[fallthrough]];
   4047        }
   4048        case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
   4049          for (;;) {
   4050            if (++pos == endPos) {
   4051              NS_HTML5_BREAK(stateloop);
   4052            }
   4053            c = P::checkChar(this, buf, pos);
   4054            switch (c) {
   4055              case '\"': {
   4056                systemIdentifier = strBufToString();
   4057                state = P::transition(
   4058                    mViewSource.get(),
   4059                    nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER,
   4060                    reconsume, pos);
   4061                NS_HTML5_BREAK(doctypesystemidentifierdoublequotedloop);
   4062              }
   4063              case '>': {
   4064                if (P::reportErrors) {
   4065                  errGtInSystemId();
   4066                }
   4067                forceQuirks = true;
   4068                systemIdentifier = strBufToString();
   4069                emitDoctypeToken(pos);
   4070                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4071                                      reconsume, pos);
   4072                if (shouldSuspend) {
   4073                  NS_HTML5_BREAK(stateloop);
   4074                }
   4075                NS_HTML5_CONTINUE(stateloop);
   4076              }
   4077              case '\r': {
   4078                appendStrBufCarriageReturn<P>();
   4079                NS_HTML5_BREAK(stateloop);
   4080              }
   4081              case '\n': {
   4082                appendStrBufLineFeed<P>();
   4083                continue;
   4084              }
   4085              case '\0': {
   4086                c = 0xfffd;
   4087                [[fallthrough]];
   4088              }
   4089              default: {
   4090                appendStrBuf(c);
   4091                continue;
   4092              }
   4093            }
   4094          }
   4095        doctypesystemidentifierdoublequotedloop_end:;
   4096          [[fallthrough]];
   4097        }
   4098        case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
   4099          for (;;) {
   4100            if (++pos == endPos) {
   4101              NS_HTML5_BREAK(stateloop);
   4102            }
   4103            c = P::checkChar(this, buf, pos);
   4104            switch (c) {
   4105              case '\r': {
   4106                P::silentCarriageReturn(this);
   4107                NS_HTML5_BREAK(stateloop);
   4108              }
   4109              case '\n': {
   4110                P::silentLineFeed(this);
   4111                [[fallthrough]];
   4112              }
   4113              case ' ':
   4114              case '\t':
   4115              case '\f': {
   4116                continue;
   4117              }
   4118              case '>': {
   4119                emitDoctypeToken(pos);
   4120                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4121                                      reconsume, pos);
   4122                if (shouldSuspend) {
   4123                  NS_HTML5_BREAK(stateloop);
   4124                }
   4125                NS_HTML5_CONTINUE(stateloop);
   4126              }
   4127              default: {
   4128                bogusDoctypeWithoutQuirks();
   4129                state = P::transition(mViewSource.get(),
   4130                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   4131                                      reconsume, pos);
   4132                NS_HTML5_BREAK(afterdoctypesystemidentifierloop);
   4133              }
   4134            }
   4135          }
   4136        afterdoctypesystemidentifierloop_end:;
   4137          [[fallthrough]];
   4138        }
   4139        case BOGUS_DOCTYPE: {
   4140          for (;;) {
   4141            if (reconsume) {
   4142              reconsume = false;
   4143            } else {
   4144              if (++pos == endPos) {
   4145                NS_HTML5_BREAK(stateloop);
   4146              }
   4147              c = P::checkChar(this, buf, pos);
   4148            }
   4149            switch (c) {
   4150              case '>': {
   4151                emitDoctypeToken(pos);
   4152                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4153                                      reconsume, pos);
   4154                if (shouldSuspend) {
   4155                  NS_HTML5_BREAK(stateloop);
   4156                }
   4157                NS_HTML5_CONTINUE(stateloop);
   4158              }
   4159              case '\r': {
   4160                P::silentCarriageReturn(this);
   4161                NS_HTML5_BREAK(stateloop);
   4162              }
   4163              case '\n': {
   4164                P::silentLineFeed(this);
   4165                [[fallthrough]];
   4166              }
   4167              default: {
   4168                continue;
   4169              }
   4170            }
   4171          }
   4172        }
   4173        case DOCTYPE_YSTEM: {
   4174          for (;;) {
   4175            if (++pos == endPos) {
   4176              NS_HTML5_BREAK(stateloop);
   4177            }
   4178            c = P::checkChar(this, buf, pos);
   4179            if (index < 5) {
   4180              char16_t folded = c;
   4181              if (c >= 'A' && c <= 'Z') {
   4182                folded += 0x20;
   4183              }
   4184              if (folded != nsHtml5Tokenizer::YSTEM[index]) {
   4185                bogusDoctype();
   4186                reconsume = true;
   4187                state = P::transition(mViewSource.get(),
   4188                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   4189                                      reconsume, pos);
   4190                NS_HTML5_CONTINUE(stateloop);
   4191              }
   4192              index++;
   4193              NS_HTML5_CONTINUE(stateloop);
   4194            } else {
   4195              reconsume = true;
   4196              state =
   4197                  P::transition(mViewSource.get(),
   4198                                nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD,
   4199                                reconsume, pos);
   4200              NS_HTML5_BREAK(doctypeystemloop);
   4201            }
   4202          }
   4203        doctypeystemloop_end:;
   4204          [[fallthrough]];
   4205        }
   4206        case AFTER_DOCTYPE_SYSTEM_KEYWORD: {
   4207          for (;;) {
   4208            if (reconsume) {
   4209              reconsume = false;
   4210            } else {
   4211              if (++pos == endPos) {
   4212                NS_HTML5_BREAK(stateloop);
   4213              }
   4214              c = P::checkChar(this, buf, pos);
   4215            }
   4216            switch (c) {
   4217              case '\r': {
   4218                P::silentCarriageReturn(this);
   4219                state = P::transition(
   4220                    mViewSource.get(),
   4221                    nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER,
   4222                    reconsume, pos);
   4223                NS_HTML5_BREAK(stateloop);
   4224              }
   4225              case '\n': {
   4226                P::silentLineFeed(this);
   4227                [[fallthrough]];
   4228              }
   4229              case ' ':
   4230              case '\t':
   4231              case '\f': {
   4232                state = P::transition(
   4233                    mViewSource.get(),
   4234                    nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER,
   4235                    reconsume, pos);
   4236                NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
   4237              }
   4238              case '\"': {
   4239                if (P::reportErrors) {
   4240                  errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
   4241                }
   4242                clearStrBufBeforeUse();
   4243                state = P::transition(
   4244                    mViewSource.get(),
   4245                    nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
   4246                    reconsume, pos);
   4247                NS_HTML5_CONTINUE(stateloop);
   4248              }
   4249              case '\'': {
   4250                if (P::reportErrors) {
   4251                  errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
   4252                }
   4253                clearStrBufBeforeUse();
   4254                state = P::transition(
   4255                    mViewSource.get(),
   4256                    nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
   4257                    reconsume, pos);
   4258                NS_HTML5_CONTINUE(stateloop);
   4259              }
   4260              case '>': {
   4261                if (P::reportErrors) {
   4262                  errExpectedPublicId();
   4263                }
   4264                forceQuirks = true;
   4265                emitDoctypeToken(pos);
   4266                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4267                                      reconsume, pos);
   4268                if (shouldSuspend) {
   4269                  NS_HTML5_BREAK(stateloop);
   4270                }
   4271                NS_HTML5_CONTINUE(stateloop);
   4272              }
   4273              default: {
   4274                bogusDoctype();
   4275                state = P::transition(mViewSource.get(),
   4276                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   4277                                      reconsume, pos);
   4278                NS_HTML5_CONTINUE(stateloop);
   4279              }
   4280            }
   4281          }
   4282        afterdoctypesystemkeywordloop_end:;
   4283          [[fallthrough]];
   4284        }
   4285        case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
   4286          for (;;) {
   4287            if (++pos == endPos) {
   4288              NS_HTML5_BREAK(stateloop);
   4289            }
   4290            c = P::checkChar(this, buf, pos);
   4291            switch (c) {
   4292              case '\r': {
   4293                P::silentCarriageReturn(this);
   4294                NS_HTML5_BREAK(stateloop);
   4295              }
   4296              case '\n': {
   4297                P::silentLineFeed(this);
   4298                [[fallthrough]];
   4299              }
   4300              case ' ':
   4301              case '\t':
   4302              case '\f': {
   4303                continue;
   4304              }
   4305              case '\"': {
   4306                clearStrBufBeforeUse();
   4307                state = P::transition(
   4308                    mViewSource.get(),
   4309                    nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
   4310                    reconsume, pos);
   4311                NS_HTML5_CONTINUE(stateloop);
   4312              }
   4313              case '\'': {
   4314                clearStrBufBeforeUse();
   4315                state = P::transition(
   4316                    mViewSource.get(),
   4317                    nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
   4318                    reconsume, pos);
   4319                NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
   4320              }
   4321              case '>': {
   4322                if (P::reportErrors) {
   4323                  errExpectedSystemId();
   4324                }
   4325                forceQuirks = true;
   4326                emitDoctypeToken(pos);
   4327                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4328                                      reconsume, pos);
   4329                if (shouldSuspend) {
   4330                  NS_HTML5_BREAK(stateloop);
   4331                }
   4332                NS_HTML5_CONTINUE(stateloop);
   4333              }
   4334              default: {
   4335                bogusDoctype();
   4336                state = P::transition(mViewSource.get(),
   4337                                      nsHtml5Tokenizer::BOGUS_DOCTYPE,
   4338                                      reconsume, pos);
   4339                NS_HTML5_CONTINUE(stateloop);
   4340              }
   4341            }
   4342          }
   4343        beforedoctypesystemidentifierloop_end:;
   4344          [[fallthrough]];
   4345        }
   4346        case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
   4347          for (;;) {
   4348            if (++pos == endPos) {
   4349              NS_HTML5_BREAK(stateloop);
   4350            }
   4351            c = P::checkChar(this, buf, pos);
   4352            switch (c) {
   4353              case '\'': {
   4354                systemIdentifier = strBufToString();
   4355                state = P::transition(
   4356                    mViewSource.get(),
   4357                    nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER,
   4358                    reconsume, pos);
   4359                NS_HTML5_CONTINUE(stateloop);
   4360              }
   4361              case '>': {
   4362                if (P::reportErrors) {
   4363                  errGtInSystemId();
   4364                }
   4365                forceQuirks = true;
   4366                systemIdentifier = strBufToString();
   4367                emitDoctypeToken(pos);
   4368                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4369                                      reconsume, pos);
   4370                if (shouldSuspend) {
   4371                  NS_HTML5_BREAK(stateloop);
   4372                }
   4373                NS_HTML5_CONTINUE(stateloop);
   4374              }
   4375              case '\r': {
   4376                appendStrBufCarriageReturn<P>();
   4377                NS_HTML5_BREAK(stateloop);
   4378              }
   4379              case '\n': {
   4380                appendStrBufLineFeed<P>();
   4381                continue;
   4382              }
   4383              case '\0': {
   4384                c = 0xfffd;
   4385                [[fallthrough]];
   4386              }
   4387              default: {
   4388                appendStrBuf(c);
   4389                continue;
   4390              }
   4391            }
   4392          }
   4393        }
   4394        case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
   4395          for (;;) {
   4396            if (++pos == endPos) {
   4397              NS_HTML5_BREAK(stateloop);
   4398            }
   4399            c = P::checkChar(this, buf, pos);
   4400            switch (c) {
   4401              case '\'': {
   4402                publicIdentifier = strBufToString();
   4403                state = P::transition(
   4404                    mViewSource.get(),
   4405                    nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER,
   4406                    reconsume, pos);
   4407                NS_HTML5_CONTINUE(stateloop);
   4408              }
   4409              case '>': {
   4410                if (P::reportErrors) {
   4411                  errGtInPublicId();
   4412                }
   4413                forceQuirks = true;
   4414                publicIdentifier = strBufToString();
   4415                emitDoctypeToken(pos);
   4416                state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4417                                      reconsume, pos);
   4418                if (shouldSuspend) {
   4419                  NS_HTML5_BREAK(stateloop);
   4420                }
   4421                NS_HTML5_CONTINUE(stateloop);
   4422              }
   4423              case '\r': {
   4424                appendStrBufCarriageReturn<P>();
   4425                NS_HTML5_BREAK(stateloop);
   4426              }
   4427              case '\n': {
   4428                appendStrBufLineFeed<P>();
   4429                continue;
   4430              }
   4431              case '\0': {
   4432                c = 0xfffd;
   4433                [[fallthrough]];
   4434              }
   4435              default: {
   4436                appendStrBuf(c);
   4437                continue;
   4438              }
   4439            }
   4440          }
   4441        }
   4442        case PROCESSING_INSTRUCTION: {
   4443          for (;;) {
   4444            if (++pos == endPos) {
   4445              NS_HTML5_BREAK(stateloop);
   4446            }
   4447            c = P::checkChar(this, buf, pos);
   4448            switch (c) {
   4449              case '\?': {
   4450                state = P::transition(
   4451                    mViewSource.get(),
   4452                    nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK,
   4453                    reconsume, pos);
   4454                NS_HTML5_BREAK(processinginstructionloop);
   4455              }
   4456              default: {
   4457                continue;
   4458              }
   4459            }
   4460          }
   4461        processinginstructionloop_end:;
   4462          [[fallthrough]];
   4463        }
   4464        case PROCESSING_INSTRUCTION_QUESTION_MARK: {
   4465          if (++pos == endPos) {
   4466            NS_HTML5_BREAK(stateloop);
   4467          }
   4468          c = P::checkChar(this, buf, pos);
   4469          switch (c) {
   4470            case '>': {
   4471              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
   4472                                    reconsume, pos);
   4473              suspendIfRequestedAfterCurrentNonTextToken();
   4474              if (shouldSuspend) {
   4475                NS_HTML5_BREAK(stateloop);
   4476              }
   4477              NS_HTML5_CONTINUE(stateloop);
   4478            }
   4479            default: {
   4480              state = P::transition(mViewSource.get(),
   4481                                    nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
   4482                                    reconsume, pos);
   4483              NS_HTML5_CONTINUE(stateloop);
   4484            }
   4485          }
   4486        }
   4487      }
   4488    }
   4489  stateloop_end:;
   4490    flushChars(buf, pos);
   4491    stateSave = state;
   4492    returnStateSave = returnState;
   4493    return pos;
   4494  }
   4495 
   4496  void initDoctypeFields();
   4497  template <class P>
   4498  inline void adjustDoubleHyphenAndAppendToStrBufCarriageReturn() {
   4499    P::silentCarriageReturn(this);
   4500    adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
   4501  }
   4502 
   4503  template <class P>
   4504  inline void adjustDoubleHyphenAndAppendToStrBufLineFeed() {
   4505    P::silentLineFeed(this);
   4506    adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
   4507  }
   4508 
   4509  template <class P>
   4510  inline void appendStrBufLineFeed() {
   4511    P::silentLineFeed(this);
   4512    appendStrBuf('\n');
   4513  }
   4514 
   4515  template <class P>
   4516  inline void appendStrBufCarriageReturn() {
   4517    P::silentCarriageReturn(this);
   4518    appendStrBuf('\n');
   4519  }
   4520 
   4521  template <class P>
   4522  inline void emitCarriageReturn(char16_t* buf, int32_t pos) {
   4523    P::silentCarriageReturn(this);
   4524    flushChars(buf, pos);
   4525    tokenHandler->characters(nsHtml5Tokenizer::LF, 0, 1);
   4526    cstart = INT32_MAX;
   4527  }
   4528 
   4529  void emitReplacementCharacter(char16_t* buf, int32_t pos);
   4530  void maybeEmitReplacementCharacter(char16_t* buf, int32_t pos);
   4531  void emitPlaintextReplacementCharacter(char16_t* buf, int32_t pos);
   4532  inline void setAdditionalAndRememberAmpersandLocation(char16_t add) {
   4533    additional = add;
   4534  }
   4535 
   4536  void bogusDoctype();
   4537  void bogusDoctypeWithoutQuirks();
   4538  void handleNcrValue(int32_t returnState);
   4539 
   4540 public:
   4541  void eof();
   4542 
   4543 private:
   4544  void emitDoctypeToken(int32_t pos);
   4545  inline void suspendIfRequestedAfterCurrentNonTextToken() {
   4546    if (suspendAfterCurrentNonTextToken) {
   4547      suspendAfterCurrentNonTextToken = false;
   4548      shouldSuspend = true;
   4549    }
   4550  }
   4551 
   4552  void suspendAfterCurrentTokenIfNotInText();
   4553  bool suspensionAfterCurrentNonTextTokenPending();
   4554 
   4555 public:
   4556  bool internalEncodingDeclaration(nsHtml5String internalCharset);
   4557 
   4558 private:
   4559  inline void emitOrAppendTwo(const char16_t* val, int32_t returnState) {
   4560    if ((returnState & DATA_AND_RCDATA_MASK)) {
   4561      appendStrBuf(val[0]);
   4562      appendStrBuf(val[1]);
   4563    } else {
   4564      tokenHandler->characters(val, 0, 2);
   4565    }
   4566  }
   4567 
   4568  inline void emitOrAppendOne(const char16_t* val, int32_t returnState) {
   4569    if ((returnState & DATA_AND_RCDATA_MASK)) {
   4570      appendStrBuf(val[0]);
   4571    } else {
   4572      tokenHandler->characters(val, 0, 1);
   4573    }
   4574  }
   4575 
   4576 public:
   4577  void end();
   4578  inline void requestSuspension() { shouldSuspend = true; }
   4579 
   4580  inline bool isInDataState() { return (stateSave == DATA); }
   4581 
   4582  void resetToDataState();
   4583  void loadState(nsHtml5Tokenizer* other);
   4584  void initializeWithoutStarting();
   4585  void setEncodingDeclarationHandler(
   4586      nsHtml5StreamParser* encodingDeclarationHandler);
   4587  ~nsHtml5Tokenizer();
   4588  static void initializeStatics();
   4589  static void releaseStatics();
   4590 
   4591 #include "nsHtml5TokenizerHSupplement.h"
   4592 };
   4593 
   4594 #endif