Backed out 2 changesets (bug 1886730) for causing detekt & klint failures CLOSED...
[gecko.git] / parser / html / nsHtml5Tokenizer.cpp
blob5092bf4bf67b292bc5c84d8707aa3904cbb241ab
1 /*
2 * Copyright (c) 2005-2007 Henri Sivonen
3 * Copyright (c) 2007-2017 Mozilla Foundation
4 * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
5 * Foundation, and Opera Software ASA.
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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.
27 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
28 * Please edit Tokenizer.java instead and regenerate.
31 #define nsHtml5Tokenizer_cpp__
33 #include "nsHtml5AttributeName.h"
34 #include "nsHtml5ElementName.h"
35 #include "nsHtml5TreeBuilder.h"
36 #include "nsHtml5StackNode.h"
37 #include "nsHtml5UTF16Buffer.h"
38 #include "nsHtml5StateSnapshot.h"
39 #include "nsHtml5Portability.h"
41 #include "nsHtml5Tokenizer.h"
43 #include "nsHtml5TokenizerLoopPolicies.h"
45 char16_t nsHtml5Tokenizer::LT_GT[] = {'<', '>'};
46 char16_t nsHtml5Tokenizer::LT_SOLIDUS[] = {'<', '/'};
47 char16_t nsHtml5Tokenizer::RSQB_RSQB[] = {']', ']'};
48 char16_t nsHtml5Tokenizer::REPLACEMENT_CHARACTER[] = {0xfffd};
49 char16_t nsHtml5Tokenizer::LF[] = {'\n'};
50 char16_t nsHtml5Tokenizer::CDATA_LSQB[] = {'C', 'D', 'A', 'T', 'A', '['};
51 char16_t nsHtml5Tokenizer::OCTYPE[] = {'o', 'c', 't', 'y', 'p', 'e'};
52 char16_t nsHtml5Tokenizer::UBLIC[] = {'u', 'b', 'l', 'i', 'c'};
53 char16_t nsHtml5Tokenizer::YSTEM[] = {'y', 's', 't', 'e', 'm'};
54 static char16_t const TITLE_ARR_DATA[] = {'t', 'i', 't', 'l', 'e'};
55 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TITLE_ARR = {
56 TITLE_ARR_DATA, MOZ_ARRAY_LENGTH(TITLE_ARR_DATA)};
57 static char16_t const SCRIPT_ARR_DATA[] = {'s', 'c', 'r', 'i', 'p', 't'};
58 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::SCRIPT_ARR = {
59 SCRIPT_ARR_DATA, MOZ_ARRAY_LENGTH(SCRIPT_ARR_DATA)};
60 static char16_t const STYLE_ARR_DATA[] = {'s', 't', 'y', 'l', 'e'};
61 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::STYLE_ARR = {
62 STYLE_ARR_DATA, MOZ_ARRAY_LENGTH(STYLE_ARR_DATA)};
63 static char16_t const PLAINTEXT_ARR_DATA[] = {'p', 'l', 'a', 'i', 'n',
64 't', 'e', 'x', 't'};
65 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::PLAINTEXT_ARR = {
66 PLAINTEXT_ARR_DATA, MOZ_ARRAY_LENGTH(PLAINTEXT_ARR_DATA)};
67 static char16_t const XMP_ARR_DATA[] = {'x', 'm', 'p'};
68 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::XMP_ARR = {
69 XMP_ARR_DATA, MOZ_ARRAY_LENGTH(XMP_ARR_DATA)};
70 static char16_t const TEXTAREA_ARR_DATA[] = {'t', 'e', 'x', 't',
71 'a', 'r', 'e', 'a'};
72 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TEXTAREA_ARR = {
73 TEXTAREA_ARR_DATA, MOZ_ARRAY_LENGTH(TEXTAREA_ARR_DATA)};
74 static char16_t const IFRAME_ARR_DATA[] = {'i', 'f', 'r', 'a', 'm', 'e'};
75 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::IFRAME_ARR = {
76 IFRAME_ARR_DATA, MOZ_ARRAY_LENGTH(IFRAME_ARR_DATA)};
77 static char16_t const NOEMBED_ARR_DATA[] = {'n', 'o', 'e', 'm', 'b', 'e', 'd'};
78 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOEMBED_ARR = {
79 NOEMBED_ARR_DATA, MOZ_ARRAY_LENGTH(NOEMBED_ARR_DATA)};
80 static char16_t const NOSCRIPT_ARR_DATA[] = {'n', 'o', 's', 'c',
81 'r', 'i', 'p', 't'};
82 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOSCRIPT_ARR = {
83 NOSCRIPT_ARR_DATA, MOZ_ARRAY_LENGTH(NOSCRIPT_ARR_DATA)};
84 static char16_t const NOFRAMES_ARR_DATA[] = {'n', 'o', 'f', 'r',
85 'a', 'm', 'e', 's'};
86 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOFRAMES_ARR = {
87 NOFRAMES_ARR_DATA, MOZ_ARRAY_LENGTH(NOFRAMES_ARR_DATA)};
89 nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler,
90 bool viewingXmlSource)
91 : tokenHandler(tokenHandler),
92 encodingDeclarationHandler(nullptr),
93 lastCR(false),
94 stateSave(0),
95 returnStateSave(0),
96 index(0),
97 forceQuirks(false),
98 additional('\0'),
99 entCol(0),
100 firstCharKey(0),
101 lo(0),
102 hi(0),
103 candidate(0),
104 charRefBufMark(0),
105 value(0),
106 seenDigits(false),
107 suspendAfterCurrentNonTextToken(false),
108 cstart(0),
109 strBufLen(0),
110 charRefBuf(jArray<char16_t, int32_t>::newJArray(32)),
111 charRefBufLen(0),
112 bmpChar(jArray<char16_t, int32_t>::newJArray(1)),
113 astralChar(jArray<char16_t, int32_t>::newJArray(2)),
114 endTagExpectation(nullptr),
115 endTagExpectationAsArray(nullptr),
116 endTag(false),
117 containsHyphen(false),
118 tagName(nullptr),
119 nonInternedTagName(new nsHtml5ElementName()),
120 attributeName(nullptr),
121 nonInternedAttributeName(new nsHtml5AttributeName()),
122 doctypeName(nullptr),
123 publicIdentifier(nullptr),
124 systemIdentifier(nullptr),
125 attributes(tokenHandler->HasBuilder() ? new nsHtml5HtmlAttributes(0)
126 : nullptr),
127 newAttributesEachTime(!tokenHandler->HasBuilder()),
128 shouldSuspend(false),
129 confident(false),
130 line(0),
131 attributeLine(0),
132 interner(nullptr),
133 viewingXmlSource(viewingXmlSource) {
134 MOZ_COUNT_CTOR(nsHtml5Tokenizer);
137 void nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner) {
138 this->interner = interner;
141 void nsHtml5Tokenizer::initLocation(nsHtml5String newPublicId,
142 nsHtml5String newSystemId) {
143 this->systemId = newSystemId;
144 this->publicId = newPublicId;
147 bool nsHtml5Tokenizer::isViewingXmlSource() { return viewingXmlSource; }
149 void nsHtml5Tokenizer::setState(int32_t specialTokenizerState) {
150 this->stateSave = specialTokenizerState;
151 this->endTagExpectation = nullptr;
152 this->endTagExpectationAsArray = nullptr;
155 void nsHtml5Tokenizer::setStateAndEndTagExpectation(
156 int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation) {
157 this->stateSave = specialTokenizerState;
158 this->endTagExpectation = endTagExpectation;
159 endTagExpectationToArray();
162 void nsHtml5Tokenizer::endTagExpectationToArray() {
163 switch (endTagExpectation->getGroup()) {
164 case nsHtml5TreeBuilder::TITLE: {
165 endTagExpectationAsArray = TITLE_ARR;
166 return;
168 case nsHtml5TreeBuilder::SCRIPT: {
169 endTagExpectationAsArray = SCRIPT_ARR;
170 return;
172 case nsHtml5TreeBuilder::STYLE: {
173 endTagExpectationAsArray = STYLE_ARR;
174 return;
176 case nsHtml5TreeBuilder::PLAINTEXT: {
177 endTagExpectationAsArray = PLAINTEXT_ARR;
178 return;
180 case nsHtml5TreeBuilder::XMP: {
181 endTagExpectationAsArray = XMP_ARR;
182 return;
184 case nsHtml5TreeBuilder::TEXTAREA: {
185 endTagExpectationAsArray = TEXTAREA_ARR;
186 return;
188 case nsHtml5TreeBuilder::IFRAME: {
189 endTagExpectationAsArray = IFRAME_ARR;
190 return;
192 case nsHtml5TreeBuilder::NOEMBED: {
193 endTagExpectationAsArray = NOEMBED_ARR;
194 return;
196 case nsHtml5TreeBuilder::NOSCRIPT: {
197 endTagExpectationAsArray = NOSCRIPT_ARR;
198 return;
200 case nsHtml5TreeBuilder::NOFRAMES: {
201 endTagExpectationAsArray = NOFRAMES_ARR;
202 return;
204 default: {
205 MOZ_ASSERT(false, "Bad end tag expectation.");
206 return;
211 void nsHtml5Tokenizer::setLineNumber(int32_t line) {
212 this->attributeLine = line;
213 this->line = line;
216 nsHtml5HtmlAttributes* nsHtml5Tokenizer::emptyAttributes() {
217 return nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES;
220 void nsHtml5Tokenizer::emitOrAppendCharRefBuf(int32_t returnState) {
221 if ((returnState & DATA_AND_RCDATA_MASK)) {
222 appendCharRefBufToStrBuf();
223 } else {
224 if (charRefBufLen > 0) {
225 tokenHandler->characters(charRefBuf, 0, charRefBufLen);
226 charRefBufLen = 0;
231 nsHtml5String nsHtml5Tokenizer::strBufToString() {
232 nsHtml5String str = nsHtml5Portability::newStringFromBuffer(
233 strBuf, 0, strBufLen, tokenHandler,
234 !newAttributesEachTime &&
235 attributeName == nsHtml5AttributeName::ATTR_CLASS);
236 clearStrBufAfterUse();
237 return str;
240 void nsHtml5Tokenizer::strBufToDoctypeName() {
241 doctypeName =
242 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen, interner);
243 clearStrBufAfterUse();
246 void nsHtml5Tokenizer::emitStrBuf() {
247 if (strBufLen > 0) {
248 tokenHandler->characters(strBuf, 0, strBufLen);
249 clearStrBufAfterUse();
253 void nsHtml5Tokenizer::appendStrBuf(char16_t* buffer, int32_t offset,
254 int32_t length) {
255 int32_t newLen = nsHtml5Portability::checkedAdd(strBufLen, length);
256 MOZ_ASSERT(newLen <= strBuf.length, "Previous buffer length insufficient.");
257 if (MOZ_UNLIKELY(strBuf.length < newLen)) {
258 if (MOZ_UNLIKELY(!EnsureBufferSpace(length))) {
259 MOZ_CRASH("Unable to recover from buffer reallocation failure");
262 nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length);
263 strBufLen = newLen;
266 void nsHtml5Tokenizer::emitComment(int32_t provisionalHyphens, int32_t pos) {
267 RememberGt(pos);
268 tokenHandler->comment(strBuf, 0, strBufLen - provisionalHyphens);
269 clearStrBufAfterUse();
270 cstart = pos + 1;
271 suspendIfRequestedAfterCurrentNonTextToken();
274 void nsHtml5Tokenizer::flushChars(char16_t* buf, int32_t pos) {
275 if (pos > cstart) {
276 tokenHandler->characters(buf, cstart, pos - cstart);
278 cstart = INT32_MAX;
281 void nsHtml5Tokenizer::strBufToElementNameString() {
282 if (containsHyphen) {
283 nsAtom* annotationName = nsHtml5ElementName::ELT_ANNOTATION_XML->getName();
284 if (nsHtml5Portability::localEqualsBuffer(annotationName, strBuf,
285 strBufLen)) {
286 tagName = nsHtml5ElementName::ELT_ANNOTATION_XML;
287 } else {
288 nonInternedTagName->setNameForNonInterned(
289 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
290 interner),
291 true);
292 tagName = nonInternedTagName;
294 } else {
295 tagName = nsHtml5ElementName::elementNameByBuffer(strBuf, strBufLen);
296 if (!tagName) {
297 nonInternedTagName->setNameForNonInterned(
298 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
299 interner),
300 false);
301 tagName = nonInternedTagName;
304 containsHyphen = false;
305 clearStrBufAfterUse();
308 int32_t nsHtml5Tokenizer::emitCurrentTagToken(bool selfClosing, int32_t pos) {
309 RememberGt(pos);
310 cstart = pos + 1;
311 maybeErrSlashInEndTag(selfClosing);
312 stateSave = nsHtml5Tokenizer::DATA;
313 nsHtml5HtmlAttributes* attrs =
314 (!attributes ? nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES : attributes);
315 if (endTag) {
316 maybeErrAttributesOnEndTag(attrs);
317 if (!viewingXmlSource) {
318 tokenHandler->endTag(tagName);
320 if (newAttributesEachTime) {
321 delete attributes;
322 attributes = nullptr;
324 } else {
325 if (viewingXmlSource) {
326 MOZ_ASSERT(newAttributesEachTime);
327 delete attributes;
328 attributes = nullptr;
329 } else {
330 tokenHandler->startTag(tagName, attrs, selfClosing);
333 tagName = nullptr;
334 if (newAttributesEachTime) {
335 attributes = nullptr;
336 } else {
337 attributes->clear(0);
339 suspendIfRequestedAfterCurrentNonTextToken();
340 return stateSave;
343 void nsHtml5Tokenizer::attributeNameComplete() {
344 attributeName =
345 nsHtml5AttributeName::nameByBuffer(strBuf, strBufLen, interner);
346 if (!attributeName) {
347 nonInternedAttributeName->setNameForNonInterned(
348 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
349 interner));
350 attributeName = nonInternedAttributeName;
352 clearStrBufAfterUse();
353 if (!attributes) {
354 attributes = new nsHtml5HtmlAttributes(0);
356 if (attributes->contains(attributeName)) {
357 errDuplicateAttribute();
358 attributeName = nullptr;
362 void nsHtml5Tokenizer::addAttributeWithoutValue() {
363 if (attributeName) {
364 attributes->addAttribute(
365 attributeName, nsHtml5Portability::newEmptyString(), attributeLine);
366 attributeName = nullptr;
367 } else {
368 clearStrBufAfterUse();
372 void nsHtml5Tokenizer::addAttributeWithValue() {
373 if (attributeName) {
374 nsHtml5String val = strBufToString();
375 if (mViewSource) {
376 mViewSource->MaybeLinkifyAttributeValue(attributeName, val);
378 attributes->addAttribute(attributeName, val, attributeLine);
379 attributeName = nullptr;
380 } else {
381 clearStrBufAfterUse();
385 void nsHtml5Tokenizer::start() {
386 initializeWithoutStarting();
387 tokenHandler->startTokenization(this);
388 if (mViewSource) {
389 line = 1;
390 col = -1;
391 nextCharOnNewLine = false;
392 } else if (tokenHandler->WantsLineAndColumn()) {
393 line = 0;
394 col = 1;
395 nextCharOnNewLine = true;
396 } else {
397 line = -1;
398 col = -1;
399 nextCharOnNewLine = false;
403 bool nsHtml5Tokenizer::tokenizeBuffer(nsHtml5UTF16Buffer* buffer) {
404 int32_t state = stateSave;
405 int32_t returnState = returnStateSave;
406 char16_t c = '\0';
407 shouldSuspend = false;
408 lastCR = false;
409 int32_t start = buffer->getStart();
410 int32_t end = buffer->getEnd();
411 int32_t pos = start - 1;
412 switch (state) {
413 case DATA:
414 case RCDATA:
415 case SCRIPT_DATA:
416 case PLAINTEXT:
417 case RAWTEXT:
418 case CDATA_SECTION:
419 case SCRIPT_DATA_ESCAPED:
420 case SCRIPT_DATA_ESCAPE_START:
421 case SCRIPT_DATA_ESCAPE_START_DASH:
422 case SCRIPT_DATA_ESCAPED_DASH:
423 case SCRIPT_DATA_ESCAPED_DASH_DASH:
424 case SCRIPT_DATA_DOUBLE_ESCAPE_START:
425 case SCRIPT_DATA_DOUBLE_ESCAPED:
426 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
427 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
428 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
429 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
430 cstart = start;
431 break;
433 default: {
434 cstart = INT32_MAX;
435 break;
438 if (mViewSource) {
439 mViewSource->SetBuffer(buffer);
440 pos = stateLoop<nsHtml5ViewSourcePolicy>(state, c, pos, buffer->getBuffer(),
441 false, returnState,
442 buffer->getEnd());
443 mViewSource->DropBuffer((pos == buffer->getEnd()) ? pos : pos + 1);
444 } else if (tokenHandler->WantsLineAndColumn()) {
445 pos = stateLoop<nsHtml5LineColPolicy>(state, c, pos, buffer->getBuffer(),
446 false, returnState, buffer->getEnd());
447 } else {
448 pos = stateLoop<nsHtml5FastestPolicy>(state, c, pos, buffer->getBuffer(),
449 false, returnState, buffer->getEnd());
451 if (pos == end) {
452 buffer->setStart(pos);
453 } else {
454 buffer->setStart(pos + 1);
456 return lastCR;
459 template <class P>
460 int32_t nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos,
461 char16_t* buf, bool reconsume,
462 int32_t returnState, int32_t endPos) {
463 bool reportedConsecutiveHyphens = false;
464 stateloop:
465 for (;;) {
466 switch (state) {
467 case DATA: {
468 for (;;) {
469 if (reconsume) {
470 reconsume = false;
471 } else {
472 if (++pos == endPos) {
473 NS_HTML5_BREAK(stateloop);
475 c = P::checkChar(this, buf, pos);
477 switch (c) {
478 case '&': {
479 flushChars(buf, pos);
480 MOZ_ASSERT(!charRefBufLen,
481 "charRefBufLen not reset after previous use!");
482 appendCharRefBuf(c);
483 setAdditionalAndRememberAmpersandLocation('\0');
484 returnState = state;
485 state =
486 P::transition(mViewSource.get(),
487 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
488 reconsume, pos);
489 NS_HTML5_CONTINUE(stateloop);
491 case '<': {
492 flushChars(buf, pos);
493 state = P::transition(mViewSource.get(),
494 nsHtml5Tokenizer::TAG_OPEN, reconsume, pos);
495 NS_HTML5_BREAK(dataloop);
497 case '\0': {
498 maybeEmitReplacementCharacter(buf, pos);
499 continue;
501 case '\r': {
502 emitCarriageReturn<P>(buf, pos);
503 NS_HTML5_BREAK(stateloop);
505 case '\n': {
506 P::silentLineFeed(this);
507 [[fallthrough]];
509 default: {
510 continue;
514 dataloop_end:;
515 [[fallthrough]];
517 case TAG_OPEN: {
518 for (;;) {
519 if (++pos == endPos) {
520 NS_HTML5_BREAK(stateloop);
522 c = P::checkChar(this, buf, pos);
523 if (c >= 'A' && c <= 'Z') {
524 endTag = false;
525 clearStrBufBeforeUse();
526 appendStrBuf((char16_t)(c + 0x20));
527 containsHyphen = false;
528 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
529 reconsume, pos);
530 NS_HTML5_BREAK(tagopenloop);
531 } else if (c >= 'a' && c <= 'z') {
532 endTag = false;
533 clearStrBufBeforeUse();
534 appendStrBuf(c);
535 containsHyphen = false;
536 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
537 reconsume, pos);
538 NS_HTML5_BREAK(tagopenloop);
540 switch (c) {
541 case '!': {
542 state = P::transition(mViewSource.get(),
543 nsHtml5Tokenizer::MARKUP_DECLARATION_OPEN,
544 reconsume, pos);
545 NS_HTML5_CONTINUE(stateloop);
547 case '/': {
548 state = P::transition(mViewSource.get(),
549 nsHtml5Tokenizer::CLOSE_TAG_OPEN, reconsume,
550 pos);
551 NS_HTML5_CONTINUE(stateloop);
553 case '\?': {
554 if (viewingXmlSource) {
555 state = P::transition(mViewSource.get(),
556 nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
557 reconsume, pos);
558 NS_HTML5_CONTINUE(stateloop);
560 if (P::reportErrors) {
561 errProcessingInstruction();
563 clearStrBufBeforeUse();
564 appendStrBuf(c);
565 state = P::transition(mViewSource.get(),
566 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
567 pos);
568 NS_HTML5_CONTINUE(stateloop);
570 case '>': {
571 if (P::reportErrors) {
572 errLtGt();
574 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
575 cstart = pos + 1;
576 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
577 reconsume, pos);
578 NS_HTML5_CONTINUE(stateloop);
580 default: {
581 if (P::reportErrors) {
582 errBadCharAfterLt(c);
584 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
585 cstart = pos;
586 reconsume = true;
587 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
588 reconsume, pos);
589 NS_HTML5_CONTINUE(stateloop);
593 tagopenloop_end:;
594 [[fallthrough]];
596 case TAG_NAME: {
597 for (;;) {
598 if (++pos == endPos) {
599 NS_HTML5_BREAK(stateloop);
601 c = P::checkChar(this, buf, pos);
602 switch (c) {
603 case '\r': {
604 P::silentCarriageReturn(this);
605 strBufToElementNameString();
606 state = P::transition(mViewSource.get(),
607 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
608 reconsume, pos);
609 NS_HTML5_BREAK(stateloop);
611 case '\n': {
612 P::silentLineFeed(this);
613 [[fallthrough]];
615 case ' ':
616 case '\t':
617 case '\f': {
618 strBufToElementNameString();
619 state = P::transition(mViewSource.get(),
620 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
621 reconsume, pos);
622 NS_HTML5_BREAK(tagnameloop);
624 case '/': {
625 strBufToElementNameString();
626 state = P::transition(mViewSource.get(),
627 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
628 reconsume, pos);
629 NS_HTML5_CONTINUE(stateloop);
631 case '>': {
632 strBufToElementNameString();
633 state = P::transition(mViewSource.get(),
634 emitCurrentTagToken(false, pos), reconsume,
635 pos);
636 if (shouldSuspend) {
637 NS_HTML5_BREAK(stateloop);
639 NS_HTML5_CONTINUE(stateloop);
641 case '\0': {
642 c = 0xfffd;
643 [[fallthrough]];
645 default: {
646 if (c >= 'A' && c <= 'Z') {
647 c += 0x20;
648 } else if (c == '-') {
649 containsHyphen = true;
651 appendStrBuf(c);
652 continue;
656 tagnameloop_end:;
657 [[fallthrough]];
659 case BEFORE_ATTRIBUTE_NAME: {
660 for (;;) {
661 if (reconsume) {
662 reconsume = false;
663 } else {
664 if (++pos == endPos) {
665 NS_HTML5_BREAK(stateloop);
667 c = P::checkChar(this, buf, pos);
669 switch (c) {
670 case '\r': {
671 P::silentCarriageReturn(this);
672 NS_HTML5_BREAK(stateloop);
674 case '\n': {
675 P::silentLineFeed(this);
676 [[fallthrough]];
678 case ' ':
679 case '\t':
680 case '\f': {
681 continue;
683 case '/': {
684 state = P::transition(mViewSource.get(),
685 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
686 reconsume, pos);
687 NS_HTML5_CONTINUE(stateloop);
689 case '>': {
690 state = P::transition(mViewSource.get(),
691 emitCurrentTagToken(false, pos), reconsume,
692 pos);
693 if (shouldSuspend) {
694 NS_HTML5_BREAK(stateloop);
696 NS_HTML5_CONTINUE(stateloop);
698 case '\0': {
699 c = 0xfffd;
700 [[fallthrough]];
702 case '\"':
703 case '\'':
704 case '<':
705 case '=': {
706 if (P::reportErrors) {
707 errBadCharBeforeAttributeNameOrNull(c);
709 [[fallthrough]];
711 default: {
712 if (c >= 'A' && c <= 'Z') {
713 c += 0x20;
715 attributeLine = line;
716 clearStrBufBeforeUse();
717 appendStrBuf(c);
718 state = P::transition(mViewSource.get(),
719 nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
720 pos);
721 NS_HTML5_BREAK(beforeattributenameloop);
725 beforeattributenameloop_end:;
726 [[fallthrough]];
728 case ATTRIBUTE_NAME: {
729 for (;;) {
730 if (++pos == endPos) {
731 NS_HTML5_BREAK(stateloop);
733 c = P::checkChar(this, buf, pos);
734 switch (c) {
735 case '\r': {
736 P::silentCarriageReturn(this);
737 attributeNameComplete();
738 state = P::transition(mViewSource.get(),
739 nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
740 reconsume, pos);
741 NS_HTML5_BREAK(stateloop);
743 case '\n': {
744 P::silentLineFeed(this);
745 [[fallthrough]];
747 case ' ':
748 case '\t':
749 case '\f': {
750 attributeNameComplete();
751 state = P::transition(mViewSource.get(),
752 nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
753 reconsume, pos);
754 NS_HTML5_CONTINUE(stateloop);
756 case '/': {
757 attributeNameComplete();
758 addAttributeWithoutValue();
759 state = P::transition(mViewSource.get(),
760 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
761 reconsume, pos);
762 NS_HTML5_CONTINUE(stateloop);
764 case '=': {
765 attributeNameComplete();
766 state = P::transition(mViewSource.get(),
767 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
768 reconsume, pos);
769 NS_HTML5_BREAK(attributenameloop);
771 case '>': {
772 attributeNameComplete();
773 addAttributeWithoutValue();
774 state = P::transition(mViewSource.get(),
775 emitCurrentTagToken(false, pos), reconsume,
776 pos);
777 if (shouldSuspend) {
778 NS_HTML5_BREAK(stateloop);
780 NS_HTML5_CONTINUE(stateloop);
782 case '\0': {
783 c = 0xfffd;
784 [[fallthrough]];
786 case '\"':
787 case '\'':
788 case '<': {
789 if (P::reportErrors) {
790 errQuoteOrLtInAttributeNameOrNull(c);
792 [[fallthrough]];
794 default: {
795 if (c >= 'A' && c <= 'Z') {
796 c += 0x20;
798 appendStrBuf(c);
799 continue;
803 attributenameloop_end:;
804 [[fallthrough]];
806 case BEFORE_ATTRIBUTE_VALUE: {
807 for (;;) {
808 if (++pos == endPos) {
809 NS_HTML5_BREAK(stateloop);
811 c = P::checkChar(this, buf, pos);
812 switch (c) {
813 case '\r': {
814 P::silentCarriageReturn(this);
815 NS_HTML5_BREAK(stateloop);
817 case '\n': {
818 P::silentLineFeed(this);
819 [[fallthrough]];
821 case ' ':
822 case '\t':
823 case '\f': {
824 continue;
826 case '\"': {
827 attributeLine = line;
828 clearStrBufBeforeUse();
829 state =
830 P::transition(mViewSource.get(),
831 nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED,
832 reconsume, pos);
833 NS_HTML5_BREAK(beforeattributevalueloop);
835 case '&': {
836 attributeLine = line;
837 clearStrBufBeforeUse();
838 reconsume = true;
839 state = P::transition(mViewSource.get(),
840 nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
841 reconsume, pos);
843 NS_HTML5_CONTINUE(stateloop);
845 case '\'': {
846 attributeLine = line;
847 clearStrBufBeforeUse();
848 state =
849 P::transition(mViewSource.get(),
850 nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED,
851 reconsume, pos);
852 NS_HTML5_CONTINUE(stateloop);
854 case '>': {
855 if (P::reportErrors) {
856 errAttributeValueMissing();
858 addAttributeWithoutValue();
859 state = P::transition(mViewSource.get(),
860 emitCurrentTagToken(false, pos), reconsume,
861 pos);
862 if (shouldSuspend) {
863 NS_HTML5_BREAK(stateloop);
865 NS_HTML5_CONTINUE(stateloop);
867 case '\0': {
868 c = 0xfffd;
869 [[fallthrough]];
871 case '<':
872 case '=':
873 case '`': {
874 if (P::reportErrors) {
875 errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
877 [[fallthrough]];
879 default: {
880 attributeLine = line;
881 clearStrBufBeforeUse();
882 appendStrBuf(c);
883 state = P::transition(mViewSource.get(),
884 nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
885 reconsume, pos);
887 NS_HTML5_CONTINUE(stateloop);
891 beforeattributevalueloop_end:;
892 [[fallthrough]];
894 case ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
895 for (;;) {
896 if (reconsume) {
897 reconsume = false;
898 } else {
899 if (++pos == endPos) {
900 NS_HTML5_BREAK(stateloop);
902 c = P::checkChar(this, buf, pos);
904 switch (c) {
905 case '\"': {
906 addAttributeWithValue();
907 state =
908 P::transition(mViewSource.get(),
909 nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
910 reconsume, pos);
911 NS_HTML5_BREAK(attributevaluedoublequotedloop);
913 case '&': {
914 MOZ_ASSERT(!charRefBufLen,
915 "charRefBufLen not reset after previous use!");
916 appendCharRefBuf(c);
917 setAdditionalAndRememberAmpersandLocation('\"');
918 returnState = state;
919 state =
920 P::transition(mViewSource.get(),
921 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
922 reconsume, pos);
923 NS_HTML5_CONTINUE(stateloop);
925 case '\r': {
926 appendStrBufCarriageReturn<P>();
927 NS_HTML5_BREAK(stateloop);
929 case '\n': {
930 appendStrBufLineFeed<P>();
931 continue;
933 case '\0': {
934 c = 0xfffd;
935 [[fallthrough]];
937 default: {
938 appendStrBuf(c);
939 continue;
943 attributevaluedoublequotedloop_end:;
944 [[fallthrough]];
946 case AFTER_ATTRIBUTE_VALUE_QUOTED: {
947 for (;;) {
948 if (++pos == endPos) {
949 NS_HTML5_BREAK(stateloop);
951 c = P::checkChar(this, buf, pos);
952 switch (c) {
953 case '\r': {
954 P::silentCarriageReturn(this);
955 state = P::transition(mViewSource.get(),
956 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
957 reconsume, pos);
958 NS_HTML5_BREAK(stateloop);
960 case '\n': {
961 P::silentLineFeed(this);
962 [[fallthrough]];
964 case ' ':
965 case '\t':
966 case '\f': {
967 state = P::transition(mViewSource.get(),
968 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
969 reconsume, pos);
970 NS_HTML5_CONTINUE(stateloop);
972 case '/': {
973 state = P::transition(mViewSource.get(),
974 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
975 reconsume, pos);
976 NS_HTML5_BREAK(afterattributevaluequotedloop);
978 case '>': {
979 state = P::transition(mViewSource.get(),
980 emitCurrentTagToken(false, pos), reconsume,
981 pos);
982 if (shouldSuspend) {
983 NS_HTML5_BREAK(stateloop);
985 NS_HTML5_CONTINUE(stateloop);
987 default: {
988 if (P::reportErrors) {
989 errNoSpaceBetweenAttributes();
991 reconsume = true;
992 state = P::transition(mViewSource.get(),
993 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
994 reconsume, pos);
995 NS_HTML5_CONTINUE(stateloop);
999 afterattributevaluequotedloop_end:;
1000 [[fallthrough]];
1002 case SELF_CLOSING_START_TAG: {
1003 if (++pos == endPos) {
1004 NS_HTML5_BREAK(stateloop);
1006 c = P::checkChar(this, buf, pos);
1007 switch (c) {
1008 case '>': {
1009 state =
1010 P::transition(mViewSource.get(), emitCurrentTagToken(true, pos),
1011 reconsume, pos);
1012 if (shouldSuspend) {
1013 NS_HTML5_BREAK(stateloop);
1015 NS_HTML5_CONTINUE(stateloop);
1017 default: {
1018 if (P::reportErrors) {
1019 errSlashNotFollowedByGt();
1021 reconsume = true;
1022 state = P::transition(mViewSource.get(),
1023 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1024 reconsume, pos);
1025 NS_HTML5_CONTINUE(stateloop);
1029 case ATTRIBUTE_VALUE_UNQUOTED: {
1030 for (;;) {
1031 if (reconsume) {
1032 reconsume = false;
1033 } else {
1034 if (++pos == endPos) {
1035 NS_HTML5_BREAK(stateloop);
1037 c = P::checkChar(this, buf, pos);
1039 switch (c) {
1040 case '\r': {
1041 P::silentCarriageReturn(this);
1042 addAttributeWithValue();
1043 state = P::transition(mViewSource.get(),
1044 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1045 reconsume, pos);
1046 NS_HTML5_BREAK(stateloop);
1048 case '\n': {
1049 P::silentLineFeed(this);
1050 [[fallthrough]];
1052 case ' ':
1053 case '\t':
1054 case '\f': {
1055 addAttributeWithValue();
1056 state = P::transition(mViewSource.get(),
1057 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1058 reconsume, pos);
1059 NS_HTML5_CONTINUE(stateloop);
1061 case '&': {
1062 MOZ_ASSERT(!charRefBufLen,
1063 "charRefBufLen not reset after previous use!");
1064 appendCharRefBuf(c);
1065 setAdditionalAndRememberAmpersandLocation('>');
1066 returnState = state;
1067 state =
1068 P::transition(mViewSource.get(),
1069 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
1070 reconsume, pos);
1071 NS_HTML5_CONTINUE(stateloop);
1073 case '>': {
1074 addAttributeWithValue();
1075 state = P::transition(mViewSource.get(),
1076 emitCurrentTagToken(false, pos), reconsume,
1077 pos);
1078 if (shouldSuspend) {
1079 NS_HTML5_BREAK(stateloop);
1081 NS_HTML5_CONTINUE(stateloop);
1083 case '\0': {
1084 c = 0xfffd;
1085 [[fallthrough]];
1087 case '<':
1088 case '\"':
1089 case '\'':
1090 case '=':
1091 case '`': {
1092 if (P::reportErrors) {
1093 errUnquotedAttributeValOrNull(c);
1095 [[fallthrough]];
1097 default: {
1098 appendStrBuf(c);
1099 continue;
1104 case AFTER_ATTRIBUTE_NAME: {
1105 for (;;) {
1106 if (++pos == endPos) {
1107 NS_HTML5_BREAK(stateloop);
1109 c = P::checkChar(this, buf, pos);
1110 switch (c) {
1111 case '\r': {
1112 P::silentCarriageReturn(this);
1113 NS_HTML5_BREAK(stateloop);
1115 case '\n': {
1116 P::silentLineFeed(this);
1117 [[fallthrough]];
1119 case ' ':
1120 case '\t':
1121 case '\f': {
1122 continue;
1124 case '/': {
1125 addAttributeWithoutValue();
1126 state = P::transition(mViewSource.get(),
1127 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
1128 reconsume, pos);
1129 NS_HTML5_CONTINUE(stateloop);
1131 case '=': {
1132 state = P::transition(mViewSource.get(),
1133 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
1134 reconsume, pos);
1135 NS_HTML5_CONTINUE(stateloop);
1137 case '>': {
1138 addAttributeWithoutValue();
1139 state = P::transition(mViewSource.get(),
1140 emitCurrentTagToken(false, pos), reconsume,
1141 pos);
1142 if (shouldSuspend) {
1143 NS_HTML5_BREAK(stateloop);
1145 NS_HTML5_CONTINUE(stateloop);
1147 case '\0': {
1148 c = 0xfffd;
1149 [[fallthrough]];
1151 case '\"':
1152 case '\'':
1153 case '<': {
1154 if (P::reportErrors) {
1155 errQuoteOrLtInAttributeNameOrNull(c);
1157 [[fallthrough]];
1159 default: {
1160 addAttributeWithoutValue();
1161 if (c >= 'A' && c <= 'Z') {
1162 c += 0x20;
1164 clearStrBufBeforeUse();
1165 appendStrBuf(c);
1166 state = P::transition(mViewSource.get(),
1167 nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
1168 pos);
1169 NS_HTML5_CONTINUE(stateloop);
1174 case MARKUP_DECLARATION_OPEN: {
1175 for (;;) {
1176 if (++pos == endPos) {
1177 NS_HTML5_BREAK(stateloop);
1179 c = P::checkChar(this, buf, pos);
1180 switch (c) {
1181 case '-': {
1182 clearStrBufBeforeUse();
1183 appendStrBuf(c);
1184 state = P::transition(mViewSource.get(),
1185 nsHtml5Tokenizer::MARKUP_DECLARATION_HYPHEN,
1186 reconsume, pos);
1187 NS_HTML5_BREAK(markupdeclarationopenloop);
1189 case 'd':
1190 case 'D': {
1191 clearStrBufBeforeUse();
1192 appendStrBuf(c);
1193 index = 0;
1194 state = P::transition(mViewSource.get(),
1195 nsHtml5Tokenizer::MARKUP_DECLARATION_OCTYPE,
1196 reconsume, pos);
1197 NS_HTML5_CONTINUE(stateloop);
1199 case '[': {
1200 if (tokenHandler->cdataSectionAllowed()) {
1201 clearStrBufBeforeUse();
1202 appendStrBuf(c);
1203 index = 0;
1204 state = P::transition(mViewSource.get(),
1205 nsHtml5Tokenizer::CDATA_START, reconsume,
1206 pos);
1207 NS_HTML5_CONTINUE(stateloop);
1209 [[fallthrough]];
1211 default: {
1212 if (P::reportErrors) {
1213 errBogusComment();
1215 clearStrBufBeforeUse();
1216 reconsume = true;
1217 state = P::transition(mViewSource.get(),
1218 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1219 pos);
1220 NS_HTML5_CONTINUE(stateloop);
1224 markupdeclarationopenloop_end:;
1225 [[fallthrough]];
1227 case MARKUP_DECLARATION_HYPHEN: {
1228 for (;;) {
1229 if (++pos == endPos) {
1230 NS_HTML5_BREAK(stateloop);
1232 c = P::checkChar(this, buf, pos);
1233 switch (c) {
1234 case '-': {
1235 clearStrBufAfterOneHyphen();
1236 state = P::transition(mViewSource.get(),
1237 nsHtml5Tokenizer::COMMENT_START, reconsume,
1238 pos);
1239 NS_HTML5_BREAK(markupdeclarationhyphenloop);
1241 default: {
1242 if (P::reportErrors) {
1243 errBogusComment();
1245 reconsume = true;
1246 state = P::transition(mViewSource.get(),
1247 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1248 pos);
1249 NS_HTML5_CONTINUE(stateloop);
1253 markupdeclarationhyphenloop_end:;
1254 [[fallthrough]];
1256 case COMMENT_START: {
1257 reportedConsecutiveHyphens = false;
1258 for (;;) {
1259 if (++pos == endPos) {
1260 NS_HTML5_BREAK(stateloop);
1262 c = P::checkChar(this, buf, pos);
1263 switch (c) {
1264 case '-': {
1265 appendStrBuf(c);
1266 state = P::transition(mViewSource.get(),
1267 nsHtml5Tokenizer::COMMENT_START_DASH,
1268 reconsume, pos);
1269 NS_HTML5_CONTINUE(stateloop);
1271 case '>': {
1272 if (P::reportErrors) {
1273 errPrematureEndOfComment();
1275 emitComment(0, pos);
1276 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1277 reconsume, pos);
1278 if (shouldSuspend) {
1279 NS_HTML5_BREAK(stateloop);
1281 NS_HTML5_CONTINUE(stateloop);
1283 case '<': {
1284 appendStrBuf(c);
1285 state = P::transition(mViewSource.get(),
1286 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1287 reconsume, pos);
1288 NS_HTML5_CONTINUE(stateloop);
1290 case '\r': {
1291 appendStrBufCarriageReturn<P>();
1292 state = P::transition(mViewSource.get(),
1293 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1294 NS_HTML5_BREAK(stateloop);
1296 case '\n': {
1297 appendStrBufLineFeed<P>();
1298 state = P::transition(mViewSource.get(),
1299 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1300 NS_HTML5_BREAK(commentstartloop);
1302 case '\0': {
1303 c = 0xfffd;
1304 [[fallthrough]];
1306 default: {
1307 appendStrBuf(c);
1308 state = P::transition(mViewSource.get(),
1309 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1310 NS_HTML5_BREAK(commentstartloop);
1314 commentstartloop_end:;
1315 [[fallthrough]];
1317 case COMMENT: {
1318 for (;;) {
1319 if (++pos == endPos) {
1320 NS_HTML5_BREAK(stateloop);
1322 c = P::checkChar(this, buf, pos);
1323 switch (c) {
1324 case '-': {
1325 appendStrBuf(c);
1326 state = P::transition(mViewSource.get(),
1327 nsHtml5Tokenizer::COMMENT_END_DASH,
1328 reconsume, pos);
1329 NS_HTML5_BREAK(commentloop);
1331 case '<': {
1332 appendStrBuf(c);
1333 state = P::transition(mViewSource.get(),
1334 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1335 reconsume, pos);
1336 NS_HTML5_CONTINUE(stateloop);
1338 case '\r': {
1339 appendStrBufCarriageReturn<P>();
1340 NS_HTML5_BREAK(stateloop);
1342 case '\n': {
1343 appendStrBufLineFeed<P>();
1344 continue;
1346 case '\0': {
1347 c = 0xfffd;
1348 [[fallthrough]];
1350 default: {
1351 appendStrBuf(c);
1352 continue;
1356 commentloop_end:;
1357 [[fallthrough]];
1359 case COMMENT_END_DASH: {
1360 for (;;) {
1361 if (++pos == endPos) {
1362 NS_HTML5_BREAK(stateloop);
1364 c = P::checkChar(this, buf, pos);
1365 switch (c) {
1366 case '-': {
1367 appendStrBuf(c);
1368 state =
1369 P::transition(mViewSource.get(),
1370 nsHtml5Tokenizer::COMMENT_END, reconsume, pos);
1371 NS_HTML5_BREAK(commentenddashloop);
1373 case '<': {
1374 appendStrBuf(c);
1375 state = P::transition(mViewSource.get(),
1376 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1377 reconsume, pos);
1378 NS_HTML5_CONTINUE(stateloop);
1380 case '\r': {
1381 appendStrBufCarriageReturn<P>();
1382 state = P::transition(mViewSource.get(),
1383 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1384 NS_HTML5_BREAK(stateloop);
1386 case '\n': {
1387 appendStrBufLineFeed<P>();
1388 state = P::transition(mViewSource.get(),
1389 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1390 NS_HTML5_CONTINUE(stateloop);
1392 case '\0': {
1393 c = 0xfffd;
1394 [[fallthrough]];
1396 default: {
1397 appendStrBuf(c);
1398 state = P::transition(mViewSource.get(),
1399 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1400 NS_HTML5_CONTINUE(stateloop);
1404 commentenddashloop_end:;
1405 [[fallthrough]];
1407 case COMMENT_END: {
1408 for (;;) {
1409 if (++pos == endPos) {
1410 NS_HTML5_BREAK(stateloop);
1412 c = P::checkChar(this, buf, pos);
1413 switch (c) {
1414 case '>': {
1415 emitComment(2, pos);
1416 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1417 reconsume, pos);
1418 if (shouldSuspend) {
1419 NS_HTML5_BREAK(stateloop);
1421 NS_HTML5_CONTINUE(stateloop);
1423 case '-': {
1424 adjustDoubleHyphenAndAppendToStrBufAndErr(
1425 c, reportedConsecutiveHyphens);
1426 reportedConsecutiveHyphens = true;
1427 continue;
1429 case '<': {
1430 appendStrBuf(c);
1431 state = P::transition(mViewSource.get(),
1432 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1433 reconsume, pos);
1434 NS_HTML5_CONTINUE(stateloop);
1436 case '\r': {
1437 adjustDoubleHyphenAndAppendToStrBufCarriageReturn<P>();
1438 state = P::transition(mViewSource.get(),
1439 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1440 NS_HTML5_BREAK(stateloop);
1442 case '\n': {
1443 adjustDoubleHyphenAndAppendToStrBufLineFeed<P>();
1444 state = P::transition(mViewSource.get(),
1445 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1446 NS_HTML5_CONTINUE(stateloop);
1448 case '!': {
1449 appendStrBuf(c);
1450 state = P::transition(mViewSource.get(),
1451 nsHtml5Tokenizer::COMMENT_END_BANG,
1452 reconsume, pos);
1453 NS_HTML5_BREAK(commentendloop);
1455 case '\0': {
1456 c = 0xfffd;
1457 [[fallthrough]];
1459 default: {
1460 adjustDoubleHyphenAndAppendToStrBufAndErr(
1461 c, reportedConsecutiveHyphens);
1462 reportedConsecutiveHyphens = true;
1463 state = P::transition(mViewSource.get(),
1464 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1465 NS_HTML5_CONTINUE(stateloop);
1469 commentendloop_end:;
1470 [[fallthrough]];
1472 case COMMENT_END_BANG: {
1473 for (;;) {
1474 if (++pos == endPos) {
1475 NS_HTML5_BREAK(stateloop);
1477 c = P::checkChar(this, buf, pos);
1478 switch (c) {
1479 case '>': {
1480 emitComment(3, pos);
1481 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1482 reconsume, pos);
1483 if (shouldSuspend) {
1484 NS_HTML5_BREAK(stateloop);
1486 NS_HTML5_CONTINUE(stateloop);
1488 case '-': {
1489 appendStrBuf(c);
1490 state = P::transition(mViewSource.get(),
1491 nsHtml5Tokenizer::COMMENT_END_DASH,
1492 reconsume, pos);
1493 NS_HTML5_CONTINUE(stateloop);
1495 case '\r': {
1496 appendStrBufCarriageReturn<P>();
1497 state = P::transition(mViewSource.get(),
1498 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1499 NS_HTML5_BREAK(stateloop);
1501 case '\n': {
1502 appendStrBufLineFeed<P>();
1503 state = P::transition(mViewSource.get(),
1504 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1505 NS_HTML5_CONTINUE(stateloop);
1507 case '\0': {
1508 c = 0xfffd;
1509 [[fallthrough]];
1511 default: {
1512 appendStrBuf(c);
1513 state = P::transition(mViewSource.get(),
1514 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1515 NS_HTML5_CONTINUE(stateloop);
1520 case COMMENT_LESSTHAN: {
1521 for (;;) {
1522 if (++pos == endPos) {
1523 NS_HTML5_BREAK(stateloop);
1525 c = P::checkChar(this, buf, pos);
1526 switch (c) {
1527 case '!': {
1528 appendStrBuf(c);
1529 state = P::transition(mViewSource.get(),
1530 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG,
1531 reconsume, pos);
1532 NS_HTML5_BREAK(commentlessthanloop);
1534 case '<': {
1535 appendStrBuf(c);
1536 continue;
1538 case '-': {
1539 appendStrBuf(c);
1540 state = P::transition(mViewSource.get(),
1541 nsHtml5Tokenizer::COMMENT_END_DASH,
1542 reconsume, pos);
1543 NS_HTML5_CONTINUE(stateloop);
1545 case '\r': {
1546 appendStrBufCarriageReturn<P>();
1547 state = P::transition(mViewSource.get(),
1548 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1549 NS_HTML5_BREAK(stateloop);
1551 case '\n': {
1552 appendStrBufLineFeed<P>();
1553 state = P::transition(mViewSource.get(),
1554 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1555 NS_HTML5_CONTINUE(stateloop);
1557 case '\0': {
1558 c = 0xfffd;
1559 [[fallthrough]];
1561 default: {
1562 appendStrBuf(c);
1563 state = P::transition(mViewSource.get(),
1564 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1565 NS_HTML5_CONTINUE(stateloop);
1569 commentlessthanloop_end:;
1570 [[fallthrough]];
1572 case COMMENT_LESSTHAN_BANG: {
1573 for (;;) {
1574 if (++pos == endPos) {
1575 NS_HTML5_BREAK(stateloop);
1577 c = P::checkChar(this, buf, pos);
1578 switch (c) {
1579 case '-': {
1580 appendStrBuf(c);
1581 state = P::transition(
1582 mViewSource.get(),
1583 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH, reconsume, pos);
1584 NS_HTML5_BREAK(commentlessthanbangloop);
1586 case '<': {
1587 appendStrBuf(c);
1588 state = P::transition(mViewSource.get(),
1589 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1590 reconsume, pos);
1591 NS_HTML5_CONTINUE(stateloop);
1593 case '\r': {
1594 appendStrBufCarriageReturn<P>();
1595 state = P::transition(mViewSource.get(),
1596 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1597 NS_HTML5_BREAK(stateloop);
1599 case '\n': {
1600 appendStrBufLineFeed<P>();
1601 state = P::transition(mViewSource.get(),
1602 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1603 NS_HTML5_CONTINUE(stateloop);
1605 case '\0': {
1606 c = 0xfffd;
1607 [[fallthrough]];
1609 default: {
1610 appendStrBuf(c);
1611 state = P::transition(mViewSource.get(),
1612 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1613 NS_HTML5_CONTINUE(stateloop);
1617 commentlessthanbangloop_end:;
1618 [[fallthrough]];
1620 case COMMENT_LESSTHAN_BANG_DASH: {
1621 if (++pos == endPos) {
1622 NS_HTML5_BREAK(stateloop);
1624 c = P::checkChar(this, buf, pos);
1625 switch (c) {
1626 case '-': {
1627 appendStrBuf(c);
1628 state =
1629 P::transition(mViewSource.get(),
1630 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH,
1631 reconsume, pos);
1632 break;
1634 case '<': {
1635 appendStrBuf(c);
1636 state = P::transition(mViewSource.get(),
1637 nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
1638 pos);
1639 NS_HTML5_CONTINUE(stateloop);
1641 case '\r': {
1642 appendStrBufCarriageReturn<P>();
1643 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1644 reconsume, pos);
1645 NS_HTML5_BREAK(stateloop);
1647 case '\n': {
1648 appendStrBufLineFeed<P>();
1649 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1650 reconsume, pos);
1651 NS_HTML5_CONTINUE(stateloop);
1653 case '\0': {
1654 c = 0xfffd;
1655 [[fallthrough]];
1657 default: {
1658 appendStrBuf(c);
1659 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1660 reconsume, pos);
1661 NS_HTML5_CONTINUE(stateloop);
1664 [[fallthrough]];
1666 case COMMENT_LESSTHAN_BANG_DASH_DASH: {
1667 if (++pos == endPos) {
1668 NS_HTML5_BREAK(stateloop);
1670 c = P::checkChar(this, buf, pos);
1671 switch (c) {
1672 case '>': {
1673 appendStrBuf(c);
1674 emitComment(3, pos);
1675 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1676 reconsume, pos);
1677 if (shouldSuspend) {
1678 NS_HTML5_BREAK(stateloop);
1680 NS_HTML5_CONTINUE(stateloop);
1682 case '-': {
1683 if (P::reportErrors) {
1684 errNestedComment();
1686 adjustDoubleHyphenAndAppendToStrBufAndErr(
1687 c, reportedConsecutiveHyphens);
1688 reportedConsecutiveHyphens = true;
1689 state =
1690 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
1691 reconsume, pos);
1692 NS_HTML5_CONTINUE(stateloop);
1694 case '\r': {
1695 c = '\n';
1696 P::silentCarriageReturn(this);
1697 if (P::reportErrors) {
1698 errNestedComment();
1700 adjustDoubleHyphenAndAppendToStrBufAndErr(
1701 c, reportedConsecutiveHyphens);
1702 reportedConsecutiveHyphens = true;
1703 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1704 reconsume, pos);
1705 NS_HTML5_BREAK(stateloop);
1707 case '\n': {
1708 P::silentLineFeed(this);
1709 if (P::reportErrors) {
1710 errNestedComment();
1712 adjustDoubleHyphenAndAppendToStrBufAndErr(
1713 c, reportedConsecutiveHyphens);
1714 reportedConsecutiveHyphens = true;
1715 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1716 reconsume, pos);
1717 NS_HTML5_CONTINUE(stateloop);
1719 case '!': {
1720 if (P::reportErrors) {
1721 errNestedComment();
1723 adjustDoubleHyphenAndAppendToStrBufAndErr(
1724 c, reportedConsecutiveHyphens);
1725 reportedConsecutiveHyphens = true;
1726 state = P::transition(mViewSource.get(),
1727 nsHtml5Tokenizer::COMMENT_END_BANG, reconsume,
1728 pos);
1729 NS_HTML5_CONTINUE(stateloop);
1731 case '\0': {
1732 c = 0xfffd;
1733 [[fallthrough]];
1735 default: {
1736 if (P::reportErrors) {
1737 errNestedComment();
1739 adjustDoubleHyphenAndAppendToStrBufAndErr(
1740 c, reportedConsecutiveHyphens);
1741 reportedConsecutiveHyphens = true;
1742 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1743 reconsume, pos);
1744 NS_HTML5_CONTINUE(stateloop);
1748 case COMMENT_START_DASH: {
1749 if (++pos == endPos) {
1750 NS_HTML5_BREAK(stateloop);
1752 c = P::checkChar(this, buf, pos);
1753 switch (c) {
1754 case '-': {
1755 appendStrBuf(c);
1756 state =
1757 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
1758 reconsume, pos);
1759 NS_HTML5_CONTINUE(stateloop);
1761 case '>': {
1762 if (P::reportErrors) {
1763 errPrematureEndOfComment();
1765 emitComment(1, pos);
1766 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1767 reconsume, pos);
1768 if (shouldSuspend) {
1769 NS_HTML5_BREAK(stateloop);
1771 NS_HTML5_CONTINUE(stateloop);
1773 case '<': {
1774 appendStrBuf(c);
1775 state = P::transition(mViewSource.get(),
1776 nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
1777 pos);
1778 NS_HTML5_CONTINUE(stateloop);
1780 case '\r': {
1781 appendStrBufCarriageReturn<P>();
1782 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1783 reconsume, pos);
1784 NS_HTML5_BREAK(stateloop);
1786 case '\n': {
1787 appendStrBufLineFeed<P>();
1788 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1789 reconsume, pos);
1790 NS_HTML5_CONTINUE(stateloop);
1792 case '\0': {
1793 c = 0xfffd;
1794 [[fallthrough]];
1796 default: {
1797 appendStrBuf(c);
1798 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1799 reconsume, pos);
1800 NS_HTML5_CONTINUE(stateloop);
1804 case CDATA_START: {
1805 for (;;) {
1806 if (++pos == endPos) {
1807 NS_HTML5_BREAK(stateloop);
1809 c = P::checkChar(this, buf, pos);
1810 if (index < 6) {
1811 if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
1812 appendStrBuf(c);
1813 } else {
1814 if (P::reportErrors) {
1815 errBogusComment();
1817 reconsume = true;
1818 state = P::transition(mViewSource.get(),
1819 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1820 pos);
1821 NS_HTML5_CONTINUE(stateloop);
1823 index++;
1824 continue;
1825 } else {
1826 clearStrBufAfterUse();
1827 cstart = pos;
1828 reconsume = true;
1829 state =
1830 P::transition(mViewSource.get(),
1831 nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
1832 break;
1835 [[fallthrough]];
1837 case CDATA_SECTION: {
1838 for (;;) {
1839 if (reconsume) {
1840 reconsume = false;
1841 } else {
1842 if (++pos == endPos) {
1843 NS_HTML5_BREAK(stateloop);
1845 c = P::checkChar(this, buf, pos);
1847 switch (c) {
1848 case ']': {
1849 flushChars(buf, pos);
1850 state =
1851 P::transition(mViewSource.get(), nsHtml5Tokenizer::CDATA_RSQB,
1852 reconsume, pos);
1853 NS_HTML5_BREAK(cdatasectionloop);
1855 case '\0': {
1856 maybeEmitReplacementCharacter(buf, pos);
1857 continue;
1859 case '\r': {
1860 emitCarriageReturn<P>(buf, pos);
1861 NS_HTML5_BREAK(stateloop);
1863 case '\n': {
1864 P::silentLineFeed(this);
1865 [[fallthrough]];
1867 default: {
1868 continue;
1872 cdatasectionloop_end:;
1873 [[fallthrough]];
1875 case CDATA_RSQB: {
1876 if (++pos == endPos) {
1877 NS_HTML5_BREAK(stateloop);
1879 c = P::checkChar(this, buf, pos);
1880 switch (c) {
1881 case ']': {
1882 state = P::transition(mViewSource.get(),
1883 nsHtml5Tokenizer::CDATA_RSQB_RSQB, reconsume,
1884 pos);
1885 break;
1887 default: {
1888 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
1889 cstart = pos;
1890 reconsume = true;
1891 state =
1892 P::transition(mViewSource.get(),
1893 nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
1894 NS_HTML5_CONTINUE(stateloop);
1897 [[fallthrough]];
1899 case CDATA_RSQB_RSQB: {
1900 for (;;) {
1901 if (++pos == endPos) {
1902 NS_HTML5_BREAK(stateloop);
1904 c = P::checkChar(this, buf, pos);
1905 switch (c) {
1906 case ']': {
1907 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
1908 continue;
1910 case '>': {
1911 cstart = pos + 1;
1912 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1913 reconsume, pos);
1914 suspendIfRequestedAfterCurrentNonTextToken();
1915 if (shouldSuspend) {
1916 NS_HTML5_BREAK(stateloop);
1918 NS_HTML5_CONTINUE(stateloop);
1920 default: {
1921 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
1922 cstart = pos;
1923 reconsume = true;
1924 state = P::transition(mViewSource.get(),
1925 nsHtml5Tokenizer::CDATA_SECTION, reconsume,
1926 pos);
1927 NS_HTML5_CONTINUE(stateloop);
1932 case ATTRIBUTE_VALUE_SINGLE_QUOTED: {
1933 for (;;) {
1934 if (reconsume) {
1935 reconsume = false;
1936 } else {
1937 if (++pos == endPos) {
1938 NS_HTML5_BREAK(stateloop);
1940 c = P::checkChar(this, buf, pos);
1942 switch (c) {
1943 case '\'': {
1944 addAttributeWithValue();
1945 state =
1946 P::transition(mViewSource.get(),
1947 nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
1948 reconsume, pos);
1949 NS_HTML5_CONTINUE(stateloop);
1951 case '&': {
1952 MOZ_ASSERT(!charRefBufLen,
1953 "charRefBufLen not reset after previous use!");
1954 appendCharRefBuf(c);
1955 setAdditionalAndRememberAmpersandLocation('\'');
1956 returnState = state;
1957 state =
1958 P::transition(mViewSource.get(),
1959 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
1960 reconsume, pos);
1961 NS_HTML5_BREAK(attributevaluesinglequotedloop);
1963 case '\r': {
1964 appendStrBufCarriageReturn<P>();
1965 NS_HTML5_BREAK(stateloop);
1967 case '\n': {
1968 appendStrBufLineFeed<P>();
1969 continue;
1971 case '\0': {
1972 c = 0xfffd;
1973 [[fallthrough]];
1975 default: {
1976 appendStrBuf(c);
1977 continue;
1981 attributevaluesinglequotedloop_end:;
1982 [[fallthrough]];
1984 case CONSUME_CHARACTER_REFERENCE: {
1985 if (++pos == endPos) {
1986 NS_HTML5_BREAK(stateloop);
1988 c = P::checkChar(this, buf, pos);
1989 switch (c) {
1990 case ' ':
1991 case '\t':
1992 case '\n':
1993 case '\r':
1994 case '\f':
1995 case '<':
1996 case '&':
1997 case '\0':
1998 case ';': {
1999 emitOrAppendCharRefBuf(returnState);
2000 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2001 cstart = pos;
2003 reconsume = true;
2004 state =
2005 P::transition(mViewSource.get(), returnState, reconsume, pos);
2006 NS_HTML5_CONTINUE(stateloop);
2008 case '#': {
2009 appendCharRefBuf('#');
2010 state =
2011 P::transition(mViewSource.get(), nsHtml5Tokenizer::CONSUME_NCR,
2012 reconsume, pos);
2013 NS_HTML5_CONTINUE(stateloop);
2015 default: {
2016 if (c == additional) {
2017 emitOrAppendCharRefBuf(returnState);
2018 reconsume = true;
2019 state =
2020 P::transition(mViewSource.get(), returnState, reconsume, pos);
2021 NS_HTML5_CONTINUE(stateloop);
2023 if (c >= 'a' && c <= 'z') {
2024 firstCharKey = c - 'a' + 26;
2025 } else if (c >= 'A' && c <= 'Z') {
2026 firstCharKey = c - 'A';
2027 } else {
2028 if (c == ';') {
2029 if (P::reportErrors) {
2030 errNoNamedCharacterMatch();
2033 emitOrAppendCharRefBuf(returnState);
2034 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2035 cstart = pos;
2037 reconsume = true;
2038 state =
2039 P::transition(mViewSource.get(), returnState, reconsume, pos);
2040 NS_HTML5_CONTINUE(stateloop);
2042 appendCharRefBuf(c);
2043 state =
2044 P::transition(mViewSource.get(),
2045 nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP,
2046 reconsume, pos);
2047 break;
2050 [[fallthrough]];
2052 case CHARACTER_REFERENCE_HILO_LOOKUP: {
2054 if (++pos == endPos) {
2055 NS_HTML5_BREAK(stateloop);
2057 c = P::checkChar(this, buf, pos);
2058 int32_t hilo = 0;
2059 if (c <= 'z') {
2060 const int32_t* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c];
2061 if (row) {
2062 hilo = row[firstCharKey];
2065 if (!hilo) {
2066 if (c == ';') {
2067 if (P::reportErrors) {
2068 errNoNamedCharacterMatch();
2071 emitOrAppendCharRefBuf(returnState);
2072 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2073 cstart = pos;
2075 reconsume = true;
2076 state =
2077 P::transition(mViewSource.get(), returnState, reconsume, pos);
2078 NS_HTML5_CONTINUE(stateloop);
2080 appendCharRefBuf(c);
2081 lo = hilo & 0xFFFF;
2082 hi = hilo >> 16;
2083 entCol = -1;
2084 candidate = -1;
2085 charRefBufMark = 0;
2086 state = P::transition(mViewSource.get(),
2087 nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL,
2088 reconsume, pos);
2090 [[fallthrough]];
2092 case CHARACTER_REFERENCE_TAIL: {
2093 for (;;) {
2094 if (++pos == endPos) {
2095 NS_HTML5_BREAK(stateloop);
2097 c = P::checkChar(this, buf, pos);
2098 entCol++;
2099 for (;;) {
2100 if (hi < lo) {
2101 NS_HTML5_BREAK(outer);
2103 if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
2104 candidate = lo;
2105 charRefBufMark = charRefBufLen;
2106 lo++;
2107 } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
2108 NS_HTML5_BREAK(outer);
2109 } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
2110 lo++;
2111 } else {
2112 NS_HTML5_BREAK(loloop);
2115 loloop_end:;
2116 for (;;) {
2117 if (hi < lo) {
2118 NS_HTML5_BREAK(outer);
2120 if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
2121 NS_HTML5_BREAK(hiloop);
2123 if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
2124 NS_HTML5_BREAK(outer);
2125 } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
2126 hi--;
2127 } else {
2128 NS_HTML5_BREAK(hiloop);
2131 hiloop_end:;
2132 if (c == ';') {
2133 if (entCol + 1 == nsHtml5NamedCharacters::NAMES[lo].length()) {
2134 candidate = lo;
2135 charRefBufMark = charRefBufLen;
2137 NS_HTML5_BREAK(outer);
2139 if (hi < lo) {
2140 NS_HTML5_BREAK(outer);
2142 appendCharRefBuf(c);
2143 continue;
2145 outer_end:;
2146 if (candidate == -1) {
2147 if (c == ';') {
2148 if (P::reportErrors) {
2149 errNoNamedCharacterMatch();
2152 emitOrAppendCharRefBuf(returnState);
2153 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2154 cstart = pos;
2156 reconsume = true;
2157 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2158 NS_HTML5_CONTINUE(stateloop);
2159 } else {
2160 const nsHtml5CharacterName& candidateName =
2161 nsHtml5NamedCharacters::NAMES[candidate];
2162 if (!candidateName.length() ||
2163 candidateName.charAt(candidateName.length() - 1) != ';') {
2164 if ((returnState & DATA_AND_RCDATA_MASK)) {
2165 char16_t ch;
2166 if (charRefBufMark == charRefBufLen) {
2167 ch = c;
2168 } else {
2169 ch = charRefBuf[charRefBufMark];
2171 if (ch == '=' || (ch >= '0' && ch <= '9') ||
2172 (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
2173 if (c == ';') {
2174 if (P::reportErrors) {
2175 errNoNamedCharacterMatch();
2178 appendCharRefBufToStrBuf();
2179 reconsume = true;
2180 state = P::transition(mViewSource.get(), returnState, reconsume,
2181 pos);
2182 NS_HTML5_CONTINUE(stateloop);
2185 if ((returnState & DATA_AND_RCDATA_MASK)) {
2186 if (P::reportErrors) {
2187 errUnescapedAmpersandInterpretedAsCharacterReference();
2189 } else {
2190 if (P::reportErrors) {
2191 errNotSemicolonTerminated();
2195 P::completedNamedCharacterReference(mViewSource.get());
2196 const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
2197 if (!val[1]) {
2198 emitOrAppendOne(val, returnState);
2199 } else {
2200 emitOrAppendTwo(val, returnState);
2202 if (charRefBufMark < charRefBufLen) {
2203 if ((returnState & DATA_AND_RCDATA_MASK)) {
2204 appendStrBuf(charRefBuf, charRefBufMark,
2205 charRefBufLen - charRefBufMark);
2206 } else {
2207 tokenHandler->characters(charRefBuf, charRefBufMark,
2208 charRefBufLen - charRefBufMark);
2211 bool earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
2212 charRefBufLen = 0;
2213 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2214 cstart = earlyBreak ? pos + 1 : pos;
2216 reconsume = !earlyBreak;
2217 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2218 NS_HTML5_CONTINUE(stateloop);
2221 case CONSUME_NCR: {
2222 if (++pos == endPos) {
2223 NS_HTML5_BREAK(stateloop);
2225 c = P::checkChar(this, buf, pos);
2226 value = 0;
2227 seenDigits = false;
2228 switch (c) {
2229 case 'x':
2230 case 'X': {
2231 appendCharRefBuf(c);
2232 state =
2233 P::transition(mViewSource.get(), nsHtml5Tokenizer::HEX_NCR_LOOP,
2234 reconsume, pos);
2235 NS_HTML5_CONTINUE(stateloop);
2237 default: {
2238 reconsume = true;
2239 state = P::transition(mViewSource.get(),
2240 nsHtml5Tokenizer::DECIMAL_NRC_LOOP, reconsume,
2241 pos);
2242 break;
2245 [[fallthrough]];
2247 case DECIMAL_NRC_LOOP: {
2248 for (;;) {
2249 if (reconsume) {
2250 reconsume = false;
2251 } else {
2252 if (++pos == endPos) {
2253 NS_HTML5_BREAK(stateloop);
2255 c = P::checkChar(this, buf, pos);
2257 MOZ_ASSERT(value >= 0, "value must not become negative.");
2258 if (c >= '0' && c <= '9') {
2259 seenDigits = true;
2260 if (value <= 0x10FFFF) {
2261 value *= 10;
2262 value += c - '0';
2264 continue;
2265 } else if (c == ';') {
2266 if (seenDigits) {
2267 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2268 cstart = pos + 1;
2270 state = P::transition(mViewSource.get(),
2271 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2272 reconsume, pos);
2273 NS_HTML5_BREAK(decimalloop);
2274 } else {
2275 if (P::reportErrors) {
2276 errNoDigitsInNCR();
2278 appendCharRefBuf(';');
2279 emitOrAppendCharRefBuf(returnState);
2280 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2281 cstart = pos + 1;
2283 state =
2284 P::transition(mViewSource.get(), returnState, reconsume, pos);
2285 NS_HTML5_CONTINUE(stateloop);
2287 } else {
2288 if (!seenDigits) {
2289 if (P::reportErrors) {
2290 errNoDigitsInNCR();
2292 emitOrAppendCharRefBuf(returnState);
2293 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2294 cstart = pos;
2296 reconsume = true;
2297 state =
2298 P::transition(mViewSource.get(), returnState, reconsume, pos);
2299 NS_HTML5_CONTINUE(stateloop);
2300 } else {
2301 if (P::reportErrors) {
2302 errCharRefLacksSemicolon();
2304 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2305 cstart = pos;
2307 reconsume = true;
2308 state = P::transition(mViewSource.get(),
2309 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2310 reconsume, pos);
2311 NS_HTML5_BREAK(decimalloop);
2315 decimalloop_end:;
2316 [[fallthrough]];
2318 case HANDLE_NCR_VALUE: {
2319 charRefBufLen = 0;
2320 handleNcrValue(returnState);
2321 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2322 NS_HTML5_CONTINUE(stateloop);
2324 case HEX_NCR_LOOP: {
2325 for (;;) {
2326 if (++pos == endPos) {
2327 NS_HTML5_BREAK(stateloop);
2329 c = P::checkChar(this, buf, pos);
2330 MOZ_ASSERT(value >= 0, "value must not become negative.");
2331 if (c >= '0' && c <= '9') {
2332 seenDigits = true;
2333 if (value <= 0x10FFFF) {
2334 value *= 16;
2335 value += c - '0';
2337 continue;
2338 } else if (c >= 'A' && c <= 'F') {
2339 seenDigits = true;
2340 if (value <= 0x10FFFF) {
2341 value *= 16;
2342 value += c - 'A' + 10;
2344 continue;
2345 } else if (c >= 'a' && c <= 'f') {
2346 seenDigits = true;
2347 if (value <= 0x10FFFF) {
2348 value *= 16;
2349 value += c - 'a' + 10;
2351 continue;
2352 } else if (c == ';') {
2353 if (seenDigits) {
2354 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2355 cstart = pos + 1;
2357 state = P::transition(mViewSource.get(),
2358 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2359 reconsume, pos);
2360 NS_HTML5_CONTINUE(stateloop);
2361 } else {
2362 if (P::reportErrors) {
2363 errNoDigitsInNCR();
2365 appendCharRefBuf(';');
2366 emitOrAppendCharRefBuf(returnState);
2367 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2368 cstart = pos + 1;
2370 state =
2371 P::transition(mViewSource.get(), returnState, reconsume, pos);
2372 NS_HTML5_CONTINUE(stateloop);
2374 } else {
2375 if (!seenDigits) {
2376 if (P::reportErrors) {
2377 errNoDigitsInNCR();
2379 emitOrAppendCharRefBuf(returnState);
2380 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2381 cstart = pos;
2383 reconsume = true;
2384 state =
2385 P::transition(mViewSource.get(), returnState, reconsume, pos);
2386 NS_HTML5_CONTINUE(stateloop);
2387 } else {
2388 if (P::reportErrors) {
2389 errCharRefLacksSemicolon();
2391 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2392 cstart = pos;
2394 reconsume = true;
2395 state = P::transition(mViewSource.get(),
2396 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2397 reconsume, pos);
2398 NS_HTML5_CONTINUE(stateloop);
2403 case PLAINTEXT: {
2404 for (;;) {
2405 if (reconsume) {
2406 reconsume = false;
2407 } else {
2408 if (++pos == endPos) {
2409 NS_HTML5_BREAK(stateloop);
2411 c = P::checkChar(this, buf, pos);
2413 switch (c) {
2414 case '\0': {
2415 emitPlaintextReplacementCharacter(buf, pos);
2416 continue;
2418 case '\r': {
2419 emitCarriageReturn<P>(buf, pos);
2420 NS_HTML5_BREAK(stateloop);
2422 case '\n': {
2423 P::silentLineFeed(this);
2424 [[fallthrough]];
2426 default: {
2427 continue;
2432 case CLOSE_TAG_OPEN: {
2433 if (++pos == endPos) {
2434 NS_HTML5_BREAK(stateloop);
2436 c = P::checkChar(this, buf, pos);
2437 switch (c) {
2438 case '>': {
2439 if (P::reportErrors) {
2440 errLtSlashGt();
2442 cstart = pos + 1;
2443 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2444 reconsume, pos);
2445 NS_HTML5_CONTINUE(stateloop);
2447 case '\r': {
2448 P::silentCarriageReturn(this);
2449 if (P::reportErrors) {
2450 errGarbageAfterLtSlash();
2452 clearStrBufBeforeUse();
2453 appendStrBuf('\n');
2454 state =
2455 P::transition(mViewSource.get(),
2456 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
2457 NS_HTML5_BREAK(stateloop);
2459 case '\n': {
2460 P::silentLineFeed(this);
2461 if (P::reportErrors) {
2462 errGarbageAfterLtSlash();
2464 clearStrBufBeforeUse();
2465 appendStrBuf(c);
2466 state =
2467 P::transition(mViewSource.get(),
2468 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
2469 NS_HTML5_CONTINUE(stateloop);
2471 case '\0': {
2472 c = 0xfffd;
2473 [[fallthrough]];
2475 default: {
2476 if (c >= 'A' && c <= 'Z') {
2477 c += 0x20;
2479 if (c >= 'a' && c <= 'z') {
2480 endTag = true;
2481 clearStrBufBeforeUse();
2482 appendStrBuf(c);
2483 containsHyphen = false;
2484 state = P::transition(mViewSource.get(),
2485 nsHtml5Tokenizer::TAG_NAME, reconsume, pos);
2486 NS_HTML5_CONTINUE(stateloop);
2487 } else {
2488 if (P::reportErrors) {
2489 errGarbageAfterLtSlash();
2491 clearStrBufBeforeUse();
2492 appendStrBuf(c);
2493 state = P::transition(mViewSource.get(),
2494 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2495 pos);
2496 NS_HTML5_CONTINUE(stateloop);
2501 case RCDATA: {
2502 for (;;) {
2503 if (reconsume) {
2504 reconsume = false;
2505 } else {
2506 if (++pos == endPos) {
2507 NS_HTML5_BREAK(stateloop);
2509 c = P::checkChar(this, buf, pos);
2511 switch (c) {
2512 case '&': {
2513 flushChars(buf, pos);
2514 MOZ_ASSERT(!charRefBufLen,
2515 "charRefBufLen not reset after previous use!");
2516 appendCharRefBuf(c);
2517 setAdditionalAndRememberAmpersandLocation('\0');
2518 returnState = state;
2519 state =
2520 P::transition(mViewSource.get(),
2521 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
2522 reconsume, pos);
2523 NS_HTML5_CONTINUE(stateloop);
2525 case '<': {
2526 flushChars(buf, pos);
2527 returnState = state;
2528 state =
2529 P::transition(mViewSource.get(),
2530 nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
2531 reconsume, pos);
2532 NS_HTML5_CONTINUE(stateloop);
2534 case '\0': {
2535 emitReplacementCharacter(buf, pos);
2536 continue;
2538 case '\r': {
2539 emitCarriageReturn<P>(buf, pos);
2540 NS_HTML5_BREAK(stateloop);
2542 case '\n': {
2543 P::silentLineFeed(this);
2544 [[fallthrough]];
2546 default: {
2547 continue;
2552 case RAWTEXT: {
2553 for (;;) {
2554 if (reconsume) {
2555 reconsume = false;
2556 } else {
2557 if (++pos == endPos) {
2558 NS_HTML5_BREAK(stateloop);
2560 c = P::checkChar(this, buf, pos);
2562 switch (c) {
2563 case '<': {
2564 flushChars(buf, pos);
2565 returnState = state;
2566 state =
2567 P::transition(mViewSource.get(),
2568 nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
2569 reconsume, pos);
2570 NS_HTML5_BREAK(rawtextloop);
2572 case '\0': {
2573 emitReplacementCharacter(buf, pos);
2574 continue;
2576 case '\r': {
2577 emitCarriageReturn<P>(buf, pos);
2578 NS_HTML5_BREAK(stateloop);
2580 case '\n': {
2581 P::silentLineFeed(this);
2582 [[fallthrough]];
2584 default: {
2585 continue;
2589 rawtextloop_end:;
2590 [[fallthrough]];
2592 case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
2593 for (;;) {
2594 if (++pos == endPos) {
2595 NS_HTML5_BREAK(stateloop);
2597 c = P::checkChar(this, buf, pos);
2598 switch (c) {
2599 case '/': {
2600 index = 0;
2601 clearStrBufBeforeUse();
2602 state = P::transition(mViewSource.get(),
2603 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
2604 reconsume, pos);
2605 NS_HTML5_BREAK(rawtextrcdatalessthansignloop);
2607 default: {
2608 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2609 cstart = pos;
2610 reconsume = true;
2611 state =
2612 P::transition(mViewSource.get(), returnState, reconsume, pos);
2613 NS_HTML5_CONTINUE(stateloop);
2617 rawtextrcdatalessthansignloop_end:;
2618 [[fallthrough]];
2620 case NON_DATA_END_TAG_NAME: {
2621 for (;;) {
2622 if (++pos == endPos) {
2623 NS_HTML5_BREAK(stateloop);
2625 c = P::checkChar(this, buf, pos);
2626 if (!endTagExpectationAsArray) {
2627 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2628 cstart = pos;
2629 reconsume = true;
2630 state =
2631 P::transition(mViewSource.get(), returnState, reconsume, pos);
2632 NS_HTML5_CONTINUE(stateloop);
2633 } else if (index < endTagExpectationAsArray.length) {
2634 char16_t e = endTagExpectationAsArray[index];
2635 char16_t folded = c;
2636 if (c >= 'A' && c <= 'Z') {
2637 folded += 0x20;
2639 if (folded != e) {
2640 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2641 emitStrBuf();
2642 cstart = pos;
2643 reconsume = true;
2644 state =
2645 P::transition(mViewSource.get(), returnState, reconsume, pos);
2646 NS_HTML5_CONTINUE(stateloop);
2648 appendStrBuf(c);
2649 index++;
2650 continue;
2651 } else {
2652 endTag = true;
2653 tagName = endTagExpectation;
2654 switch (c) {
2655 case '\r': {
2656 P::silentCarriageReturn(this);
2657 clearStrBufAfterUse();
2658 state = P::transition(mViewSource.get(),
2659 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
2660 reconsume, pos);
2661 NS_HTML5_BREAK(stateloop);
2663 case '\n': {
2664 P::silentLineFeed(this);
2665 [[fallthrough]];
2667 case ' ':
2668 case '\t':
2669 case '\f': {
2670 clearStrBufAfterUse();
2671 state = P::transition(mViewSource.get(),
2672 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
2673 reconsume, pos);
2674 NS_HTML5_CONTINUE(stateloop);
2676 case '/': {
2677 clearStrBufAfterUse();
2678 state = P::transition(mViewSource.get(),
2679 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
2680 reconsume, pos);
2681 NS_HTML5_CONTINUE(stateloop);
2683 case '>': {
2684 clearStrBufAfterUse();
2685 state = P::transition(mViewSource.get(),
2686 emitCurrentTagToken(false, pos),
2687 reconsume, pos);
2688 if (shouldSuspend) {
2689 NS_HTML5_BREAK(stateloop);
2691 NS_HTML5_CONTINUE(stateloop);
2693 default: {
2694 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2695 emitStrBuf();
2696 cstart = pos;
2697 reconsume = true;
2698 state = P::transition(mViewSource.get(), returnState, reconsume,
2699 pos);
2700 NS_HTML5_CONTINUE(stateloop);
2706 case BOGUS_COMMENT: {
2707 for (;;) {
2708 if (reconsume) {
2709 reconsume = false;
2710 } else {
2711 if (++pos == endPos) {
2712 NS_HTML5_BREAK(stateloop);
2714 c = P::checkChar(this, buf, pos);
2716 switch (c) {
2717 case '>': {
2718 emitComment(0, pos);
2719 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2720 reconsume, pos);
2721 if (shouldSuspend) {
2722 NS_HTML5_BREAK(stateloop);
2724 NS_HTML5_CONTINUE(stateloop);
2726 case '-': {
2727 appendStrBuf(c);
2728 state = P::transition(mViewSource.get(),
2729 nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN,
2730 reconsume, pos);
2731 NS_HTML5_BREAK(boguscommentloop);
2733 case '\r': {
2734 appendStrBufCarriageReturn<P>();
2735 NS_HTML5_BREAK(stateloop);
2737 case '\n': {
2738 appendStrBufLineFeed<P>();
2739 continue;
2741 case '\0': {
2742 c = 0xfffd;
2743 [[fallthrough]];
2745 default: {
2746 appendStrBuf(c);
2747 continue;
2751 boguscommentloop_end:;
2752 [[fallthrough]];
2754 case BOGUS_COMMENT_HYPHEN: {
2755 boguscommenthyphenloop:
2756 for (;;) {
2757 if (++pos == endPos) {
2758 NS_HTML5_BREAK(stateloop);
2760 c = P::checkChar(this, buf, pos);
2761 switch (c) {
2762 case '>': {
2763 emitComment(0, pos);
2764 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2765 reconsume, pos);
2766 if (shouldSuspend) {
2767 NS_HTML5_BREAK(stateloop);
2769 NS_HTML5_CONTINUE(stateloop);
2771 case '-': {
2772 appendSecondHyphenToBogusComment();
2773 NS_HTML5_CONTINUE(boguscommenthyphenloop);
2775 case '\r': {
2776 appendStrBufCarriageReturn<P>();
2777 state = P::transition(mViewSource.get(),
2778 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2779 pos);
2780 NS_HTML5_BREAK(stateloop);
2782 case '\n': {
2783 appendStrBufLineFeed<P>();
2784 state = P::transition(mViewSource.get(),
2785 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2786 pos);
2787 NS_HTML5_CONTINUE(stateloop);
2789 case '\0': {
2790 c = 0xfffd;
2791 [[fallthrough]];
2793 default: {
2794 appendStrBuf(c);
2795 state = P::transition(mViewSource.get(),
2796 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2797 pos);
2798 NS_HTML5_CONTINUE(stateloop);
2803 case SCRIPT_DATA: {
2804 for (;;) {
2805 if (reconsume) {
2806 reconsume = false;
2807 } else {
2808 if (++pos == endPos) {
2809 NS_HTML5_BREAK(stateloop);
2811 c = P::checkChar(this, buf, pos);
2813 switch (c) {
2814 case '<': {
2815 flushChars(buf, pos);
2816 returnState = state;
2817 state = P::transition(
2818 mViewSource.get(),
2819 nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos);
2820 NS_HTML5_BREAK(scriptdataloop);
2822 case '\0': {
2823 emitReplacementCharacter(buf, pos);
2824 continue;
2826 case '\r': {
2827 emitCarriageReturn<P>(buf, pos);
2828 NS_HTML5_BREAK(stateloop);
2830 case '\n': {
2831 P::silentLineFeed(this);
2832 [[fallthrough]];
2834 default: {
2835 continue;
2839 scriptdataloop_end:;
2840 [[fallthrough]];
2842 case SCRIPT_DATA_LESS_THAN_SIGN: {
2843 for (;;) {
2844 if (++pos == endPos) {
2845 NS_HTML5_BREAK(stateloop);
2847 c = P::checkChar(this, buf, pos);
2848 switch (c) {
2849 case '/': {
2850 index = 0;
2851 clearStrBufBeforeUse();
2852 state = P::transition(mViewSource.get(),
2853 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
2854 reconsume, pos);
2855 NS_HTML5_CONTINUE(stateloop);
2857 case '!': {
2858 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2859 cstart = pos;
2860 state = P::transition(mViewSource.get(),
2861 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START,
2862 reconsume, pos);
2863 NS_HTML5_BREAK(scriptdatalessthansignloop);
2865 default: {
2866 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2867 cstart = pos;
2868 reconsume = true;
2869 state =
2870 P::transition(mViewSource.get(),
2871 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2872 NS_HTML5_CONTINUE(stateloop);
2876 scriptdatalessthansignloop_end:;
2877 [[fallthrough]];
2879 case SCRIPT_DATA_ESCAPE_START: {
2880 for (;;) {
2881 if (++pos == endPos) {
2882 NS_HTML5_BREAK(stateloop);
2884 c = P::checkChar(this, buf, pos);
2885 switch (c) {
2886 case '-': {
2887 state =
2888 P::transition(mViewSource.get(),
2889 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START_DASH,
2890 reconsume, pos);
2891 NS_HTML5_BREAK(scriptdataescapestartloop);
2893 default: {
2894 reconsume = true;
2895 state =
2896 P::transition(mViewSource.get(),
2897 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2898 NS_HTML5_CONTINUE(stateloop);
2902 scriptdataescapestartloop_end:;
2903 [[fallthrough]];
2905 case SCRIPT_DATA_ESCAPE_START_DASH: {
2906 for (;;) {
2907 if (++pos == endPos) {
2908 NS_HTML5_BREAK(stateloop);
2910 c = P::checkChar(this, buf, pos);
2911 switch (c) {
2912 case '-': {
2913 state =
2914 P::transition(mViewSource.get(),
2915 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
2916 reconsume, pos);
2917 NS_HTML5_BREAK(scriptdataescapestartdashloop);
2919 default: {
2920 reconsume = true;
2921 state =
2922 P::transition(mViewSource.get(),
2923 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2924 NS_HTML5_CONTINUE(stateloop);
2928 scriptdataescapestartdashloop_end:;
2929 [[fallthrough]];
2931 case SCRIPT_DATA_ESCAPED_DASH_DASH: {
2932 for (;;) {
2933 if (++pos == endPos) {
2934 NS_HTML5_BREAK(stateloop);
2936 c = P::checkChar(this, buf, pos);
2937 switch (c) {
2938 case '-': {
2939 continue;
2941 case '<': {
2942 flushChars(buf, pos);
2943 state = P::transition(
2944 mViewSource.get(),
2945 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
2946 reconsume, pos);
2947 NS_HTML5_CONTINUE(stateloop);
2949 case '>': {
2950 state =
2951 P::transition(mViewSource.get(),
2952 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2953 NS_HTML5_CONTINUE(stateloop);
2955 case '\0': {
2956 emitReplacementCharacter(buf, pos);
2957 state = P::transition(mViewSource.get(),
2958 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2959 reconsume, pos);
2960 NS_HTML5_BREAK(scriptdataescapeddashdashloop);
2962 case '\r': {
2963 emitCarriageReturn<P>(buf, pos);
2964 state = P::transition(mViewSource.get(),
2965 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2966 reconsume, pos);
2967 NS_HTML5_BREAK(stateloop);
2969 case '\n': {
2970 P::silentLineFeed(this);
2971 [[fallthrough]];
2973 default: {
2974 state = P::transition(mViewSource.get(),
2975 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2976 reconsume, pos);
2977 NS_HTML5_BREAK(scriptdataescapeddashdashloop);
2981 scriptdataescapeddashdashloop_end:;
2982 [[fallthrough]];
2984 case SCRIPT_DATA_ESCAPED: {
2985 for (;;) {
2986 if (reconsume) {
2987 reconsume = false;
2988 } else {
2989 if (++pos == endPos) {
2990 NS_HTML5_BREAK(stateloop);
2992 c = P::checkChar(this, buf, pos);
2994 switch (c) {
2995 case '-': {
2996 state = P::transition(mViewSource.get(),
2997 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH,
2998 reconsume, pos);
2999 NS_HTML5_BREAK(scriptdataescapedloop);
3001 case '<': {
3002 flushChars(buf, pos);
3003 state = P::transition(
3004 mViewSource.get(),
3005 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
3006 reconsume, pos);
3007 NS_HTML5_CONTINUE(stateloop);
3009 case '\0': {
3010 emitReplacementCharacter(buf, pos);
3011 continue;
3013 case '\r': {
3014 emitCarriageReturn<P>(buf, pos);
3015 NS_HTML5_BREAK(stateloop);
3017 case '\n': {
3018 P::silentLineFeed(this);
3019 [[fallthrough]];
3021 default: {
3022 continue;
3026 scriptdataescapedloop_end:;
3027 [[fallthrough]];
3029 case SCRIPT_DATA_ESCAPED_DASH: {
3030 for (;;) {
3031 if (++pos == endPos) {
3032 NS_HTML5_BREAK(stateloop);
3034 c = P::checkChar(this, buf, pos);
3035 switch (c) {
3036 case '-': {
3037 state =
3038 P::transition(mViewSource.get(),
3039 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
3040 reconsume, pos);
3041 NS_HTML5_CONTINUE(stateloop);
3043 case '<': {
3044 flushChars(buf, pos);
3045 state = P::transition(
3046 mViewSource.get(),
3047 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
3048 reconsume, pos);
3049 NS_HTML5_BREAK(scriptdataescapeddashloop);
3051 case '\0': {
3052 emitReplacementCharacter(buf, pos);
3053 state = P::transition(mViewSource.get(),
3054 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3055 reconsume, pos);
3056 NS_HTML5_CONTINUE(stateloop);
3058 case '\r': {
3059 emitCarriageReturn<P>(buf, pos);
3060 state = P::transition(mViewSource.get(),
3061 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3062 reconsume, pos);
3063 NS_HTML5_BREAK(stateloop);
3065 case '\n': {
3066 P::silentLineFeed(this);
3067 [[fallthrough]];
3069 default: {
3070 state = P::transition(mViewSource.get(),
3071 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3072 reconsume, pos);
3073 NS_HTML5_CONTINUE(stateloop);
3077 scriptdataescapeddashloop_end:;
3078 [[fallthrough]];
3080 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
3081 for (;;) {
3082 if (++pos == endPos) {
3083 NS_HTML5_BREAK(stateloop);
3085 c = P::checkChar(this, buf, pos);
3086 switch (c) {
3087 case '/': {
3088 index = 0;
3089 clearStrBufBeforeUse();
3090 returnState = nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED;
3091 state = P::transition(mViewSource.get(),
3092 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
3093 reconsume, pos);
3094 NS_HTML5_CONTINUE(stateloop);
3096 case 'S':
3097 case 's': {
3098 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
3099 cstart = pos;
3100 index = 1;
3101 state = P::transition(
3102 mViewSource.get(),
3103 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume,
3104 pos);
3105 NS_HTML5_BREAK(scriptdataescapedlessthanloop);
3107 default: {
3108 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
3109 cstart = pos;
3110 reconsume = true;
3111 state = P::transition(mViewSource.get(),
3112 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3113 reconsume, pos);
3114 NS_HTML5_CONTINUE(stateloop);
3118 scriptdataescapedlessthanloop_end:;
3119 [[fallthrough]];
3121 case SCRIPT_DATA_DOUBLE_ESCAPE_START: {
3122 for (;;) {
3123 if (++pos == endPos) {
3124 NS_HTML5_BREAK(stateloop);
3126 c = P::checkChar(this, buf, pos);
3127 MOZ_ASSERT(index > 0);
3128 if (index < 6) {
3129 char16_t folded = c;
3130 if (c >= 'A' && c <= 'Z') {
3131 folded += 0x20;
3133 if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
3134 reconsume = true;
3135 state = P::transition(mViewSource.get(),
3136 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3137 reconsume, pos);
3138 NS_HTML5_CONTINUE(stateloop);
3140 index++;
3141 continue;
3143 switch (c) {
3144 case '\r': {
3145 emitCarriageReturn<P>(buf, pos);
3146 state = P::transition(
3147 mViewSource.get(),
3148 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3149 NS_HTML5_BREAK(stateloop);
3151 case '\n': {
3152 P::silentLineFeed(this);
3153 [[fallthrough]];
3155 case ' ':
3156 case '\t':
3157 case '\f':
3158 case '/':
3159 case '>': {
3160 state = P::transition(
3161 mViewSource.get(),
3162 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3163 NS_HTML5_BREAK(scriptdatadoubleescapestartloop);
3165 default: {
3166 reconsume = true;
3167 state = P::transition(mViewSource.get(),
3168 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3169 reconsume, pos);
3170 NS_HTML5_CONTINUE(stateloop);
3174 scriptdatadoubleescapestartloop_end:;
3175 [[fallthrough]];
3177 case SCRIPT_DATA_DOUBLE_ESCAPED: {
3178 for (;;) {
3179 if (reconsume) {
3180 reconsume = false;
3181 } else {
3182 if (++pos == endPos) {
3183 NS_HTML5_BREAK(stateloop);
3185 c = P::checkChar(this, buf, pos);
3187 switch (c) {
3188 case '-': {
3189 state = P::transition(
3190 mViewSource.get(),
3191 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume,
3192 pos);
3193 NS_HTML5_BREAK(scriptdatadoubleescapedloop);
3195 case '<': {
3196 state = P::transition(
3197 mViewSource.get(),
3198 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3199 reconsume, pos);
3200 NS_HTML5_CONTINUE(stateloop);
3202 case '\0': {
3203 emitReplacementCharacter(buf, pos);
3204 continue;
3206 case '\r': {
3207 emitCarriageReturn<P>(buf, pos);
3208 NS_HTML5_BREAK(stateloop);
3210 case '\n': {
3211 P::silentLineFeed(this);
3212 [[fallthrough]];
3214 default: {
3215 continue;
3219 scriptdatadoubleescapedloop_end:;
3220 [[fallthrough]];
3222 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
3223 for (;;) {
3224 if (++pos == endPos) {
3225 NS_HTML5_BREAK(stateloop);
3227 c = P::checkChar(this, buf, pos);
3228 switch (c) {
3229 case '-': {
3230 state = P::transition(
3231 mViewSource.get(),
3232 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH,
3233 reconsume, pos);
3234 NS_HTML5_BREAK(scriptdatadoubleescapeddashloop);
3236 case '<': {
3237 state = P::transition(
3238 mViewSource.get(),
3239 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3240 reconsume, pos);
3241 NS_HTML5_CONTINUE(stateloop);
3243 case '\0': {
3244 emitReplacementCharacter(buf, pos);
3245 state = P::transition(
3246 mViewSource.get(),
3247 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3248 NS_HTML5_CONTINUE(stateloop);
3250 case '\r': {
3251 emitCarriageReturn<P>(buf, pos);
3252 state = P::transition(
3253 mViewSource.get(),
3254 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3255 NS_HTML5_BREAK(stateloop);
3257 case '\n': {
3258 P::silentLineFeed(this);
3259 [[fallthrough]];
3261 default: {
3262 state = P::transition(
3263 mViewSource.get(),
3264 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3265 NS_HTML5_CONTINUE(stateloop);
3269 scriptdatadoubleescapeddashloop_end:;
3270 [[fallthrough]];
3272 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
3273 for (;;) {
3274 if (++pos == endPos) {
3275 NS_HTML5_BREAK(stateloop);
3277 c = P::checkChar(this, buf, pos);
3278 switch (c) {
3279 case '-': {
3280 continue;
3282 case '<': {
3283 state = P::transition(
3284 mViewSource.get(),
3285 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3286 reconsume, pos);
3287 NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop);
3289 case '>': {
3290 state =
3291 P::transition(mViewSource.get(),
3292 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
3293 NS_HTML5_CONTINUE(stateloop);
3295 case '\0': {
3296 emitReplacementCharacter(buf, pos);
3297 state = P::transition(
3298 mViewSource.get(),
3299 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3300 NS_HTML5_CONTINUE(stateloop);
3302 case '\r': {
3303 emitCarriageReturn<P>(buf, pos);
3304 state = P::transition(
3305 mViewSource.get(),
3306 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3307 NS_HTML5_BREAK(stateloop);
3309 case '\n': {
3310 P::silentLineFeed(this);
3311 [[fallthrough]];
3313 default: {
3314 state = P::transition(
3315 mViewSource.get(),
3316 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3317 NS_HTML5_CONTINUE(stateloop);
3321 scriptdatadoubleescapeddashdashloop_end:;
3322 [[fallthrough]];
3324 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
3325 for (;;) {
3326 if (++pos == endPos) {
3327 NS_HTML5_BREAK(stateloop);
3329 c = P::checkChar(this, buf, pos);
3330 switch (c) {
3331 case '/': {
3332 index = 0;
3333 state =
3334 P::transition(mViewSource.get(),
3335 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_END,
3336 reconsume, pos);
3337 NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop);
3339 default: {
3340 reconsume = true;
3341 state = P::transition(
3342 mViewSource.get(),
3343 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3344 NS_HTML5_CONTINUE(stateloop);
3348 scriptdatadoubleescapedlessthanloop_end:;
3349 [[fallthrough]];
3351 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
3352 for (;;) {
3353 if (++pos == endPos) {
3354 NS_HTML5_BREAK(stateloop);
3356 c = P::checkChar(this, buf, pos);
3357 if (index < 6) {
3358 char16_t folded = c;
3359 if (c >= 'A' && c <= 'Z') {
3360 folded += 0x20;
3362 if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
3363 reconsume = true;
3364 state = P::transition(
3365 mViewSource.get(),
3366 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3367 NS_HTML5_CONTINUE(stateloop);
3369 index++;
3370 continue;
3372 switch (c) {
3373 case '\r': {
3374 emitCarriageReturn<P>(buf, pos);
3375 state = P::transition(mViewSource.get(),
3376 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3377 reconsume, pos);
3378 NS_HTML5_BREAK(stateloop);
3380 case '\n': {
3381 P::silentLineFeed(this);
3382 [[fallthrough]];
3384 case ' ':
3385 case '\t':
3386 case '\f':
3387 case '/':
3388 case '>': {
3389 state = P::transition(mViewSource.get(),
3390 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3391 reconsume, pos);
3392 NS_HTML5_CONTINUE(stateloop);
3394 default: {
3395 reconsume = true;
3396 state = P::transition(
3397 mViewSource.get(),
3398 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3399 NS_HTML5_CONTINUE(stateloop);
3404 case MARKUP_DECLARATION_OCTYPE: {
3405 for (;;) {
3406 if (++pos == endPos) {
3407 NS_HTML5_BREAK(stateloop);
3409 c = P::checkChar(this, buf, pos);
3410 if (index < 6) {
3411 char16_t folded = c;
3412 if (c >= 'A' && c <= 'Z') {
3413 folded += 0x20;
3415 if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
3416 appendStrBuf(c);
3417 } else {
3418 if (P::reportErrors) {
3419 errBogusComment();
3421 reconsume = true;
3422 state = P::transition(mViewSource.get(),
3423 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
3424 pos);
3425 NS_HTML5_CONTINUE(stateloop);
3427 index++;
3428 continue;
3429 } else {
3430 reconsume = true;
3431 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DOCTYPE,
3432 reconsume, pos);
3433 NS_HTML5_BREAK(markupdeclarationdoctypeloop);
3436 markupdeclarationdoctypeloop_end:;
3437 [[fallthrough]];
3439 case DOCTYPE: {
3440 for (;;) {
3441 if (reconsume) {
3442 reconsume = false;
3443 } else {
3444 if (++pos == endPos) {
3445 NS_HTML5_BREAK(stateloop);
3447 c = P::checkChar(this, buf, pos);
3449 initDoctypeFields();
3450 switch (c) {
3451 case '\r': {
3452 P::silentCarriageReturn(this);
3453 state = P::transition(mViewSource.get(),
3454 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3455 reconsume, pos);
3456 NS_HTML5_BREAK(stateloop);
3458 case '\n': {
3459 P::silentLineFeed(this);
3460 [[fallthrough]];
3462 case ' ':
3463 case '\t':
3464 case '\f': {
3465 state = P::transition(mViewSource.get(),
3466 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3467 reconsume, pos);
3468 NS_HTML5_BREAK(doctypeloop);
3470 default: {
3471 if (P::reportErrors) {
3472 errMissingSpaceBeforeDoctypeName();
3474 reconsume = true;
3475 state = P::transition(mViewSource.get(),
3476 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3477 reconsume, pos);
3478 NS_HTML5_BREAK(doctypeloop);
3482 doctypeloop_end:;
3483 [[fallthrough]];
3485 case BEFORE_DOCTYPE_NAME: {
3486 for (;;) {
3487 if (reconsume) {
3488 reconsume = false;
3489 } else {
3490 if (++pos == endPos) {
3491 NS_HTML5_BREAK(stateloop);
3493 c = P::checkChar(this, buf, pos);
3495 switch (c) {
3496 case '\r': {
3497 P::silentCarriageReturn(this);
3498 NS_HTML5_BREAK(stateloop);
3500 case '\n': {
3501 P::silentLineFeed(this);
3502 [[fallthrough]];
3504 case ' ':
3505 case '\t':
3506 case '\f': {
3507 continue;
3509 case '>': {
3510 if (P::reportErrors) {
3511 errNamelessDoctype();
3513 forceQuirks = true;
3514 emitDoctypeToken(pos);
3515 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3516 reconsume, pos);
3517 if (shouldSuspend) {
3518 NS_HTML5_BREAK(stateloop);
3520 NS_HTML5_CONTINUE(stateloop);
3522 case '\0': {
3523 c = 0xfffd;
3524 [[fallthrough]];
3526 default: {
3527 if (c >= 'A' && c <= 'Z') {
3528 c += 0x20;
3530 clearStrBufBeforeUse();
3531 appendStrBuf(c);
3532 state =
3533 P::transition(mViewSource.get(),
3534 nsHtml5Tokenizer::DOCTYPE_NAME, reconsume, pos);
3535 NS_HTML5_BREAK(beforedoctypenameloop);
3539 beforedoctypenameloop_end:;
3540 [[fallthrough]];
3542 case DOCTYPE_NAME: {
3543 for (;;) {
3544 if (++pos == endPos) {
3545 NS_HTML5_BREAK(stateloop);
3547 c = P::checkChar(this, buf, pos);
3548 switch (c) {
3549 case '\r': {
3550 P::silentCarriageReturn(this);
3551 strBufToDoctypeName();
3552 state = P::transition(mViewSource.get(),
3553 nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
3554 reconsume, pos);
3555 NS_HTML5_BREAK(stateloop);
3557 case '\n': {
3558 P::silentLineFeed(this);
3559 [[fallthrough]];
3561 case ' ':
3562 case '\t':
3563 case '\f': {
3564 strBufToDoctypeName();
3565 state = P::transition(mViewSource.get(),
3566 nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
3567 reconsume, pos);
3568 NS_HTML5_BREAK(doctypenameloop);
3570 case '>': {
3571 strBufToDoctypeName();
3572 emitDoctypeToken(pos);
3573 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3574 reconsume, pos);
3575 if (shouldSuspend) {
3576 NS_HTML5_BREAK(stateloop);
3578 NS_HTML5_CONTINUE(stateloop);
3580 case '\0': {
3581 c = 0xfffd;
3582 [[fallthrough]];
3584 default: {
3585 if (c >= 'A' && c <= 'Z') {
3586 c += 0x0020;
3588 appendStrBuf(c);
3589 continue;
3593 doctypenameloop_end:;
3594 [[fallthrough]];
3596 case AFTER_DOCTYPE_NAME: {
3597 for (;;) {
3598 if (++pos == endPos) {
3599 NS_HTML5_BREAK(stateloop);
3601 c = P::checkChar(this, buf, pos);
3602 switch (c) {
3603 case '\r': {
3604 P::silentCarriageReturn(this);
3605 NS_HTML5_BREAK(stateloop);
3607 case '\n': {
3608 P::silentLineFeed(this);
3609 [[fallthrough]];
3611 case ' ':
3612 case '\t':
3613 case '\f': {
3614 continue;
3616 case '>': {
3617 emitDoctypeToken(pos);
3618 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3619 reconsume, pos);
3620 if (shouldSuspend) {
3621 NS_HTML5_BREAK(stateloop);
3623 NS_HTML5_CONTINUE(stateloop);
3625 case 'p':
3626 case 'P': {
3627 index = 0;
3628 state = P::transition(mViewSource.get(),
3629 nsHtml5Tokenizer::DOCTYPE_UBLIC, reconsume,
3630 pos);
3631 NS_HTML5_BREAK(afterdoctypenameloop);
3633 case 's':
3634 case 'S': {
3635 index = 0;
3636 state = P::transition(mViewSource.get(),
3637 nsHtml5Tokenizer::DOCTYPE_YSTEM, reconsume,
3638 pos);
3639 NS_HTML5_CONTINUE(stateloop);
3641 default: {
3642 bogusDoctype();
3643 state = P::transition(mViewSource.get(),
3644 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3645 pos);
3646 NS_HTML5_CONTINUE(stateloop);
3650 afterdoctypenameloop_end:;
3651 [[fallthrough]];
3653 case DOCTYPE_UBLIC: {
3654 for (;;) {
3655 if (++pos == endPos) {
3656 NS_HTML5_BREAK(stateloop);
3658 c = P::checkChar(this, buf, pos);
3659 if (index < 5) {
3660 char16_t folded = c;
3661 if (c >= 'A' && c <= 'Z') {
3662 folded += 0x20;
3664 if (folded != nsHtml5Tokenizer::UBLIC[index]) {
3665 bogusDoctype();
3666 reconsume = true;
3667 state = P::transition(mViewSource.get(),
3668 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3669 pos);
3670 NS_HTML5_CONTINUE(stateloop);
3672 index++;
3673 continue;
3674 } else {
3675 reconsume = true;
3676 state = P::transition(
3677 mViewSource.get(),
3678 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
3679 NS_HTML5_BREAK(doctypeublicloop);
3682 doctypeublicloop_end:;
3683 [[fallthrough]];
3685 case AFTER_DOCTYPE_PUBLIC_KEYWORD: {
3686 for (;;) {
3687 if (reconsume) {
3688 reconsume = false;
3689 } else {
3690 if (++pos == endPos) {
3691 NS_HTML5_BREAK(stateloop);
3693 c = P::checkChar(this, buf, pos);
3695 switch (c) {
3696 case '\r': {
3697 P::silentCarriageReturn(this);
3698 state = P::transition(
3699 mViewSource.get(),
3700 nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3701 pos);
3702 NS_HTML5_BREAK(stateloop);
3704 case '\n': {
3705 P::silentLineFeed(this);
3706 [[fallthrough]];
3708 case ' ':
3709 case '\t':
3710 case '\f': {
3711 state = P::transition(
3712 mViewSource.get(),
3713 nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3714 pos);
3715 NS_HTML5_BREAK(afterdoctypepublickeywordloop);
3717 case '\"': {
3718 if (P::reportErrors) {
3719 errNoSpaceBetweenDoctypePublicKeywordAndQuote();
3721 clearStrBufBeforeUse();
3722 state = P::transition(
3723 mViewSource.get(),
3724 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
3725 reconsume, pos);
3726 NS_HTML5_CONTINUE(stateloop);
3728 case '\'': {
3729 if (P::reportErrors) {
3730 errNoSpaceBetweenDoctypePublicKeywordAndQuote();
3732 clearStrBufBeforeUse();
3733 state = P::transition(
3734 mViewSource.get(),
3735 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
3736 reconsume, pos);
3737 NS_HTML5_CONTINUE(stateloop);
3739 case '>': {
3740 if (P::reportErrors) {
3741 errExpectedPublicId();
3743 forceQuirks = true;
3744 emitDoctypeToken(pos);
3745 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3746 reconsume, pos);
3747 if (shouldSuspend) {
3748 NS_HTML5_BREAK(stateloop);
3750 NS_HTML5_CONTINUE(stateloop);
3752 default: {
3753 bogusDoctype();
3754 state = P::transition(mViewSource.get(),
3755 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3756 pos);
3757 NS_HTML5_CONTINUE(stateloop);
3761 afterdoctypepublickeywordloop_end:;
3762 [[fallthrough]];
3764 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
3765 for (;;) {
3766 if (++pos == endPos) {
3767 NS_HTML5_BREAK(stateloop);
3769 c = P::checkChar(this, buf, pos);
3770 switch (c) {
3771 case '\r': {
3772 P::silentCarriageReturn(this);
3773 NS_HTML5_BREAK(stateloop);
3775 case '\n': {
3776 P::silentLineFeed(this);
3777 [[fallthrough]];
3779 case ' ':
3780 case '\t':
3781 case '\f': {
3782 continue;
3784 case '\"': {
3785 clearStrBufBeforeUse();
3786 state = P::transition(
3787 mViewSource.get(),
3788 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
3789 reconsume, pos);
3790 NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
3792 case '\'': {
3793 clearStrBufBeforeUse();
3794 state = P::transition(
3795 mViewSource.get(),
3796 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
3797 reconsume, pos);
3798 NS_HTML5_CONTINUE(stateloop);
3800 case '>': {
3801 if (P::reportErrors) {
3802 errExpectedPublicId();
3804 forceQuirks = true;
3805 emitDoctypeToken(pos);
3806 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3807 reconsume, pos);
3808 if (shouldSuspend) {
3809 NS_HTML5_BREAK(stateloop);
3811 NS_HTML5_CONTINUE(stateloop);
3813 default: {
3814 bogusDoctype();
3815 state = P::transition(mViewSource.get(),
3816 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3817 pos);
3818 NS_HTML5_CONTINUE(stateloop);
3822 beforedoctypepublicidentifierloop_end:;
3823 [[fallthrough]];
3825 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
3826 for (;;) {
3827 if (++pos == endPos) {
3828 NS_HTML5_BREAK(stateloop);
3830 c = P::checkChar(this, buf, pos);
3831 switch (c) {
3832 case '\"': {
3833 publicIdentifier = strBufToString();
3834 state = P::transition(
3835 mViewSource.get(),
3836 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3837 pos);
3838 NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
3840 case '>': {
3841 if (P::reportErrors) {
3842 errGtInPublicId();
3844 forceQuirks = true;
3845 publicIdentifier = strBufToString();
3846 emitDoctypeToken(pos);
3847 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3848 reconsume, pos);
3849 if (shouldSuspend) {
3850 NS_HTML5_BREAK(stateloop);
3852 NS_HTML5_CONTINUE(stateloop);
3854 case '\r': {
3855 appendStrBufCarriageReturn<P>();
3856 NS_HTML5_BREAK(stateloop);
3858 case '\n': {
3859 appendStrBufLineFeed<P>();
3860 continue;
3862 case '\0': {
3863 c = 0xfffd;
3864 [[fallthrough]];
3866 default: {
3867 appendStrBuf(c);
3868 continue;
3872 doctypepublicidentifierdoublequotedloop_end:;
3873 [[fallthrough]];
3875 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
3876 for (;;) {
3877 if (++pos == endPos) {
3878 NS_HTML5_BREAK(stateloop);
3880 c = P::checkChar(this, buf, pos);
3881 switch (c) {
3882 case '\r': {
3883 P::silentCarriageReturn(this);
3884 state = P::transition(
3885 mViewSource.get(),
3886 nsHtml5Tokenizer::
3887 BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
3888 reconsume, pos);
3889 NS_HTML5_BREAK(stateloop);
3891 case '\n': {
3892 P::silentLineFeed(this);
3893 [[fallthrough]];
3895 case ' ':
3896 case '\t':
3897 case '\f': {
3898 state = P::transition(
3899 mViewSource.get(),
3900 nsHtml5Tokenizer::
3901 BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
3902 reconsume, pos);
3903 NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
3905 case '>': {
3906 emitDoctypeToken(pos);
3907 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3908 reconsume, pos);
3909 if (shouldSuspend) {
3910 NS_HTML5_BREAK(stateloop);
3912 NS_HTML5_CONTINUE(stateloop);
3914 case '\"': {
3915 if (P::reportErrors) {
3916 errNoSpaceBetweenPublicAndSystemIds();
3918 clearStrBufBeforeUse();
3919 state = P::transition(
3920 mViewSource.get(),
3921 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
3922 reconsume, pos);
3923 NS_HTML5_CONTINUE(stateloop);
3925 case '\'': {
3926 if (P::reportErrors) {
3927 errNoSpaceBetweenPublicAndSystemIds();
3929 clearStrBufBeforeUse();
3930 state = P::transition(
3931 mViewSource.get(),
3932 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
3933 reconsume, pos);
3934 NS_HTML5_CONTINUE(stateloop);
3936 default: {
3937 bogusDoctype();
3938 state = P::transition(mViewSource.get(),
3939 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3940 pos);
3941 NS_HTML5_CONTINUE(stateloop);
3945 afterdoctypepublicidentifierloop_end:;
3946 [[fallthrough]];
3948 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
3949 for (;;) {
3950 if (++pos == endPos) {
3951 NS_HTML5_BREAK(stateloop);
3953 c = P::checkChar(this, buf, pos);
3954 switch (c) {
3955 case '\r': {
3956 P::silentCarriageReturn(this);
3957 NS_HTML5_BREAK(stateloop);
3959 case '\n': {
3960 P::silentLineFeed(this);
3961 [[fallthrough]];
3963 case ' ':
3964 case '\t':
3965 case '\f': {
3966 continue;
3968 case '>': {
3969 emitDoctypeToken(pos);
3970 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3971 reconsume, pos);
3972 if (shouldSuspend) {
3973 NS_HTML5_BREAK(stateloop);
3975 NS_HTML5_CONTINUE(stateloop);
3977 case '\"': {
3978 clearStrBufBeforeUse();
3979 state = P::transition(
3980 mViewSource.get(),
3981 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
3982 reconsume, pos);
3983 NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop);
3985 case '\'': {
3986 clearStrBufBeforeUse();
3987 state = P::transition(
3988 mViewSource.get(),
3989 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
3990 reconsume, pos);
3991 NS_HTML5_CONTINUE(stateloop);
3993 default: {
3994 bogusDoctype();
3995 state = P::transition(mViewSource.get(),
3996 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3997 pos);
3998 NS_HTML5_CONTINUE(stateloop);
4002 betweendoctypepublicandsystemidentifiersloop_end:;
4003 [[fallthrough]];
4005 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
4006 for (;;) {
4007 if (++pos == endPos) {
4008 NS_HTML5_BREAK(stateloop);
4010 c = P::checkChar(this, buf, pos);
4011 switch (c) {
4012 case '\"': {
4013 systemIdentifier = strBufToString();
4014 state = P::transition(
4015 mViewSource.get(),
4016 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4017 pos);
4018 NS_HTML5_BREAK(doctypesystemidentifierdoublequotedloop);
4020 case '>': {
4021 if (P::reportErrors) {
4022 errGtInSystemId();
4024 forceQuirks = true;
4025 systemIdentifier = strBufToString();
4026 emitDoctypeToken(pos);
4027 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4028 reconsume, pos);
4029 if (shouldSuspend) {
4030 NS_HTML5_BREAK(stateloop);
4032 NS_HTML5_CONTINUE(stateloop);
4034 case '\r': {
4035 appendStrBufCarriageReturn<P>();
4036 NS_HTML5_BREAK(stateloop);
4038 case '\n': {
4039 appendStrBufLineFeed<P>();
4040 continue;
4042 case '\0': {
4043 c = 0xfffd;
4044 [[fallthrough]];
4046 default: {
4047 appendStrBuf(c);
4048 continue;
4052 doctypesystemidentifierdoublequotedloop_end:;
4053 [[fallthrough]];
4055 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
4056 for (;;) {
4057 if (++pos == endPos) {
4058 NS_HTML5_BREAK(stateloop);
4060 c = P::checkChar(this, buf, pos);
4061 switch (c) {
4062 case '\r': {
4063 P::silentCarriageReturn(this);
4064 NS_HTML5_BREAK(stateloop);
4066 case '\n': {
4067 P::silentLineFeed(this);
4068 [[fallthrough]];
4070 case ' ':
4071 case '\t':
4072 case '\f': {
4073 continue;
4075 case '>': {
4076 emitDoctypeToken(pos);
4077 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4078 reconsume, pos);
4079 if (shouldSuspend) {
4080 NS_HTML5_BREAK(stateloop);
4082 NS_HTML5_CONTINUE(stateloop);
4084 default: {
4085 bogusDoctypeWithoutQuirks();
4086 state = P::transition(mViewSource.get(),
4087 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4088 pos);
4089 NS_HTML5_BREAK(afterdoctypesystemidentifierloop);
4093 afterdoctypesystemidentifierloop_end:;
4094 [[fallthrough]];
4096 case BOGUS_DOCTYPE: {
4097 for (;;) {
4098 if (reconsume) {
4099 reconsume = false;
4100 } else {
4101 if (++pos == endPos) {
4102 NS_HTML5_BREAK(stateloop);
4104 c = P::checkChar(this, buf, pos);
4106 switch (c) {
4107 case '>': {
4108 emitDoctypeToken(pos);
4109 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4110 reconsume, pos);
4111 if (shouldSuspend) {
4112 NS_HTML5_BREAK(stateloop);
4114 NS_HTML5_CONTINUE(stateloop);
4116 case '\r': {
4117 P::silentCarriageReturn(this);
4118 NS_HTML5_BREAK(stateloop);
4120 case '\n': {
4121 P::silentLineFeed(this);
4122 [[fallthrough]];
4124 default: {
4125 continue;
4130 case DOCTYPE_YSTEM: {
4131 for (;;) {
4132 if (++pos == endPos) {
4133 NS_HTML5_BREAK(stateloop);
4135 c = P::checkChar(this, buf, pos);
4136 if (index < 5) {
4137 char16_t folded = c;
4138 if (c >= 'A' && c <= 'Z') {
4139 folded += 0x20;
4141 if (folded != nsHtml5Tokenizer::YSTEM[index]) {
4142 bogusDoctype();
4143 reconsume = true;
4144 state = P::transition(mViewSource.get(),
4145 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4146 pos);
4147 NS_HTML5_CONTINUE(stateloop);
4149 index++;
4150 NS_HTML5_CONTINUE(stateloop);
4151 } else {
4152 reconsume = true;
4153 state = P::transition(
4154 mViewSource.get(),
4155 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
4156 NS_HTML5_BREAK(doctypeystemloop);
4159 doctypeystemloop_end:;
4160 [[fallthrough]];
4162 case AFTER_DOCTYPE_SYSTEM_KEYWORD: {
4163 for (;;) {
4164 if (reconsume) {
4165 reconsume = false;
4166 } else {
4167 if (++pos == endPos) {
4168 NS_HTML5_BREAK(stateloop);
4170 c = P::checkChar(this, buf, pos);
4172 switch (c) {
4173 case '\r': {
4174 P::silentCarriageReturn(this);
4175 state = P::transition(
4176 mViewSource.get(),
4177 nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4178 pos);
4179 NS_HTML5_BREAK(stateloop);
4181 case '\n': {
4182 P::silentLineFeed(this);
4183 [[fallthrough]];
4185 case ' ':
4186 case '\t':
4187 case '\f': {
4188 state = P::transition(
4189 mViewSource.get(),
4190 nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4191 pos);
4192 NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
4194 case '\"': {
4195 if (P::reportErrors) {
4196 errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
4198 clearStrBufBeforeUse();
4199 state = P::transition(
4200 mViewSource.get(),
4201 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
4202 reconsume, pos);
4203 NS_HTML5_CONTINUE(stateloop);
4205 case '\'': {
4206 if (P::reportErrors) {
4207 errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
4209 clearStrBufBeforeUse();
4210 state = P::transition(
4211 mViewSource.get(),
4212 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
4213 reconsume, pos);
4214 NS_HTML5_CONTINUE(stateloop);
4216 case '>': {
4217 if (P::reportErrors) {
4218 errExpectedPublicId();
4220 forceQuirks = true;
4221 emitDoctypeToken(pos);
4222 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4223 reconsume, pos);
4224 if (shouldSuspend) {
4225 NS_HTML5_BREAK(stateloop);
4227 NS_HTML5_CONTINUE(stateloop);
4229 default: {
4230 bogusDoctype();
4231 state = P::transition(mViewSource.get(),
4232 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4233 pos);
4234 NS_HTML5_CONTINUE(stateloop);
4238 afterdoctypesystemkeywordloop_end:;
4239 [[fallthrough]];
4241 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
4242 for (;;) {
4243 if (++pos == endPos) {
4244 NS_HTML5_BREAK(stateloop);
4246 c = P::checkChar(this, buf, pos);
4247 switch (c) {
4248 case '\r': {
4249 P::silentCarriageReturn(this);
4250 NS_HTML5_BREAK(stateloop);
4252 case '\n': {
4253 P::silentLineFeed(this);
4254 [[fallthrough]];
4256 case ' ':
4257 case '\t':
4258 case '\f': {
4259 continue;
4261 case '\"': {
4262 clearStrBufBeforeUse();
4263 state = P::transition(
4264 mViewSource.get(),
4265 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
4266 reconsume, pos);
4267 NS_HTML5_CONTINUE(stateloop);
4269 case '\'': {
4270 clearStrBufBeforeUse();
4271 state = P::transition(
4272 mViewSource.get(),
4273 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
4274 reconsume, pos);
4275 NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
4277 case '>': {
4278 if (P::reportErrors) {
4279 errExpectedSystemId();
4281 forceQuirks = true;
4282 emitDoctypeToken(pos);
4283 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4284 reconsume, pos);
4285 if (shouldSuspend) {
4286 NS_HTML5_BREAK(stateloop);
4288 NS_HTML5_CONTINUE(stateloop);
4290 default: {
4291 bogusDoctype();
4292 state = P::transition(mViewSource.get(),
4293 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4294 pos);
4295 NS_HTML5_CONTINUE(stateloop);
4299 beforedoctypesystemidentifierloop_end:;
4300 [[fallthrough]];
4302 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
4303 for (;;) {
4304 if (++pos == endPos) {
4305 NS_HTML5_BREAK(stateloop);
4307 c = P::checkChar(this, buf, pos);
4308 switch (c) {
4309 case '\'': {
4310 systemIdentifier = strBufToString();
4311 state = P::transition(
4312 mViewSource.get(),
4313 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4314 pos);
4315 NS_HTML5_CONTINUE(stateloop);
4317 case '>': {
4318 if (P::reportErrors) {
4319 errGtInSystemId();
4321 forceQuirks = true;
4322 systemIdentifier = strBufToString();
4323 emitDoctypeToken(pos);
4324 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4325 reconsume, pos);
4326 if (shouldSuspend) {
4327 NS_HTML5_BREAK(stateloop);
4329 NS_HTML5_CONTINUE(stateloop);
4331 case '\r': {
4332 appendStrBufCarriageReturn<P>();
4333 NS_HTML5_BREAK(stateloop);
4335 case '\n': {
4336 appendStrBufLineFeed<P>();
4337 continue;
4339 case '\0': {
4340 c = 0xfffd;
4341 [[fallthrough]];
4343 default: {
4344 appendStrBuf(c);
4345 continue;
4350 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
4351 for (;;) {
4352 if (++pos == endPos) {
4353 NS_HTML5_BREAK(stateloop);
4355 c = P::checkChar(this, buf, pos);
4356 switch (c) {
4357 case '\'': {
4358 publicIdentifier = strBufToString();
4359 state = P::transition(
4360 mViewSource.get(),
4361 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
4362 pos);
4363 NS_HTML5_CONTINUE(stateloop);
4365 case '>': {
4366 if (P::reportErrors) {
4367 errGtInPublicId();
4369 forceQuirks = true;
4370 publicIdentifier = strBufToString();
4371 emitDoctypeToken(pos);
4372 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4373 reconsume, pos);
4374 if (shouldSuspend) {
4375 NS_HTML5_BREAK(stateloop);
4377 NS_HTML5_CONTINUE(stateloop);
4379 case '\r': {
4380 appendStrBufCarriageReturn<P>();
4381 NS_HTML5_BREAK(stateloop);
4383 case '\n': {
4384 appendStrBufLineFeed<P>();
4385 continue;
4387 case '\0': {
4388 c = 0xfffd;
4389 [[fallthrough]];
4391 default: {
4392 appendStrBuf(c);
4393 continue;
4398 case PROCESSING_INSTRUCTION: {
4399 for (;;) {
4400 if (++pos == endPos) {
4401 NS_HTML5_BREAK(stateloop);
4403 c = P::checkChar(this, buf, pos);
4404 switch (c) {
4405 case '\?': {
4406 state = P::transition(
4407 mViewSource.get(),
4408 nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK,
4409 reconsume, pos);
4410 NS_HTML5_BREAK(processinginstructionloop);
4412 default: {
4413 continue;
4417 processinginstructionloop_end:;
4418 [[fallthrough]];
4420 case PROCESSING_INSTRUCTION_QUESTION_MARK: {
4421 if (++pos == endPos) {
4422 NS_HTML5_BREAK(stateloop);
4424 c = P::checkChar(this, buf, pos);
4425 switch (c) {
4426 case '>': {
4427 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4428 reconsume, pos);
4429 suspendIfRequestedAfterCurrentNonTextToken();
4430 if (shouldSuspend) {
4431 NS_HTML5_BREAK(stateloop);
4433 NS_HTML5_CONTINUE(stateloop);
4435 default: {
4436 state = P::transition(mViewSource.get(),
4437 nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
4438 reconsume, pos);
4439 NS_HTML5_CONTINUE(stateloop);
4445 stateloop_end:;
4446 flushChars(buf, pos);
4447 stateSave = state;
4448 returnStateSave = returnState;
4449 return pos;
4452 void nsHtml5Tokenizer::initDoctypeFields() {
4453 clearStrBufAfterUse();
4454 doctypeName = nullptr;
4455 if (systemIdentifier) {
4456 systemIdentifier.Release();
4457 systemIdentifier = nullptr;
4459 if (publicIdentifier) {
4460 publicIdentifier.Release();
4461 publicIdentifier = nullptr;
4463 forceQuirks = false;
4466 template <class P>
4467 void nsHtml5Tokenizer::adjustDoubleHyphenAndAppendToStrBufCarriageReturn() {
4468 P::silentCarriageReturn(this);
4469 adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
4472 template <class P>
4473 void nsHtml5Tokenizer::adjustDoubleHyphenAndAppendToStrBufLineFeed() {
4474 P::silentLineFeed(this);
4475 adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
4478 template <class P>
4479 void nsHtml5Tokenizer::appendStrBufLineFeed() {
4480 P::silentLineFeed(this);
4481 appendStrBuf('\n');
4484 template <class P>
4485 void nsHtml5Tokenizer::appendStrBufCarriageReturn() {
4486 P::silentCarriageReturn(this);
4487 appendStrBuf('\n');
4490 template <class P>
4491 void nsHtml5Tokenizer::emitCarriageReturn(char16_t* buf, int32_t pos) {
4492 P::silentCarriageReturn(this);
4493 flushChars(buf, pos);
4494 tokenHandler->characters(nsHtml5Tokenizer::LF, 0, 1);
4495 cstart = INT32_MAX;
4498 void nsHtml5Tokenizer::emitReplacementCharacter(char16_t* buf, int32_t pos) {
4499 flushChars(buf, pos);
4500 tokenHandler->zeroOriginatingReplacementCharacter();
4501 cstart = pos + 1;
4504 void nsHtml5Tokenizer::maybeEmitReplacementCharacter(char16_t* buf,
4505 int32_t pos) {
4506 flushChars(buf, pos);
4507 tokenHandler->zeroOrReplacementCharacter();
4508 cstart = pos + 1;
4511 void nsHtml5Tokenizer::emitPlaintextReplacementCharacter(char16_t* buf,
4512 int32_t pos) {
4513 flushChars(buf, pos);
4514 tokenHandler->characters(REPLACEMENT_CHARACTER, 0, 1);
4515 cstart = pos + 1;
4518 void nsHtml5Tokenizer::setAdditionalAndRememberAmpersandLocation(char16_t add) {
4519 additional = add;
4522 void nsHtml5Tokenizer::bogusDoctype() {
4523 errBogusDoctype();
4524 forceQuirks = true;
4527 void nsHtml5Tokenizer::bogusDoctypeWithoutQuirks() {
4528 errBogusDoctype();
4529 forceQuirks = false;
4532 void nsHtml5Tokenizer::handleNcrValue(int32_t returnState) {
4533 if (value <= 0xFFFF) {
4534 if (value >= 0x80 && value <= 0x9f) {
4535 errNcrInC1Range();
4536 char16_t* val = nsHtml5NamedCharacters::WINDOWS_1252[value - 0x80];
4537 emitOrAppendOne(val, returnState);
4538 } else if (value == 0x0) {
4539 errNcrZero();
4540 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4541 } else if ((value & 0xF800) == 0xD800) {
4542 errNcrSurrogate();
4543 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4544 } else {
4545 char16_t ch = (char16_t)value;
4546 bmpChar[0] = ch;
4547 emitOrAppendOne(bmpChar, returnState);
4549 } else if (value <= 0x10FFFF) {
4550 astralChar[0] = (char16_t)(nsHtml5Tokenizer::LEAD_OFFSET + (value >> 10));
4551 astralChar[1] = (char16_t)(0xDC00 + (value & 0x3FF));
4552 emitOrAppendTwo(astralChar, returnState);
4553 } else {
4554 errNcrOutOfRange();
4555 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4559 void nsHtml5Tokenizer::eof() {
4560 int32_t state = stateSave;
4561 int32_t returnState = returnStateSave;
4562 eofloop:
4563 for (;;) {
4564 switch (state) {
4565 case SCRIPT_DATA_LESS_THAN_SIGN:
4566 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
4567 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4568 NS_HTML5_BREAK(eofloop);
4570 case TAG_OPEN: {
4571 errEofAfterLt();
4572 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4573 NS_HTML5_BREAK(eofloop);
4575 case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
4576 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4577 NS_HTML5_BREAK(eofloop);
4579 case NON_DATA_END_TAG_NAME: {
4580 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
4581 emitStrBuf();
4582 NS_HTML5_BREAK(eofloop);
4584 case CLOSE_TAG_OPEN: {
4585 errEofAfterLt();
4586 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
4587 NS_HTML5_BREAK(eofloop);
4589 case TAG_NAME: {
4590 errEofInTagName();
4591 NS_HTML5_BREAK(eofloop);
4593 case BEFORE_ATTRIBUTE_NAME:
4594 case AFTER_ATTRIBUTE_VALUE_QUOTED:
4595 case SELF_CLOSING_START_TAG: {
4596 errEofWithoutGt();
4597 NS_HTML5_BREAK(eofloop);
4599 case ATTRIBUTE_NAME: {
4600 errEofInAttributeName();
4601 NS_HTML5_BREAK(eofloop);
4603 case AFTER_ATTRIBUTE_NAME:
4604 case BEFORE_ATTRIBUTE_VALUE: {
4605 errEofWithoutGt();
4606 NS_HTML5_BREAK(eofloop);
4608 case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
4609 case ATTRIBUTE_VALUE_SINGLE_QUOTED:
4610 case ATTRIBUTE_VALUE_UNQUOTED: {
4611 errEofInAttributeValue();
4612 NS_HTML5_BREAK(eofloop);
4614 case BOGUS_COMMENT: {
4615 emitComment(0, 0);
4616 NS_HTML5_BREAK(eofloop);
4618 case BOGUS_COMMENT_HYPHEN: {
4619 emitComment(0, 0);
4620 NS_HTML5_BREAK(eofloop);
4622 case MARKUP_DECLARATION_OPEN: {
4623 errBogusComment();
4624 emitComment(0, 0);
4625 NS_HTML5_BREAK(eofloop);
4627 case MARKUP_DECLARATION_HYPHEN: {
4628 errBogusComment();
4629 emitComment(0, 0);
4630 NS_HTML5_BREAK(eofloop);
4632 case MARKUP_DECLARATION_OCTYPE: {
4633 if (index < 6) {
4634 errBogusComment();
4635 emitComment(0, 0);
4636 } else {
4637 errEofInDoctype();
4638 doctypeName = nullptr;
4639 if (systemIdentifier) {
4640 systemIdentifier.Release();
4641 systemIdentifier = nullptr;
4643 if (publicIdentifier) {
4644 publicIdentifier.Release();
4645 publicIdentifier = nullptr;
4647 forceQuirks = true;
4648 emitDoctypeToken(0);
4649 NS_HTML5_BREAK(eofloop);
4651 NS_HTML5_BREAK(eofloop);
4653 case COMMENT_START:
4654 case COMMENT:
4655 case COMMENT_LESSTHAN:
4656 case COMMENT_LESSTHAN_BANG: {
4657 errEofInComment();
4658 emitComment(0, 0);
4659 NS_HTML5_BREAK(eofloop);
4661 case COMMENT_END:
4662 case COMMENT_LESSTHAN_BANG_DASH_DASH: {
4663 errEofInComment();
4664 emitComment(2, 0);
4665 NS_HTML5_BREAK(eofloop);
4667 case COMMENT_END_DASH:
4668 case COMMENT_START_DASH:
4669 case COMMENT_LESSTHAN_BANG_DASH: {
4670 errEofInComment();
4671 emitComment(1, 0);
4672 NS_HTML5_BREAK(eofloop);
4674 case COMMENT_END_BANG: {
4675 errEofInComment();
4676 emitComment(3, 0);
4677 NS_HTML5_BREAK(eofloop);
4679 case DOCTYPE:
4680 case BEFORE_DOCTYPE_NAME: {
4681 errEofInDoctype();
4682 forceQuirks = true;
4683 emitDoctypeToken(0);
4684 NS_HTML5_BREAK(eofloop);
4686 case DOCTYPE_NAME: {
4687 errEofInDoctype();
4688 strBufToDoctypeName();
4689 forceQuirks = true;
4690 emitDoctypeToken(0);
4691 NS_HTML5_BREAK(eofloop);
4693 case DOCTYPE_UBLIC:
4694 case DOCTYPE_YSTEM:
4695 case AFTER_DOCTYPE_NAME:
4696 case AFTER_DOCTYPE_PUBLIC_KEYWORD:
4697 case AFTER_DOCTYPE_SYSTEM_KEYWORD:
4698 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
4699 errEofInDoctype();
4700 forceQuirks = true;
4701 emitDoctypeToken(0);
4702 NS_HTML5_BREAK(eofloop);
4704 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
4705 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
4706 errEofInPublicId();
4707 forceQuirks = true;
4708 publicIdentifier = strBufToString();
4709 emitDoctypeToken(0);
4710 NS_HTML5_BREAK(eofloop);
4712 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
4713 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
4714 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
4715 errEofInDoctype();
4716 forceQuirks = true;
4717 emitDoctypeToken(0);
4718 NS_HTML5_BREAK(eofloop);
4720 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
4721 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
4722 errEofInSystemId();
4723 forceQuirks = true;
4724 systemIdentifier = strBufToString();
4725 emitDoctypeToken(0);
4726 NS_HTML5_BREAK(eofloop);
4728 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
4729 errEofInDoctype();
4730 forceQuirks = true;
4731 emitDoctypeToken(0);
4732 NS_HTML5_BREAK(eofloop);
4734 case BOGUS_DOCTYPE: {
4735 emitDoctypeToken(0);
4736 NS_HTML5_BREAK(eofloop);
4738 case CONSUME_CHARACTER_REFERENCE: {
4739 emitOrAppendCharRefBuf(returnState);
4740 state = returnState;
4741 continue;
4743 case CHARACTER_REFERENCE_HILO_LOOKUP: {
4744 emitOrAppendCharRefBuf(returnState);
4745 state = returnState;
4746 continue;
4748 case CHARACTER_REFERENCE_TAIL: {
4749 for (;;) {
4750 char16_t c = '\0';
4751 entCol++;
4752 for (;;) {
4753 if (hi == -1) {
4754 NS_HTML5_BREAK(hiloop);
4756 if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
4757 NS_HTML5_BREAK(hiloop);
4759 if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
4760 NS_HTML5_BREAK(outer);
4761 } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
4762 hi--;
4763 } else {
4764 NS_HTML5_BREAK(hiloop);
4767 hiloop_end:;
4768 for (;;) {
4769 if (hi < lo) {
4770 NS_HTML5_BREAK(outer);
4772 if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
4773 candidate = lo;
4774 charRefBufMark = charRefBufLen;
4775 lo++;
4776 } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
4777 NS_HTML5_BREAK(outer);
4778 } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
4779 lo++;
4780 } else {
4781 NS_HTML5_BREAK(loloop);
4784 loloop_end:;
4785 if (hi < lo) {
4786 NS_HTML5_BREAK(outer);
4788 continue;
4790 outer_end:;
4791 if (candidate == -1) {
4792 emitOrAppendCharRefBuf(returnState);
4793 state = returnState;
4794 NS_HTML5_CONTINUE(eofloop);
4795 } else {
4796 const nsHtml5CharacterName& candidateName =
4797 nsHtml5NamedCharacters::NAMES[candidate];
4798 if (!candidateName.length() ||
4799 candidateName.charAt(candidateName.length() - 1) != ';') {
4800 if ((returnState & DATA_AND_RCDATA_MASK)) {
4801 char16_t ch;
4802 if (charRefBufMark == charRefBufLen) {
4803 ch = '\0';
4804 } else {
4805 ch = charRefBuf[charRefBufMark];
4807 if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') ||
4808 (ch >= 'a' && ch <= 'z')) {
4809 appendCharRefBufToStrBuf();
4810 state = returnState;
4811 NS_HTML5_CONTINUE(eofloop);
4814 if ((returnState & DATA_AND_RCDATA_MASK)) {
4815 errUnescapedAmpersandInterpretedAsCharacterReference();
4816 } else {
4817 errNotSemicolonTerminated();
4820 const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
4821 if (!val[1]) {
4822 emitOrAppendOne(val, returnState);
4823 } else {
4824 emitOrAppendTwo(val, returnState);
4826 if (charRefBufMark < charRefBufLen) {
4827 if ((returnState & DATA_AND_RCDATA_MASK)) {
4828 appendStrBuf(charRefBuf, charRefBufMark,
4829 charRefBufLen - charRefBufMark);
4830 } else {
4831 tokenHandler->characters(charRefBuf, charRefBufMark,
4832 charRefBufLen - charRefBufMark);
4835 charRefBufLen = 0;
4836 state = returnState;
4837 NS_HTML5_CONTINUE(eofloop);
4840 case CONSUME_NCR:
4841 case DECIMAL_NRC_LOOP:
4842 case HEX_NCR_LOOP: {
4843 if (!seenDigits) {
4844 errNoDigitsInNCR();
4845 emitOrAppendCharRefBuf(returnState);
4846 state = returnState;
4847 continue;
4848 } else {
4849 errCharRefLacksSemicolon();
4851 handleNcrValue(returnState);
4852 state = returnState;
4853 continue;
4855 case CDATA_RSQB: {
4856 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
4857 NS_HTML5_BREAK(eofloop);
4859 case CDATA_RSQB_RSQB: {
4860 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
4861 NS_HTML5_BREAK(eofloop);
4863 case DATA:
4864 default: {
4865 NS_HTML5_BREAK(eofloop);
4869 eofloop_end:;
4870 tokenHandler->eof();
4871 return;
4874 void nsHtml5Tokenizer::emitDoctypeToken(int32_t pos) {
4875 RememberGt(pos);
4876 cstart = pos + 1;
4877 tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier,
4878 forceQuirks);
4879 doctypeName = nullptr;
4880 publicIdentifier.Release();
4881 publicIdentifier = nullptr;
4882 systemIdentifier.Release();
4883 systemIdentifier = nullptr;
4884 suspendIfRequestedAfterCurrentNonTextToken();
4887 void nsHtml5Tokenizer::suspendIfRequestedAfterCurrentNonTextToken() {
4888 if (suspendAfterCurrentNonTextToken) {
4889 suspendAfterCurrentNonTextToken = false;
4890 shouldSuspend = true;
4894 void nsHtml5Tokenizer::suspendAfterCurrentTokenIfNotInText() {
4895 switch (stateSave) {
4896 case DATA:
4897 case RCDATA:
4898 case SCRIPT_DATA:
4899 case RAWTEXT:
4900 case SCRIPT_DATA_ESCAPED:
4901 case PLAINTEXT:
4902 case NON_DATA_END_TAG_NAME:
4903 case SCRIPT_DATA_LESS_THAN_SIGN:
4904 case SCRIPT_DATA_ESCAPE_START:
4905 case SCRIPT_DATA_ESCAPE_START_DASH:
4906 case SCRIPT_DATA_ESCAPED_DASH:
4907 case SCRIPT_DATA_ESCAPED_DASH_DASH:
4908 case RAWTEXT_RCDATA_LESS_THAN_SIGN:
4909 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
4910 case SCRIPT_DATA_DOUBLE_ESCAPE_START:
4911 case SCRIPT_DATA_DOUBLE_ESCAPED:
4912 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
4913 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
4914 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
4915 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
4916 return;
4918 case TAG_NAME:
4919 case BEFORE_ATTRIBUTE_NAME:
4920 case ATTRIBUTE_NAME:
4921 case AFTER_ATTRIBUTE_NAME:
4922 case BEFORE_ATTRIBUTE_VALUE:
4923 case AFTER_ATTRIBUTE_VALUE_QUOTED:
4924 case BOGUS_COMMENT:
4925 case MARKUP_DECLARATION_OPEN:
4926 case DOCTYPE:
4927 case BEFORE_DOCTYPE_NAME:
4928 case DOCTYPE_NAME:
4929 case AFTER_DOCTYPE_NAME:
4930 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
4931 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
4932 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
4933 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
4934 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
4935 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
4936 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
4937 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
4938 case BOGUS_DOCTYPE:
4939 case COMMENT_START:
4940 case COMMENT_START_DASH:
4941 case COMMENT:
4942 case COMMENT_END_DASH:
4943 case COMMENT_END:
4944 case COMMENT_END_BANG:
4945 case TAG_OPEN:
4946 case CLOSE_TAG_OPEN:
4947 case MARKUP_DECLARATION_HYPHEN:
4948 case MARKUP_DECLARATION_OCTYPE:
4949 case DOCTYPE_UBLIC:
4950 case DOCTYPE_YSTEM:
4951 case AFTER_DOCTYPE_PUBLIC_KEYWORD:
4952 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
4953 case AFTER_DOCTYPE_SYSTEM_KEYWORD:
4954 case SELF_CLOSING_START_TAG:
4955 case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
4956 case ATTRIBUTE_VALUE_SINGLE_QUOTED:
4957 case ATTRIBUTE_VALUE_UNQUOTED:
4958 case BOGUS_COMMENT_HYPHEN:
4959 case COMMENT_LESSTHAN:
4960 case COMMENT_LESSTHAN_BANG:
4961 case COMMENT_LESSTHAN_BANG_DASH:
4962 case COMMENT_LESSTHAN_BANG_DASH_DASH:
4963 case CDATA_START:
4964 case CDATA_SECTION:
4965 case CDATA_RSQB:
4966 case CDATA_RSQB_RSQB:
4967 case PROCESSING_INSTRUCTION:
4968 case PROCESSING_INSTRUCTION_QUESTION_MARK: {
4969 break;
4971 case CONSUME_CHARACTER_REFERENCE:
4972 case CONSUME_NCR:
4973 case CHARACTER_REFERENCE_TAIL:
4974 case HEX_NCR_LOOP:
4975 case DECIMAL_NRC_LOOP:
4976 case HANDLE_NCR_VALUE:
4977 case HANDLE_NCR_VALUE_RECONSUME:
4978 case CHARACTER_REFERENCE_HILO_LOOKUP: {
4979 if (returnStateSave == DATA || returnStateSave == RCDATA) {
4980 return;
4982 break;
4984 default: {
4985 MOZ_ASSERT(false, "Incomplete switch");
4986 return;
4989 suspendAfterCurrentNonTextToken = true;
4992 bool nsHtml5Tokenizer::suspensionAfterCurrentNonTextTokenPending() {
4993 return suspendAfterCurrentNonTextToken;
4996 bool nsHtml5Tokenizer::internalEncodingDeclaration(
4997 nsHtml5String internalCharset) {
4998 if (encodingDeclarationHandler) {
4999 return encodingDeclarationHandler->internalEncodingDeclaration(
5000 internalCharset);
5002 return false;
5005 void nsHtml5Tokenizer::emitOrAppendTwo(const char16_t* val,
5006 int32_t returnState) {
5007 if ((returnState & DATA_AND_RCDATA_MASK)) {
5008 appendStrBuf(val[0]);
5009 appendStrBuf(val[1]);
5010 } else {
5011 tokenHandler->characters(val, 0, 2);
5015 void nsHtml5Tokenizer::emitOrAppendOne(const char16_t* val,
5016 int32_t returnState) {
5017 if ((returnState & DATA_AND_RCDATA_MASK)) {
5018 appendStrBuf(val[0]);
5019 } else {
5020 tokenHandler->characters(val, 0, 1);
5024 void nsHtml5Tokenizer::end() {
5025 strBuf = nullptr;
5026 doctypeName = nullptr;
5027 if (systemIdentifier) {
5028 systemIdentifier.Release();
5029 systemIdentifier = nullptr;
5031 if (publicIdentifier) {
5032 publicIdentifier.Release();
5033 publicIdentifier = nullptr;
5035 tagName = nullptr;
5036 nonInternedTagName->setNameForNonInterned(nullptr, false);
5037 attributeName = nullptr;
5038 nonInternedAttributeName->setNameForNonInterned(nullptr);
5039 tokenHandler->endTokenization();
5040 if (attributes) {
5041 attributes->clear(0);
5045 void nsHtml5Tokenizer::requestSuspension() { shouldSuspend = true; }
5047 bool nsHtml5Tokenizer::isInDataState() { return (stateSave == DATA); }
5049 void nsHtml5Tokenizer::resetToDataState() {
5050 clearStrBufAfterUse();
5051 charRefBufLen = 0;
5052 stateSave = nsHtml5Tokenizer::DATA;
5053 lastCR = false;
5054 index = 0;
5055 forceQuirks = false;
5056 additional = '\0';
5057 entCol = -1;
5058 firstCharKey = -1;
5059 lo = 0;
5060 hi = 0;
5061 candidate = -1;
5062 charRefBufMark = 0;
5063 value = 0;
5064 seenDigits = false;
5065 suspendAfterCurrentNonTextToken = false;
5066 endTag = false;
5067 shouldSuspend = false;
5068 initDoctypeFields();
5069 containsHyphen = false;
5070 tagName = nullptr;
5071 attributeName = nullptr;
5072 if (newAttributesEachTime) {
5073 if (attributes) {
5074 delete attributes;
5075 attributes = nullptr;
5080 void nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other) {
5081 strBufLen = other->strBufLen;
5082 if (strBufLen > strBuf.length) {
5083 strBuf = jArray<char16_t, int32_t>::newJArray(strBufLen);
5085 nsHtml5ArrayCopy::arraycopy(other->strBuf, strBuf, strBufLen);
5086 charRefBufLen = other->charRefBufLen;
5087 nsHtml5ArrayCopy::arraycopy(other->charRefBuf, charRefBuf, charRefBufLen);
5088 stateSave = other->stateSave;
5089 returnStateSave = other->returnStateSave;
5090 endTagExpectation = other->endTagExpectation;
5091 endTagExpectationAsArray = other->endTagExpectationAsArray;
5092 lastCR = other->lastCR;
5093 index = other->index;
5094 forceQuirks = other->forceQuirks;
5095 additional = other->additional;
5096 entCol = other->entCol;
5097 firstCharKey = other->firstCharKey;
5098 lo = other->lo;
5099 hi = other->hi;
5100 candidate = other->candidate;
5101 charRefBufMark = other->charRefBufMark;
5102 value = other->value;
5103 seenDigits = other->seenDigits;
5104 endTag = other->endTag;
5105 shouldSuspend = false;
5106 suspendAfterCurrentNonTextToken = false;
5107 doctypeName = other->doctypeName;
5108 systemIdentifier.Release();
5109 if (!other->systemIdentifier) {
5110 systemIdentifier = nullptr;
5111 } else {
5112 systemIdentifier =
5113 nsHtml5Portability::newStringFromString(other->systemIdentifier);
5115 publicIdentifier.Release();
5116 if (!other->publicIdentifier) {
5117 publicIdentifier = nullptr;
5118 } else {
5119 publicIdentifier =
5120 nsHtml5Portability::newStringFromString(other->publicIdentifier);
5122 containsHyphen = other->containsHyphen;
5123 if (!other->tagName) {
5124 tagName = nullptr;
5125 } else if (other->tagName->isInterned()) {
5126 tagName = other->tagName;
5127 } else {
5128 nonInternedTagName->setNameForNonInterned(other->tagName->getName(),
5129 other->tagName->isCustom());
5130 tagName = nonInternedTagName;
5132 if (!other->attributeName) {
5133 attributeName = nullptr;
5134 } else if (other->attributeName->isInterned()) {
5135 attributeName = other->attributeName;
5136 } else {
5137 nonInternedAttributeName->setNameForNonInterned(
5138 other->attributeName->getLocal(nsHtml5AttributeName::HTML));
5139 attributeName = nonInternedAttributeName;
5141 delete attributes;
5142 if (!other->attributes) {
5143 attributes = nullptr;
5144 } else {
5145 attributes = other->attributes->cloneAttributes();
5149 void nsHtml5Tokenizer::initializeWithoutStarting() {
5150 confident = false;
5151 strBuf = nullptr;
5152 line = 1;
5153 attributeLine = 1;
5154 resetToDataState();
5157 void nsHtml5Tokenizer::setEncodingDeclarationHandler(
5158 nsHtml5StreamParser* encodingDeclarationHandler) {
5159 this->encodingDeclarationHandler = encodingDeclarationHandler;
5162 nsHtml5Tokenizer::~nsHtml5Tokenizer() {
5163 MOZ_COUNT_DTOR(nsHtml5Tokenizer);
5164 delete nonInternedTagName;
5165 nonInternedTagName = nullptr;
5166 delete nonInternedAttributeName;
5167 nonInternedAttributeName = nullptr;
5168 delete attributes;
5169 attributes = nullptr;
5172 void nsHtml5Tokenizer::initializeStatics() {}
5174 void nsHtml5Tokenizer::releaseStatics() {}
5176 #include "nsHtml5TokenizerCppSupplement.h"