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