Bug 1845715 - Check for failure when getting RegExp match result template r=iain
[gecko.git] / parser / html / nsHtml5Tokenizer.cpp
blobb5de5a9266637a689a752d5d62e95d99077db96b
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 "jArray.h"
34 #include "nsAHtml5TreeBuilderState.h"
35 #include "nsAtom.h"
36 #include "nsGkAtoms.h"
37 #include "nsHtml5ArrayCopy.h"
38 #include "nsHtml5AtomTable.h"
39 #include "nsHtml5DocumentMode.h"
40 #include "nsHtml5Highlighter.h"
41 #include "nsHtml5Macros.h"
42 #include "nsHtml5NamedCharacters.h"
43 #include "nsHtml5NamedCharactersAccel.h"
44 #include "nsHtml5String.h"
45 #include "nsHtml5TokenizerLoopPolicies.h"
46 #include "nsIContent.h"
47 #include "nsTraceRefcnt.h"
49 #include "nsHtml5AttributeName.h"
50 #include "nsHtml5ElementName.h"
51 #include "nsHtml5TreeBuilder.h"
52 #include "nsHtml5StackNode.h"
53 #include "nsHtml5UTF16Buffer.h"
54 #include "nsHtml5StateSnapshot.h"
55 #include "nsHtml5Portability.h"
57 #include "nsHtml5Tokenizer.h"
59 char16_t nsHtml5Tokenizer::LT_GT[] = {'<', '>'};
60 char16_t nsHtml5Tokenizer::LT_SOLIDUS[] = {'<', '/'};
61 char16_t nsHtml5Tokenizer::RSQB_RSQB[] = {']', ']'};
62 char16_t nsHtml5Tokenizer::REPLACEMENT_CHARACTER[] = {0xfffd};
63 char16_t nsHtml5Tokenizer::LF[] = {'\n'};
64 char16_t nsHtml5Tokenizer::CDATA_LSQB[] = {'C', 'D', 'A', 'T', 'A', '['};
65 char16_t nsHtml5Tokenizer::OCTYPE[] = {'o', 'c', 't', 'y', 'p', 'e'};
66 char16_t nsHtml5Tokenizer::UBLIC[] = {'u', 'b', 'l', 'i', 'c'};
67 char16_t nsHtml5Tokenizer::YSTEM[] = {'y', 's', 't', 'e', 'm'};
68 static char16_t const TITLE_ARR_DATA[] = {'t', 'i', 't', 'l', 'e'};
69 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TITLE_ARR = {
70 TITLE_ARR_DATA, MOZ_ARRAY_LENGTH(TITLE_ARR_DATA)};
71 static char16_t const SCRIPT_ARR_DATA[] = {'s', 'c', 'r', 'i', 'p', 't'};
72 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::SCRIPT_ARR = {
73 SCRIPT_ARR_DATA, MOZ_ARRAY_LENGTH(SCRIPT_ARR_DATA)};
74 static char16_t const STYLE_ARR_DATA[] = {'s', 't', 'y', 'l', 'e'};
75 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::STYLE_ARR = {
76 STYLE_ARR_DATA, MOZ_ARRAY_LENGTH(STYLE_ARR_DATA)};
77 static char16_t const PLAINTEXT_ARR_DATA[] = {'p', 'l', 'a', 'i', 'n',
78 't', 'e', 'x', 't'};
79 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::PLAINTEXT_ARR = {
80 PLAINTEXT_ARR_DATA, MOZ_ARRAY_LENGTH(PLAINTEXT_ARR_DATA)};
81 static char16_t const XMP_ARR_DATA[] = {'x', 'm', 'p'};
82 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::XMP_ARR = {
83 XMP_ARR_DATA, MOZ_ARRAY_LENGTH(XMP_ARR_DATA)};
84 static char16_t const TEXTAREA_ARR_DATA[] = {'t', 'e', 'x', 't',
85 'a', 'r', 'e', 'a'};
86 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TEXTAREA_ARR = {
87 TEXTAREA_ARR_DATA, MOZ_ARRAY_LENGTH(TEXTAREA_ARR_DATA)};
88 static char16_t const IFRAME_ARR_DATA[] = {'i', 'f', 'r', 'a', 'm', 'e'};
89 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::IFRAME_ARR = {
90 IFRAME_ARR_DATA, MOZ_ARRAY_LENGTH(IFRAME_ARR_DATA)};
91 static char16_t const NOEMBED_ARR_DATA[] = {'n', 'o', 'e', 'm', 'b', 'e', 'd'};
92 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOEMBED_ARR = {
93 NOEMBED_ARR_DATA, MOZ_ARRAY_LENGTH(NOEMBED_ARR_DATA)};
94 static char16_t const NOSCRIPT_ARR_DATA[] = {'n', 'o', 's', 'c',
95 'r', 'i', 'p', 't'};
96 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOSCRIPT_ARR = {
97 NOSCRIPT_ARR_DATA, MOZ_ARRAY_LENGTH(NOSCRIPT_ARR_DATA)};
98 static char16_t const NOFRAMES_ARR_DATA[] = {'n', 'o', 'f', 'r',
99 'a', 'm', 'e', 's'};
100 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOFRAMES_ARR = {
101 NOFRAMES_ARR_DATA, MOZ_ARRAY_LENGTH(NOFRAMES_ARR_DATA)};
103 nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler,
104 bool viewingXmlSource)
105 : tokenHandler(tokenHandler),
106 encodingDeclarationHandler(nullptr),
107 lastCR(false),
108 stateSave(0),
109 returnStateSave(0),
110 index(0),
111 forceQuirks(false),
112 additional('\0'),
113 entCol(0),
114 firstCharKey(0),
115 lo(0),
116 hi(0),
117 candidate(0),
118 charRefBufMark(0),
119 value(0),
120 seenDigits(false),
121 suspendAfterCurrentNonTextToken(false),
122 cstart(0),
123 strBufLen(0),
124 charRefBuf(jArray<char16_t, int32_t>::newJArray(32)),
125 charRefBufLen(0),
126 bmpChar(jArray<char16_t, int32_t>::newJArray(1)),
127 astralChar(jArray<char16_t, int32_t>::newJArray(2)),
128 endTagExpectation(nullptr),
129 endTagExpectationAsArray(nullptr),
130 endTag(false),
131 containsHyphen(false),
132 tagName(nullptr),
133 nonInternedTagName(new nsHtml5ElementName()),
134 attributeName(nullptr),
135 nonInternedAttributeName(new nsHtml5AttributeName()),
136 doctypeName(nullptr),
137 publicIdentifier(nullptr),
138 systemIdentifier(nullptr),
139 attributes(tokenHandler->HasBuilder() ? new nsHtml5HtmlAttributes(0)
140 : nullptr),
141 newAttributesEachTime(!tokenHandler->HasBuilder()),
142 shouldSuspend(false),
143 confident(false),
144 line(0),
145 attributeLine(0),
146 interner(nullptr),
147 viewingXmlSource(viewingXmlSource) {
148 MOZ_COUNT_CTOR(nsHtml5Tokenizer);
151 void nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner) {
152 this->interner = interner;
155 void nsHtml5Tokenizer::initLocation(nsHtml5String newPublicId,
156 nsHtml5String newSystemId) {
157 this->systemId = newSystemId;
158 this->publicId = newPublicId;
161 bool nsHtml5Tokenizer::isViewingXmlSource() { return viewingXmlSource; }
163 void nsHtml5Tokenizer::setState(int32_t specialTokenizerState) {
164 this->stateSave = specialTokenizerState;
165 this->endTagExpectation = nullptr;
166 this->endTagExpectationAsArray = nullptr;
169 void nsHtml5Tokenizer::setStateAndEndTagExpectation(
170 int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation) {
171 this->stateSave = specialTokenizerState;
172 this->endTagExpectation = endTagExpectation;
173 endTagExpectationToArray();
176 void nsHtml5Tokenizer::endTagExpectationToArray() {
177 switch (endTagExpectation->getGroup()) {
178 case nsHtml5TreeBuilder::TITLE: {
179 endTagExpectationAsArray = TITLE_ARR;
180 return;
182 case nsHtml5TreeBuilder::SCRIPT: {
183 endTagExpectationAsArray = SCRIPT_ARR;
184 return;
186 case nsHtml5TreeBuilder::STYLE: {
187 endTagExpectationAsArray = STYLE_ARR;
188 return;
190 case nsHtml5TreeBuilder::PLAINTEXT: {
191 endTagExpectationAsArray = PLAINTEXT_ARR;
192 return;
194 case nsHtml5TreeBuilder::XMP: {
195 endTagExpectationAsArray = XMP_ARR;
196 return;
198 case nsHtml5TreeBuilder::TEXTAREA: {
199 endTagExpectationAsArray = TEXTAREA_ARR;
200 return;
202 case nsHtml5TreeBuilder::IFRAME: {
203 endTagExpectationAsArray = IFRAME_ARR;
204 return;
206 case nsHtml5TreeBuilder::NOEMBED: {
207 endTagExpectationAsArray = NOEMBED_ARR;
208 return;
210 case nsHtml5TreeBuilder::NOSCRIPT: {
211 endTagExpectationAsArray = NOSCRIPT_ARR;
212 return;
214 case nsHtml5TreeBuilder::NOFRAMES: {
215 endTagExpectationAsArray = NOFRAMES_ARR;
216 return;
218 default: {
219 MOZ_ASSERT(false, "Bad end tag expectation.");
220 return;
225 void nsHtml5Tokenizer::setLineNumber(int32_t line) {
226 this->attributeLine = line;
227 this->line = line;
230 nsHtml5HtmlAttributes* nsHtml5Tokenizer::emptyAttributes() {
231 return nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES;
234 void nsHtml5Tokenizer::emitOrAppendCharRefBuf(int32_t returnState) {
235 if ((returnState & DATA_AND_RCDATA_MASK)) {
236 appendCharRefBufToStrBuf();
237 } else {
238 if (charRefBufLen > 0) {
239 tokenHandler->characters(charRefBuf, 0, charRefBufLen);
240 charRefBufLen = 0;
245 nsHtml5String nsHtml5Tokenizer::strBufToString() {
246 nsHtml5String str = nsHtml5Portability::newStringFromBuffer(
247 strBuf, 0, strBufLen, tokenHandler,
248 !newAttributesEachTime &&
249 attributeName == nsHtml5AttributeName::ATTR_CLASS);
250 clearStrBufAfterUse();
251 return str;
254 void nsHtml5Tokenizer::strBufToDoctypeName() {
255 doctypeName =
256 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen, interner);
257 clearStrBufAfterUse();
260 void nsHtml5Tokenizer::emitStrBuf() {
261 if (strBufLen > 0) {
262 tokenHandler->characters(strBuf, 0, strBufLen);
263 clearStrBufAfterUse();
267 void nsHtml5Tokenizer::appendStrBuf(char16_t* buffer, int32_t offset,
268 int32_t length) {
269 int32_t newLen = nsHtml5Portability::checkedAdd(strBufLen, length);
270 MOZ_ASSERT(newLen <= strBuf.length, "Previous buffer length insufficient.");
271 if (MOZ_UNLIKELY(strBuf.length < newLen)) {
272 if (MOZ_UNLIKELY(!EnsureBufferSpace(length))) {
273 MOZ_CRASH("Unable to recover from buffer reallocation failure");
276 nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length);
277 strBufLen = newLen;
280 void nsHtml5Tokenizer::emitComment(int32_t provisionalHyphens, int32_t pos) {
281 RememberGt(pos);
282 tokenHandler->comment(strBuf, 0, strBufLen - provisionalHyphens);
283 clearStrBufAfterUse();
284 cstart = pos + 1;
285 suspendIfRequestedAfterCurrentNonTextToken();
288 void nsHtml5Tokenizer::flushChars(char16_t* buf, int32_t pos) {
289 if (pos > cstart) {
290 tokenHandler->characters(buf, cstart, pos - cstart);
292 cstart = INT32_MAX;
295 void nsHtml5Tokenizer::strBufToElementNameString() {
296 if (containsHyphen) {
297 nsAtom* annotationName = nsHtml5ElementName::ELT_ANNOTATION_XML->getName();
298 if (nsHtml5Portability::localEqualsBuffer(annotationName, strBuf,
299 strBufLen)) {
300 tagName = nsHtml5ElementName::ELT_ANNOTATION_XML;
301 } else {
302 nonInternedTagName->setNameForNonInterned(
303 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
304 interner),
305 true);
306 tagName = nonInternedTagName;
308 } else {
309 tagName =
310 nsHtml5ElementName::elementNameByBuffer(strBuf, strBufLen, interner);
311 if (!tagName) {
312 nonInternedTagName->setNameForNonInterned(
313 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
314 interner),
315 false);
316 tagName = nonInternedTagName;
319 containsHyphen = false;
320 clearStrBufAfterUse();
323 int32_t nsHtml5Tokenizer::emitCurrentTagToken(bool selfClosing, int32_t pos) {
324 RememberGt(pos);
325 cstart = pos + 1;
326 maybeErrSlashInEndTag(selfClosing);
327 stateSave = nsHtml5Tokenizer::DATA;
328 nsHtml5HtmlAttributes* attrs =
329 (!attributes ? nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES : attributes);
330 if (endTag) {
331 maybeErrAttributesOnEndTag(attrs);
332 if (!viewingXmlSource) {
333 tokenHandler->endTag(tagName);
335 if (newAttributesEachTime) {
336 delete attributes;
337 attributes = nullptr;
339 } else {
340 if (viewingXmlSource) {
341 MOZ_ASSERT(newAttributesEachTime);
342 delete attributes;
343 attributes = nullptr;
344 } else {
345 tokenHandler->startTag(tagName, attrs, selfClosing);
348 tagName = nullptr;
349 if (newAttributesEachTime) {
350 attributes = nullptr;
351 } else {
352 attributes->clear(0);
354 suspendIfRequestedAfterCurrentNonTextToken();
355 return stateSave;
358 void nsHtml5Tokenizer::attributeNameComplete() {
359 attributeName =
360 nsHtml5AttributeName::nameByBuffer(strBuf, strBufLen, interner);
361 if (!attributeName) {
362 nonInternedAttributeName->setNameForNonInterned(
363 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
364 interner));
365 attributeName = nonInternedAttributeName;
367 clearStrBufAfterUse();
368 if (!attributes) {
369 attributes = new nsHtml5HtmlAttributes(0);
371 if (attributes->contains(attributeName)) {
372 errDuplicateAttribute();
373 attributeName = nullptr;
377 void nsHtml5Tokenizer::addAttributeWithoutValue() {
378 if (attributeName) {
379 attributes->addAttribute(
380 attributeName, nsHtml5Portability::newEmptyString(), attributeLine);
381 attributeName = nullptr;
382 } else {
383 clearStrBufAfterUse();
387 void nsHtml5Tokenizer::addAttributeWithValue() {
388 if (attributeName) {
389 nsHtml5String val = strBufToString();
390 if (mViewSource) {
391 mViewSource->MaybeLinkifyAttributeValue(attributeName, val);
393 attributes->addAttribute(attributeName, val, attributeLine);
394 attributeName = nullptr;
395 } else {
396 clearStrBufAfterUse();
400 void nsHtml5Tokenizer::start() {
401 initializeWithoutStarting();
402 tokenHandler->startTokenization(this);
403 line = 0;
404 col = 1;
405 nextCharOnNewLine = true;
408 bool nsHtml5Tokenizer::tokenizeBuffer(nsHtml5UTF16Buffer* buffer) {
409 int32_t state = stateSave;
410 int32_t returnState = returnStateSave;
411 char16_t c = '\0';
412 shouldSuspend = false;
413 lastCR = false;
414 int32_t start = buffer->getStart();
415 int32_t end = buffer->getEnd();
416 int32_t pos = start - 1;
417 switch (state) {
418 case DATA:
419 case RCDATA:
420 case SCRIPT_DATA:
421 case PLAINTEXT:
422 case RAWTEXT:
423 case CDATA_SECTION:
424 case SCRIPT_DATA_ESCAPED:
425 case SCRIPT_DATA_ESCAPE_START:
426 case SCRIPT_DATA_ESCAPE_START_DASH:
427 case SCRIPT_DATA_ESCAPED_DASH:
428 case SCRIPT_DATA_ESCAPED_DASH_DASH:
429 case SCRIPT_DATA_DOUBLE_ESCAPE_START:
430 case SCRIPT_DATA_DOUBLE_ESCAPED:
431 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
432 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
433 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
434 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
435 cstart = start;
436 break;
438 default: {
439 cstart = INT32_MAX;
440 break;
443 if (mViewSource) {
444 mViewSource->SetBuffer(buffer);
445 pos = stateLoop<nsHtml5ViewSourcePolicy>(state, c, pos, buffer->getBuffer(),
446 false, returnState,
447 buffer->getEnd());
448 mViewSource->DropBuffer((pos == buffer->getEnd()) ? pos : pos + 1);
449 } else {
450 pos = stateLoop<nsHtml5SilentPolicy>(state, c, pos, buffer->getBuffer(),
451 false, returnState, buffer->getEnd());
453 if (pos == end) {
454 buffer->setStart(pos);
455 } else {
456 buffer->setStart(pos + 1);
458 return lastCR;
461 template <class P>
462 int32_t nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos,
463 char16_t* buf, bool reconsume,
464 int32_t returnState, int32_t endPos) {
465 bool reportedConsecutiveHyphens = false;
466 stateloop:
467 for (;;) {
468 switch (state) {
469 case DATA: {
470 for (;;) {
471 if (reconsume) {
472 reconsume = false;
473 } else {
474 if (++pos == endPos) {
475 NS_HTML5_BREAK(stateloop);
477 c = checkChar(buf, pos);
479 switch (c) {
480 case '&': {
481 flushChars(buf, pos);
482 MOZ_ASSERT(!charRefBufLen,
483 "charRefBufLen not reset after previous use!");
484 appendCharRefBuf(c);
485 setAdditionalAndRememberAmpersandLocation('\0');
486 returnState = state;
487 state =
488 P::transition(mViewSource.get(),
489 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
490 reconsume, pos);
491 NS_HTML5_CONTINUE(stateloop);
493 case '<': {
494 flushChars(buf, pos);
495 state = P::transition(mViewSource.get(),
496 nsHtml5Tokenizer::TAG_OPEN, reconsume, pos);
497 NS_HTML5_BREAK(dataloop);
499 case '\0': {
500 maybeEmitReplacementCharacter(buf, pos);
501 continue;
503 case '\r': {
504 emitCarriageReturn(buf, pos);
505 NS_HTML5_BREAK(stateloop);
507 case '\n': {
508 silentLineFeed();
509 [[fallthrough]];
511 default: {
512 continue;
516 dataloop_end:;
517 [[fallthrough]];
519 case TAG_OPEN: {
520 for (;;) {
521 if (++pos == endPos) {
522 NS_HTML5_BREAK(stateloop);
524 c = checkChar(buf, pos);
525 if (c >= 'A' && c <= 'Z') {
526 endTag = false;
527 clearStrBufBeforeUse();
528 appendStrBuf((char16_t)(c + 0x20));
529 containsHyphen = false;
530 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
531 reconsume, pos);
532 NS_HTML5_BREAK(tagopenloop);
533 } else if (c >= 'a' && c <= 'z') {
534 endTag = false;
535 clearStrBufBeforeUse();
536 appendStrBuf(c);
537 containsHyphen = false;
538 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
539 reconsume, pos);
540 NS_HTML5_BREAK(tagopenloop);
542 switch (c) {
543 case '!': {
544 state = P::transition(mViewSource.get(),
545 nsHtml5Tokenizer::MARKUP_DECLARATION_OPEN,
546 reconsume, pos);
547 NS_HTML5_CONTINUE(stateloop);
549 case '/': {
550 state = P::transition(mViewSource.get(),
551 nsHtml5Tokenizer::CLOSE_TAG_OPEN, reconsume,
552 pos);
553 NS_HTML5_CONTINUE(stateloop);
555 case '\?': {
556 if (viewingXmlSource) {
557 state = P::transition(mViewSource.get(),
558 nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
559 reconsume, pos);
560 NS_HTML5_CONTINUE(stateloop);
562 if (P::reportErrors) {
563 errProcessingInstruction();
565 clearStrBufBeforeUse();
566 appendStrBuf(c);
567 state = P::transition(mViewSource.get(),
568 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
569 pos);
570 NS_HTML5_CONTINUE(stateloop);
572 case '>': {
573 if (P::reportErrors) {
574 errLtGt();
576 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
577 cstart = pos + 1;
578 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
579 reconsume, pos);
580 NS_HTML5_CONTINUE(stateloop);
582 default: {
583 if (P::reportErrors) {
584 errBadCharAfterLt(c);
586 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
587 cstart = pos;
588 reconsume = true;
589 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
590 reconsume, pos);
591 NS_HTML5_CONTINUE(stateloop);
595 tagopenloop_end:;
596 [[fallthrough]];
598 case TAG_NAME: {
599 for (;;) {
600 if (++pos == endPos) {
601 NS_HTML5_BREAK(stateloop);
603 c = checkChar(buf, pos);
604 switch (c) {
605 case '\r': {
606 silentCarriageReturn();
607 strBufToElementNameString();
608 state = P::transition(mViewSource.get(),
609 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
610 reconsume, pos);
611 NS_HTML5_BREAK(stateloop);
613 case '\n': {
614 silentLineFeed();
615 [[fallthrough]];
617 case ' ':
618 case '\t':
619 case '\f': {
620 strBufToElementNameString();
621 state = P::transition(mViewSource.get(),
622 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
623 reconsume, pos);
624 NS_HTML5_BREAK(tagnameloop);
626 case '/': {
627 strBufToElementNameString();
628 state = P::transition(mViewSource.get(),
629 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
630 reconsume, pos);
631 NS_HTML5_CONTINUE(stateloop);
633 case '>': {
634 strBufToElementNameString();
635 state = P::transition(mViewSource.get(),
636 emitCurrentTagToken(false, pos), reconsume,
637 pos);
638 if (shouldSuspend) {
639 NS_HTML5_BREAK(stateloop);
641 NS_HTML5_CONTINUE(stateloop);
643 case '\0': {
644 c = 0xfffd;
645 [[fallthrough]];
647 default: {
648 if (c >= 'A' && c <= 'Z') {
649 c += 0x20;
650 } else if (c == '-') {
651 containsHyphen = true;
653 appendStrBuf(c);
654 continue;
658 tagnameloop_end:;
659 [[fallthrough]];
661 case BEFORE_ATTRIBUTE_NAME: {
662 for (;;) {
663 if (reconsume) {
664 reconsume = false;
665 } else {
666 if (++pos == endPos) {
667 NS_HTML5_BREAK(stateloop);
669 c = checkChar(buf, pos);
671 switch (c) {
672 case '\r': {
673 silentCarriageReturn();
674 NS_HTML5_BREAK(stateloop);
676 case '\n': {
677 silentLineFeed();
678 [[fallthrough]];
680 case ' ':
681 case '\t':
682 case '\f': {
683 continue;
685 case '/': {
686 state = P::transition(mViewSource.get(),
687 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
688 reconsume, pos);
689 NS_HTML5_CONTINUE(stateloop);
691 case '>': {
692 state = P::transition(mViewSource.get(),
693 emitCurrentTagToken(false, pos), reconsume,
694 pos);
695 if (shouldSuspend) {
696 NS_HTML5_BREAK(stateloop);
698 NS_HTML5_CONTINUE(stateloop);
700 case '\0': {
701 c = 0xfffd;
702 [[fallthrough]];
704 case '\"':
705 case '\'':
706 case '<':
707 case '=': {
708 if (P::reportErrors) {
709 errBadCharBeforeAttributeNameOrNull(c);
711 [[fallthrough]];
713 default: {
714 if (c >= 'A' && c <= 'Z') {
715 c += 0x20;
717 attributeLine = line;
718 clearStrBufBeforeUse();
719 appendStrBuf(c);
720 state = P::transition(mViewSource.get(),
721 nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
722 pos);
723 NS_HTML5_BREAK(beforeattributenameloop);
727 beforeattributenameloop_end:;
728 [[fallthrough]];
730 case ATTRIBUTE_NAME: {
731 for (;;) {
732 if (++pos == endPos) {
733 NS_HTML5_BREAK(stateloop);
735 c = checkChar(buf, pos);
736 switch (c) {
737 case '\r': {
738 silentCarriageReturn();
739 attributeNameComplete();
740 state = P::transition(mViewSource.get(),
741 nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
742 reconsume, pos);
743 NS_HTML5_BREAK(stateloop);
745 case '\n': {
746 silentLineFeed();
747 [[fallthrough]];
749 case ' ':
750 case '\t':
751 case '\f': {
752 attributeNameComplete();
753 state = P::transition(mViewSource.get(),
754 nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
755 reconsume, pos);
756 NS_HTML5_CONTINUE(stateloop);
758 case '/': {
759 attributeNameComplete();
760 addAttributeWithoutValue();
761 state = P::transition(mViewSource.get(),
762 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
763 reconsume, pos);
764 NS_HTML5_CONTINUE(stateloop);
766 case '=': {
767 attributeNameComplete();
768 state = P::transition(mViewSource.get(),
769 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
770 reconsume, pos);
771 NS_HTML5_BREAK(attributenameloop);
773 case '>': {
774 attributeNameComplete();
775 addAttributeWithoutValue();
776 state = P::transition(mViewSource.get(),
777 emitCurrentTagToken(false, pos), reconsume,
778 pos);
779 if (shouldSuspend) {
780 NS_HTML5_BREAK(stateloop);
782 NS_HTML5_CONTINUE(stateloop);
784 case '\0': {
785 c = 0xfffd;
786 [[fallthrough]];
788 case '\"':
789 case '\'':
790 case '<': {
791 if (P::reportErrors) {
792 errQuoteOrLtInAttributeNameOrNull(c);
794 [[fallthrough]];
796 default: {
797 if (c >= 'A' && c <= 'Z') {
798 c += 0x20;
800 appendStrBuf(c);
801 continue;
805 attributenameloop_end:;
806 [[fallthrough]];
808 case BEFORE_ATTRIBUTE_VALUE: {
809 for (;;) {
810 if (++pos == endPos) {
811 NS_HTML5_BREAK(stateloop);
813 c = checkChar(buf, pos);
814 switch (c) {
815 case '\r': {
816 silentCarriageReturn();
817 NS_HTML5_BREAK(stateloop);
819 case '\n': {
820 silentLineFeed();
821 [[fallthrough]];
823 case ' ':
824 case '\t':
825 case '\f': {
826 continue;
828 case '\"': {
829 attributeLine = line;
830 clearStrBufBeforeUse();
831 state =
832 P::transition(mViewSource.get(),
833 nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED,
834 reconsume, pos);
835 NS_HTML5_BREAK(beforeattributevalueloop);
837 case '&': {
838 attributeLine = line;
839 clearStrBufBeforeUse();
840 reconsume = true;
841 state = P::transition(mViewSource.get(),
842 nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
843 reconsume, pos);
845 NS_HTML5_CONTINUE(stateloop);
847 case '\'': {
848 attributeLine = line;
849 clearStrBufBeforeUse();
850 state =
851 P::transition(mViewSource.get(),
852 nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED,
853 reconsume, pos);
854 NS_HTML5_CONTINUE(stateloop);
856 case '>': {
857 if (P::reportErrors) {
858 errAttributeValueMissing();
860 addAttributeWithoutValue();
861 state = P::transition(mViewSource.get(),
862 emitCurrentTagToken(false, pos), reconsume,
863 pos);
864 if (shouldSuspend) {
865 NS_HTML5_BREAK(stateloop);
867 NS_HTML5_CONTINUE(stateloop);
869 case '\0': {
870 c = 0xfffd;
871 [[fallthrough]];
873 case '<':
874 case '=':
875 case '`': {
876 if (P::reportErrors) {
877 errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
879 [[fallthrough]];
881 default: {
882 attributeLine = line;
883 clearStrBufBeforeUse();
884 appendStrBuf(c);
885 state = P::transition(mViewSource.get(),
886 nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
887 reconsume, pos);
889 NS_HTML5_CONTINUE(stateloop);
893 beforeattributevalueloop_end:;
894 [[fallthrough]];
896 case ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
897 for (;;) {
898 if (reconsume) {
899 reconsume = false;
900 } else {
901 if (++pos == endPos) {
902 NS_HTML5_BREAK(stateloop);
904 c = checkChar(buf, pos);
906 switch (c) {
907 case '\"': {
908 addAttributeWithValue();
909 state =
910 P::transition(mViewSource.get(),
911 nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
912 reconsume, pos);
913 NS_HTML5_BREAK(attributevaluedoublequotedloop);
915 case '&': {
916 MOZ_ASSERT(!charRefBufLen,
917 "charRefBufLen not reset after previous use!");
918 appendCharRefBuf(c);
919 setAdditionalAndRememberAmpersandLocation('\"');
920 returnState = state;
921 state =
922 P::transition(mViewSource.get(),
923 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
924 reconsume, pos);
925 NS_HTML5_CONTINUE(stateloop);
927 case '\r': {
928 appendStrBufCarriageReturn();
929 NS_HTML5_BREAK(stateloop);
931 case '\n': {
932 appendStrBufLineFeed();
933 continue;
935 case '\0': {
936 c = 0xfffd;
937 [[fallthrough]];
939 default: {
940 appendStrBuf(c);
941 continue;
945 attributevaluedoublequotedloop_end:;
946 [[fallthrough]];
948 case AFTER_ATTRIBUTE_VALUE_QUOTED: {
949 for (;;) {
950 if (++pos == endPos) {
951 NS_HTML5_BREAK(stateloop);
953 c = checkChar(buf, pos);
954 switch (c) {
955 case '\r': {
956 silentCarriageReturn();
957 state = P::transition(mViewSource.get(),
958 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
959 reconsume, pos);
960 NS_HTML5_BREAK(stateloop);
962 case '\n': {
963 silentLineFeed();
964 [[fallthrough]];
966 case ' ':
967 case '\t':
968 case '\f': {
969 state = P::transition(mViewSource.get(),
970 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
971 reconsume, pos);
972 NS_HTML5_CONTINUE(stateloop);
974 case '/': {
975 state = P::transition(mViewSource.get(),
976 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
977 reconsume, pos);
978 NS_HTML5_BREAK(afterattributevaluequotedloop);
980 case '>': {
981 state = P::transition(mViewSource.get(),
982 emitCurrentTagToken(false, pos), reconsume,
983 pos);
984 if (shouldSuspend) {
985 NS_HTML5_BREAK(stateloop);
987 NS_HTML5_CONTINUE(stateloop);
989 default: {
990 if (P::reportErrors) {
991 errNoSpaceBetweenAttributes();
993 reconsume = true;
994 state = P::transition(mViewSource.get(),
995 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
996 reconsume, pos);
997 NS_HTML5_CONTINUE(stateloop);
1001 afterattributevaluequotedloop_end:;
1002 [[fallthrough]];
1004 case SELF_CLOSING_START_TAG: {
1005 if (++pos == endPos) {
1006 NS_HTML5_BREAK(stateloop);
1008 c = checkChar(buf, pos);
1009 switch (c) {
1010 case '>': {
1011 state =
1012 P::transition(mViewSource.get(), emitCurrentTagToken(true, pos),
1013 reconsume, pos);
1014 if (shouldSuspend) {
1015 NS_HTML5_BREAK(stateloop);
1017 NS_HTML5_CONTINUE(stateloop);
1019 default: {
1020 if (P::reportErrors) {
1021 errSlashNotFollowedByGt();
1023 reconsume = true;
1024 state = P::transition(mViewSource.get(),
1025 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1026 reconsume, pos);
1027 NS_HTML5_CONTINUE(stateloop);
1031 case ATTRIBUTE_VALUE_UNQUOTED: {
1032 for (;;) {
1033 if (reconsume) {
1034 reconsume = false;
1035 } else {
1036 if (++pos == endPos) {
1037 NS_HTML5_BREAK(stateloop);
1039 c = checkChar(buf, pos);
1041 switch (c) {
1042 case '\r': {
1043 silentCarriageReturn();
1044 addAttributeWithValue();
1045 state = P::transition(mViewSource.get(),
1046 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1047 reconsume, pos);
1048 NS_HTML5_BREAK(stateloop);
1050 case '\n': {
1051 silentLineFeed();
1052 [[fallthrough]];
1054 case ' ':
1055 case '\t':
1056 case '\f': {
1057 addAttributeWithValue();
1058 state = P::transition(mViewSource.get(),
1059 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1060 reconsume, pos);
1061 NS_HTML5_CONTINUE(stateloop);
1063 case '&': {
1064 MOZ_ASSERT(!charRefBufLen,
1065 "charRefBufLen not reset after previous use!");
1066 appendCharRefBuf(c);
1067 setAdditionalAndRememberAmpersandLocation('>');
1068 returnState = state;
1069 state =
1070 P::transition(mViewSource.get(),
1071 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
1072 reconsume, pos);
1073 NS_HTML5_CONTINUE(stateloop);
1075 case '>': {
1076 addAttributeWithValue();
1077 state = P::transition(mViewSource.get(),
1078 emitCurrentTagToken(false, pos), reconsume,
1079 pos);
1080 if (shouldSuspend) {
1081 NS_HTML5_BREAK(stateloop);
1083 NS_HTML5_CONTINUE(stateloop);
1085 case '\0': {
1086 c = 0xfffd;
1087 [[fallthrough]];
1089 case '<':
1090 case '\"':
1091 case '\'':
1092 case '=':
1093 case '`': {
1094 if (P::reportErrors) {
1095 errUnquotedAttributeValOrNull(c);
1097 [[fallthrough]];
1099 default: {
1100 appendStrBuf(c);
1101 continue;
1106 case AFTER_ATTRIBUTE_NAME: {
1107 for (;;) {
1108 if (++pos == endPos) {
1109 NS_HTML5_BREAK(stateloop);
1111 c = checkChar(buf, pos);
1112 switch (c) {
1113 case '\r': {
1114 silentCarriageReturn();
1115 NS_HTML5_BREAK(stateloop);
1117 case '\n': {
1118 silentLineFeed();
1119 [[fallthrough]];
1121 case ' ':
1122 case '\t':
1123 case '\f': {
1124 continue;
1126 case '/': {
1127 addAttributeWithoutValue();
1128 state = P::transition(mViewSource.get(),
1129 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
1130 reconsume, pos);
1131 NS_HTML5_CONTINUE(stateloop);
1133 case '=': {
1134 state = P::transition(mViewSource.get(),
1135 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
1136 reconsume, pos);
1137 NS_HTML5_CONTINUE(stateloop);
1139 case '>': {
1140 addAttributeWithoutValue();
1141 state = P::transition(mViewSource.get(),
1142 emitCurrentTagToken(false, pos), reconsume,
1143 pos);
1144 if (shouldSuspend) {
1145 NS_HTML5_BREAK(stateloop);
1147 NS_HTML5_CONTINUE(stateloop);
1149 case '\0': {
1150 c = 0xfffd;
1151 [[fallthrough]];
1153 case '\"':
1154 case '\'':
1155 case '<': {
1156 if (P::reportErrors) {
1157 errQuoteOrLtInAttributeNameOrNull(c);
1159 [[fallthrough]];
1161 default: {
1162 addAttributeWithoutValue();
1163 if (c >= 'A' && c <= 'Z') {
1164 c += 0x20;
1166 clearStrBufBeforeUse();
1167 appendStrBuf(c);
1168 state = P::transition(mViewSource.get(),
1169 nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
1170 pos);
1171 NS_HTML5_CONTINUE(stateloop);
1176 case MARKUP_DECLARATION_OPEN: {
1177 for (;;) {
1178 if (++pos == endPos) {
1179 NS_HTML5_BREAK(stateloop);
1181 c = checkChar(buf, pos);
1182 switch (c) {
1183 case '-': {
1184 clearStrBufBeforeUse();
1185 appendStrBuf(c);
1186 state = P::transition(mViewSource.get(),
1187 nsHtml5Tokenizer::MARKUP_DECLARATION_HYPHEN,
1188 reconsume, pos);
1189 NS_HTML5_BREAK(markupdeclarationopenloop);
1191 case 'd':
1192 case 'D': {
1193 clearStrBufBeforeUse();
1194 appendStrBuf(c);
1195 index = 0;
1196 state = P::transition(mViewSource.get(),
1197 nsHtml5Tokenizer::MARKUP_DECLARATION_OCTYPE,
1198 reconsume, pos);
1199 NS_HTML5_CONTINUE(stateloop);
1201 case '[': {
1202 if (tokenHandler->cdataSectionAllowed()) {
1203 clearStrBufBeforeUse();
1204 appendStrBuf(c);
1205 index = 0;
1206 state = P::transition(mViewSource.get(),
1207 nsHtml5Tokenizer::CDATA_START, reconsume,
1208 pos);
1209 NS_HTML5_CONTINUE(stateloop);
1211 [[fallthrough]];
1213 default: {
1214 if (P::reportErrors) {
1215 errBogusComment();
1217 clearStrBufBeforeUse();
1218 reconsume = true;
1219 state = P::transition(mViewSource.get(),
1220 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1221 pos);
1222 NS_HTML5_CONTINUE(stateloop);
1226 markupdeclarationopenloop_end:;
1227 [[fallthrough]];
1229 case MARKUP_DECLARATION_HYPHEN: {
1230 for (;;) {
1231 if (++pos == endPos) {
1232 NS_HTML5_BREAK(stateloop);
1234 c = checkChar(buf, pos);
1235 switch (c) {
1236 case '-': {
1237 clearStrBufAfterOneHyphen();
1238 state = P::transition(mViewSource.get(),
1239 nsHtml5Tokenizer::COMMENT_START, reconsume,
1240 pos);
1241 NS_HTML5_BREAK(markupdeclarationhyphenloop);
1243 default: {
1244 if (P::reportErrors) {
1245 errBogusComment();
1247 reconsume = true;
1248 state = P::transition(mViewSource.get(),
1249 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1250 pos);
1251 NS_HTML5_CONTINUE(stateloop);
1255 markupdeclarationhyphenloop_end:;
1256 [[fallthrough]];
1258 case COMMENT_START: {
1259 reportedConsecutiveHyphens = false;
1260 for (;;) {
1261 if (++pos == endPos) {
1262 NS_HTML5_BREAK(stateloop);
1264 c = checkChar(buf, pos);
1265 switch (c) {
1266 case '-': {
1267 appendStrBuf(c);
1268 state = P::transition(mViewSource.get(),
1269 nsHtml5Tokenizer::COMMENT_START_DASH,
1270 reconsume, pos);
1271 NS_HTML5_CONTINUE(stateloop);
1273 case '>': {
1274 if (P::reportErrors) {
1275 errPrematureEndOfComment();
1277 emitComment(0, pos);
1278 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1279 reconsume, pos);
1280 if (shouldSuspend) {
1281 NS_HTML5_BREAK(stateloop);
1283 NS_HTML5_CONTINUE(stateloop);
1285 case '<': {
1286 appendStrBuf(c);
1287 state = P::transition(mViewSource.get(),
1288 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1289 reconsume, pos);
1290 NS_HTML5_CONTINUE(stateloop);
1292 case '\r': {
1293 appendStrBufCarriageReturn();
1294 state = P::transition(mViewSource.get(),
1295 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1296 NS_HTML5_BREAK(stateloop);
1298 case '\n': {
1299 appendStrBufLineFeed();
1300 state = P::transition(mViewSource.get(),
1301 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1302 NS_HTML5_BREAK(commentstartloop);
1304 case '\0': {
1305 c = 0xfffd;
1306 [[fallthrough]];
1308 default: {
1309 appendStrBuf(c);
1310 state = P::transition(mViewSource.get(),
1311 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1312 NS_HTML5_BREAK(commentstartloop);
1316 commentstartloop_end:;
1317 [[fallthrough]];
1319 case COMMENT: {
1320 for (;;) {
1321 if (++pos == endPos) {
1322 NS_HTML5_BREAK(stateloop);
1324 c = checkChar(buf, pos);
1325 switch (c) {
1326 case '-': {
1327 appendStrBuf(c);
1328 state = P::transition(mViewSource.get(),
1329 nsHtml5Tokenizer::COMMENT_END_DASH,
1330 reconsume, pos);
1331 NS_HTML5_BREAK(commentloop);
1333 case '<': {
1334 appendStrBuf(c);
1335 state = P::transition(mViewSource.get(),
1336 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1337 reconsume, pos);
1338 NS_HTML5_CONTINUE(stateloop);
1340 case '\r': {
1341 appendStrBufCarriageReturn();
1342 NS_HTML5_BREAK(stateloop);
1344 case '\n': {
1345 appendStrBufLineFeed();
1346 continue;
1348 case '\0': {
1349 c = 0xfffd;
1350 [[fallthrough]];
1352 default: {
1353 appendStrBuf(c);
1354 continue;
1358 commentloop_end:;
1359 [[fallthrough]];
1361 case COMMENT_END_DASH: {
1362 for (;;) {
1363 if (++pos == endPos) {
1364 NS_HTML5_BREAK(stateloop);
1366 c = checkChar(buf, pos);
1367 switch (c) {
1368 case '-': {
1369 appendStrBuf(c);
1370 state =
1371 P::transition(mViewSource.get(),
1372 nsHtml5Tokenizer::COMMENT_END, reconsume, pos);
1373 NS_HTML5_BREAK(commentenddashloop);
1375 case '<': {
1376 appendStrBuf(c);
1377 state = P::transition(mViewSource.get(),
1378 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1379 reconsume, pos);
1380 NS_HTML5_CONTINUE(stateloop);
1382 case '\r': {
1383 appendStrBufCarriageReturn();
1384 state = P::transition(mViewSource.get(),
1385 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1386 NS_HTML5_BREAK(stateloop);
1388 case '\n': {
1389 appendStrBufLineFeed();
1390 state = P::transition(mViewSource.get(),
1391 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1392 NS_HTML5_CONTINUE(stateloop);
1394 case '\0': {
1395 c = 0xfffd;
1396 [[fallthrough]];
1398 default: {
1399 appendStrBuf(c);
1400 state = P::transition(mViewSource.get(),
1401 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1402 NS_HTML5_CONTINUE(stateloop);
1406 commentenddashloop_end:;
1407 [[fallthrough]];
1409 case COMMENT_END: {
1410 for (;;) {
1411 if (++pos == endPos) {
1412 NS_HTML5_BREAK(stateloop);
1414 c = checkChar(buf, pos);
1415 switch (c) {
1416 case '>': {
1417 emitComment(2, pos);
1418 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1419 reconsume, pos);
1420 if (shouldSuspend) {
1421 NS_HTML5_BREAK(stateloop);
1423 NS_HTML5_CONTINUE(stateloop);
1425 case '-': {
1426 adjustDoubleHyphenAndAppendToStrBufAndErr(
1427 c, reportedConsecutiveHyphens);
1428 reportedConsecutiveHyphens = true;
1429 continue;
1431 case '<': {
1432 appendStrBuf(c);
1433 state = P::transition(mViewSource.get(),
1434 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1435 reconsume, pos);
1436 NS_HTML5_CONTINUE(stateloop);
1438 case '\r': {
1439 adjustDoubleHyphenAndAppendToStrBufCarriageReturn();
1440 state = P::transition(mViewSource.get(),
1441 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1442 NS_HTML5_BREAK(stateloop);
1444 case '\n': {
1445 adjustDoubleHyphenAndAppendToStrBufLineFeed();
1446 state = P::transition(mViewSource.get(),
1447 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1448 NS_HTML5_CONTINUE(stateloop);
1450 case '!': {
1451 appendStrBuf(c);
1452 state = P::transition(mViewSource.get(),
1453 nsHtml5Tokenizer::COMMENT_END_BANG,
1454 reconsume, pos);
1455 NS_HTML5_BREAK(commentendloop);
1457 case '\0': {
1458 c = 0xfffd;
1459 [[fallthrough]];
1461 default: {
1462 adjustDoubleHyphenAndAppendToStrBufAndErr(
1463 c, reportedConsecutiveHyphens);
1464 reportedConsecutiveHyphens = true;
1465 state = P::transition(mViewSource.get(),
1466 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1467 NS_HTML5_CONTINUE(stateloop);
1471 commentendloop_end:;
1472 [[fallthrough]];
1474 case COMMENT_END_BANG: {
1475 for (;;) {
1476 if (++pos == endPos) {
1477 NS_HTML5_BREAK(stateloop);
1479 c = checkChar(buf, pos);
1480 switch (c) {
1481 case '>': {
1482 emitComment(3, pos);
1483 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1484 reconsume, pos);
1485 if (shouldSuspend) {
1486 NS_HTML5_BREAK(stateloop);
1488 NS_HTML5_CONTINUE(stateloop);
1490 case '-': {
1491 appendStrBuf(c);
1492 state = P::transition(mViewSource.get(),
1493 nsHtml5Tokenizer::COMMENT_END_DASH,
1494 reconsume, pos);
1495 NS_HTML5_CONTINUE(stateloop);
1497 case '\r': {
1498 appendStrBufCarriageReturn();
1499 state = P::transition(mViewSource.get(),
1500 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1501 NS_HTML5_BREAK(stateloop);
1503 case '\n': {
1504 appendStrBufLineFeed();
1505 state = P::transition(mViewSource.get(),
1506 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1507 NS_HTML5_CONTINUE(stateloop);
1509 case '\0': {
1510 c = 0xfffd;
1511 [[fallthrough]];
1513 default: {
1514 appendStrBuf(c);
1515 state = P::transition(mViewSource.get(),
1516 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1517 NS_HTML5_CONTINUE(stateloop);
1522 case COMMENT_LESSTHAN: {
1523 for (;;) {
1524 if (++pos == endPos) {
1525 NS_HTML5_BREAK(stateloop);
1527 c = checkChar(buf, pos);
1528 switch (c) {
1529 case '!': {
1530 appendStrBuf(c);
1531 state = P::transition(mViewSource.get(),
1532 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG,
1533 reconsume, pos);
1534 NS_HTML5_BREAK(commentlessthanloop);
1536 case '<': {
1537 appendStrBuf(c);
1538 continue;
1540 case '-': {
1541 appendStrBuf(c);
1542 state = P::transition(mViewSource.get(),
1543 nsHtml5Tokenizer::COMMENT_END_DASH,
1544 reconsume, pos);
1545 NS_HTML5_CONTINUE(stateloop);
1547 case '\r': {
1548 appendStrBufCarriageReturn();
1549 state = P::transition(mViewSource.get(),
1550 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1551 NS_HTML5_BREAK(stateloop);
1553 case '\n': {
1554 appendStrBufLineFeed();
1555 state = P::transition(mViewSource.get(),
1556 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1557 NS_HTML5_CONTINUE(stateloop);
1559 case '\0': {
1560 c = 0xfffd;
1561 [[fallthrough]];
1563 default: {
1564 appendStrBuf(c);
1565 state = P::transition(mViewSource.get(),
1566 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1567 NS_HTML5_CONTINUE(stateloop);
1571 commentlessthanloop_end:;
1572 [[fallthrough]];
1574 case COMMENT_LESSTHAN_BANG: {
1575 for (;;) {
1576 if (++pos == endPos) {
1577 NS_HTML5_BREAK(stateloop);
1579 c = checkChar(buf, pos);
1580 switch (c) {
1581 case '-': {
1582 appendStrBuf(c);
1583 state = P::transition(
1584 mViewSource.get(),
1585 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH, reconsume, pos);
1586 NS_HTML5_BREAK(commentlessthanbangloop);
1588 case '<': {
1589 appendStrBuf(c);
1590 state = P::transition(mViewSource.get(),
1591 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1592 reconsume, pos);
1593 NS_HTML5_CONTINUE(stateloop);
1595 case '\r': {
1596 appendStrBufCarriageReturn();
1597 state = P::transition(mViewSource.get(),
1598 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1599 NS_HTML5_BREAK(stateloop);
1601 case '\n': {
1602 appendStrBufLineFeed();
1603 state = P::transition(mViewSource.get(),
1604 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1605 NS_HTML5_CONTINUE(stateloop);
1607 case '\0': {
1608 c = 0xfffd;
1609 [[fallthrough]];
1611 default: {
1612 appendStrBuf(c);
1613 state = P::transition(mViewSource.get(),
1614 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1615 NS_HTML5_CONTINUE(stateloop);
1619 commentlessthanbangloop_end:;
1620 [[fallthrough]];
1622 case COMMENT_LESSTHAN_BANG_DASH: {
1623 if (++pos == endPos) {
1624 NS_HTML5_BREAK(stateloop);
1626 c = checkChar(buf, pos);
1627 switch (c) {
1628 case '-': {
1629 appendStrBuf(c);
1630 state =
1631 P::transition(mViewSource.get(),
1632 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH,
1633 reconsume, pos);
1634 break;
1636 case '<': {
1637 appendStrBuf(c);
1638 state = P::transition(mViewSource.get(),
1639 nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
1640 pos);
1641 NS_HTML5_CONTINUE(stateloop);
1643 case '\r': {
1644 appendStrBufCarriageReturn();
1645 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1646 reconsume, pos);
1647 NS_HTML5_BREAK(stateloop);
1649 case '\n': {
1650 appendStrBufLineFeed();
1651 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1652 reconsume, pos);
1653 NS_HTML5_CONTINUE(stateloop);
1655 case '\0': {
1656 c = 0xfffd;
1657 [[fallthrough]];
1659 default: {
1660 appendStrBuf(c);
1661 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1662 reconsume, pos);
1663 NS_HTML5_CONTINUE(stateloop);
1666 [[fallthrough]];
1668 case COMMENT_LESSTHAN_BANG_DASH_DASH: {
1669 if (++pos == endPos) {
1670 NS_HTML5_BREAK(stateloop);
1672 c = checkChar(buf, pos);
1673 switch (c) {
1674 case '>': {
1675 appendStrBuf(c);
1676 emitComment(3, pos);
1677 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1678 reconsume, pos);
1679 if (shouldSuspend) {
1680 NS_HTML5_BREAK(stateloop);
1682 NS_HTML5_CONTINUE(stateloop);
1684 case '-': {
1685 if (P::reportErrors) {
1686 errNestedComment();
1688 adjustDoubleHyphenAndAppendToStrBufAndErr(
1689 c, reportedConsecutiveHyphens);
1690 reportedConsecutiveHyphens = true;
1691 state =
1692 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
1693 reconsume, pos);
1694 NS_HTML5_CONTINUE(stateloop);
1696 case '\r': {
1697 c = '\n';
1698 silentCarriageReturn();
1699 if (P::reportErrors) {
1700 errNestedComment();
1702 adjustDoubleHyphenAndAppendToStrBufAndErr(
1703 c, reportedConsecutiveHyphens);
1704 reportedConsecutiveHyphens = true;
1705 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1706 reconsume, pos);
1707 NS_HTML5_BREAK(stateloop);
1709 case '\n': {
1710 silentLineFeed();
1711 if (P::reportErrors) {
1712 errNestedComment();
1714 adjustDoubleHyphenAndAppendToStrBufAndErr(
1715 c, reportedConsecutiveHyphens);
1716 reportedConsecutiveHyphens = true;
1717 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1718 reconsume, pos);
1719 NS_HTML5_CONTINUE(stateloop);
1721 case '!': {
1722 if (P::reportErrors) {
1723 errNestedComment();
1725 adjustDoubleHyphenAndAppendToStrBufAndErr(
1726 c, reportedConsecutiveHyphens);
1727 reportedConsecutiveHyphens = true;
1728 state = P::transition(mViewSource.get(),
1729 nsHtml5Tokenizer::COMMENT_END_BANG, reconsume,
1730 pos);
1731 NS_HTML5_CONTINUE(stateloop);
1733 case '\0': {
1734 c = 0xfffd;
1735 [[fallthrough]];
1737 default: {
1738 if (P::reportErrors) {
1739 errNestedComment();
1741 adjustDoubleHyphenAndAppendToStrBufAndErr(
1742 c, reportedConsecutiveHyphens);
1743 reportedConsecutiveHyphens = true;
1744 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1745 reconsume, pos);
1746 NS_HTML5_CONTINUE(stateloop);
1750 case COMMENT_START_DASH: {
1751 if (++pos == endPos) {
1752 NS_HTML5_BREAK(stateloop);
1754 c = checkChar(buf, pos);
1755 switch (c) {
1756 case '-': {
1757 appendStrBuf(c);
1758 state =
1759 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
1760 reconsume, pos);
1761 NS_HTML5_CONTINUE(stateloop);
1763 case '>': {
1764 if (P::reportErrors) {
1765 errPrematureEndOfComment();
1767 emitComment(1, pos);
1768 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1769 reconsume, pos);
1770 if (shouldSuspend) {
1771 NS_HTML5_BREAK(stateloop);
1773 NS_HTML5_CONTINUE(stateloop);
1775 case '<': {
1776 appendStrBuf(c);
1777 state = P::transition(mViewSource.get(),
1778 nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
1779 pos);
1780 NS_HTML5_CONTINUE(stateloop);
1782 case '\r': {
1783 appendStrBufCarriageReturn();
1784 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1785 reconsume, pos);
1786 NS_HTML5_BREAK(stateloop);
1788 case '\n': {
1789 appendStrBufLineFeed();
1790 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1791 reconsume, pos);
1792 NS_HTML5_CONTINUE(stateloop);
1794 case '\0': {
1795 c = 0xfffd;
1796 [[fallthrough]];
1798 default: {
1799 appendStrBuf(c);
1800 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1801 reconsume, pos);
1802 NS_HTML5_CONTINUE(stateloop);
1806 case CDATA_START: {
1807 for (;;) {
1808 if (++pos == endPos) {
1809 NS_HTML5_BREAK(stateloop);
1811 c = checkChar(buf, pos);
1812 if (index < 6) {
1813 if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
1814 appendStrBuf(c);
1815 } else {
1816 if (P::reportErrors) {
1817 errBogusComment();
1819 reconsume = true;
1820 state = P::transition(mViewSource.get(),
1821 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1822 pos);
1823 NS_HTML5_CONTINUE(stateloop);
1825 index++;
1826 continue;
1827 } else {
1828 clearStrBufAfterUse();
1829 cstart = pos;
1830 reconsume = true;
1831 state =
1832 P::transition(mViewSource.get(),
1833 nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
1834 break;
1837 [[fallthrough]];
1839 case CDATA_SECTION: {
1840 for (;;) {
1841 if (reconsume) {
1842 reconsume = false;
1843 } else {
1844 if (++pos == endPos) {
1845 NS_HTML5_BREAK(stateloop);
1847 c = checkChar(buf, pos);
1849 switch (c) {
1850 case ']': {
1851 flushChars(buf, pos);
1852 state =
1853 P::transition(mViewSource.get(), nsHtml5Tokenizer::CDATA_RSQB,
1854 reconsume, pos);
1855 NS_HTML5_BREAK(cdatasectionloop);
1857 case '\0': {
1858 maybeEmitReplacementCharacter(buf, pos);
1859 continue;
1861 case '\r': {
1862 emitCarriageReturn(buf, pos);
1863 NS_HTML5_BREAK(stateloop);
1865 case '\n': {
1866 silentLineFeed();
1867 [[fallthrough]];
1869 default: {
1870 continue;
1874 cdatasectionloop_end:;
1875 [[fallthrough]];
1877 case CDATA_RSQB: {
1878 if (++pos == endPos) {
1879 NS_HTML5_BREAK(stateloop);
1881 c = checkChar(buf, pos);
1882 switch (c) {
1883 case ']': {
1884 state = P::transition(mViewSource.get(),
1885 nsHtml5Tokenizer::CDATA_RSQB_RSQB, reconsume,
1886 pos);
1887 break;
1889 default: {
1890 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
1891 cstart = pos;
1892 reconsume = true;
1893 state =
1894 P::transition(mViewSource.get(),
1895 nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
1896 NS_HTML5_CONTINUE(stateloop);
1899 [[fallthrough]];
1901 case CDATA_RSQB_RSQB: {
1902 for (;;) {
1903 if (++pos == endPos) {
1904 NS_HTML5_BREAK(stateloop);
1906 c = checkChar(buf, pos);
1907 switch (c) {
1908 case ']': {
1909 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
1910 continue;
1912 case '>': {
1913 cstart = pos + 1;
1914 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1915 reconsume, pos);
1916 suspendIfRequestedAfterCurrentNonTextToken();
1917 if (shouldSuspend) {
1918 NS_HTML5_BREAK(stateloop);
1920 NS_HTML5_CONTINUE(stateloop);
1922 default: {
1923 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
1924 cstart = pos;
1925 reconsume = true;
1926 state = P::transition(mViewSource.get(),
1927 nsHtml5Tokenizer::CDATA_SECTION, reconsume,
1928 pos);
1929 NS_HTML5_CONTINUE(stateloop);
1934 case ATTRIBUTE_VALUE_SINGLE_QUOTED: {
1935 for (;;) {
1936 if (reconsume) {
1937 reconsume = false;
1938 } else {
1939 if (++pos == endPos) {
1940 NS_HTML5_BREAK(stateloop);
1942 c = checkChar(buf, pos);
1944 switch (c) {
1945 case '\'': {
1946 addAttributeWithValue();
1947 state =
1948 P::transition(mViewSource.get(),
1949 nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
1950 reconsume, pos);
1951 NS_HTML5_CONTINUE(stateloop);
1953 case '&': {
1954 MOZ_ASSERT(!charRefBufLen,
1955 "charRefBufLen not reset after previous use!");
1956 appendCharRefBuf(c);
1957 setAdditionalAndRememberAmpersandLocation('\'');
1958 returnState = state;
1959 state =
1960 P::transition(mViewSource.get(),
1961 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
1962 reconsume, pos);
1963 NS_HTML5_BREAK(attributevaluesinglequotedloop);
1965 case '\r': {
1966 appendStrBufCarriageReturn();
1967 NS_HTML5_BREAK(stateloop);
1969 case '\n': {
1970 appendStrBufLineFeed();
1971 continue;
1973 case '\0': {
1974 c = 0xfffd;
1975 [[fallthrough]];
1977 default: {
1978 appendStrBuf(c);
1979 continue;
1983 attributevaluesinglequotedloop_end:;
1984 [[fallthrough]];
1986 case CONSUME_CHARACTER_REFERENCE: {
1987 if (++pos == endPos) {
1988 NS_HTML5_BREAK(stateloop);
1990 c = checkChar(buf, pos);
1991 switch (c) {
1992 case ' ':
1993 case '\t':
1994 case '\n':
1995 case '\r':
1996 case '\f':
1997 case '<':
1998 case '&':
1999 case '\0':
2000 case ';': {
2001 emitOrAppendCharRefBuf(returnState);
2002 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2003 cstart = pos;
2005 reconsume = true;
2006 state =
2007 P::transition(mViewSource.get(), returnState, reconsume, pos);
2008 NS_HTML5_CONTINUE(stateloop);
2010 case '#': {
2011 appendCharRefBuf('#');
2012 state =
2013 P::transition(mViewSource.get(), nsHtml5Tokenizer::CONSUME_NCR,
2014 reconsume, pos);
2015 NS_HTML5_CONTINUE(stateloop);
2017 default: {
2018 if (c == additional) {
2019 emitOrAppendCharRefBuf(returnState);
2020 reconsume = true;
2021 state =
2022 P::transition(mViewSource.get(), returnState, reconsume, pos);
2023 NS_HTML5_CONTINUE(stateloop);
2025 if (c >= 'a' && c <= 'z') {
2026 firstCharKey = c - 'a' + 26;
2027 } else if (c >= 'A' && c <= 'Z') {
2028 firstCharKey = c - 'A';
2029 } else {
2030 if (c == ';') {
2031 if (P::reportErrors) {
2032 errNoNamedCharacterMatch();
2035 emitOrAppendCharRefBuf(returnState);
2036 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2037 cstart = pos;
2039 reconsume = true;
2040 state =
2041 P::transition(mViewSource.get(), returnState, reconsume, pos);
2042 NS_HTML5_CONTINUE(stateloop);
2044 appendCharRefBuf(c);
2045 state =
2046 P::transition(mViewSource.get(),
2047 nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP,
2048 reconsume, pos);
2049 break;
2052 [[fallthrough]];
2054 case CHARACTER_REFERENCE_HILO_LOOKUP: {
2056 if (++pos == endPos) {
2057 NS_HTML5_BREAK(stateloop);
2059 c = checkChar(buf, pos);
2060 int32_t hilo = 0;
2061 if (c <= 'z') {
2062 const int32_t* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c];
2063 if (row) {
2064 hilo = row[firstCharKey];
2067 if (!hilo) {
2068 if (c == ';') {
2069 if (P::reportErrors) {
2070 errNoNamedCharacterMatch();
2073 emitOrAppendCharRefBuf(returnState);
2074 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2075 cstart = pos;
2077 reconsume = true;
2078 state =
2079 P::transition(mViewSource.get(), returnState, reconsume, pos);
2080 NS_HTML5_CONTINUE(stateloop);
2082 appendCharRefBuf(c);
2083 lo = hilo & 0xFFFF;
2084 hi = hilo >> 16;
2085 entCol = -1;
2086 candidate = -1;
2087 charRefBufMark = 0;
2088 state = P::transition(mViewSource.get(),
2089 nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL,
2090 reconsume, pos);
2092 [[fallthrough]];
2094 case CHARACTER_REFERENCE_TAIL: {
2095 for (;;) {
2096 if (++pos == endPos) {
2097 NS_HTML5_BREAK(stateloop);
2099 c = checkChar(buf, pos);
2100 entCol++;
2101 for (;;) {
2102 if (hi < lo) {
2103 NS_HTML5_BREAK(outer);
2105 if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
2106 candidate = lo;
2107 charRefBufMark = charRefBufLen;
2108 lo++;
2109 } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
2110 NS_HTML5_BREAK(outer);
2111 } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
2112 lo++;
2113 } else {
2114 NS_HTML5_BREAK(loloop);
2117 loloop_end:;
2118 for (;;) {
2119 if (hi < lo) {
2120 NS_HTML5_BREAK(outer);
2122 if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
2123 NS_HTML5_BREAK(hiloop);
2125 if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
2126 NS_HTML5_BREAK(outer);
2127 } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
2128 hi--;
2129 } else {
2130 NS_HTML5_BREAK(hiloop);
2133 hiloop_end:;
2134 if (c == ';') {
2135 if (entCol + 1 == nsHtml5NamedCharacters::NAMES[lo].length()) {
2136 candidate = lo;
2137 charRefBufMark = charRefBufLen;
2139 NS_HTML5_BREAK(outer);
2141 if (hi < lo) {
2142 NS_HTML5_BREAK(outer);
2144 appendCharRefBuf(c);
2145 continue;
2147 outer_end:;
2148 if (candidate == -1) {
2149 if (c == ';') {
2150 if (P::reportErrors) {
2151 errNoNamedCharacterMatch();
2154 emitOrAppendCharRefBuf(returnState);
2155 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2156 cstart = pos;
2158 reconsume = true;
2159 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2160 NS_HTML5_CONTINUE(stateloop);
2161 } else {
2162 const nsHtml5CharacterName& candidateName =
2163 nsHtml5NamedCharacters::NAMES[candidate];
2164 if (!candidateName.length() ||
2165 candidateName.charAt(candidateName.length() - 1) != ';') {
2166 if ((returnState & DATA_AND_RCDATA_MASK)) {
2167 char16_t ch;
2168 if (charRefBufMark == charRefBufLen) {
2169 ch = c;
2170 } else {
2171 ch = charRefBuf[charRefBufMark];
2173 if (ch == '=' || (ch >= '0' && ch <= '9') ||
2174 (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
2175 if (c == ';') {
2176 if (P::reportErrors) {
2177 errNoNamedCharacterMatch();
2180 appendCharRefBufToStrBuf();
2181 reconsume = true;
2182 state = P::transition(mViewSource.get(), returnState, reconsume,
2183 pos);
2184 NS_HTML5_CONTINUE(stateloop);
2187 if ((returnState & DATA_AND_RCDATA_MASK)) {
2188 if (P::reportErrors) {
2189 errUnescapedAmpersandInterpretedAsCharacterReference();
2191 } else {
2192 if (P::reportErrors) {
2193 errNotSemicolonTerminated();
2197 P::completedNamedCharacterReference(mViewSource.get());
2198 const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
2199 if (!val[1]) {
2200 emitOrAppendOne(val, returnState);
2201 } else {
2202 emitOrAppendTwo(val, returnState);
2204 if (charRefBufMark < charRefBufLen) {
2205 if ((returnState & DATA_AND_RCDATA_MASK)) {
2206 appendStrBuf(charRefBuf, charRefBufMark,
2207 charRefBufLen - charRefBufMark);
2208 } else {
2209 tokenHandler->characters(charRefBuf, charRefBufMark,
2210 charRefBufLen - charRefBufMark);
2213 bool earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
2214 charRefBufLen = 0;
2215 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2216 cstart = earlyBreak ? pos + 1 : pos;
2218 reconsume = !earlyBreak;
2219 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2220 NS_HTML5_CONTINUE(stateloop);
2223 case CONSUME_NCR: {
2224 if (++pos == endPos) {
2225 NS_HTML5_BREAK(stateloop);
2227 c = checkChar(buf, pos);
2228 value = 0;
2229 seenDigits = false;
2230 switch (c) {
2231 case 'x':
2232 case 'X': {
2233 appendCharRefBuf(c);
2234 state =
2235 P::transition(mViewSource.get(), nsHtml5Tokenizer::HEX_NCR_LOOP,
2236 reconsume, pos);
2237 NS_HTML5_CONTINUE(stateloop);
2239 default: {
2240 reconsume = true;
2241 state = P::transition(mViewSource.get(),
2242 nsHtml5Tokenizer::DECIMAL_NRC_LOOP, reconsume,
2243 pos);
2244 break;
2247 [[fallthrough]];
2249 case DECIMAL_NRC_LOOP: {
2250 for (;;) {
2251 if (reconsume) {
2252 reconsume = false;
2253 } else {
2254 if (++pos == endPos) {
2255 NS_HTML5_BREAK(stateloop);
2257 c = checkChar(buf, pos);
2259 MOZ_ASSERT(value >= 0, "value must not become negative.");
2260 if (c >= '0' && c <= '9') {
2261 seenDigits = true;
2262 if (value <= 0x10FFFF) {
2263 value *= 10;
2264 value += c - '0';
2266 continue;
2267 } else if (c == ';') {
2268 if (seenDigits) {
2269 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2270 cstart = pos + 1;
2272 state = P::transition(mViewSource.get(),
2273 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2274 reconsume, pos);
2275 NS_HTML5_BREAK(decimalloop);
2276 } else {
2277 if (P::reportErrors) {
2278 errNoDigitsInNCR();
2280 appendCharRefBuf(';');
2281 emitOrAppendCharRefBuf(returnState);
2282 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2283 cstart = pos + 1;
2285 state =
2286 P::transition(mViewSource.get(), returnState, reconsume, pos);
2287 NS_HTML5_CONTINUE(stateloop);
2289 } else {
2290 if (!seenDigits) {
2291 if (P::reportErrors) {
2292 errNoDigitsInNCR();
2294 emitOrAppendCharRefBuf(returnState);
2295 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2296 cstart = pos;
2298 reconsume = true;
2299 state =
2300 P::transition(mViewSource.get(), returnState, reconsume, pos);
2301 NS_HTML5_CONTINUE(stateloop);
2302 } else {
2303 if (P::reportErrors) {
2304 errCharRefLacksSemicolon();
2306 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2307 cstart = pos;
2309 reconsume = true;
2310 state = P::transition(mViewSource.get(),
2311 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2312 reconsume, pos);
2313 NS_HTML5_BREAK(decimalloop);
2317 decimalloop_end:;
2318 [[fallthrough]];
2320 case HANDLE_NCR_VALUE: {
2321 charRefBufLen = 0;
2322 handleNcrValue(returnState);
2323 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2324 NS_HTML5_CONTINUE(stateloop);
2326 case HEX_NCR_LOOP: {
2327 for (;;) {
2328 if (++pos == endPos) {
2329 NS_HTML5_BREAK(stateloop);
2331 c = checkChar(buf, pos);
2332 MOZ_ASSERT(value >= 0, "value must not become negative.");
2333 if (c >= '0' && c <= '9') {
2334 seenDigits = true;
2335 if (value <= 0x10FFFF) {
2336 value *= 16;
2337 value += c - '0';
2339 continue;
2340 } else if (c >= 'A' && c <= 'F') {
2341 seenDigits = true;
2342 if (value <= 0x10FFFF) {
2343 value *= 16;
2344 value += c - 'A' + 10;
2346 continue;
2347 } else if (c >= 'a' && c <= 'f') {
2348 seenDigits = true;
2349 if (value <= 0x10FFFF) {
2350 value *= 16;
2351 value += c - 'a' + 10;
2353 continue;
2354 } else if (c == ';') {
2355 if (seenDigits) {
2356 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2357 cstart = pos + 1;
2359 state = P::transition(mViewSource.get(),
2360 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2361 reconsume, pos);
2362 NS_HTML5_CONTINUE(stateloop);
2363 } else {
2364 if (P::reportErrors) {
2365 errNoDigitsInNCR();
2367 appendCharRefBuf(';');
2368 emitOrAppendCharRefBuf(returnState);
2369 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2370 cstart = pos + 1;
2372 state =
2373 P::transition(mViewSource.get(), returnState, reconsume, pos);
2374 NS_HTML5_CONTINUE(stateloop);
2376 } else {
2377 if (!seenDigits) {
2378 if (P::reportErrors) {
2379 errNoDigitsInNCR();
2381 emitOrAppendCharRefBuf(returnState);
2382 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2383 cstart = pos;
2385 reconsume = true;
2386 state =
2387 P::transition(mViewSource.get(), returnState, reconsume, pos);
2388 NS_HTML5_CONTINUE(stateloop);
2389 } else {
2390 if (P::reportErrors) {
2391 errCharRefLacksSemicolon();
2393 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2394 cstart = pos;
2396 reconsume = true;
2397 state = P::transition(mViewSource.get(),
2398 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2399 reconsume, pos);
2400 NS_HTML5_CONTINUE(stateloop);
2405 case PLAINTEXT: {
2406 for (;;) {
2407 if (reconsume) {
2408 reconsume = false;
2409 } else {
2410 if (++pos == endPos) {
2411 NS_HTML5_BREAK(stateloop);
2413 c = checkChar(buf, pos);
2415 switch (c) {
2416 case '\0': {
2417 emitPlaintextReplacementCharacter(buf, pos);
2418 continue;
2420 case '\r': {
2421 emitCarriageReturn(buf, pos);
2422 NS_HTML5_BREAK(stateloop);
2424 case '\n': {
2425 silentLineFeed();
2426 [[fallthrough]];
2428 default: {
2429 continue;
2434 case CLOSE_TAG_OPEN: {
2435 if (++pos == endPos) {
2436 NS_HTML5_BREAK(stateloop);
2438 c = checkChar(buf, pos);
2439 switch (c) {
2440 case '>': {
2441 if (P::reportErrors) {
2442 errLtSlashGt();
2444 cstart = pos + 1;
2445 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2446 reconsume, pos);
2447 NS_HTML5_CONTINUE(stateloop);
2449 case '\r': {
2450 silentCarriageReturn();
2451 if (P::reportErrors) {
2452 errGarbageAfterLtSlash();
2454 clearStrBufBeforeUse();
2455 appendStrBuf('\n');
2456 state =
2457 P::transition(mViewSource.get(),
2458 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
2459 NS_HTML5_BREAK(stateloop);
2461 case '\n': {
2462 silentLineFeed();
2463 if (P::reportErrors) {
2464 errGarbageAfterLtSlash();
2466 clearStrBufBeforeUse();
2467 appendStrBuf(c);
2468 state =
2469 P::transition(mViewSource.get(),
2470 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
2471 NS_HTML5_CONTINUE(stateloop);
2473 case '\0': {
2474 c = 0xfffd;
2475 [[fallthrough]];
2477 default: {
2478 if (c >= 'A' && c <= 'Z') {
2479 c += 0x20;
2481 if (c >= 'a' && c <= 'z') {
2482 endTag = true;
2483 clearStrBufBeforeUse();
2484 appendStrBuf(c);
2485 containsHyphen = false;
2486 state = P::transition(mViewSource.get(),
2487 nsHtml5Tokenizer::TAG_NAME, reconsume, pos);
2488 NS_HTML5_CONTINUE(stateloop);
2489 } else {
2490 if (P::reportErrors) {
2491 errGarbageAfterLtSlash();
2493 clearStrBufBeforeUse();
2494 appendStrBuf(c);
2495 state = P::transition(mViewSource.get(),
2496 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2497 pos);
2498 NS_HTML5_CONTINUE(stateloop);
2503 case RCDATA: {
2504 for (;;) {
2505 if (reconsume) {
2506 reconsume = false;
2507 } else {
2508 if (++pos == endPos) {
2509 NS_HTML5_BREAK(stateloop);
2511 c = checkChar(buf, pos);
2513 switch (c) {
2514 case '&': {
2515 flushChars(buf, pos);
2516 MOZ_ASSERT(!charRefBufLen,
2517 "charRefBufLen not reset after previous use!");
2518 appendCharRefBuf(c);
2519 setAdditionalAndRememberAmpersandLocation('\0');
2520 returnState = state;
2521 state =
2522 P::transition(mViewSource.get(),
2523 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
2524 reconsume, pos);
2525 NS_HTML5_CONTINUE(stateloop);
2527 case '<': {
2528 flushChars(buf, pos);
2529 returnState = state;
2530 state =
2531 P::transition(mViewSource.get(),
2532 nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
2533 reconsume, pos);
2534 NS_HTML5_CONTINUE(stateloop);
2536 case '\0': {
2537 emitReplacementCharacter(buf, pos);
2538 continue;
2540 case '\r': {
2541 emitCarriageReturn(buf, pos);
2542 NS_HTML5_BREAK(stateloop);
2544 case '\n': {
2545 silentLineFeed();
2546 [[fallthrough]];
2548 default: {
2549 continue;
2554 case RAWTEXT: {
2555 for (;;) {
2556 if (reconsume) {
2557 reconsume = false;
2558 } else {
2559 if (++pos == endPos) {
2560 NS_HTML5_BREAK(stateloop);
2562 c = checkChar(buf, pos);
2564 switch (c) {
2565 case '<': {
2566 flushChars(buf, pos);
2567 returnState = state;
2568 state =
2569 P::transition(mViewSource.get(),
2570 nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
2571 reconsume, pos);
2572 NS_HTML5_BREAK(rawtextloop);
2574 case '\0': {
2575 emitReplacementCharacter(buf, pos);
2576 continue;
2578 case '\r': {
2579 emitCarriageReturn(buf, pos);
2580 NS_HTML5_BREAK(stateloop);
2582 case '\n': {
2583 silentLineFeed();
2584 [[fallthrough]];
2586 default: {
2587 continue;
2591 rawtextloop_end:;
2592 [[fallthrough]];
2594 case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
2595 for (;;) {
2596 if (++pos == endPos) {
2597 NS_HTML5_BREAK(stateloop);
2599 c = checkChar(buf, pos);
2600 switch (c) {
2601 case '/': {
2602 index = 0;
2603 clearStrBufBeforeUse();
2604 state = P::transition(mViewSource.get(),
2605 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
2606 reconsume, pos);
2607 NS_HTML5_BREAK(rawtextrcdatalessthansignloop);
2609 default: {
2610 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2611 cstart = pos;
2612 reconsume = true;
2613 state =
2614 P::transition(mViewSource.get(), returnState, reconsume, pos);
2615 NS_HTML5_CONTINUE(stateloop);
2619 rawtextrcdatalessthansignloop_end:;
2620 [[fallthrough]];
2622 case NON_DATA_END_TAG_NAME: {
2623 for (;;) {
2624 if (++pos == endPos) {
2625 NS_HTML5_BREAK(stateloop);
2627 c = checkChar(buf, pos);
2628 if (!endTagExpectationAsArray) {
2629 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2630 cstart = pos;
2631 reconsume = true;
2632 state =
2633 P::transition(mViewSource.get(), returnState, reconsume, pos);
2634 NS_HTML5_CONTINUE(stateloop);
2635 } else if (index < endTagExpectationAsArray.length) {
2636 char16_t e = endTagExpectationAsArray[index];
2637 char16_t folded = c;
2638 if (c >= 'A' && c <= 'Z') {
2639 folded += 0x20;
2641 if (folded != e) {
2642 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2643 emitStrBuf();
2644 cstart = pos;
2645 reconsume = true;
2646 state =
2647 P::transition(mViewSource.get(), returnState, reconsume, pos);
2648 NS_HTML5_CONTINUE(stateloop);
2650 appendStrBuf(c);
2651 index++;
2652 continue;
2653 } else {
2654 endTag = true;
2655 tagName = endTagExpectation;
2656 switch (c) {
2657 case '\r': {
2658 silentCarriageReturn();
2659 clearStrBufAfterUse();
2660 state = P::transition(mViewSource.get(),
2661 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
2662 reconsume, pos);
2663 NS_HTML5_BREAK(stateloop);
2665 case '\n': {
2666 silentLineFeed();
2667 [[fallthrough]];
2669 case ' ':
2670 case '\t':
2671 case '\f': {
2672 clearStrBufAfterUse();
2673 state = P::transition(mViewSource.get(),
2674 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
2675 reconsume, pos);
2676 NS_HTML5_CONTINUE(stateloop);
2678 case '/': {
2679 clearStrBufAfterUse();
2680 state = P::transition(mViewSource.get(),
2681 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
2682 reconsume, pos);
2683 NS_HTML5_CONTINUE(stateloop);
2685 case '>': {
2686 clearStrBufAfterUse();
2687 state = P::transition(mViewSource.get(),
2688 emitCurrentTagToken(false, pos),
2689 reconsume, pos);
2690 if (shouldSuspend) {
2691 NS_HTML5_BREAK(stateloop);
2693 NS_HTML5_CONTINUE(stateloop);
2695 default: {
2696 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2697 emitStrBuf();
2698 cstart = pos;
2699 reconsume = true;
2700 state = P::transition(mViewSource.get(), returnState, reconsume,
2701 pos);
2702 NS_HTML5_CONTINUE(stateloop);
2708 case BOGUS_COMMENT: {
2709 for (;;) {
2710 if (reconsume) {
2711 reconsume = false;
2712 } else {
2713 if (++pos == endPos) {
2714 NS_HTML5_BREAK(stateloop);
2716 c = checkChar(buf, pos);
2718 switch (c) {
2719 case '>': {
2720 emitComment(0, pos);
2721 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2722 reconsume, pos);
2723 if (shouldSuspend) {
2724 NS_HTML5_BREAK(stateloop);
2726 NS_HTML5_CONTINUE(stateloop);
2728 case '-': {
2729 appendStrBuf(c);
2730 state = P::transition(mViewSource.get(),
2731 nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN,
2732 reconsume, pos);
2733 NS_HTML5_BREAK(boguscommentloop);
2735 case '\r': {
2736 appendStrBufCarriageReturn();
2737 NS_HTML5_BREAK(stateloop);
2739 case '\n': {
2740 appendStrBufLineFeed();
2741 continue;
2743 case '\0': {
2744 c = 0xfffd;
2745 [[fallthrough]];
2747 default: {
2748 appendStrBuf(c);
2749 continue;
2753 boguscommentloop_end:;
2754 [[fallthrough]];
2756 case BOGUS_COMMENT_HYPHEN: {
2757 boguscommenthyphenloop:
2758 for (;;) {
2759 if (++pos == endPos) {
2760 NS_HTML5_BREAK(stateloop);
2762 c = checkChar(buf, pos);
2763 switch (c) {
2764 case '>': {
2765 emitComment(0, pos);
2766 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2767 reconsume, pos);
2768 if (shouldSuspend) {
2769 NS_HTML5_BREAK(stateloop);
2771 NS_HTML5_CONTINUE(stateloop);
2773 case '-': {
2774 appendSecondHyphenToBogusComment();
2775 NS_HTML5_CONTINUE(boguscommenthyphenloop);
2777 case '\r': {
2778 appendStrBufCarriageReturn();
2779 state = P::transition(mViewSource.get(),
2780 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2781 pos);
2782 NS_HTML5_BREAK(stateloop);
2784 case '\n': {
2785 appendStrBufLineFeed();
2786 state = P::transition(mViewSource.get(),
2787 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2788 pos);
2789 NS_HTML5_CONTINUE(stateloop);
2791 case '\0': {
2792 c = 0xfffd;
2793 [[fallthrough]];
2795 default: {
2796 appendStrBuf(c);
2797 state = P::transition(mViewSource.get(),
2798 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2799 pos);
2800 NS_HTML5_CONTINUE(stateloop);
2805 case SCRIPT_DATA: {
2806 for (;;) {
2807 if (reconsume) {
2808 reconsume = false;
2809 } else {
2810 if (++pos == endPos) {
2811 NS_HTML5_BREAK(stateloop);
2813 c = checkChar(buf, pos);
2815 switch (c) {
2816 case '<': {
2817 flushChars(buf, pos);
2818 returnState = state;
2819 state = P::transition(
2820 mViewSource.get(),
2821 nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos);
2822 NS_HTML5_BREAK(scriptdataloop);
2824 case '\0': {
2825 emitReplacementCharacter(buf, pos);
2826 continue;
2828 case '\r': {
2829 emitCarriageReturn(buf, pos);
2830 NS_HTML5_BREAK(stateloop);
2832 case '\n': {
2833 silentLineFeed();
2834 [[fallthrough]];
2836 default: {
2837 continue;
2841 scriptdataloop_end:;
2842 [[fallthrough]];
2844 case SCRIPT_DATA_LESS_THAN_SIGN: {
2845 for (;;) {
2846 if (++pos == endPos) {
2847 NS_HTML5_BREAK(stateloop);
2849 c = checkChar(buf, pos);
2850 switch (c) {
2851 case '/': {
2852 index = 0;
2853 clearStrBufBeforeUse();
2854 state = P::transition(mViewSource.get(),
2855 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
2856 reconsume, pos);
2857 NS_HTML5_CONTINUE(stateloop);
2859 case '!': {
2860 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2861 cstart = pos;
2862 state = P::transition(mViewSource.get(),
2863 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START,
2864 reconsume, pos);
2865 NS_HTML5_BREAK(scriptdatalessthansignloop);
2867 default: {
2868 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2869 cstart = pos;
2870 reconsume = true;
2871 state =
2872 P::transition(mViewSource.get(),
2873 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2874 NS_HTML5_CONTINUE(stateloop);
2878 scriptdatalessthansignloop_end:;
2879 [[fallthrough]];
2881 case SCRIPT_DATA_ESCAPE_START: {
2882 for (;;) {
2883 if (++pos == endPos) {
2884 NS_HTML5_BREAK(stateloop);
2886 c = checkChar(buf, pos);
2887 switch (c) {
2888 case '-': {
2889 state =
2890 P::transition(mViewSource.get(),
2891 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START_DASH,
2892 reconsume, pos);
2893 NS_HTML5_BREAK(scriptdataescapestartloop);
2895 default: {
2896 reconsume = true;
2897 state =
2898 P::transition(mViewSource.get(),
2899 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2900 NS_HTML5_CONTINUE(stateloop);
2904 scriptdataescapestartloop_end:;
2905 [[fallthrough]];
2907 case SCRIPT_DATA_ESCAPE_START_DASH: {
2908 for (;;) {
2909 if (++pos == endPos) {
2910 NS_HTML5_BREAK(stateloop);
2912 c = checkChar(buf, pos);
2913 switch (c) {
2914 case '-': {
2915 state =
2916 P::transition(mViewSource.get(),
2917 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
2918 reconsume, pos);
2919 NS_HTML5_BREAK(scriptdataescapestartdashloop);
2921 default: {
2922 reconsume = true;
2923 state =
2924 P::transition(mViewSource.get(),
2925 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2926 NS_HTML5_CONTINUE(stateloop);
2930 scriptdataescapestartdashloop_end:;
2931 [[fallthrough]];
2933 case SCRIPT_DATA_ESCAPED_DASH_DASH: {
2934 for (;;) {
2935 if (++pos == endPos) {
2936 NS_HTML5_BREAK(stateloop);
2938 c = checkChar(buf, pos);
2939 switch (c) {
2940 case '-': {
2941 continue;
2943 case '<': {
2944 flushChars(buf, pos);
2945 state = P::transition(
2946 mViewSource.get(),
2947 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
2948 reconsume, pos);
2949 NS_HTML5_CONTINUE(stateloop);
2951 case '>': {
2952 state =
2953 P::transition(mViewSource.get(),
2954 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2955 NS_HTML5_CONTINUE(stateloop);
2957 case '\0': {
2958 emitReplacementCharacter(buf, pos);
2959 state = P::transition(mViewSource.get(),
2960 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2961 reconsume, pos);
2962 NS_HTML5_BREAK(scriptdataescapeddashdashloop);
2964 case '\r': {
2965 emitCarriageReturn(buf, pos);
2966 state = P::transition(mViewSource.get(),
2967 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2968 reconsume, pos);
2969 NS_HTML5_BREAK(stateloop);
2971 case '\n': {
2972 silentLineFeed();
2973 [[fallthrough]];
2975 default: {
2976 state = P::transition(mViewSource.get(),
2977 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2978 reconsume, pos);
2979 NS_HTML5_BREAK(scriptdataescapeddashdashloop);
2983 scriptdataescapeddashdashloop_end:;
2984 [[fallthrough]];
2986 case SCRIPT_DATA_ESCAPED: {
2987 for (;;) {
2988 if (reconsume) {
2989 reconsume = false;
2990 } else {
2991 if (++pos == endPos) {
2992 NS_HTML5_BREAK(stateloop);
2994 c = checkChar(buf, pos);
2996 switch (c) {
2997 case '-': {
2998 state = P::transition(mViewSource.get(),
2999 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH,
3000 reconsume, pos);
3001 NS_HTML5_BREAK(scriptdataescapedloop);
3003 case '<': {
3004 flushChars(buf, pos);
3005 state = P::transition(
3006 mViewSource.get(),
3007 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
3008 reconsume, pos);
3009 NS_HTML5_CONTINUE(stateloop);
3011 case '\0': {
3012 emitReplacementCharacter(buf, pos);
3013 continue;
3015 case '\r': {
3016 emitCarriageReturn(buf, pos);
3017 NS_HTML5_BREAK(stateloop);
3019 case '\n': {
3020 silentLineFeed();
3021 [[fallthrough]];
3023 default: {
3024 continue;
3028 scriptdataescapedloop_end:;
3029 [[fallthrough]];
3031 case SCRIPT_DATA_ESCAPED_DASH: {
3032 for (;;) {
3033 if (++pos == endPos) {
3034 NS_HTML5_BREAK(stateloop);
3036 c = checkChar(buf, pos);
3037 switch (c) {
3038 case '-': {
3039 state =
3040 P::transition(mViewSource.get(),
3041 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
3042 reconsume, pos);
3043 NS_HTML5_CONTINUE(stateloop);
3045 case '<': {
3046 flushChars(buf, pos);
3047 state = P::transition(
3048 mViewSource.get(),
3049 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
3050 reconsume, pos);
3051 NS_HTML5_BREAK(scriptdataescapeddashloop);
3053 case '\0': {
3054 emitReplacementCharacter(buf, pos);
3055 state = P::transition(mViewSource.get(),
3056 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3057 reconsume, pos);
3058 NS_HTML5_CONTINUE(stateloop);
3060 case '\r': {
3061 emitCarriageReturn(buf, pos);
3062 state = P::transition(mViewSource.get(),
3063 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3064 reconsume, pos);
3065 NS_HTML5_BREAK(stateloop);
3067 case '\n': {
3068 silentLineFeed();
3069 [[fallthrough]];
3071 default: {
3072 state = P::transition(mViewSource.get(),
3073 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3074 reconsume, pos);
3075 NS_HTML5_CONTINUE(stateloop);
3079 scriptdataescapeddashloop_end:;
3080 [[fallthrough]];
3082 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
3083 for (;;) {
3084 if (++pos == endPos) {
3085 NS_HTML5_BREAK(stateloop);
3087 c = checkChar(buf, pos);
3088 switch (c) {
3089 case '/': {
3090 index = 0;
3091 clearStrBufBeforeUse();
3092 returnState = nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED;
3093 state = P::transition(mViewSource.get(),
3094 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
3095 reconsume, pos);
3096 NS_HTML5_CONTINUE(stateloop);
3098 case 'S':
3099 case 's': {
3100 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
3101 cstart = pos;
3102 index = 1;
3103 state = P::transition(
3104 mViewSource.get(),
3105 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume,
3106 pos);
3107 NS_HTML5_BREAK(scriptdataescapedlessthanloop);
3109 default: {
3110 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
3111 cstart = pos;
3112 reconsume = true;
3113 state = P::transition(mViewSource.get(),
3114 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3115 reconsume, pos);
3116 NS_HTML5_CONTINUE(stateloop);
3120 scriptdataescapedlessthanloop_end:;
3121 [[fallthrough]];
3123 case SCRIPT_DATA_DOUBLE_ESCAPE_START: {
3124 for (;;) {
3125 if (++pos == endPos) {
3126 NS_HTML5_BREAK(stateloop);
3128 c = checkChar(buf, pos);
3129 MOZ_ASSERT(index > 0);
3130 if (index < 6) {
3131 char16_t folded = c;
3132 if (c >= 'A' && c <= 'Z') {
3133 folded += 0x20;
3135 if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
3136 reconsume = true;
3137 state = P::transition(mViewSource.get(),
3138 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3139 reconsume, pos);
3140 NS_HTML5_CONTINUE(stateloop);
3142 index++;
3143 continue;
3145 switch (c) {
3146 case '\r': {
3147 emitCarriageReturn(buf, pos);
3148 state = P::transition(
3149 mViewSource.get(),
3150 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3151 NS_HTML5_BREAK(stateloop);
3153 case '\n': {
3154 silentLineFeed();
3155 [[fallthrough]];
3157 case ' ':
3158 case '\t':
3159 case '\f':
3160 case '/':
3161 case '>': {
3162 state = P::transition(
3163 mViewSource.get(),
3164 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3165 NS_HTML5_BREAK(scriptdatadoubleescapestartloop);
3167 default: {
3168 reconsume = true;
3169 state = P::transition(mViewSource.get(),
3170 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3171 reconsume, pos);
3172 NS_HTML5_CONTINUE(stateloop);
3176 scriptdatadoubleescapestartloop_end:;
3177 [[fallthrough]];
3179 case SCRIPT_DATA_DOUBLE_ESCAPED: {
3180 for (;;) {
3181 if (reconsume) {
3182 reconsume = false;
3183 } else {
3184 if (++pos == endPos) {
3185 NS_HTML5_BREAK(stateloop);
3187 c = checkChar(buf, pos);
3189 switch (c) {
3190 case '-': {
3191 state = P::transition(
3192 mViewSource.get(),
3193 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume,
3194 pos);
3195 NS_HTML5_BREAK(scriptdatadoubleescapedloop);
3197 case '<': {
3198 state = P::transition(
3199 mViewSource.get(),
3200 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3201 reconsume, pos);
3202 NS_HTML5_CONTINUE(stateloop);
3204 case '\0': {
3205 emitReplacementCharacter(buf, pos);
3206 continue;
3208 case '\r': {
3209 emitCarriageReturn(buf, pos);
3210 NS_HTML5_BREAK(stateloop);
3212 case '\n': {
3213 silentLineFeed();
3214 [[fallthrough]];
3216 default: {
3217 continue;
3221 scriptdatadoubleescapedloop_end:;
3222 [[fallthrough]];
3224 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
3225 for (;;) {
3226 if (++pos == endPos) {
3227 NS_HTML5_BREAK(stateloop);
3229 c = checkChar(buf, pos);
3230 switch (c) {
3231 case '-': {
3232 state = P::transition(
3233 mViewSource.get(),
3234 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH,
3235 reconsume, pos);
3236 NS_HTML5_BREAK(scriptdatadoubleescapeddashloop);
3238 case '<': {
3239 state = P::transition(
3240 mViewSource.get(),
3241 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3242 reconsume, pos);
3243 NS_HTML5_CONTINUE(stateloop);
3245 case '\0': {
3246 emitReplacementCharacter(buf, pos);
3247 state = P::transition(
3248 mViewSource.get(),
3249 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3250 NS_HTML5_CONTINUE(stateloop);
3252 case '\r': {
3253 emitCarriageReturn(buf, pos);
3254 state = P::transition(
3255 mViewSource.get(),
3256 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3257 NS_HTML5_BREAK(stateloop);
3259 case '\n': {
3260 silentLineFeed();
3261 [[fallthrough]];
3263 default: {
3264 state = P::transition(
3265 mViewSource.get(),
3266 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3267 NS_HTML5_CONTINUE(stateloop);
3271 scriptdatadoubleescapeddashloop_end:;
3272 [[fallthrough]];
3274 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
3275 for (;;) {
3276 if (++pos == endPos) {
3277 NS_HTML5_BREAK(stateloop);
3279 c = checkChar(buf, pos);
3280 switch (c) {
3281 case '-': {
3282 continue;
3284 case '<': {
3285 state = P::transition(
3286 mViewSource.get(),
3287 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3288 reconsume, pos);
3289 NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop);
3291 case '>': {
3292 state =
3293 P::transition(mViewSource.get(),
3294 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
3295 NS_HTML5_CONTINUE(stateloop);
3297 case '\0': {
3298 emitReplacementCharacter(buf, pos);
3299 state = P::transition(
3300 mViewSource.get(),
3301 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3302 NS_HTML5_CONTINUE(stateloop);
3304 case '\r': {
3305 emitCarriageReturn(buf, pos);
3306 state = P::transition(
3307 mViewSource.get(),
3308 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3309 NS_HTML5_BREAK(stateloop);
3311 case '\n': {
3312 silentLineFeed();
3313 [[fallthrough]];
3315 default: {
3316 state = P::transition(
3317 mViewSource.get(),
3318 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3319 NS_HTML5_CONTINUE(stateloop);
3323 scriptdatadoubleescapeddashdashloop_end:;
3324 [[fallthrough]];
3326 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
3327 for (;;) {
3328 if (++pos == endPos) {
3329 NS_HTML5_BREAK(stateloop);
3331 c = checkChar(buf, pos);
3332 switch (c) {
3333 case '/': {
3334 index = 0;
3335 state =
3336 P::transition(mViewSource.get(),
3337 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_END,
3338 reconsume, pos);
3339 NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop);
3341 default: {
3342 reconsume = true;
3343 state = P::transition(
3344 mViewSource.get(),
3345 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3346 NS_HTML5_CONTINUE(stateloop);
3350 scriptdatadoubleescapedlessthanloop_end:;
3351 [[fallthrough]];
3353 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
3354 for (;;) {
3355 if (++pos == endPos) {
3356 NS_HTML5_BREAK(stateloop);
3358 c = checkChar(buf, pos);
3359 if (index < 6) {
3360 char16_t folded = c;
3361 if (c >= 'A' && c <= 'Z') {
3362 folded += 0x20;
3364 if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
3365 reconsume = true;
3366 state = P::transition(
3367 mViewSource.get(),
3368 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3369 NS_HTML5_CONTINUE(stateloop);
3371 index++;
3372 continue;
3374 switch (c) {
3375 case '\r': {
3376 emitCarriageReturn(buf, pos);
3377 state = P::transition(mViewSource.get(),
3378 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3379 reconsume, pos);
3380 NS_HTML5_BREAK(stateloop);
3382 case '\n': {
3383 silentLineFeed();
3384 [[fallthrough]];
3386 case ' ':
3387 case '\t':
3388 case '\f':
3389 case '/':
3390 case '>': {
3391 state = P::transition(mViewSource.get(),
3392 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3393 reconsume, pos);
3394 NS_HTML5_CONTINUE(stateloop);
3396 default: {
3397 reconsume = true;
3398 state = P::transition(
3399 mViewSource.get(),
3400 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3401 NS_HTML5_CONTINUE(stateloop);
3406 case MARKUP_DECLARATION_OCTYPE: {
3407 for (;;) {
3408 if (++pos == endPos) {
3409 NS_HTML5_BREAK(stateloop);
3411 c = checkChar(buf, pos);
3412 if (index < 6) {
3413 char16_t folded = c;
3414 if (c >= 'A' && c <= 'Z') {
3415 folded += 0x20;
3417 if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
3418 appendStrBuf(c);
3419 } else {
3420 if (P::reportErrors) {
3421 errBogusComment();
3423 reconsume = true;
3424 state = P::transition(mViewSource.get(),
3425 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
3426 pos);
3427 NS_HTML5_CONTINUE(stateloop);
3429 index++;
3430 continue;
3431 } else {
3432 reconsume = true;
3433 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DOCTYPE,
3434 reconsume, pos);
3435 NS_HTML5_BREAK(markupdeclarationdoctypeloop);
3438 markupdeclarationdoctypeloop_end:;
3439 [[fallthrough]];
3441 case DOCTYPE: {
3442 for (;;) {
3443 if (reconsume) {
3444 reconsume = false;
3445 } else {
3446 if (++pos == endPos) {
3447 NS_HTML5_BREAK(stateloop);
3449 c = checkChar(buf, pos);
3451 initDoctypeFields();
3452 switch (c) {
3453 case '\r': {
3454 silentCarriageReturn();
3455 state = P::transition(mViewSource.get(),
3456 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3457 reconsume, pos);
3458 NS_HTML5_BREAK(stateloop);
3460 case '\n': {
3461 silentLineFeed();
3462 [[fallthrough]];
3464 case ' ':
3465 case '\t':
3466 case '\f': {
3467 state = P::transition(mViewSource.get(),
3468 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3469 reconsume, pos);
3470 NS_HTML5_BREAK(doctypeloop);
3472 default: {
3473 if (P::reportErrors) {
3474 errMissingSpaceBeforeDoctypeName();
3476 reconsume = true;
3477 state = P::transition(mViewSource.get(),
3478 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3479 reconsume, pos);
3480 NS_HTML5_BREAK(doctypeloop);
3484 doctypeloop_end:;
3485 [[fallthrough]];
3487 case BEFORE_DOCTYPE_NAME: {
3488 for (;;) {
3489 if (reconsume) {
3490 reconsume = false;
3491 } else {
3492 if (++pos == endPos) {
3493 NS_HTML5_BREAK(stateloop);
3495 c = checkChar(buf, pos);
3497 switch (c) {
3498 case '\r': {
3499 silentCarriageReturn();
3500 NS_HTML5_BREAK(stateloop);
3502 case '\n': {
3503 silentLineFeed();
3504 [[fallthrough]];
3506 case ' ':
3507 case '\t':
3508 case '\f': {
3509 continue;
3511 case '>': {
3512 if (P::reportErrors) {
3513 errNamelessDoctype();
3515 forceQuirks = true;
3516 emitDoctypeToken(pos);
3517 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3518 reconsume, pos);
3519 if (shouldSuspend) {
3520 NS_HTML5_BREAK(stateloop);
3522 NS_HTML5_CONTINUE(stateloop);
3524 case '\0': {
3525 c = 0xfffd;
3526 [[fallthrough]];
3528 default: {
3529 if (c >= 'A' && c <= 'Z') {
3530 c += 0x20;
3532 clearStrBufBeforeUse();
3533 appendStrBuf(c);
3534 state =
3535 P::transition(mViewSource.get(),
3536 nsHtml5Tokenizer::DOCTYPE_NAME, reconsume, pos);
3537 NS_HTML5_BREAK(beforedoctypenameloop);
3541 beforedoctypenameloop_end:;
3542 [[fallthrough]];
3544 case DOCTYPE_NAME: {
3545 for (;;) {
3546 if (++pos == endPos) {
3547 NS_HTML5_BREAK(stateloop);
3549 c = checkChar(buf, pos);
3550 switch (c) {
3551 case '\r': {
3552 silentCarriageReturn();
3553 strBufToDoctypeName();
3554 state = P::transition(mViewSource.get(),
3555 nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
3556 reconsume, pos);
3557 NS_HTML5_BREAK(stateloop);
3559 case '\n': {
3560 silentLineFeed();
3561 [[fallthrough]];
3563 case ' ':
3564 case '\t':
3565 case '\f': {
3566 strBufToDoctypeName();
3567 state = P::transition(mViewSource.get(),
3568 nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
3569 reconsume, pos);
3570 NS_HTML5_BREAK(doctypenameloop);
3572 case '>': {
3573 strBufToDoctypeName();
3574 emitDoctypeToken(pos);
3575 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3576 reconsume, pos);
3577 if (shouldSuspend) {
3578 NS_HTML5_BREAK(stateloop);
3580 NS_HTML5_CONTINUE(stateloop);
3582 case '\0': {
3583 c = 0xfffd;
3584 [[fallthrough]];
3586 default: {
3587 if (c >= 'A' && c <= 'Z') {
3588 c += 0x0020;
3590 appendStrBuf(c);
3591 continue;
3595 doctypenameloop_end:;
3596 [[fallthrough]];
3598 case AFTER_DOCTYPE_NAME: {
3599 for (;;) {
3600 if (++pos == endPos) {
3601 NS_HTML5_BREAK(stateloop);
3603 c = checkChar(buf, pos);
3604 switch (c) {
3605 case '\r': {
3606 silentCarriageReturn();
3607 NS_HTML5_BREAK(stateloop);
3609 case '\n': {
3610 silentLineFeed();
3611 [[fallthrough]];
3613 case ' ':
3614 case '\t':
3615 case '\f': {
3616 continue;
3618 case '>': {
3619 emitDoctypeToken(pos);
3620 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3621 reconsume, pos);
3622 if (shouldSuspend) {
3623 NS_HTML5_BREAK(stateloop);
3625 NS_HTML5_CONTINUE(stateloop);
3627 case 'p':
3628 case 'P': {
3629 index = 0;
3630 state = P::transition(mViewSource.get(),
3631 nsHtml5Tokenizer::DOCTYPE_UBLIC, reconsume,
3632 pos);
3633 NS_HTML5_BREAK(afterdoctypenameloop);
3635 case 's':
3636 case 'S': {
3637 index = 0;
3638 state = P::transition(mViewSource.get(),
3639 nsHtml5Tokenizer::DOCTYPE_YSTEM, reconsume,
3640 pos);
3641 NS_HTML5_CONTINUE(stateloop);
3643 default: {
3644 bogusDoctype();
3645 state = P::transition(mViewSource.get(),
3646 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3647 pos);
3648 NS_HTML5_CONTINUE(stateloop);
3652 afterdoctypenameloop_end:;
3653 [[fallthrough]];
3655 case DOCTYPE_UBLIC: {
3656 for (;;) {
3657 if (++pos == endPos) {
3658 NS_HTML5_BREAK(stateloop);
3660 c = checkChar(buf, pos);
3661 if (index < 5) {
3662 char16_t folded = c;
3663 if (c >= 'A' && c <= 'Z') {
3664 folded += 0x20;
3666 if (folded != nsHtml5Tokenizer::UBLIC[index]) {
3667 bogusDoctype();
3668 reconsume = true;
3669 state = P::transition(mViewSource.get(),
3670 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3671 pos);
3672 NS_HTML5_CONTINUE(stateloop);
3674 index++;
3675 continue;
3676 } else {
3677 reconsume = true;
3678 state = P::transition(
3679 mViewSource.get(),
3680 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
3681 NS_HTML5_BREAK(doctypeublicloop);
3684 doctypeublicloop_end:;
3685 [[fallthrough]];
3687 case AFTER_DOCTYPE_PUBLIC_KEYWORD: {
3688 for (;;) {
3689 if (reconsume) {
3690 reconsume = false;
3691 } else {
3692 if (++pos == endPos) {
3693 NS_HTML5_BREAK(stateloop);
3695 c = checkChar(buf, pos);
3697 switch (c) {
3698 case '\r': {
3699 silentCarriageReturn();
3700 state = P::transition(
3701 mViewSource.get(),
3702 nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3703 pos);
3704 NS_HTML5_BREAK(stateloop);
3706 case '\n': {
3707 silentLineFeed();
3708 [[fallthrough]];
3710 case ' ':
3711 case '\t':
3712 case '\f': {
3713 state = P::transition(
3714 mViewSource.get(),
3715 nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3716 pos);
3717 NS_HTML5_BREAK(afterdoctypepublickeywordloop);
3719 case '\"': {
3720 if (P::reportErrors) {
3721 errNoSpaceBetweenDoctypePublicKeywordAndQuote();
3723 clearStrBufBeforeUse();
3724 state = P::transition(
3725 mViewSource.get(),
3726 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
3727 reconsume, pos);
3728 NS_HTML5_CONTINUE(stateloop);
3730 case '\'': {
3731 if (P::reportErrors) {
3732 errNoSpaceBetweenDoctypePublicKeywordAndQuote();
3734 clearStrBufBeforeUse();
3735 state = P::transition(
3736 mViewSource.get(),
3737 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
3738 reconsume, pos);
3739 NS_HTML5_CONTINUE(stateloop);
3741 case '>': {
3742 if (P::reportErrors) {
3743 errExpectedPublicId();
3745 forceQuirks = true;
3746 emitDoctypeToken(pos);
3747 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3748 reconsume, pos);
3749 if (shouldSuspend) {
3750 NS_HTML5_BREAK(stateloop);
3752 NS_HTML5_CONTINUE(stateloop);
3754 default: {
3755 bogusDoctype();
3756 state = P::transition(mViewSource.get(),
3757 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3758 pos);
3759 NS_HTML5_CONTINUE(stateloop);
3763 afterdoctypepublickeywordloop_end:;
3764 [[fallthrough]];
3766 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
3767 for (;;) {
3768 if (++pos == endPos) {
3769 NS_HTML5_BREAK(stateloop);
3771 c = checkChar(buf, pos);
3772 switch (c) {
3773 case '\r': {
3774 silentCarriageReturn();
3775 NS_HTML5_BREAK(stateloop);
3777 case '\n': {
3778 silentLineFeed();
3779 [[fallthrough]];
3781 case ' ':
3782 case '\t':
3783 case '\f': {
3784 continue;
3786 case '\"': {
3787 clearStrBufBeforeUse();
3788 state = P::transition(
3789 mViewSource.get(),
3790 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
3791 reconsume, pos);
3792 NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
3794 case '\'': {
3795 clearStrBufBeforeUse();
3796 state = P::transition(
3797 mViewSource.get(),
3798 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
3799 reconsume, pos);
3800 NS_HTML5_CONTINUE(stateloop);
3802 case '>': {
3803 if (P::reportErrors) {
3804 errExpectedPublicId();
3806 forceQuirks = true;
3807 emitDoctypeToken(pos);
3808 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3809 reconsume, pos);
3810 if (shouldSuspend) {
3811 NS_HTML5_BREAK(stateloop);
3813 NS_HTML5_CONTINUE(stateloop);
3815 default: {
3816 bogusDoctype();
3817 state = P::transition(mViewSource.get(),
3818 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3819 pos);
3820 NS_HTML5_CONTINUE(stateloop);
3824 beforedoctypepublicidentifierloop_end:;
3825 [[fallthrough]];
3827 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
3828 for (;;) {
3829 if (++pos == endPos) {
3830 NS_HTML5_BREAK(stateloop);
3832 c = checkChar(buf, pos);
3833 switch (c) {
3834 case '\"': {
3835 publicIdentifier = strBufToString();
3836 state = P::transition(
3837 mViewSource.get(),
3838 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3839 pos);
3840 NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
3842 case '>': {
3843 if (P::reportErrors) {
3844 errGtInPublicId();
3846 forceQuirks = true;
3847 publicIdentifier = strBufToString();
3848 emitDoctypeToken(pos);
3849 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3850 reconsume, pos);
3851 if (shouldSuspend) {
3852 NS_HTML5_BREAK(stateloop);
3854 NS_HTML5_CONTINUE(stateloop);
3856 case '\r': {
3857 appendStrBufCarriageReturn();
3858 NS_HTML5_BREAK(stateloop);
3860 case '\n': {
3861 appendStrBufLineFeed();
3862 continue;
3864 case '\0': {
3865 c = 0xfffd;
3866 [[fallthrough]];
3868 default: {
3869 appendStrBuf(c);
3870 continue;
3874 doctypepublicidentifierdoublequotedloop_end:;
3875 [[fallthrough]];
3877 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
3878 for (;;) {
3879 if (++pos == endPos) {
3880 NS_HTML5_BREAK(stateloop);
3882 c = checkChar(buf, pos);
3883 switch (c) {
3884 case '\r': {
3885 silentCarriageReturn();
3886 state = P::transition(
3887 mViewSource.get(),
3888 nsHtml5Tokenizer::
3889 BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
3890 reconsume, pos);
3891 NS_HTML5_BREAK(stateloop);
3893 case '\n': {
3894 silentLineFeed();
3895 [[fallthrough]];
3897 case ' ':
3898 case '\t':
3899 case '\f': {
3900 state = P::transition(
3901 mViewSource.get(),
3902 nsHtml5Tokenizer::
3903 BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
3904 reconsume, pos);
3905 NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
3907 case '>': {
3908 emitDoctypeToken(pos);
3909 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3910 reconsume, pos);
3911 if (shouldSuspend) {
3912 NS_HTML5_BREAK(stateloop);
3914 NS_HTML5_CONTINUE(stateloop);
3916 case '\"': {
3917 if (P::reportErrors) {
3918 errNoSpaceBetweenPublicAndSystemIds();
3920 clearStrBufBeforeUse();
3921 state = P::transition(
3922 mViewSource.get(),
3923 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
3924 reconsume, pos);
3925 NS_HTML5_CONTINUE(stateloop);
3927 case '\'': {
3928 if (P::reportErrors) {
3929 errNoSpaceBetweenPublicAndSystemIds();
3931 clearStrBufBeforeUse();
3932 state = P::transition(
3933 mViewSource.get(),
3934 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
3935 reconsume, pos);
3936 NS_HTML5_CONTINUE(stateloop);
3938 default: {
3939 bogusDoctype();
3940 state = P::transition(mViewSource.get(),
3941 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3942 pos);
3943 NS_HTML5_CONTINUE(stateloop);
3947 afterdoctypepublicidentifierloop_end:;
3948 [[fallthrough]];
3950 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
3951 for (;;) {
3952 if (++pos == endPos) {
3953 NS_HTML5_BREAK(stateloop);
3955 c = checkChar(buf, pos);
3956 switch (c) {
3957 case '\r': {
3958 silentCarriageReturn();
3959 NS_HTML5_BREAK(stateloop);
3961 case '\n': {
3962 silentLineFeed();
3963 [[fallthrough]];
3965 case ' ':
3966 case '\t':
3967 case '\f': {
3968 continue;
3970 case '>': {
3971 emitDoctypeToken(pos);
3972 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3973 reconsume, pos);
3974 if (shouldSuspend) {
3975 NS_HTML5_BREAK(stateloop);
3977 NS_HTML5_CONTINUE(stateloop);
3979 case '\"': {
3980 clearStrBufBeforeUse();
3981 state = P::transition(
3982 mViewSource.get(),
3983 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
3984 reconsume, pos);
3985 NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop);
3987 case '\'': {
3988 clearStrBufBeforeUse();
3989 state = P::transition(
3990 mViewSource.get(),
3991 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
3992 reconsume, pos);
3993 NS_HTML5_CONTINUE(stateloop);
3995 default: {
3996 bogusDoctype();
3997 state = P::transition(mViewSource.get(),
3998 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3999 pos);
4000 NS_HTML5_CONTINUE(stateloop);
4004 betweendoctypepublicandsystemidentifiersloop_end:;
4005 [[fallthrough]];
4007 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
4008 for (;;) {
4009 if (++pos == endPos) {
4010 NS_HTML5_BREAK(stateloop);
4012 c = checkChar(buf, pos);
4013 switch (c) {
4014 case '\"': {
4015 systemIdentifier = strBufToString();
4016 state = P::transition(
4017 mViewSource.get(),
4018 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4019 pos);
4020 NS_HTML5_BREAK(doctypesystemidentifierdoublequotedloop);
4022 case '>': {
4023 if (P::reportErrors) {
4024 errGtInSystemId();
4026 forceQuirks = true;
4027 systemIdentifier = strBufToString();
4028 emitDoctypeToken(pos);
4029 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4030 reconsume, pos);
4031 if (shouldSuspend) {
4032 NS_HTML5_BREAK(stateloop);
4034 NS_HTML5_CONTINUE(stateloop);
4036 case '\r': {
4037 appendStrBufCarriageReturn();
4038 NS_HTML5_BREAK(stateloop);
4040 case '\n': {
4041 appendStrBufLineFeed();
4042 continue;
4044 case '\0': {
4045 c = 0xfffd;
4046 [[fallthrough]];
4048 default: {
4049 appendStrBuf(c);
4050 continue;
4054 doctypesystemidentifierdoublequotedloop_end:;
4055 [[fallthrough]];
4057 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
4058 for (;;) {
4059 if (++pos == endPos) {
4060 NS_HTML5_BREAK(stateloop);
4062 c = checkChar(buf, pos);
4063 switch (c) {
4064 case '\r': {
4065 silentCarriageReturn();
4066 NS_HTML5_BREAK(stateloop);
4068 case '\n': {
4069 silentLineFeed();
4070 [[fallthrough]];
4072 case ' ':
4073 case '\t':
4074 case '\f': {
4075 continue;
4077 case '>': {
4078 emitDoctypeToken(pos);
4079 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4080 reconsume, pos);
4081 if (shouldSuspend) {
4082 NS_HTML5_BREAK(stateloop);
4084 NS_HTML5_CONTINUE(stateloop);
4086 default: {
4087 bogusDoctypeWithoutQuirks();
4088 state = P::transition(mViewSource.get(),
4089 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4090 pos);
4091 NS_HTML5_BREAK(afterdoctypesystemidentifierloop);
4095 afterdoctypesystemidentifierloop_end:;
4096 [[fallthrough]];
4098 case BOGUS_DOCTYPE: {
4099 for (;;) {
4100 if (reconsume) {
4101 reconsume = false;
4102 } else {
4103 if (++pos == endPos) {
4104 NS_HTML5_BREAK(stateloop);
4106 c = checkChar(buf, pos);
4108 switch (c) {
4109 case '>': {
4110 emitDoctypeToken(pos);
4111 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4112 reconsume, pos);
4113 if (shouldSuspend) {
4114 NS_HTML5_BREAK(stateloop);
4116 NS_HTML5_CONTINUE(stateloop);
4118 case '\r': {
4119 silentCarriageReturn();
4120 NS_HTML5_BREAK(stateloop);
4122 case '\n': {
4123 silentLineFeed();
4124 [[fallthrough]];
4126 default: {
4127 continue;
4132 case DOCTYPE_YSTEM: {
4133 for (;;) {
4134 if (++pos == endPos) {
4135 NS_HTML5_BREAK(stateloop);
4137 c = checkChar(buf, pos);
4138 if (index < 5) {
4139 char16_t folded = c;
4140 if (c >= 'A' && c <= 'Z') {
4141 folded += 0x20;
4143 if (folded != nsHtml5Tokenizer::YSTEM[index]) {
4144 bogusDoctype();
4145 reconsume = true;
4146 state = P::transition(mViewSource.get(),
4147 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4148 pos);
4149 NS_HTML5_CONTINUE(stateloop);
4151 index++;
4152 NS_HTML5_CONTINUE(stateloop);
4153 } else {
4154 reconsume = true;
4155 state = P::transition(
4156 mViewSource.get(),
4157 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
4158 NS_HTML5_BREAK(doctypeystemloop);
4161 doctypeystemloop_end:;
4162 [[fallthrough]];
4164 case AFTER_DOCTYPE_SYSTEM_KEYWORD: {
4165 for (;;) {
4166 if (reconsume) {
4167 reconsume = false;
4168 } else {
4169 if (++pos == endPos) {
4170 NS_HTML5_BREAK(stateloop);
4172 c = checkChar(buf, pos);
4174 switch (c) {
4175 case '\r': {
4176 silentCarriageReturn();
4177 state = P::transition(
4178 mViewSource.get(),
4179 nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4180 pos);
4181 NS_HTML5_BREAK(stateloop);
4183 case '\n': {
4184 silentLineFeed();
4185 [[fallthrough]];
4187 case ' ':
4188 case '\t':
4189 case '\f': {
4190 state = P::transition(
4191 mViewSource.get(),
4192 nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4193 pos);
4194 NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
4196 case '\"': {
4197 if (P::reportErrors) {
4198 errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
4200 clearStrBufBeforeUse();
4201 state = P::transition(
4202 mViewSource.get(),
4203 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
4204 reconsume, pos);
4205 NS_HTML5_CONTINUE(stateloop);
4207 case '\'': {
4208 if (P::reportErrors) {
4209 errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
4211 clearStrBufBeforeUse();
4212 state = P::transition(
4213 mViewSource.get(),
4214 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
4215 reconsume, pos);
4216 NS_HTML5_CONTINUE(stateloop);
4218 case '>': {
4219 if (P::reportErrors) {
4220 errExpectedPublicId();
4222 forceQuirks = true;
4223 emitDoctypeToken(pos);
4224 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4225 reconsume, pos);
4226 if (shouldSuspend) {
4227 NS_HTML5_BREAK(stateloop);
4229 NS_HTML5_CONTINUE(stateloop);
4231 default: {
4232 bogusDoctype();
4233 state = P::transition(mViewSource.get(),
4234 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4235 pos);
4236 NS_HTML5_CONTINUE(stateloop);
4240 afterdoctypesystemkeywordloop_end:;
4241 [[fallthrough]];
4243 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
4244 for (;;) {
4245 if (++pos == endPos) {
4246 NS_HTML5_BREAK(stateloop);
4248 c = checkChar(buf, pos);
4249 switch (c) {
4250 case '\r': {
4251 silentCarriageReturn();
4252 NS_HTML5_BREAK(stateloop);
4254 case '\n': {
4255 silentLineFeed();
4256 [[fallthrough]];
4258 case ' ':
4259 case '\t':
4260 case '\f': {
4261 continue;
4263 case '\"': {
4264 clearStrBufBeforeUse();
4265 state = P::transition(
4266 mViewSource.get(),
4267 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
4268 reconsume, pos);
4269 NS_HTML5_CONTINUE(stateloop);
4271 case '\'': {
4272 clearStrBufBeforeUse();
4273 state = P::transition(
4274 mViewSource.get(),
4275 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
4276 reconsume, pos);
4277 NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
4279 case '>': {
4280 if (P::reportErrors) {
4281 errExpectedSystemId();
4283 forceQuirks = true;
4284 emitDoctypeToken(pos);
4285 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4286 reconsume, pos);
4287 if (shouldSuspend) {
4288 NS_HTML5_BREAK(stateloop);
4290 NS_HTML5_CONTINUE(stateloop);
4292 default: {
4293 bogusDoctype();
4294 state = P::transition(mViewSource.get(),
4295 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4296 pos);
4297 NS_HTML5_CONTINUE(stateloop);
4301 beforedoctypesystemidentifierloop_end:;
4302 [[fallthrough]];
4304 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
4305 for (;;) {
4306 if (++pos == endPos) {
4307 NS_HTML5_BREAK(stateloop);
4309 c = checkChar(buf, pos);
4310 switch (c) {
4311 case '\'': {
4312 systemIdentifier = strBufToString();
4313 state = P::transition(
4314 mViewSource.get(),
4315 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4316 pos);
4317 NS_HTML5_CONTINUE(stateloop);
4319 case '>': {
4320 if (P::reportErrors) {
4321 errGtInSystemId();
4323 forceQuirks = true;
4324 systemIdentifier = strBufToString();
4325 emitDoctypeToken(pos);
4326 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4327 reconsume, pos);
4328 if (shouldSuspend) {
4329 NS_HTML5_BREAK(stateloop);
4331 NS_HTML5_CONTINUE(stateloop);
4333 case '\r': {
4334 appendStrBufCarriageReturn();
4335 NS_HTML5_BREAK(stateloop);
4337 case '\n': {
4338 appendStrBufLineFeed();
4339 continue;
4341 case '\0': {
4342 c = 0xfffd;
4343 [[fallthrough]];
4345 default: {
4346 appendStrBuf(c);
4347 continue;
4352 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
4353 for (;;) {
4354 if (++pos == endPos) {
4355 NS_HTML5_BREAK(stateloop);
4357 c = checkChar(buf, pos);
4358 switch (c) {
4359 case '\'': {
4360 publicIdentifier = strBufToString();
4361 state = P::transition(
4362 mViewSource.get(),
4363 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
4364 pos);
4365 NS_HTML5_CONTINUE(stateloop);
4367 case '>': {
4368 if (P::reportErrors) {
4369 errGtInPublicId();
4371 forceQuirks = true;
4372 publicIdentifier = strBufToString();
4373 emitDoctypeToken(pos);
4374 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4375 reconsume, pos);
4376 if (shouldSuspend) {
4377 NS_HTML5_BREAK(stateloop);
4379 NS_HTML5_CONTINUE(stateloop);
4381 case '\r': {
4382 appendStrBufCarriageReturn();
4383 NS_HTML5_BREAK(stateloop);
4385 case '\n': {
4386 appendStrBufLineFeed();
4387 continue;
4389 case '\0': {
4390 c = 0xfffd;
4391 [[fallthrough]];
4393 default: {
4394 appendStrBuf(c);
4395 continue;
4400 case PROCESSING_INSTRUCTION: {
4401 for (;;) {
4402 if (++pos == endPos) {
4403 NS_HTML5_BREAK(stateloop);
4405 c = checkChar(buf, pos);
4406 switch (c) {
4407 case '\?': {
4408 state = P::transition(
4409 mViewSource.get(),
4410 nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK,
4411 reconsume, pos);
4412 NS_HTML5_BREAK(processinginstructionloop);
4414 default: {
4415 continue;
4419 processinginstructionloop_end:;
4420 [[fallthrough]];
4422 case PROCESSING_INSTRUCTION_QUESTION_MARK: {
4423 if (++pos == endPos) {
4424 NS_HTML5_BREAK(stateloop);
4426 c = checkChar(buf, pos);
4427 switch (c) {
4428 case '>': {
4429 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4430 reconsume, pos);
4431 suspendIfRequestedAfterCurrentNonTextToken();
4432 if (shouldSuspend) {
4433 NS_HTML5_BREAK(stateloop);
4435 NS_HTML5_CONTINUE(stateloop);
4437 default: {
4438 state = P::transition(mViewSource.get(),
4439 nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
4440 reconsume, pos);
4441 NS_HTML5_CONTINUE(stateloop);
4447 stateloop_end:;
4448 flushChars(buf, pos);
4449 stateSave = state;
4450 returnStateSave = returnState;
4451 return pos;
4454 void nsHtml5Tokenizer::initDoctypeFields() {
4455 clearStrBufAfterUse();
4456 doctypeName = nullptr;
4457 if (systemIdentifier) {
4458 systemIdentifier.Release();
4459 systemIdentifier = nullptr;
4461 if (publicIdentifier) {
4462 publicIdentifier.Release();
4463 publicIdentifier = nullptr;
4465 forceQuirks = false;
4468 void nsHtml5Tokenizer::emitCarriageReturn(char16_t* buf, int32_t pos) {
4469 silentCarriageReturn();
4470 flushChars(buf, pos);
4471 tokenHandler->characters(nsHtml5Tokenizer::LF, 0, 1);
4472 cstart = INT32_MAX;
4475 void nsHtml5Tokenizer::emitReplacementCharacter(char16_t* buf, int32_t pos) {
4476 flushChars(buf, pos);
4477 tokenHandler->zeroOriginatingReplacementCharacter();
4478 cstart = pos + 1;
4481 void nsHtml5Tokenizer::maybeEmitReplacementCharacter(char16_t* buf,
4482 int32_t pos) {
4483 flushChars(buf, pos);
4484 tokenHandler->zeroOrReplacementCharacter();
4485 cstart = pos + 1;
4488 void nsHtml5Tokenizer::emitPlaintextReplacementCharacter(char16_t* buf,
4489 int32_t pos) {
4490 flushChars(buf, pos);
4491 tokenHandler->characters(REPLACEMENT_CHARACTER, 0, 1);
4492 cstart = pos + 1;
4495 void nsHtml5Tokenizer::setAdditionalAndRememberAmpersandLocation(char16_t add) {
4496 additional = add;
4499 void nsHtml5Tokenizer::bogusDoctype() {
4500 errBogusDoctype();
4501 forceQuirks = true;
4504 void nsHtml5Tokenizer::bogusDoctypeWithoutQuirks() {
4505 errBogusDoctype();
4506 forceQuirks = false;
4509 void nsHtml5Tokenizer::handleNcrValue(int32_t returnState) {
4510 if (value <= 0xFFFF) {
4511 if (value >= 0x80 && value <= 0x9f) {
4512 errNcrInC1Range();
4513 char16_t* val = nsHtml5NamedCharacters::WINDOWS_1252[value - 0x80];
4514 emitOrAppendOne(val, returnState);
4515 } else if (value == 0x0) {
4516 errNcrZero();
4517 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4518 } else if ((value & 0xF800) == 0xD800) {
4519 errNcrSurrogate();
4520 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4521 } else {
4522 char16_t ch = (char16_t)value;
4523 bmpChar[0] = ch;
4524 emitOrAppendOne(bmpChar, returnState);
4526 } else if (value <= 0x10FFFF) {
4527 astralChar[0] = (char16_t)(nsHtml5Tokenizer::LEAD_OFFSET + (value >> 10));
4528 astralChar[1] = (char16_t)(0xDC00 + (value & 0x3FF));
4529 emitOrAppendTwo(astralChar, returnState);
4530 } else {
4531 errNcrOutOfRange();
4532 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4536 void nsHtml5Tokenizer::eof() {
4537 int32_t state = stateSave;
4538 int32_t returnState = returnStateSave;
4539 eofloop:
4540 for (;;) {
4541 switch (state) {
4542 case SCRIPT_DATA_LESS_THAN_SIGN:
4543 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
4544 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4545 NS_HTML5_BREAK(eofloop);
4547 case TAG_OPEN: {
4548 errEofAfterLt();
4549 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4550 NS_HTML5_BREAK(eofloop);
4552 case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
4553 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4554 NS_HTML5_BREAK(eofloop);
4556 case NON_DATA_END_TAG_NAME: {
4557 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
4558 emitStrBuf();
4559 NS_HTML5_BREAK(eofloop);
4561 case CLOSE_TAG_OPEN: {
4562 errEofAfterLt();
4563 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
4564 NS_HTML5_BREAK(eofloop);
4566 case TAG_NAME: {
4567 errEofInTagName();
4568 NS_HTML5_BREAK(eofloop);
4570 case BEFORE_ATTRIBUTE_NAME:
4571 case AFTER_ATTRIBUTE_VALUE_QUOTED:
4572 case SELF_CLOSING_START_TAG: {
4573 errEofWithoutGt();
4574 NS_HTML5_BREAK(eofloop);
4576 case ATTRIBUTE_NAME: {
4577 errEofInAttributeName();
4578 NS_HTML5_BREAK(eofloop);
4580 case AFTER_ATTRIBUTE_NAME:
4581 case BEFORE_ATTRIBUTE_VALUE: {
4582 errEofWithoutGt();
4583 NS_HTML5_BREAK(eofloop);
4585 case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
4586 case ATTRIBUTE_VALUE_SINGLE_QUOTED:
4587 case ATTRIBUTE_VALUE_UNQUOTED: {
4588 errEofInAttributeValue();
4589 NS_HTML5_BREAK(eofloop);
4591 case BOGUS_COMMENT: {
4592 emitComment(0, 0);
4593 NS_HTML5_BREAK(eofloop);
4595 case BOGUS_COMMENT_HYPHEN: {
4596 emitComment(0, 0);
4597 NS_HTML5_BREAK(eofloop);
4599 case MARKUP_DECLARATION_OPEN: {
4600 errBogusComment();
4601 emitComment(0, 0);
4602 NS_HTML5_BREAK(eofloop);
4604 case MARKUP_DECLARATION_HYPHEN: {
4605 errBogusComment();
4606 emitComment(0, 0);
4607 NS_HTML5_BREAK(eofloop);
4609 case MARKUP_DECLARATION_OCTYPE: {
4610 if (index < 6) {
4611 errBogusComment();
4612 emitComment(0, 0);
4613 } else {
4614 errEofInDoctype();
4615 doctypeName = nullptr;
4616 if (systemIdentifier) {
4617 systemIdentifier.Release();
4618 systemIdentifier = nullptr;
4620 if (publicIdentifier) {
4621 publicIdentifier.Release();
4622 publicIdentifier = nullptr;
4624 forceQuirks = true;
4625 emitDoctypeToken(0);
4626 NS_HTML5_BREAK(eofloop);
4628 NS_HTML5_BREAK(eofloop);
4630 case COMMENT_START:
4631 case COMMENT:
4632 case COMMENT_LESSTHAN:
4633 case COMMENT_LESSTHAN_BANG: {
4634 errEofInComment();
4635 emitComment(0, 0);
4636 NS_HTML5_BREAK(eofloop);
4638 case COMMENT_END:
4639 case COMMENT_LESSTHAN_BANG_DASH_DASH: {
4640 errEofInComment();
4641 emitComment(2, 0);
4642 NS_HTML5_BREAK(eofloop);
4644 case COMMENT_END_DASH:
4645 case COMMENT_START_DASH:
4646 case COMMENT_LESSTHAN_BANG_DASH: {
4647 errEofInComment();
4648 emitComment(1, 0);
4649 NS_HTML5_BREAK(eofloop);
4651 case COMMENT_END_BANG: {
4652 errEofInComment();
4653 emitComment(3, 0);
4654 NS_HTML5_BREAK(eofloop);
4656 case DOCTYPE:
4657 case BEFORE_DOCTYPE_NAME: {
4658 errEofInDoctype();
4659 forceQuirks = true;
4660 emitDoctypeToken(0);
4661 NS_HTML5_BREAK(eofloop);
4663 case DOCTYPE_NAME: {
4664 errEofInDoctype();
4665 strBufToDoctypeName();
4666 forceQuirks = true;
4667 emitDoctypeToken(0);
4668 NS_HTML5_BREAK(eofloop);
4670 case DOCTYPE_UBLIC:
4671 case DOCTYPE_YSTEM:
4672 case AFTER_DOCTYPE_NAME:
4673 case AFTER_DOCTYPE_PUBLIC_KEYWORD:
4674 case AFTER_DOCTYPE_SYSTEM_KEYWORD:
4675 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
4676 errEofInDoctype();
4677 forceQuirks = true;
4678 emitDoctypeToken(0);
4679 NS_HTML5_BREAK(eofloop);
4681 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
4682 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
4683 errEofInPublicId();
4684 forceQuirks = true;
4685 publicIdentifier = strBufToString();
4686 emitDoctypeToken(0);
4687 NS_HTML5_BREAK(eofloop);
4689 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
4690 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
4691 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
4692 errEofInDoctype();
4693 forceQuirks = true;
4694 emitDoctypeToken(0);
4695 NS_HTML5_BREAK(eofloop);
4697 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
4698 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
4699 errEofInSystemId();
4700 forceQuirks = true;
4701 systemIdentifier = strBufToString();
4702 emitDoctypeToken(0);
4703 NS_HTML5_BREAK(eofloop);
4705 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
4706 errEofInDoctype();
4707 forceQuirks = true;
4708 emitDoctypeToken(0);
4709 NS_HTML5_BREAK(eofloop);
4711 case BOGUS_DOCTYPE: {
4712 emitDoctypeToken(0);
4713 NS_HTML5_BREAK(eofloop);
4715 case CONSUME_CHARACTER_REFERENCE: {
4716 emitOrAppendCharRefBuf(returnState);
4717 state = returnState;
4718 continue;
4720 case CHARACTER_REFERENCE_HILO_LOOKUP: {
4721 emitOrAppendCharRefBuf(returnState);
4722 state = returnState;
4723 continue;
4725 case CHARACTER_REFERENCE_TAIL: {
4726 for (;;) {
4727 char16_t c = '\0';
4728 entCol++;
4729 for (;;) {
4730 if (hi == -1) {
4731 NS_HTML5_BREAK(hiloop);
4733 if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
4734 NS_HTML5_BREAK(hiloop);
4736 if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
4737 NS_HTML5_BREAK(outer);
4738 } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
4739 hi--;
4740 } else {
4741 NS_HTML5_BREAK(hiloop);
4744 hiloop_end:;
4745 for (;;) {
4746 if (hi < lo) {
4747 NS_HTML5_BREAK(outer);
4749 if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
4750 candidate = lo;
4751 charRefBufMark = charRefBufLen;
4752 lo++;
4753 } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
4754 NS_HTML5_BREAK(outer);
4755 } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
4756 lo++;
4757 } else {
4758 NS_HTML5_BREAK(loloop);
4761 loloop_end:;
4762 if (hi < lo) {
4763 NS_HTML5_BREAK(outer);
4765 continue;
4767 outer_end:;
4768 if (candidate == -1) {
4769 emitOrAppendCharRefBuf(returnState);
4770 state = returnState;
4771 NS_HTML5_CONTINUE(eofloop);
4772 } else {
4773 const nsHtml5CharacterName& candidateName =
4774 nsHtml5NamedCharacters::NAMES[candidate];
4775 if (!candidateName.length() ||
4776 candidateName.charAt(candidateName.length() - 1) != ';') {
4777 if ((returnState & DATA_AND_RCDATA_MASK)) {
4778 char16_t ch;
4779 if (charRefBufMark == charRefBufLen) {
4780 ch = '\0';
4781 } else {
4782 ch = charRefBuf[charRefBufMark];
4784 if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') ||
4785 (ch >= 'a' && ch <= 'z')) {
4786 appendCharRefBufToStrBuf();
4787 state = returnState;
4788 NS_HTML5_CONTINUE(eofloop);
4791 if ((returnState & DATA_AND_RCDATA_MASK)) {
4792 errUnescapedAmpersandInterpretedAsCharacterReference();
4793 } else {
4794 errNotSemicolonTerminated();
4797 const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
4798 if (!val[1]) {
4799 emitOrAppendOne(val, returnState);
4800 } else {
4801 emitOrAppendTwo(val, returnState);
4803 if (charRefBufMark < charRefBufLen) {
4804 if ((returnState & DATA_AND_RCDATA_MASK)) {
4805 appendStrBuf(charRefBuf, charRefBufMark,
4806 charRefBufLen - charRefBufMark);
4807 } else {
4808 tokenHandler->characters(charRefBuf, charRefBufMark,
4809 charRefBufLen - charRefBufMark);
4812 charRefBufLen = 0;
4813 state = returnState;
4814 NS_HTML5_CONTINUE(eofloop);
4817 case CONSUME_NCR:
4818 case DECIMAL_NRC_LOOP:
4819 case HEX_NCR_LOOP: {
4820 if (!seenDigits) {
4821 errNoDigitsInNCR();
4822 emitOrAppendCharRefBuf(returnState);
4823 state = returnState;
4824 continue;
4825 } else {
4826 errCharRefLacksSemicolon();
4828 handleNcrValue(returnState);
4829 state = returnState;
4830 continue;
4832 case CDATA_RSQB: {
4833 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
4834 NS_HTML5_BREAK(eofloop);
4836 case CDATA_RSQB_RSQB: {
4837 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
4838 NS_HTML5_BREAK(eofloop);
4840 case DATA:
4841 default: {
4842 NS_HTML5_BREAK(eofloop);
4846 eofloop_end:;
4847 tokenHandler->eof();
4848 return;
4851 void nsHtml5Tokenizer::emitDoctypeToken(int32_t pos) {
4852 RememberGt(pos);
4853 cstart = pos + 1;
4854 tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier,
4855 forceQuirks);
4856 doctypeName = nullptr;
4857 publicIdentifier.Release();
4858 publicIdentifier = nullptr;
4859 systemIdentifier.Release();
4860 systemIdentifier = nullptr;
4861 suspendIfRequestedAfterCurrentNonTextToken();
4864 void nsHtml5Tokenizer::suspendIfRequestedAfterCurrentNonTextToken() {
4865 if (suspendAfterCurrentNonTextToken) {
4866 suspendAfterCurrentNonTextToken = false;
4867 shouldSuspend = true;
4871 void nsHtml5Tokenizer::suspendAfterCurrentTokenIfNotInText() {
4872 switch (stateSave) {
4873 case DATA:
4874 case RCDATA:
4875 case SCRIPT_DATA:
4876 case RAWTEXT:
4877 case SCRIPT_DATA_ESCAPED:
4878 case PLAINTEXT:
4879 case NON_DATA_END_TAG_NAME:
4880 case SCRIPT_DATA_LESS_THAN_SIGN:
4881 case SCRIPT_DATA_ESCAPE_START:
4882 case SCRIPT_DATA_ESCAPE_START_DASH:
4883 case SCRIPT_DATA_ESCAPED_DASH:
4884 case SCRIPT_DATA_ESCAPED_DASH_DASH:
4885 case RAWTEXT_RCDATA_LESS_THAN_SIGN:
4886 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
4887 case SCRIPT_DATA_DOUBLE_ESCAPE_START:
4888 case SCRIPT_DATA_DOUBLE_ESCAPED:
4889 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
4890 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
4891 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
4892 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
4893 return;
4895 case TAG_NAME:
4896 case BEFORE_ATTRIBUTE_NAME:
4897 case ATTRIBUTE_NAME:
4898 case AFTER_ATTRIBUTE_NAME:
4899 case BEFORE_ATTRIBUTE_VALUE:
4900 case AFTER_ATTRIBUTE_VALUE_QUOTED:
4901 case BOGUS_COMMENT:
4902 case MARKUP_DECLARATION_OPEN:
4903 case DOCTYPE:
4904 case BEFORE_DOCTYPE_NAME:
4905 case DOCTYPE_NAME:
4906 case AFTER_DOCTYPE_NAME:
4907 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
4908 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
4909 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
4910 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
4911 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
4912 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
4913 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
4914 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
4915 case BOGUS_DOCTYPE:
4916 case COMMENT_START:
4917 case COMMENT_START_DASH:
4918 case COMMENT:
4919 case COMMENT_END_DASH:
4920 case COMMENT_END:
4921 case COMMENT_END_BANG:
4922 case TAG_OPEN:
4923 case CLOSE_TAG_OPEN:
4924 case MARKUP_DECLARATION_HYPHEN:
4925 case MARKUP_DECLARATION_OCTYPE:
4926 case DOCTYPE_UBLIC:
4927 case DOCTYPE_YSTEM:
4928 case AFTER_DOCTYPE_PUBLIC_KEYWORD:
4929 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
4930 case AFTER_DOCTYPE_SYSTEM_KEYWORD:
4931 case SELF_CLOSING_START_TAG:
4932 case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
4933 case ATTRIBUTE_VALUE_SINGLE_QUOTED:
4934 case ATTRIBUTE_VALUE_UNQUOTED:
4935 case BOGUS_COMMENT_HYPHEN:
4936 case COMMENT_LESSTHAN:
4937 case COMMENT_LESSTHAN_BANG:
4938 case COMMENT_LESSTHAN_BANG_DASH:
4939 case COMMENT_LESSTHAN_BANG_DASH_DASH:
4940 case CDATA_START:
4941 case CDATA_SECTION:
4942 case CDATA_RSQB:
4943 case CDATA_RSQB_RSQB:
4944 case PROCESSING_INSTRUCTION:
4945 case PROCESSING_INSTRUCTION_QUESTION_MARK: {
4946 break;
4948 case CONSUME_CHARACTER_REFERENCE:
4949 case CONSUME_NCR:
4950 case CHARACTER_REFERENCE_TAIL:
4951 case HEX_NCR_LOOP:
4952 case DECIMAL_NRC_LOOP:
4953 case HANDLE_NCR_VALUE:
4954 case HANDLE_NCR_VALUE_RECONSUME:
4955 case CHARACTER_REFERENCE_HILO_LOOKUP: {
4956 if (returnStateSave == DATA || returnStateSave == RCDATA) {
4957 return;
4959 break;
4961 default: {
4962 MOZ_ASSERT(false, "Incomplete switch");
4963 return;
4966 suspendAfterCurrentNonTextToken = true;
4969 bool nsHtml5Tokenizer::suspensionAfterCurrentNonTextTokenPending() {
4970 return suspendAfterCurrentNonTextToken;
4973 bool nsHtml5Tokenizer::internalEncodingDeclaration(
4974 nsHtml5String internalCharset) {
4975 if (encodingDeclarationHandler) {
4976 return encodingDeclarationHandler->internalEncodingDeclaration(
4977 internalCharset);
4979 return false;
4982 void nsHtml5Tokenizer::emitOrAppendTwo(const char16_t* val,
4983 int32_t returnState) {
4984 if ((returnState & DATA_AND_RCDATA_MASK)) {
4985 appendStrBuf(val[0]);
4986 appendStrBuf(val[1]);
4987 } else {
4988 tokenHandler->characters(val, 0, 2);
4992 void nsHtml5Tokenizer::emitOrAppendOne(const char16_t* val,
4993 int32_t returnState) {
4994 if ((returnState & DATA_AND_RCDATA_MASK)) {
4995 appendStrBuf(val[0]);
4996 } else {
4997 tokenHandler->characters(val, 0, 1);
5001 void nsHtml5Tokenizer::end() {
5002 strBuf = nullptr;
5003 doctypeName = nullptr;
5004 if (systemIdentifier) {
5005 systemIdentifier.Release();
5006 systemIdentifier = nullptr;
5008 if (publicIdentifier) {
5009 publicIdentifier.Release();
5010 publicIdentifier = nullptr;
5012 tagName = nullptr;
5013 nonInternedTagName->setNameForNonInterned(nullptr, false);
5014 attributeName = nullptr;
5015 nonInternedAttributeName->setNameForNonInterned(nullptr);
5016 tokenHandler->endTokenization();
5017 if (attributes) {
5018 attributes->clear(0);
5022 void nsHtml5Tokenizer::requestSuspension() { shouldSuspend = true; }
5024 bool nsHtml5Tokenizer::isInDataState() { return (stateSave == DATA); }
5026 void nsHtml5Tokenizer::resetToDataState() {
5027 clearStrBufAfterUse();
5028 charRefBufLen = 0;
5029 stateSave = nsHtml5Tokenizer::DATA;
5030 lastCR = false;
5031 index = 0;
5032 forceQuirks = false;
5033 additional = '\0';
5034 entCol = -1;
5035 firstCharKey = -1;
5036 lo = 0;
5037 hi = 0;
5038 candidate = -1;
5039 charRefBufMark = 0;
5040 value = 0;
5041 seenDigits = false;
5042 suspendAfterCurrentNonTextToken = false;
5043 endTag = false;
5044 shouldSuspend = false;
5045 initDoctypeFields();
5046 containsHyphen = false;
5047 tagName = nullptr;
5048 attributeName = nullptr;
5049 if (newAttributesEachTime) {
5050 if (attributes) {
5051 delete attributes;
5052 attributes = nullptr;
5057 void nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other) {
5058 strBufLen = other->strBufLen;
5059 if (strBufLen > strBuf.length) {
5060 strBuf = jArray<char16_t, int32_t>::newJArray(strBufLen);
5062 nsHtml5ArrayCopy::arraycopy(other->strBuf, strBuf, strBufLen);
5063 charRefBufLen = other->charRefBufLen;
5064 nsHtml5ArrayCopy::arraycopy(other->charRefBuf, charRefBuf, charRefBufLen);
5065 stateSave = other->stateSave;
5066 returnStateSave = other->returnStateSave;
5067 endTagExpectation = other->endTagExpectation;
5068 endTagExpectationAsArray = other->endTagExpectationAsArray;
5069 lastCR = other->lastCR;
5070 index = other->index;
5071 forceQuirks = other->forceQuirks;
5072 additional = other->additional;
5073 entCol = other->entCol;
5074 firstCharKey = other->firstCharKey;
5075 lo = other->lo;
5076 hi = other->hi;
5077 candidate = other->candidate;
5078 charRefBufMark = other->charRefBufMark;
5079 value = other->value;
5080 seenDigits = other->seenDigits;
5081 endTag = other->endTag;
5082 shouldSuspend = false;
5083 suspendAfterCurrentNonTextToken = false;
5084 doctypeName = other->doctypeName;
5085 systemIdentifier.Release();
5086 if (!other->systemIdentifier) {
5087 systemIdentifier = nullptr;
5088 } else {
5089 systemIdentifier =
5090 nsHtml5Portability::newStringFromString(other->systemIdentifier);
5092 publicIdentifier.Release();
5093 if (!other->publicIdentifier) {
5094 publicIdentifier = nullptr;
5095 } else {
5096 publicIdentifier =
5097 nsHtml5Portability::newStringFromString(other->publicIdentifier);
5099 containsHyphen = other->containsHyphen;
5100 if (!other->tagName) {
5101 tagName = nullptr;
5102 } else if (other->tagName->isInterned()) {
5103 tagName = other->tagName;
5104 } else {
5105 nonInternedTagName->setNameForNonInterned(other->tagName->getName(),
5106 other->tagName->isCustom());
5107 tagName = nonInternedTagName;
5109 if (!other->attributeName) {
5110 attributeName = nullptr;
5111 } else if (other->attributeName->isInterned()) {
5112 attributeName = other->attributeName;
5113 } else {
5114 nonInternedAttributeName->setNameForNonInterned(
5115 other->attributeName->getLocal(nsHtml5AttributeName::HTML));
5116 attributeName = nonInternedAttributeName;
5118 delete attributes;
5119 if (!other->attributes) {
5120 attributes = nullptr;
5121 } else {
5122 attributes = other->attributes->cloneAttributes();
5126 void nsHtml5Tokenizer::initializeWithoutStarting() {
5127 confident = false;
5128 strBuf = nullptr;
5129 line = 1;
5130 attributeLine = 1;
5131 resetToDataState();
5134 void nsHtml5Tokenizer::setEncodingDeclarationHandler(
5135 nsHtml5StreamParser* encodingDeclarationHandler) {
5136 this->encodingDeclarationHandler = encodingDeclarationHandler;
5139 nsHtml5Tokenizer::~nsHtml5Tokenizer() {
5140 MOZ_COUNT_DTOR(nsHtml5Tokenizer);
5141 delete nonInternedTagName;
5142 nonInternedTagName = nullptr;
5143 delete nonInternedAttributeName;
5144 nonInternedAttributeName = nullptr;
5145 delete attributes;
5146 attributes = nullptr;
5149 void nsHtml5Tokenizer::initializeStatics() {}
5151 void nsHtml5Tokenizer::releaseStatics() {}
5153 #include "nsHtml5TokenizerCppSupplement.h"