Bug 1930352 - Fix android lint failure. a=lint-fix CLOSED TREE
[gecko.git] / parser / html / nsHtml5Tokenizer.cpp
blob1a305d95cb6263f231c36e4b2c3f1182c68a17e6
1 /*
2 * Copyright (c) 2005-2007 Henri Sivonen
3 * Copyright (c) 2007-2017 Mozilla Foundation
4 * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
5 * Foundation, and Opera Software ASA.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
27 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
28 * Please edit Tokenizer.java instead and regenerate.
31 #define nsHtml5Tokenizer_cpp__
33 #include "nsHtml5AttributeName.h"
34 #include "nsHtml5ElementName.h"
35 #include "nsHtml5TreeBuilder.h"
36 #include "nsHtml5StackNode.h"
37 #include "nsHtml5UTF16Buffer.h"
38 #include "nsHtml5StateSnapshot.h"
39 #include "nsHtml5Portability.h"
41 #include "nsHtml5Tokenizer.h"
43 #include "nsHtml5TokenizerLoopPolicies.h"
45 char16_t nsHtml5Tokenizer::LT_GT[] = {'<', '>'};
46 char16_t nsHtml5Tokenizer::LT_SOLIDUS[] = {'<', '/'};
47 char16_t nsHtml5Tokenizer::RSQB_RSQB[] = {']', ']'};
48 char16_t nsHtml5Tokenizer::REPLACEMENT_CHARACTER[] = {0xfffd};
49 char16_t nsHtml5Tokenizer::LF[] = {'\n'};
50 char16_t nsHtml5Tokenizer::CDATA_LSQB[] = {'C', 'D', 'A', 'T', 'A', '['};
51 char16_t nsHtml5Tokenizer::OCTYPE[] = {'o', 'c', 't', 'y', 'p', 'e'};
52 char16_t nsHtml5Tokenizer::UBLIC[] = {'u', 'b', 'l', 'i', 'c'};
53 char16_t nsHtml5Tokenizer::YSTEM[] = {'y', 's', 't', 'e', 'm'};
54 static char16_t const TITLE_ARR_DATA[] = {'t', 'i', 't', 'l', 'e'};
55 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TITLE_ARR = {
56 TITLE_ARR_DATA, std::size(TITLE_ARR_DATA)};
57 static char16_t const SCRIPT_ARR_DATA[] = {'s', 'c', 'r', 'i', 'p', 't'};
58 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::SCRIPT_ARR = {
59 SCRIPT_ARR_DATA, std::size(SCRIPT_ARR_DATA)};
60 static char16_t const STYLE_ARR_DATA[] = {'s', 't', 'y', 'l', 'e'};
61 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::STYLE_ARR = {
62 STYLE_ARR_DATA, std::size(STYLE_ARR_DATA)};
63 static char16_t const PLAINTEXT_ARR_DATA[] = {'p', 'l', 'a', 'i', 'n',
64 't', 'e', 'x', 't'};
65 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::PLAINTEXT_ARR = {
66 PLAINTEXT_ARR_DATA, std::size(PLAINTEXT_ARR_DATA)};
67 static char16_t const XMP_ARR_DATA[] = {'x', 'm', 'p'};
68 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::XMP_ARR = {
69 XMP_ARR_DATA, std::size(XMP_ARR_DATA)};
70 static char16_t const TEXTAREA_ARR_DATA[] = {'t', 'e', 'x', 't',
71 'a', 'r', 'e', 'a'};
72 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TEXTAREA_ARR = {
73 TEXTAREA_ARR_DATA, std::size(TEXTAREA_ARR_DATA)};
74 static char16_t const IFRAME_ARR_DATA[] = {'i', 'f', 'r', 'a', 'm', 'e'};
75 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::IFRAME_ARR = {
76 IFRAME_ARR_DATA, std::size(IFRAME_ARR_DATA)};
77 static char16_t const NOEMBED_ARR_DATA[] = {'n', 'o', 'e', 'm', 'b', 'e', 'd'};
78 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOEMBED_ARR = {
79 NOEMBED_ARR_DATA, std::size(NOEMBED_ARR_DATA)};
80 static char16_t const NOSCRIPT_ARR_DATA[] = {'n', 'o', 's', 'c',
81 'r', 'i', 'p', 't'};
82 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOSCRIPT_ARR = {
83 NOSCRIPT_ARR_DATA, std::size(NOSCRIPT_ARR_DATA)};
84 static char16_t const NOFRAMES_ARR_DATA[] = {'n', 'o', 'f', 'r',
85 'a', 'm', 'e', 's'};
86 staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOFRAMES_ARR = {
87 NOFRAMES_ARR_DATA, std::size(NOFRAMES_ARR_DATA)};
89 nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler,
90 bool viewingXmlSource)
91 : tokenHandler(tokenHandler),
92 encodingDeclarationHandler(nullptr),
93 lastCR(false),
94 stateSave(0),
95 returnStateSave(0),
96 index(0),
97 forceQuirks(false),
98 additional('\0'),
99 entCol(0),
100 firstCharKey(0),
101 lo(0),
102 hi(0),
103 candidate(0),
104 charRefBufMark(0),
105 value(0),
106 seenDigits(false),
107 suspendAfterCurrentNonTextToken(false),
108 cstart(0),
109 strBufLen(0),
110 charRefBuf(jArray<char16_t, int32_t>::newJArray(32)),
111 charRefBufLen(0),
112 bmpChar(jArray<char16_t, int32_t>::newJArray(1)),
113 astralChar(jArray<char16_t, int32_t>::newJArray(2)),
114 endTagExpectation(nullptr),
115 endTagExpectationAsArray(nullptr),
116 endTag(false),
117 containsHyphen(false),
118 tagName(nullptr),
119 nonInternedTagName(new nsHtml5ElementName()),
120 attributeName(nullptr),
121 nonInternedAttributeName(new nsHtml5AttributeName()),
122 doctypeName(nullptr),
123 publicIdentifier(nullptr),
124 systemIdentifier(nullptr),
125 attributes(tokenHandler->HasBuilder() ? new nsHtml5HtmlAttributes(0)
126 : nullptr),
127 newAttributesEachTime(!tokenHandler->HasBuilder()),
128 shouldSuspend(false),
129 keepBuffer(false),
130 confident(false),
131 line(0),
132 attributeLine(0),
133 interner(nullptr),
134 viewingXmlSource(viewingXmlSource) {
135 MOZ_COUNT_CTOR(nsHtml5Tokenizer);
138 void nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner) {
139 this->interner = interner;
142 void nsHtml5Tokenizer::initLocation(nsHtml5String newPublicId,
143 nsHtml5String newSystemId) {
144 this->systemId = newSystemId;
145 this->publicId = newPublicId;
148 bool nsHtml5Tokenizer::isViewingXmlSource() { return viewingXmlSource; }
150 void nsHtml5Tokenizer::setKeepBuffer(bool keepBuffer) {
151 this->keepBuffer = keepBuffer;
154 bool nsHtml5Tokenizer::dropBufferIfLongerThan(int32_t length) {
155 if (strBuf.length > length) {
156 strBuf = nullptr;
157 return true;
159 return false;
162 void nsHtml5Tokenizer::setState(int32_t specialTokenizerState) {
163 this->stateSave = specialTokenizerState;
164 this->endTagExpectation = nullptr;
165 this->endTagExpectationAsArray = nullptr;
168 void nsHtml5Tokenizer::setStateAndEndTagExpectation(
169 int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation) {
170 this->stateSave = specialTokenizerState;
171 this->endTagExpectation = endTagExpectation;
172 endTagExpectationToArray();
175 void nsHtml5Tokenizer::endTagExpectationToArray() {
176 switch (endTagExpectation->getGroup()) {
177 case nsHtml5TreeBuilder::TITLE: {
178 endTagExpectationAsArray = TITLE_ARR;
179 return;
181 case nsHtml5TreeBuilder::SCRIPT: {
182 endTagExpectationAsArray = SCRIPT_ARR;
183 return;
185 case nsHtml5TreeBuilder::STYLE: {
186 endTagExpectationAsArray = STYLE_ARR;
187 return;
189 case nsHtml5TreeBuilder::PLAINTEXT: {
190 endTagExpectationAsArray = PLAINTEXT_ARR;
191 return;
193 case nsHtml5TreeBuilder::XMP: {
194 endTagExpectationAsArray = XMP_ARR;
195 return;
197 case nsHtml5TreeBuilder::TEXTAREA: {
198 endTagExpectationAsArray = TEXTAREA_ARR;
199 return;
201 case nsHtml5TreeBuilder::IFRAME: {
202 endTagExpectationAsArray = IFRAME_ARR;
203 return;
205 case nsHtml5TreeBuilder::NOEMBED: {
206 endTagExpectationAsArray = NOEMBED_ARR;
207 return;
209 case nsHtml5TreeBuilder::NOSCRIPT: {
210 endTagExpectationAsArray = NOSCRIPT_ARR;
211 return;
213 case nsHtml5TreeBuilder::NOFRAMES: {
214 endTagExpectationAsArray = NOFRAMES_ARR;
215 return;
217 default: {
218 MOZ_ASSERT(false, "Bad end tag expectation.");
219 return;
224 void nsHtml5Tokenizer::setLineNumber(int32_t line) {
225 this->attributeLine = line;
226 this->line = line;
229 nsHtml5HtmlAttributes* nsHtml5Tokenizer::emptyAttributes() {
230 return nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES;
233 void nsHtml5Tokenizer::emitOrAppendCharRefBuf(int32_t returnState) {
234 if ((returnState & DATA_AND_RCDATA_MASK)) {
235 appendCharRefBufToStrBuf();
236 } else {
237 if (charRefBufLen > 0) {
238 tokenHandler->characters(charRefBuf, 0, charRefBufLen);
239 charRefBufLen = 0;
244 nsHtml5String nsHtml5Tokenizer::strBufToString() {
245 nsHtml5String str = nsHtml5Portability::newStringFromBuffer(
246 strBuf, 0, strBufLen, tokenHandler,
247 !newAttributesEachTime &&
248 attributeName == nsHtml5AttributeName::ATTR_CLASS);
249 clearStrBufAfterUse();
250 return str;
253 void nsHtml5Tokenizer::strBufToDoctypeName() {
254 doctypeName =
255 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen, interner);
256 clearStrBufAfterUse();
259 void nsHtml5Tokenizer::emitStrBuf() {
260 if (strBufLen > 0) {
261 tokenHandler->characters(strBuf, 0, strBufLen);
262 clearStrBufAfterUse();
266 void nsHtml5Tokenizer::appendStrBuf(char16_t* buffer, int32_t offset,
267 int32_t length) {
268 int32_t newLen = nsHtml5Portability::checkedAdd(strBufLen, length);
269 MOZ_ASSERT(newLen <= strBuf.length, "Previous buffer length insufficient.");
270 if (MOZ_UNLIKELY(strBuf.length < newLen)) {
271 if (MOZ_UNLIKELY(!EnsureBufferSpace(length))) {
272 MOZ_CRASH("Unable to recover from buffer reallocation failure");
275 nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length);
276 strBufLen = newLen;
279 void nsHtml5Tokenizer::emitComment(int32_t provisionalHyphens, int32_t pos) {
280 RememberGt(pos);
281 tokenHandler->comment(strBuf, 0, strBufLen - provisionalHyphens);
282 clearStrBufAfterUse();
283 cstart = pos + 1;
284 suspendIfRequestedAfterCurrentNonTextToken();
287 void nsHtml5Tokenizer::flushChars(char16_t* buf, int32_t pos) {
288 if (pos > cstart) {
289 tokenHandler->characters(buf, cstart, pos - cstart);
291 cstart = INT32_MAX;
294 void nsHtml5Tokenizer::strBufToElementNameString() {
295 if (containsHyphen) {
296 nsAtom* annotationName = nsHtml5ElementName::ELT_ANNOTATION_XML->getName();
297 if (nsHtml5Portability::localEqualsBuffer(annotationName, strBuf,
298 strBufLen)) {
299 tagName = nsHtml5ElementName::ELT_ANNOTATION_XML;
300 } else {
301 nonInternedTagName->setNameForNonInterned(
302 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
303 interner),
304 true);
305 tagName = nonInternedTagName;
307 } else {
308 tagName = nsHtml5ElementName::elementNameByBuffer(strBuf, strBufLen);
309 if (!tagName) {
310 nonInternedTagName->setNameForNonInterned(
311 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
312 interner),
313 false);
314 tagName = nonInternedTagName;
317 containsHyphen = false;
318 clearStrBufAfterUse();
321 int32_t nsHtml5Tokenizer::emitCurrentTagToken(bool selfClosing, int32_t pos) {
322 RememberGt(pos);
323 cstart = pos + 1;
324 maybeErrSlashInEndTag(selfClosing);
325 stateSave = nsHtml5Tokenizer::DATA;
326 nsHtml5HtmlAttributes* attrs =
327 (!attributes ? nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES : attributes);
328 if (endTag) {
329 maybeErrAttributesOnEndTag(attrs);
330 if (!viewingXmlSource) {
331 tokenHandler->endTag(tagName);
333 if (newAttributesEachTime) {
334 delete attributes;
335 attributes = nullptr;
337 } else {
338 if (viewingXmlSource) {
339 MOZ_ASSERT(newAttributesEachTime);
340 delete attributes;
341 attributes = nullptr;
342 } else {
343 tokenHandler->startTag(tagName, attrs, selfClosing);
346 tagName = nullptr;
347 if (newAttributesEachTime) {
348 attributes = nullptr;
349 } else {
350 attributes->clear(0);
352 suspendIfRequestedAfterCurrentNonTextToken();
353 return stateSave;
356 void nsHtml5Tokenizer::attributeNameComplete() {
357 attributeName =
358 nsHtml5AttributeName::nameByBuffer(strBuf, strBufLen, interner);
359 if (!attributeName) {
360 nonInternedAttributeName->setNameForNonInterned(
361 nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
362 interner));
363 attributeName = nonInternedAttributeName;
365 clearStrBufAfterUse();
366 if (!attributes) {
367 attributes = new nsHtml5HtmlAttributes(0);
369 if (attributes->contains(attributeName)) {
370 errDuplicateAttribute();
371 attributeName = nullptr;
375 void nsHtml5Tokenizer::addAttributeWithoutValue() {
376 if (attributeName) {
377 attributes->addAttribute(
378 attributeName, nsHtml5Portability::newEmptyString(), attributeLine);
379 attributeName = nullptr;
380 } else {
381 clearStrBufAfterUse();
385 void nsHtml5Tokenizer::addAttributeWithValue() {
386 if (attributeName) {
387 nsHtml5String val = strBufToString();
388 if (mViewSource) {
389 mViewSource->MaybeLinkifyAttributeValue(attributeName, val);
391 attributes->addAttribute(attributeName, val, attributeLine);
392 attributeName = nullptr;
393 } else {
394 clearStrBufAfterUse();
398 void nsHtml5Tokenizer::start() {
399 initializeWithoutStarting();
400 tokenHandler->startTokenization(this);
401 if (mViewSource) {
402 line = 1;
403 col = -1;
404 nextCharOnNewLine = false;
405 } else if (tokenHandler->WantsLineAndColumn()) {
406 line = 0;
407 col = 1;
408 nextCharOnNewLine = true;
409 } else {
410 line = -1;
411 col = -1;
412 nextCharOnNewLine = false;
416 bool nsHtml5Tokenizer::tokenizeBuffer(nsHtml5UTF16Buffer* buffer) {
417 int32_t state = stateSave;
418 int32_t returnState = returnStateSave;
419 char16_t c = '\0';
420 shouldSuspend = false;
421 lastCR = false;
422 int32_t start = buffer->getStart();
423 int32_t end = buffer->getEnd();
424 int32_t pos = start - 1;
425 switch (state) {
426 case DATA:
427 case RCDATA:
428 case SCRIPT_DATA:
429 case PLAINTEXT:
430 case RAWTEXT:
431 case CDATA_SECTION:
432 case SCRIPT_DATA_ESCAPED:
433 case SCRIPT_DATA_ESCAPE_START:
434 case SCRIPT_DATA_ESCAPE_START_DASH:
435 case SCRIPT_DATA_ESCAPED_DASH:
436 case SCRIPT_DATA_ESCAPED_DASH_DASH:
437 case SCRIPT_DATA_DOUBLE_ESCAPE_START:
438 case SCRIPT_DATA_DOUBLE_ESCAPED:
439 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
440 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
441 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
442 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
443 cstart = start;
444 break;
446 default: {
447 cstart = INT32_MAX;
448 break;
451 if (mViewSource) {
452 mViewSource->SetBuffer(buffer);
453 pos = stateLoop<nsHtml5ViewSourcePolicy>(state, c, pos, buffer->getBuffer(),
454 false, returnState,
455 buffer->getEnd());
456 mViewSource->DropBuffer((pos == buffer->getEnd()) ? pos : pos + 1);
457 } else if (tokenHandler->WantsLineAndColumn()) {
458 pos = stateLoop<nsHtml5LineColPolicy>(state, c, pos, buffer->getBuffer(),
459 false, returnState, buffer->getEnd());
460 } else {
461 pos = stateLoop<nsHtml5FastestPolicy>(state, c, pos, buffer->getBuffer(),
462 false, returnState, buffer->getEnd());
464 if (pos == end) {
465 buffer->setStart(pos);
466 } else {
467 buffer->setStart(pos + 1);
469 return lastCR;
472 template <class P>
473 int32_t nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos,
474 char16_t* buf, bool reconsume,
475 int32_t returnState, int32_t endPos) {
476 bool reportedConsecutiveHyphens = false;
477 stateloop:
478 for (;;) {
479 switch (state) {
480 case DATA: {
481 for (;;) {
482 if (reconsume) {
483 reconsume = false;
484 } else {
485 if (++pos == endPos) {
486 NS_HTML5_BREAK(stateloop);
488 c = P::checkChar(this, buf, pos);
490 switch (c) {
491 case '&': {
492 flushChars(buf, pos);
493 MOZ_ASSERT(!charRefBufLen,
494 "charRefBufLen not reset after previous use!");
495 appendCharRefBuf(c);
496 setAdditionalAndRememberAmpersandLocation('\0');
497 returnState = state;
498 state =
499 P::transition(mViewSource.get(),
500 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
501 reconsume, pos);
502 NS_HTML5_CONTINUE(stateloop);
504 case '<': {
505 flushChars(buf, pos);
506 state = P::transition(mViewSource.get(),
507 nsHtml5Tokenizer::TAG_OPEN, reconsume, pos);
508 NS_HTML5_BREAK(dataloop);
510 case '\0': {
511 maybeEmitReplacementCharacter(buf, pos);
512 continue;
514 case '\r': {
515 emitCarriageReturn<P>(buf, pos);
516 NS_HTML5_BREAK(stateloop);
518 case '\n': {
519 P::silentLineFeed(this);
520 [[fallthrough]];
522 default: {
523 continue;
527 dataloop_end:;
528 [[fallthrough]];
530 case TAG_OPEN: {
531 for (;;) {
532 if (++pos == endPos) {
533 NS_HTML5_BREAK(stateloop);
535 c = P::checkChar(this, buf, pos);
536 if (c >= 'A' && c <= 'Z') {
537 endTag = false;
538 clearStrBufBeforeUse();
539 appendStrBuf((char16_t)(c + 0x20));
540 containsHyphen = false;
541 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
542 reconsume, pos);
543 NS_HTML5_BREAK(tagopenloop);
544 } else if (c >= 'a' && c <= 'z') {
545 endTag = false;
546 clearStrBufBeforeUse();
547 appendStrBuf(c);
548 containsHyphen = false;
549 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
550 reconsume, pos);
551 NS_HTML5_BREAK(tagopenloop);
553 switch (c) {
554 case '!': {
555 state = P::transition(mViewSource.get(),
556 nsHtml5Tokenizer::MARKUP_DECLARATION_OPEN,
557 reconsume, pos);
558 NS_HTML5_CONTINUE(stateloop);
560 case '/': {
561 state = P::transition(mViewSource.get(),
562 nsHtml5Tokenizer::CLOSE_TAG_OPEN, reconsume,
563 pos);
564 NS_HTML5_CONTINUE(stateloop);
566 case '\?': {
567 if (viewingXmlSource) {
568 state = P::transition(mViewSource.get(),
569 nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
570 reconsume, pos);
571 NS_HTML5_CONTINUE(stateloop);
573 if (P::reportErrors) {
574 errProcessingInstruction();
576 clearStrBufBeforeUse();
577 appendStrBuf(c);
578 state = P::transition(mViewSource.get(),
579 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
580 pos);
581 NS_HTML5_CONTINUE(stateloop);
583 case '>': {
584 if (P::reportErrors) {
585 errLtGt();
587 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
588 cstart = pos + 1;
589 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
590 reconsume, pos);
591 NS_HTML5_CONTINUE(stateloop);
593 default: {
594 if (P::reportErrors) {
595 errBadCharAfterLt(c);
597 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
598 cstart = pos;
599 reconsume = true;
600 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
601 reconsume, pos);
602 NS_HTML5_CONTINUE(stateloop);
606 tagopenloop_end:;
607 [[fallthrough]];
609 case TAG_NAME: {
610 for (;;) {
611 if (++pos == endPos) {
612 NS_HTML5_BREAK(stateloop);
614 c = P::checkChar(this, buf, pos);
615 switch (c) {
616 case '\r': {
617 P::silentCarriageReturn(this);
618 strBufToElementNameString();
619 state = P::transition(mViewSource.get(),
620 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
621 reconsume, pos);
622 NS_HTML5_BREAK(stateloop);
624 case '\n': {
625 P::silentLineFeed(this);
626 [[fallthrough]];
628 case ' ':
629 case '\t':
630 case '\f': {
631 strBufToElementNameString();
632 state = P::transition(mViewSource.get(),
633 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
634 reconsume, pos);
635 NS_HTML5_BREAK(tagnameloop);
637 case '/': {
638 strBufToElementNameString();
639 state = P::transition(mViewSource.get(),
640 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
641 reconsume, pos);
642 NS_HTML5_CONTINUE(stateloop);
644 case '>': {
645 strBufToElementNameString();
646 state = P::transition(mViewSource.get(),
647 emitCurrentTagToken(false, pos), reconsume,
648 pos);
649 if (shouldSuspend) {
650 NS_HTML5_BREAK(stateloop);
652 NS_HTML5_CONTINUE(stateloop);
654 case '\0': {
655 c = 0xfffd;
656 [[fallthrough]];
658 default: {
659 if (c >= 'A' && c <= 'Z') {
660 c += 0x20;
661 } else if (c == '-') {
662 containsHyphen = true;
664 appendStrBuf(c);
665 continue;
669 tagnameloop_end:;
670 [[fallthrough]];
672 case BEFORE_ATTRIBUTE_NAME: {
673 for (;;) {
674 if (reconsume) {
675 reconsume = false;
676 } else {
677 if (++pos == endPos) {
678 NS_HTML5_BREAK(stateloop);
680 c = P::checkChar(this, buf, pos);
682 switch (c) {
683 case '\r': {
684 P::silentCarriageReturn(this);
685 NS_HTML5_BREAK(stateloop);
687 case '\n': {
688 P::silentLineFeed(this);
689 [[fallthrough]];
691 case ' ':
692 case '\t':
693 case '\f': {
694 continue;
696 case '/': {
697 state = P::transition(mViewSource.get(),
698 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
699 reconsume, pos);
700 NS_HTML5_CONTINUE(stateloop);
702 case '>': {
703 state = P::transition(mViewSource.get(),
704 emitCurrentTagToken(false, pos), reconsume,
705 pos);
706 if (shouldSuspend) {
707 NS_HTML5_BREAK(stateloop);
709 NS_HTML5_CONTINUE(stateloop);
711 case '\0': {
712 c = 0xfffd;
713 [[fallthrough]];
715 case '\"':
716 case '\'':
717 case '<':
718 case '=': {
719 if (P::reportErrors) {
720 errBadCharBeforeAttributeNameOrNull(c);
722 [[fallthrough]];
724 default: {
725 if (c >= 'A' && c <= 'Z') {
726 c += 0x20;
728 attributeLine = line;
729 clearStrBufBeforeUse();
730 appendStrBuf(c);
731 state = P::transition(mViewSource.get(),
732 nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
733 pos);
734 NS_HTML5_BREAK(beforeattributenameloop);
738 beforeattributenameloop_end:;
739 [[fallthrough]];
741 case ATTRIBUTE_NAME: {
742 for (;;) {
743 if (++pos == endPos) {
744 NS_HTML5_BREAK(stateloop);
746 c = P::checkChar(this, buf, pos);
747 switch (c) {
748 case '\r': {
749 P::silentCarriageReturn(this);
750 attributeNameComplete();
751 state = P::transition(mViewSource.get(),
752 nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
753 reconsume, pos);
754 NS_HTML5_BREAK(stateloop);
756 case '\n': {
757 P::silentLineFeed(this);
758 [[fallthrough]];
760 case ' ':
761 case '\t':
762 case '\f': {
763 attributeNameComplete();
764 state = P::transition(mViewSource.get(),
765 nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
766 reconsume, pos);
767 NS_HTML5_CONTINUE(stateloop);
769 case '/': {
770 attributeNameComplete();
771 addAttributeWithoutValue();
772 state = P::transition(mViewSource.get(),
773 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
774 reconsume, pos);
775 NS_HTML5_CONTINUE(stateloop);
777 case '=': {
778 attributeNameComplete();
779 state = P::transition(mViewSource.get(),
780 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
781 reconsume, pos);
782 NS_HTML5_BREAK(attributenameloop);
784 case '>': {
785 attributeNameComplete();
786 addAttributeWithoutValue();
787 state = P::transition(mViewSource.get(),
788 emitCurrentTagToken(false, pos), reconsume,
789 pos);
790 if (shouldSuspend) {
791 NS_HTML5_BREAK(stateloop);
793 NS_HTML5_CONTINUE(stateloop);
795 case '\0': {
796 c = 0xfffd;
797 [[fallthrough]];
799 case '\"':
800 case '\'':
801 case '<': {
802 if (P::reportErrors) {
803 errQuoteOrLtInAttributeNameOrNull(c);
805 [[fallthrough]];
807 default: {
808 if (c >= 'A' && c <= 'Z') {
809 c += 0x20;
811 appendStrBuf(c);
812 continue;
816 attributenameloop_end:;
817 [[fallthrough]];
819 case BEFORE_ATTRIBUTE_VALUE: {
820 for (;;) {
821 if (++pos == endPos) {
822 NS_HTML5_BREAK(stateloop);
824 c = P::checkChar(this, buf, pos);
825 switch (c) {
826 case '\r': {
827 P::silentCarriageReturn(this);
828 NS_HTML5_BREAK(stateloop);
830 case '\n': {
831 P::silentLineFeed(this);
832 [[fallthrough]];
834 case ' ':
835 case '\t':
836 case '\f': {
837 continue;
839 case '\"': {
840 attributeLine = line;
841 clearStrBufBeforeUse();
842 state =
843 P::transition(mViewSource.get(),
844 nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED,
845 reconsume, pos);
846 NS_HTML5_BREAK(beforeattributevalueloop);
848 case '&': {
849 attributeLine = line;
850 clearStrBufBeforeUse();
851 reconsume = true;
852 state = P::transition(mViewSource.get(),
853 nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
854 reconsume, pos);
856 NS_HTML5_CONTINUE(stateloop);
858 case '\'': {
859 attributeLine = line;
860 clearStrBufBeforeUse();
861 state =
862 P::transition(mViewSource.get(),
863 nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED,
864 reconsume, pos);
865 NS_HTML5_CONTINUE(stateloop);
867 case '>': {
868 if (P::reportErrors) {
869 errAttributeValueMissing();
871 addAttributeWithoutValue();
872 state = P::transition(mViewSource.get(),
873 emitCurrentTagToken(false, pos), reconsume,
874 pos);
875 if (shouldSuspend) {
876 NS_HTML5_BREAK(stateloop);
878 NS_HTML5_CONTINUE(stateloop);
880 case '\0': {
881 c = 0xfffd;
882 [[fallthrough]];
884 case '<':
885 case '=':
886 case '`': {
887 if (P::reportErrors) {
888 errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
890 [[fallthrough]];
892 default: {
893 attributeLine = line;
894 clearStrBufBeforeUse();
895 appendStrBuf(c);
896 state = P::transition(mViewSource.get(),
897 nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
898 reconsume, pos);
900 NS_HTML5_CONTINUE(stateloop);
904 beforeattributevalueloop_end:;
905 [[fallthrough]];
907 case ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
908 for (;;) {
909 if (reconsume) {
910 reconsume = false;
911 } else {
912 if (++pos == endPos) {
913 NS_HTML5_BREAK(stateloop);
915 c = P::checkChar(this, buf, pos);
917 switch (c) {
918 case '\"': {
919 addAttributeWithValue();
920 state =
921 P::transition(mViewSource.get(),
922 nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
923 reconsume, pos);
924 NS_HTML5_BREAK(attributevaluedoublequotedloop);
926 case '&': {
927 MOZ_ASSERT(!charRefBufLen,
928 "charRefBufLen not reset after previous use!");
929 appendCharRefBuf(c);
930 setAdditionalAndRememberAmpersandLocation('\"');
931 returnState = state;
932 state =
933 P::transition(mViewSource.get(),
934 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
935 reconsume, pos);
936 NS_HTML5_CONTINUE(stateloop);
938 case '\r': {
939 appendStrBufCarriageReturn<P>();
940 NS_HTML5_BREAK(stateloop);
942 case '\n': {
943 appendStrBufLineFeed<P>();
944 continue;
946 case '\0': {
947 c = 0xfffd;
948 [[fallthrough]];
950 default: {
951 appendStrBuf(c);
952 continue;
956 attributevaluedoublequotedloop_end:;
957 [[fallthrough]];
959 case AFTER_ATTRIBUTE_VALUE_QUOTED: {
960 for (;;) {
961 if (++pos == endPos) {
962 NS_HTML5_BREAK(stateloop);
964 c = P::checkChar(this, buf, pos);
965 switch (c) {
966 case '\r': {
967 P::silentCarriageReturn(this);
968 state = P::transition(mViewSource.get(),
969 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
970 reconsume, pos);
971 NS_HTML5_BREAK(stateloop);
973 case '\n': {
974 P::silentLineFeed(this);
975 [[fallthrough]];
977 case ' ':
978 case '\t':
979 case '\f': {
980 state = P::transition(mViewSource.get(),
981 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
982 reconsume, pos);
983 NS_HTML5_CONTINUE(stateloop);
985 case '/': {
986 state = P::transition(mViewSource.get(),
987 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
988 reconsume, pos);
989 NS_HTML5_BREAK(afterattributevaluequotedloop);
991 case '>': {
992 state = P::transition(mViewSource.get(),
993 emitCurrentTagToken(false, pos), reconsume,
994 pos);
995 if (shouldSuspend) {
996 NS_HTML5_BREAK(stateloop);
998 NS_HTML5_CONTINUE(stateloop);
1000 default: {
1001 if (P::reportErrors) {
1002 errNoSpaceBetweenAttributes();
1004 reconsume = true;
1005 state = P::transition(mViewSource.get(),
1006 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1007 reconsume, pos);
1008 NS_HTML5_CONTINUE(stateloop);
1012 afterattributevaluequotedloop_end:;
1013 [[fallthrough]];
1015 case SELF_CLOSING_START_TAG: {
1016 if (++pos == endPos) {
1017 NS_HTML5_BREAK(stateloop);
1019 c = P::checkChar(this, buf, pos);
1020 switch (c) {
1021 case '>': {
1022 state =
1023 P::transition(mViewSource.get(), emitCurrentTagToken(true, pos),
1024 reconsume, pos);
1025 if (shouldSuspend) {
1026 NS_HTML5_BREAK(stateloop);
1028 NS_HTML5_CONTINUE(stateloop);
1030 default: {
1031 if (P::reportErrors) {
1032 errSlashNotFollowedByGt();
1034 reconsume = true;
1035 state = P::transition(mViewSource.get(),
1036 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1037 reconsume, pos);
1038 NS_HTML5_CONTINUE(stateloop);
1042 case ATTRIBUTE_VALUE_UNQUOTED: {
1043 for (;;) {
1044 if (reconsume) {
1045 reconsume = false;
1046 } else {
1047 if (++pos == endPos) {
1048 NS_HTML5_BREAK(stateloop);
1050 c = P::checkChar(this, buf, pos);
1052 switch (c) {
1053 case '\r': {
1054 P::silentCarriageReturn(this);
1055 addAttributeWithValue();
1056 state = P::transition(mViewSource.get(),
1057 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1058 reconsume, pos);
1059 NS_HTML5_BREAK(stateloop);
1061 case '\n': {
1062 P::silentLineFeed(this);
1063 [[fallthrough]];
1065 case ' ':
1066 case '\t':
1067 case '\f': {
1068 addAttributeWithValue();
1069 state = P::transition(mViewSource.get(),
1070 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
1071 reconsume, pos);
1072 NS_HTML5_CONTINUE(stateloop);
1074 case '&': {
1075 MOZ_ASSERT(!charRefBufLen,
1076 "charRefBufLen not reset after previous use!");
1077 appendCharRefBuf(c);
1078 setAdditionalAndRememberAmpersandLocation('>');
1079 returnState = state;
1080 state =
1081 P::transition(mViewSource.get(),
1082 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
1083 reconsume, pos);
1084 NS_HTML5_CONTINUE(stateloop);
1086 case '>': {
1087 addAttributeWithValue();
1088 state = P::transition(mViewSource.get(),
1089 emitCurrentTagToken(false, pos), reconsume,
1090 pos);
1091 if (shouldSuspend) {
1092 NS_HTML5_BREAK(stateloop);
1094 NS_HTML5_CONTINUE(stateloop);
1096 case '\0': {
1097 c = 0xfffd;
1098 [[fallthrough]];
1100 case '<':
1101 case '\"':
1102 case '\'':
1103 case '=':
1104 case '`': {
1105 if (P::reportErrors) {
1106 errUnquotedAttributeValOrNull(c);
1108 [[fallthrough]];
1110 default: {
1111 appendStrBuf(c);
1112 continue;
1117 case AFTER_ATTRIBUTE_NAME: {
1118 for (;;) {
1119 if (++pos == endPos) {
1120 NS_HTML5_BREAK(stateloop);
1122 c = P::checkChar(this, buf, pos);
1123 switch (c) {
1124 case '\r': {
1125 P::silentCarriageReturn(this);
1126 NS_HTML5_BREAK(stateloop);
1128 case '\n': {
1129 P::silentLineFeed(this);
1130 [[fallthrough]];
1132 case ' ':
1133 case '\t':
1134 case '\f': {
1135 continue;
1137 case '/': {
1138 addAttributeWithoutValue();
1139 state = P::transition(mViewSource.get(),
1140 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
1141 reconsume, pos);
1142 NS_HTML5_CONTINUE(stateloop);
1144 case '=': {
1145 state = P::transition(mViewSource.get(),
1146 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
1147 reconsume, pos);
1148 NS_HTML5_CONTINUE(stateloop);
1150 case '>': {
1151 addAttributeWithoutValue();
1152 state = P::transition(mViewSource.get(),
1153 emitCurrentTagToken(false, pos), reconsume,
1154 pos);
1155 if (shouldSuspend) {
1156 NS_HTML5_BREAK(stateloop);
1158 NS_HTML5_CONTINUE(stateloop);
1160 case '\0': {
1161 c = 0xfffd;
1162 [[fallthrough]];
1164 case '\"':
1165 case '\'':
1166 case '<': {
1167 if (P::reportErrors) {
1168 errQuoteOrLtInAttributeNameOrNull(c);
1170 [[fallthrough]];
1172 default: {
1173 addAttributeWithoutValue();
1174 if (c >= 'A' && c <= 'Z') {
1175 c += 0x20;
1177 clearStrBufBeforeUse();
1178 appendStrBuf(c);
1179 state = P::transition(mViewSource.get(),
1180 nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
1181 pos);
1182 NS_HTML5_CONTINUE(stateloop);
1187 case MARKUP_DECLARATION_OPEN: {
1188 for (;;) {
1189 if (++pos == endPos) {
1190 NS_HTML5_BREAK(stateloop);
1192 c = P::checkChar(this, buf, pos);
1193 switch (c) {
1194 case '-': {
1195 clearStrBufBeforeUse();
1196 appendStrBuf(c);
1197 state = P::transition(mViewSource.get(),
1198 nsHtml5Tokenizer::MARKUP_DECLARATION_HYPHEN,
1199 reconsume, pos);
1200 NS_HTML5_BREAK(markupdeclarationopenloop);
1202 case 'd':
1203 case 'D': {
1204 clearStrBufBeforeUse();
1205 appendStrBuf(c);
1206 index = 0;
1207 state = P::transition(mViewSource.get(),
1208 nsHtml5Tokenizer::MARKUP_DECLARATION_OCTYPE,
1209 reconsume, pos);
1210 NS_HTML5_CONTINUE(stateloop);
1212 case '[': {
1213 if (tokenHandler->cdataSectionAllowed()) {
1214 clearStrBufBeforeUse();
1215 appendStrBuf(c);
1216 index = 0;
1217 state = P::transition(mViewSource.get(),
1218 nsHtml5Tokenizer::CDATA_START, reconsume,
1219 pos);
1220 NS_HTML5_CONTINUE(stateloop);
1222 [[fallthrough]];
1224 default: {
1225 if (P::reportErrors) {
1226 errBogusComment();
1228 clearStrBufBeforeUse();
1229 reconsume = true;
1230 state = P::transition(mViewSource.get(),
1231 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1232 pos);
1233 NS_HTML5_CONTINUE(stateloop);
1237 markupdeclarationopenloop_end:;
1238 [[fallthrough]];
1240 case MARKUP_DECLARATION_HYPHEN: {
1241 for (;;) {
1242 if (++pos == endPos) {
1243 NS_HTML5_BREAK(stateloop);
1245 c = P::checkChar(this, buf, pos);
1246 switch (c) {
1247 case '-': {
1248 clearStrBufAfterOneHyphen();
1249 state = P::transition(mViewSource.get(),
1250 nsHtml5Tokenizer::COMMENT_START, reconsume,
1251 pos);
1252 NS_HTML5_BREAK(markupdeclarationhyphenloop);
1254 default: {
1255 if (P::reportErrors) {
1256 errBogusComment();
1258 reconsume = true;
1259 state = P::transition(mViewSource.get(),
1260 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1261 pos);
1262 NS_HTML5_CONTINUE(stateloop);
1266 markupdeclarationhyphenloop_end:;
1267 [[fallthrough]];
1269 case COMMENT_START: {
1270 reportedConsecutiveHyphens = false;
1271 for (;;) {
1272 if (++pos == endPos) {
1273 NS_HTML5_BREAK(stateloop);
1275 c = P::checkChar(this, buf, pos);
1276 switch (c) {
1277 case '-': {
1278 appendStrBuf(c);
1279 state = P::transition(mViewSource.get(),
1280 nsHtml5Tokenizer::COMMENT_START_DASH,
1281 reconsume, pos);
1282 NS_HTML5_CONTINUE(stateloop);
1284 case '>': {
1285 if (P::reportErrors) {
1286 errPrematureEndOfComment();
1288 emitComment(0, pos);
1289 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1290 reconsume, pos);
1291 if (shouldSuspend) {
1292 NS_HTML5_BREAK(stateloop);
1294 NS_HTML5_CONTINUE(stateloop);
1296 case '<': {
1297 appendStrBuf(c);
1298 state = P::transition(mViewSource.get(),
1299 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1300 reconsume, pos);
1301 NS_HTML5_CONTINUE(stateloop);
1303 case '\r': {
1304 appendStrBufCarriageReturn<P>();
1305 state = P::transition(mViewSource.get(),
1306 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1307 NS_HTML5_BREAK(stateloop);
1309 case '\n': {
1310 appendStrBufLineFeed<P>();
1311 state = P::transition(mViewSource.get(),
1312 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1313 NS_HTML5_BREAK(commentstartloop);
1315 case '\0': {
1316 c = 0xfffd;
1317 [[fallthrough]];
1319 default: {
1320 appendStrBuf(c);
1321 state = P::transition(mViewSource.get(),
1322 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1323 NS_HTML5_BREAK(commentstartloop);
1327 commentstartloop_end:;
1328 [[fallthrough]];
1330 case COMMENT: {
1331 for (;;) {
1332 if (++pos == endPos) {
1333 NS_HTML5_BREAK(stateloop);
1335 c = P::checkChar(this, buf, pos);
1336 switch (c) {
1337 case '-': {
1338 appendStrBuf(c);
1339 state = P::transition(mViewSource.get(),
1340 nsHtml5Tokenizer::COMMENT_END_DASH,
1341 reconsume, pos);
1342 NS_HTML5_BREAK(commentloop);
1344 case '<': {
1345 appendStrBuf(c);
1346 state = P::transition(mViewSource.get(),
1347 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1348 reconsume, pos);
1349 NS_HTML5_CONTINUE(stateloop);
1351 case '\r': {
1352 appendStrBufCarriageReturn<P>();
1353 NS_HTML5_BREAK(stateloop);
1355 case '\n': {
1356 appendStrBufLineFeed<P>();
1357 continue;
1359 case '\0': {
1360 c = 0xfffd;
1361 [[fallthrough]];
1363 default: {
1364 appendStrBuf(c);
1365 continue;
1369 commentloop_end:;
1370 [[fallthrough]];
1372 case COMMENT_END_DASH: {
1373 for (;;) {
1374 if (++pos == endPos) {
1375 NS_HTML5_BREAK(stateloop);
1377 c = P::checkChar(this, buf, pos);
1378 switch (c) {
1379 case '-': {
1380 appendStrBuf(c);
1381 state =
1382 P::transition(mViewSource.get(),
1383 nsHtml5Tokenizer::COMMENT_END, reconsume, pos);
1384 NS_HTML5_BREAK(commentenddashloop);
1386 case '<': {
1387 appendStrBuf(c);
1388 state = P::transition(mViewSource.get(),
1389 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1390 reconsume, pos);
1391 NS_HTML5_CONTINUE(stateloop);
1393 case '\r': {
1394 appendStrBufCarriageReturn<P>();
1395 state = P::transition(mViewSource.get(),
1396 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1397 NS_HTML5_BREAK(stateloop);
1399 case '\n': {
1400 appendStrBufLineFeed<P>();
1401 state = P::transition(mViewSource.get(),
1402 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1403 NS_HTML5_CONTINUE(stateloop);
1405 case '\0': {
1406 c = 0xfffd;
1407 [[fallthrough]];
1409 default: {
1410 appendStrBuf(c);
1411 state = P::transition(mViewSource.get(),
1412 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1413 NS_HTML5_CONTINUE(stateloop);
1417 commentenddashloop_end:;
1418 [[fallthrough]];
1420 case COMMENT_END: {
1421 for (;;) {
1422 if (++pos == endPos) {
1423 NS_HTML5_BREAK(stateloop);
1425 c = P::checkChar(this, buf, pos);
1426 switch (c) {
1427 case '>': {
1428 emitComment(2, pos);
1429 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1430 reconsume, pos);
1431 if (shouldSuspend) {
1432 NS_HTML5_BREAK(stateloop);
1434 NS_HTML5_CONTINUE(stateloop);
1436 case '-': {
1437 adjustDoubleHyphenAndAppendToStrBufAndErr(
1438 c, reportedConsecutiveHyphens);
1439 reportedConsecutiveHyphens = true;
1440 continue;
1442 case '<': {
1443 appendStrBuf(c);
1444 state = P::transition(mViewSource.get(),
1445 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1446 reconsume, pos);
1447 NS_HTML5_CONTINUE(stateloop);
1449 case '\r': {
1450 adjustDoubleHyphenAndAppendToStrBufCarriageReturn<P>();
1451 state = P::transition(mViewSource.get(),
1452 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1453 NS_HTML5_BREAK(stateloop);
1455 case '\n': {
1456 adjustDoubleHyphenAndAppendToStrBufLineFeed<P>();
1457 state = P::transition(mViewSource.get(),
1458 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1459 NS_HTML5_CONTINUE(stateloop);
1461 case '!': {
1462 appendStrBuf(c);
1463 state = P::transition(mViewSource.get(),
1464 nsHtml5Tokenizer::COMMENT_END_BANG,
1465 reconsume, pos);
1466 NS_HTML5_BREAK(commentendloop);
1468 case '\0': {
1469 c = 0xfffd;
1470 [[fallthrough]];
1472 default: {
1473 adjustDoubleHyphenAndAppendToStrBufAndErr(
1474 c, reportedConsecutiveHyphens);
1475 reportedConsecutiveHyphens = true;
1476 state = P::transition(mViewSource.get(),
1477 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1478 NS_HTML5_CONTINUE(stateloop);
1482 commentendloop_end:;
1483 [[fallthrough]];
1485 case COMMENT_END_BANG: {
1486 for (;;) {
1487 if (++pos == endPos) {
1488 NS_HTML5_BREAK(stateloop);
1490 c = P::checkChar(this, buf, pos);
1491 switch (c) {
1492 case '>': {
1493 emitComment(3, pos);
1494 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1495 reconsume, pos);
1496 if (shouldSuspend) {
1497 NS_HTML5_BREAK(stateloop);
1499 NS_HTML5_CONTINUE(stateloop);
1501 case '-': {
1502 appendStrBuf(c);
1503 state = P::transition(mViewSource.get(),
1504 nsHtml5Tokenizer::COMMENT_END_DASH,
1505 reconsume, pos);
1506 NS_HTML5_CONTINUE(stateloop);
1508 case '\r': {
1509 appendStrBufCarriageReturn<P>();
1510 state = P::transition(mViewSource.get(),
1511 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1512 NS_HTML5_BREAK(stateloop);
1514 case '\n': {
1515 appendStrBufLineFeed<P>();
1516 state = P::transition(mViewSource.get(),
1517 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1518 NS_HTML5_CONTINUE(stateloop);
1520 case '\0': {
1521 c = 0xfffd;
1522 [[fallthrough]];
1524 default: {
1525 appendStrBuf(c);
1526 state = P::transition(mViewSource.get(),
1527 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1528 NS_HTML5_CONTINUE(stateloop);
1533 case COMMENT_LESSTHAN: {
1534 for (;;) {
1535 if (++pos == endPos) {
1536 NS_HTML5_BREAK(stateloop);
1538 c = P::checkChar(this, buf, pos);
1539 switch (c) {
1540 case '!': {
1541 appendStrBuf(c);
1542 state = P::transition(mViewSource.get(),
1543 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG,
1544 reconsume, pos);
1545 NS_HTML5_BREAK(commentlessthanloop);
1547 case '<': {
1548 appendStrBuf(c);
1549 continue;
1551 case '-': {
1552 appendStrBuf(c);
1553 state = P::transition(mViewSource.get(),
1554 nsHtml5Tokenizer::COMMENT_END_DASH,
1555 reconsume, pos);
1556 NS_HTML5_CONTINUE(stateloop);
1558 case '\r': {
1559 appendStrBufCarriageReturn<P>();
1560 state = P::transition(mViewSource.get(),
1561 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1562 NS_HTML5_BREAK(stateloop);
1564 case '\n': {
1565 appendStrBufLineFeed<P>();
1566 state = P::transition(mViewSource.get(),
1567 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1568 NS_HTML5_CONTINUE(stateloop);
1570 case '\0': {
1571 c = 0xfffd;
1572 [[fallthrough]];
1574 default: {
1575 appendStrBuf(c);
1576 state = P::transition(mViewSource.get(),
1577 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1578 NS_HTML5_CONTINUE(stateloop);
1582 commentlessthanloop_end:;
1583 [[fallthrough]];
1585 case COMMENT_LESSTHAN_BANG: {
1586 for (;;) {
1587 if (++pos == endPos) {
1588 NS_HTML5_BREAK(stateloop);
1590 c = P::checkChar(this, buf, pos);
1591 switch (c) {
1592 case '-': {
1593 appendStrBuf(c);
1594 state = P::transition(
1595 mViewSource.get(),
1596 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH, reconsume, pos);
1597 NS_HTML5_BREAK(commentlessthanbangloop);
1599 case '<': {
1600 appendStrBuf(c);
1601 state = P::transition(mViewSource.get(),
1602 nsHtml5Tokenizer::COMMENT_LESSTHAN,
1603 reconsume, pos);
1604 NS_HTML5_CONTINUE(stateloop);
1606 case '\r': {
1607 appendStrBufCarriageReturn<P>();
1608 state = P::transition(mViewSource.get(),
1609 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1610 NS_HTML5_BREAK(stateloop);
1612 case '\n': {
1613 appendStrBufLineFeed<P>();
1614 state = P::transition(mViewSource.get(),
1615 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1616 NS_HTML5_CONTINUE(stateloop);
1618 case '\0': {
1619 c = 0xfffd;
1620 [[fallthrough]];
1622 default: {
1623 appendStrBuf(c);
1624 state = P::transition(mViewSource.get(),
1625 nsHtml5Tokenizer::COMMENT, reconsume, pos);
1626 NS_HTML5_CONTINUE(stateloop);
1630 commentlessthanbangloop_end:;
1631 [[fallthrough]];
1633 case COMMENT_LESSTHAN_BANG_DASH: {
1634 if (++pos == endPos) {
1635 NS_HTML5_BREAK(stateloop);
1637 c = P::checkChar(this, buf, pos);
1638 switch (c) {
1639 case '-': {
1640 appendStrBuf(c);
1641 state =
1642 P::transition(mViewSource.get(),
1643 nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH,
1644 reconsume, pos);
1645 break;
1647 case '<': {
1648 appendStrBuf(c);
1649 state = P::transition(mViewSource.get(),
1650 nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
1651 pos);
1652 NS_HTML5_CONTINUE(stateloop);
1654 case '\r': {
1655 appendStrBufCarriageReturn<P>();
1656 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1657 reconsume, pos);
1658 NS_HTML5_BREAK(stateloop);
1660 case '\n': {
1661 appendStrBufLineFeed<P>();
1662 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1663 reconsume, pos);
1664 NS_HTML5_CONTINUE(stateloop);
1666 case '\0': {
1667 c = 0xfffd;
1668 [[fallthrough]];
1670 default: {
1671 appendStrBuf(c);
1672 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1673 reconsume, pos);
1674 NS_HTML5_CONTINUE(stateloop);
1677 [[fallthrough]];
1679 case COMMENT_LESSTHAN_BANG_DASH_DASH: {
1680 if (++pos == endPos) {
1681 NS_HTML5_BREAK(stateloop);
1683 c = P::checkChar(this, buf, pos);
1684 switch (c) {
1685 case '>': {
1686 appendStrBuf(c);
1687 emitComment(3, pos);
1688 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1689 reconsume, pos);
1690 if (shouldSuspend) {
1691 NS_HTML5_BREAK(stateloop);
1693 NS_HTML5_CONTINUE(stateloop);
1695 case '-': {
1696 if (P::reportErrors) {
1697 errNestedComment();
1699 adjustDoubleHyphenAndAppendToStrBufAndErr(
1700 c, reportedConsecutiveHyphens);
1701 reportedConsecutiveHyphens = true;
1702 state =
1703 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
1704 reconsume, pos);
1705 NS_HTML5_CONTINUE(stateloop);
1707 case '\r': {
1708 c = '\n';
1709 P::silentCarriageReturn(this);
1710 if (P::reportErrors) {
1711 errNestedComment();
1713 adjustDoubleHyphenAndAppendToStrBufAndErr(
1714 c, reportedConsecutiveHyphens);
1715 reportedConsecutiveHyphens = true;
1716 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1717 reconsume, pos);
1718 NS_HTML5_BREAK(stateloop);
1720 case '\n': {
1721 P::silentLineFeed(this);
1722 if (P::reportErrors) {
1723 errNestedComment();
1725 adjustDoubleHyphenAndAppendToStrBufAndErr(
1726 c, reportedConsecutiveHyphens);
1727 reportedConsecutiveHyphens = true;
1728 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1729 reconsume, pos);
1730 NS_HTML5_CONTINUE(stateloop);
1732 case '!': {
1733 if (P::reportErrors) {
1734 errNestedComment();
1736 adjustDoubleHyphenAndAppendToStrBufAndErr(
1737 c, reportedConsecutiveHyphens);
1738 reportedConsecutiveHyphens = true;
1739 state = P::transition(mViewSource.get(),
1740 nsHtml5Tokenizer::COMMENT_END_BANG, reconsume,
1741 pos);
1742 NS_HTML5_CONTINUE(stateloop);
1744 case '\0': {
1745 c = 0xfffd;
1746 [[fallthrough]];
1748 default: {
1749 if (P::reportErrors) {
1750 errNestedComment();
1752 adjustDoubleHyphenAndAppendToStrBufAndErr(
1753 c, reportedConsecutiveHyphens);
1754 reportedConsecutiveHyphens = true;
1755 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1756 reconsume, pos);
1757 NS_HTML5_CONTINUE(stateloop);
1761 case COMMENT_START_DASH: {
1762 if (++pos == endPos) {
1763 NS_HTML5_BREAK(stateloop);
1765 c = P::checkChar(this, buf, pos);
1766 switch (c) {
1767 case '-': {
1768 appendStrBuf(c);
1769 state =
1770 P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
1771 reconsume, pos);
1772 NS_HTML5_CONTINUE(stateloop);
1774 case '>': {
1775 if (P::reportErrors) {
1776 errPrematureEndOfComment();
1778 emitComment(1, pos);
1779 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1780 reconsume, pos);
1781 if (shouldSuspend) {
1782 NS_HTML5_BREAK(stateloop);
1784 NS_HTML5_CONTINUE(stateloop);
1786 case '<': {
1787 appendStrBuf(c);
1788 state = P::transition(mViewSource.get(),
1789 nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
1790 pos);
1791 NS_HTML5_CONTINUE(stateloop);
1793 case '\r': {
1794 appendStrBufCarriageReturn<P>();
1795 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1796 reconsume, pos);
1797 NS_HTML5_BREAK(stateloop);
1799 case '\n': {
1800 appendStrBufLineFeed<P>();
1801 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1802 reconsume, pos);
1803 NS_HTML5_CONTINUE(stateloop);
1805 case '\0': {
1806 c = 0xfffd;
1807 [[fallthrough]];
1809 default: {
1810 appendStrBuf(c);
1811 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
1812 reconsume, pos);
1813 NS_HTML5_CONTINUE(stateloop);
1817 case CDATA_START: {
1818 for (;;) {
1819 if (++pos == endPos) {
1820 NS_HTML5_BREAK(stateloop);
1822 c = P::checkChar(this, buf, pos);
1823 if (index < 6) {
1824 if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
1825 appendStrBuf(c);
1826 } else {
1827 if (P::reportErrors) {
1828 errBogusComment();
1830 reconsume = true;
1831 state = P::transition(mViewSource.get(),
1832 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
1833 pos);
1834 NS_HTML5_CONTINUE(stateloop);
1836 index++;
1837 continue;
1838 } else {
1839 clearStrBufAfterUse();
1840 cstart = pos;
1841 reconsume = true;
1842 state =
1843 P::transition(mViewSource.get(),
1844 nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
1845 break;
1848 [[fallthrough]];
1850 case CDATA_SECTION: {
1851 for (;;) {
1852 if (reconsume) {
1853 reconsume = false;
1854 } else {
1855 if (++pos == endPos) {
1856 NS_HTML5_BREAK(stateloop);
1858 c = P::checkChar(this, buf, pos);
1860 switch (c) {
1861 case ']': {
1862 flushChars(buf, pos);
1863 state =
1864 P::transition(mViewSource.get(), nsHtml5Tokenizer::CDATA_RSQB,
1865 reconsume, pos);
1866 NS_HTML5_BREAK(cdatasectionloop);
1868 case '\0': {
1869 maybeEmitReplacementCharacter(buf, pos);
1870 continue;
1872 case '\r': {
1873 emitCarriageReturn<P>(buf, pos);
1874 NS_HTML5_BREAK(stateloop);
1876 case '\n': {
1877 P::silentLineFeed(this);
1878 [[fallthrough]];
1880 default: {
1881 continue;
1885 cdatasectionloop_end:;
1886 [[fallthrough]];
1888 case CDATA_RSQB: {
1889 if (++pos == endPos) {
1890 NS_HTML5_BREAK(stateloop);
1892 c = P::checkChar(this, buf, pos);
1893 switch (c) {
1894 case ']': {
1895 state = P::transition(mViewSource.get(),
1896 nsHtml5Tokenizer::CDATA_RSQB_RSQB, reconsume,
1897 pos);
1898 break;
1900 default: {
1901 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
1902 cstart = pos;
1903 reconsume = true;
1904 state =
1905 P::transition(mViewSource.get(),
1906 nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
1907 NS_HTML5_CONTINUE(stateloop);
1910 [[fallthrough]];
1912 case CDATA_RSQB_RSQB: {
1913 for (;;) {
1914 if (++pos == endPos) {
1915 NS_HTML5_BREAK(stateloop);
1917 c = P::checkChar(this, buf, pos);
1918 switch (c) {
1919 case ']': {
1920 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
1921 continue;
1923 case '>': {
1924 cstart = pos + 1;
1925 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
1926 reconsume, pos);
1927 suspendIfRequestedAfterCurrentNonTextToken();
1928 if (shouldSuspend) {
1929 NS_HTML5_BREAK(stateloop);
1931 NS_HTML5_CONTINUE(stateloop);
1933 default: {
1934 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
1935 cstart = pos;
1936 reconsume = true;
1937 state = P::transition(mViewSource.get(),
1938 nsHtml5Tokenizer::CDATA_SECTION, reconsume,
1939 pos);
1940 NS_HTML5_CONTINUE(stateloop);
1945 case ATTRIBUTE_VALUE_SINGLE_QUOTED: {
1946 for (;;) {
1947 if (reconsume) {
1948 reconsume = false;
1949 } else {
1950 if (++pos == endPos) {
1951 NS_HTML5_BREAK(stateloop);
1953 c = P::checkChar(this, buf, pos);
1955 switch (c) {
1956 case '\'': {
1957 addAttributeWithValue();
1958 state =
1959 P::transition(mViewSource.get(),
1960 nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
1961 reconsume, pos);
1962 NS_HTML5_CONTINUE(stateloop);
1964 case '&': {
1965 MOZ_ASSERT(!charRefBufLen,
1966 "charRefBufLen not reset after previous use!");
1967 appendCharRefBuf(c);
1968 setAdditionalAndRememberAmpersandLocation('\'');
1969 returnState = state;
1970 state =
1971 P::transition(mViewSource.get(),
1972 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
1973 reconsume, pos);
1974 NS_HTML5_BREAK(attributevaluesinglequotedloop);
1976 case '\r': {
1977 appendStrBufCarriageReturn<P>();
1978 NS_HTML5_BREAK(stateloop);
1980 case '\n': {
1981 appendStrBufLineFeed<P>();
1982 continue;
1984 case '\0': {
1985 c = 0xfffd;
1986 [[fallthrough]];
1988 default: {
1989 appendStrBuf(c);
1990 continue;
1994 attributevaluesinglequotedloop_end:;
1995 [[fallthrough]];
1997 case CONSUME_CHARACTER_REFERENCE: {
1998 if (++pos == endPos) {
1999 NS_HTML5_BREAK(stateloop);
2001 c = P::checkChar(this, buf, pos);
2002 switch (c) {
2003 case ' ':
2004 case '\t':
2005 case '\n':
2006 case '\r':
2007 case '\f':
2008 case '<':
2009 case '&':
2010 case '\0':
2011 case ';': {
2012 emitOrAppendCharRefBuf(returnState);
2013 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2014 cstart = pos;
2016 reconsume = true;
2017 state =
2018 P::transition(mViewSource.get(), returnState, reconsume, pos);
2019 NS_HTML5_CONTINUE(stateloop);
2021 case '#': {
2022 appendCharRefBuf('#');
2023 state =
2024 P::transition(mViewSource.get(), nsHtml5Tokenizer::CONSUME_NCR,
2025 reconsume, pos);
2026 NS_HTML5_CONTINUE(stateloop);
2028 default: {
2029 if (c == additional) {
2030 emitOrAppendCharRefBuf(returnState);
2031 reconsume = true;
2032 state =
2033 P::transition(mViewSource.get(), returnState, reconsume, pos);
2034 NS_HTML5_CONTINUE(stateloop);
2036 if (c >= 'a' && c <= 'z') {
2037 firstCharKey = c - 'a' + 26;
2038 } else if (c >= 'A' && c <= 'Z') {
2039 firstCharKey = c - 'A';
2040 } else {
2041 if (c == ';') {
2042 if (P::reportErrors) {
2043 errNoNamedCharacterMatch();
2046 emitOrAppendCharRefBuf(returnState);
2047 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2048 cstart = pos;
2050 reconsume = true;
2051 state =
2052 P::transition(mViewSource.get(), returnState, reconsume, pos);
2053 NS_HTML5_CONTINUE(stateloop);
2055 appendCharRefBuf(c);
2056 state =
2057 P::transition(mViewSource.get(),
2058 nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP,
2059 reconsume, pos);
2060 break;
2063 [[fallthrough]];
2065 case CHARACTER_REFERENCE_HILO_LOOKUP: {
2067 if (++pos == endPos) {
2068 NS_HTML5_BREAK(stateloop);
2070 c = P::checkChar(this, buf, pos);
2071 int32_t hilo = 0;
2072 if (c <= 'z') {
2073 const int32_t* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c];
2074 if (row) {
2075 hilo = row[firstCharKey];
2078 if (!hilo) {
2079 if (c == ';') {
2080 if (P::reportErrors) {
2081 errNoNamedCharacterMatch();
2084 emitOrAppendCharRefBuf(returnState);
2085 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2086 cstart = pos;
2088 reconsume = true;
2089 state =
2090 P::transition(mViewSource.get(), returnState, reconsume, pos);
2091 NS_HTML5_CONTINUE(stateloop);
2093 appendCharRefBuf(c);
2094 lo = hilo & 0xFFFF;
2095 hi = hilo >> 16;
2096 entCol = -1;
2097 candidate = -1;
2098 charRefBufMark = 0;
2099 state = P::transition(mViewSource.get(),
2100 nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL,
2101 reconsume, pos);
2103 [[fallthrough]];
2105 case CHARACTER_REFERENCE_TAIL: {
2106 for (;;) {
2107 if (++pos == endPos) {
2108 NS_HTML5_BREAK(stateloop);
2110 c = P::checkChar(this, buf, pos);
2111 entCol++;
2112 for (;;) {
2113 if (hi < lo) {
2114 NS_HTML5_BREAK(outer);
2116 if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
2117 candidate = lo;
2118 charRefBufMark = charRefBufLen;
2119 lo++;
2120 } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
2121 NS_HTML5_BREAK(outer);
2122 } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
2123 lo++;
2124 } else {
2125 NS_HTML5_BREAK(loloop);
2128 loloop_end:;
2129 for (;;) {
2130 if (hi < lo) {
2131 NS_HTML5_BREAK(outer);
2133 if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
2134 NS_HTML5_BREAK(hiloop);
2136 if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
2137 NS_HTML5_BREAK(outer);
2138 } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
2139 hi--;
2140 } else {
2141 NS_HTML5_BREAK(hiloop);
2144 hiloop_end:;
2145 if (c == ';') {
2146 if (entCol + 1 == nsHtml5NamedCharacters::NAMES[lo].length()) {
2147 candidate = lo;
2148 charRefBufMark = charRefBufLen;
2150 NS_HTML5_BREAK(outer);
2152 if (hi < lo) {
2153 NS_HTML5_BREAK(outer);
2155 appendCharRefBuf(c);
2156 continue;
2158 outer_end:;
2159 if (candidate == -1) {
2160 if (c == ';') {
2161 if (P::reportErrors) {
2162 errNoNamedCharacterMatch();
2165 emitOrAppendCharRefBuf(returnState);
2166 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2167 cstart = pos;
2169 reconsume = true;
2170 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2171 NS_HTML5_CONTINUE(stateloop);
2172 } else {
2173 const nsHtml5CharacterName& candidateName =
2174 nsHtml5NamedCharacters::NAMES[candidate];
2175 if (!candidateName.length() ||
2176 candidateName.charAt(candidateName.length() - 1) != ';') {
2177 if ((returnState & DATA_AND_RCDATA_MASK)) {
2178 char16_t ch;
2179 if (charRefBufMark == charRefBufLen) {
2180 ch = c;
2181 } else {
2182 ch = charRefBuf[charRefBufMark];
2184 if (ch == '=' || (ch >= '0' && ch <= '9') ||
2185 (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
2186 if (c == ';') {
2187 if (P::reportErrors) {
2188 errNoNamedCharacterMatch();
2191 appendCharRefBufToStrBuf();
2192 reconsume = true;
2193 state = P::transition(mViewSource.get(), returnState, reconsume,
2194 pos);
2195 NS_HTML5_CONTINUE(stateloop);
2198 if ((returnState & DATA_AND_RCDATA_MASK)) {
2199 if (P::reportErrors) {
2200 errUnescapedAmpersandInterpretedAsCharacterReference();
2202 } else {
2203 if (P::reportErrors) {
2204 errNotSemicolonTerminated();
2208 P::completedNamedCharacterReference(mViewSource.get());
2209 const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
2210 if (!val[1]) {
2211 emitOrAppendOne(val, returnState);
2212 } else {
2213 emitOrAppendTwo(val, returnState);
2215 if (charRefBufMark < charRefBufLen) {
2216 if ((returnState & DATA_AND_RCDATA_MASK)) {
2217 appendStrBuf(charRefBuf, charRefBufMark,
2218 charRefBufLen - charRefBufMark);
2219 } else {
2220 tokenHandler->characters(charRefBuf, charRefBufMark,
2221 charRefBufLen - charRefBufMark);
2224 bool earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
2225 charRefBufLen = 0;
2226 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2227 cstart = earlyBreak ? pos + 1 : pos;
2229 reconsume = !earlyBreak;
2230 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2231 NS_HTML5_CONTINUE(stateloop);
2234 case CONSUME_NCR: {
2235 if (++pos == endPos) {
2236 NS_HTML5_BREAK(stateloop);
2238 c = P::checkChar(this, buf, pos);
2239 value = 0;
2240 seenDigits = false;
2241 switch (c) {
2242 case 'x':
2243 case 'X': {
2244 appendCharRefBuf(c);
2245 state =
2246 P::transition(mViewSource.get(), nsHtml5Tokenizer::HEX_NCR_LOOP,
2247 reconsume, pos);
2248 NS_HTML5_CONTINUE(stateloop);
2250 default: {
2251 reconsume = true;
2252 state = P::transition(mViewSource.get(),
2253 nsHtml5Tokenizer::DECIMAL_NRC_LOOP, reconsume,
2254 pos);
2255 break;
2258 [[fallthrough]];
2260 case DECIMAL_NRC_LOOP: {
2261 for (;;) {
2262 if (reconsume) {
2263 reconsume = false;
2264 } else {
2265 if (++pos == endPos) {
2266 NS_HTML5_BREAK(stateloop);
2268 c = P::checkChar(this, buf, pos);
2270 MOZ_ASSERT(value >= 0, "value must not become negative.");
2271 if (c >= '0' && c <= '9') {
2272 seenDigits = true;
2273 if (value <= 0x10FFFF) {
2274 value *= 10;
2275 value += c - '0';
2277 continue;
2278 } else if (c == ';') {
2279 if (seenDigits) {
2280 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2281 cstart = pos + 1;
2283 state = P::transition(mViewSource.get(),
2284 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2285 reconsume, pos);
2286 NS_HTML5_BREAK(decimalloop);
2287 } else {
2288 if (P::reportErrors) {
2289 errNoDigitsInNCR();
2291 appendCharRefBuf(';');
2292 emitOrAppendCharRefBuf(returnState);
2293 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2294 cstart = pos + 1;
2296 state =
2297 P::transition(mViewSource.get(), returnState, reconsume, pos);
2298 NS_HTML5_CONTINUE(stateloop);
2300 } else {
2301 if (!seenDigits) {
2302 if (P::reportErrors) {
2303 errNoDigitsInNCR();
2305 emitOrAppendCharRefBuf(returnState);
2306 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2307 cstart = pos;
2309 reconsume = true;
2310 state =
2311 P::transition(mViewSource.get(), returnState, reconsume, pos);
2312 NS_HTML5_CONTINUE(stateloop);
2313 } else {
2314 if (P::reportErrors) {
2315 errCharRefLacksSemicolon();
2317 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2318 cstart = pos;
2320 reconsume = true;
2321 state = P::transition(mViewSource.get(),
2322 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2323 reconsume, pos);
2324 NS_HTML5_BREAK(decimalloop);
2328 decimalloop_end:;
2329 [[fallthrough]];
2331 case HANDLE_NCR_VALUE: {
2332 charRefBufLen = 0;
2333 handleNcrValue(returnState);
2334 state = P::transition(mViewSource.get(), returnState, reconsume, pos);
2335 NS_HTML5_CONTINUE(stateloop);
2337 case HEX_NCR_LOOP: {
2338 for (;;) {
2339 if (++pos == endPos) {
2340 NS_HTML5_BREAK(stateloop);
2342 c = P::checkChar(this, buf, pos);
2343 MOZ_ASSERT(value >= 0, "value must not become negative.");
2344 if (c >= '0' && c <= '9') {
2345 seenDigits = true;
2346 if (value <= 0x10FFFF) {
2347 value *= 16;
2348 value += c - '0';
2350 continue;
2351 } else if (c >= 'A' && c <= 'F') {
2352 seenDigits = true;
2353 if (value <= 0x10FFFF) {
2354 value *= 16;
2355 value += c - 'A' + 10;
2357 continue;
2358 } else if (c >= 'a' && c <= 'f') {
2359 seenDigits = true;
2360 if (value <= 0x10FFFF) {
2361 value *= 16;
2362 value += c - 'a' + 10;
2364 continue;
2365 } else if (c == ';') {
2366 if (seenDigits) {
2367 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2368 cstart = pos + 1;
2370 state = P::transition(mViewSource.get(),
2371 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2372 reconsume, pos);
2373 NS_HTML5_CONTINUE(stateloop);
2374 } else {
2375 if (P::reportErrors) {
2376 errNoDigitsInNCR();
2378 appendCharRefBuf(';');
2379 emitOrAppendCharRefBuf(returnState);
2380 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2381 cstart = pos + 1;
2383 state =
2384 P::transition(mViewSource.get(), returnState, reconsume, pos);
2385 NS_HTML5_CONTINUE(stateloop);
2387 } else {
2388 if (!seenDigits) {
2389 if (P::reportErrors) {
2390 errNoDigitsInNCR();
2392 emitOrAppendCharRefBuf(returnState);
2393 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2394 cstart = pos;
2396 reconsume = true;
2397 state =
2398 P::transition(mViewSource.get(), returnState, reconsume, pos);
2399 NS_HTML5_CONTINUE(stateloop);
2400 } else {
2401 if (P::reportErrors) {
2402 errCharRefLacksSemicolon();
2404 if (!(returnState & DATA_AND_RCDATA_MASK)) {
2405 cstart = pos;
2407 reconsume = true;
2408 state = P::transition(mViewSource.get(),
2409 nsHtml5Tokenizer::HANDLE_NCR_VALUE,
2410 reconsume, pos);
2411 NS_HTML5_CONTINUE(stateloop);
2416 case PLAINTEXT: {
2417 for (;;) {
2418 if (reconsume) {
2419 reconsume = false;
2420 } else {
2421 if (++pos == endPos) {
2422 NS_HTML5_BREAK(stateloop);
2424 c = P::checkChar(this, buf, pos);
2426 switch (c) {
2427 case '\0': {
2428 emitPlaintextReplacementCharacter(buf, pos);
2429 continue;
2431 case '\r': {
2432 emitCarriageReturn<P>(buf, pos);
2433 NS_HTML5_BREAK(stateloop);
2435 case '\n': {
2436 P::silentLineFeed(this);
2437 [[fallthrough]];
2439 default: {
2440 continue;
2445 case CLOSE_TAG_OPEN: {
2446 if (++pos == endPos) {
2447 NS_HTML5_BREAK(stateloop);
2449 c = P::checkChar(this, buf, pos);
2450 switch (c) {
2451 case '>': {
2452 if (P::reportErrors) {
2453 errLtSlashGt();
2455 cstart = pos + 1;
2456 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2457 reconsume, pos);
2458 NS_HTML5_CONTINUE(stateloop);
2460 case '\r': {
2461 P::silentCarriageReturn(this);
2462 if (P::reportErrors) {
2463 errGarbageAfterLtSlash();
2465 clearStrBufBeforeUse();
2466 appendStrBuf('\n');
2467 state =
2468 P::transition(mViewSource.get(),
2469 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
2470 NS_HTML5_BREAK(stateloop);
2472 case '\n': {
2473 P::silentLineFeed(this);
2474 if (P::reportErrors) {
2475 errGarbageAfterLtSlash();
2477 clearStrBufBeforeUse();
2478 appendStrBuf(c);
2479 state =
2480 P::transition(mViewSource.get(),
2481 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
2482 NS_HTML5_CONTINUE(stateloop);
2484 case '\0': {
2485 c = 0xfffd;
2486 [[fallthrough]];
2488 default: {
2489 if (c >= 'A' && c <= 'Z') {
2490 c += 0x20;
2492 if (c >= 'a' && c <= 'z') {
2493 endTag = true;
2494 clearStrBufBeforeUse();
2495 appendStrBuf(c);
2496 containsHyphen = false;
2497 state = P::transition(mViewSource.get(),
2498 nsHtml5Tokenizer::TAG_NAME, reconsume, pos);
2499 NS_HTML5_CONTINUE(stateloop);
2500 } else {
2501 if (P::reportErrors) {
2502 errGarbageAfterLtSlash();
2504 clearStrBufBeforeUse();
2505 appendStrBuf(c);
2506 state = P::transition(mViewSource.get(),
2507 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2508 pos);
2509 NS_HTML5_CONTINUE(stateloop);
2514 case RCDATA: {
2515 for (;;) {
2516 if (reconsume) {
2517 reconsume = false;
2518 } else {
2519 if (++pos == endPos) {
2520 NS_HTML5_BREAK(stateloop);
2522 c = P::checkChar(this, buf, pos);
2524 switch (c) {
2525 case '&': {
2526 flushChars(buf, pos);
2527 MOZ_ASSERT(!charRefBufLen,
2528 "charRefBufLen not reset after previous use!");
2529 appendCharRefBuf(c);
2530 setAdditionalAndRememberAmpersandLocation('\0');
2531 returnState = state;
2532 state =
2533 P::transition(mViewSource.get(),
2534 nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
2535 reconsume, pos);
2536 NS_HTML5_CONTINUE(stateloop);
2538 case '<': {
2539 flushChars(buf, pos);
2540 returnState = state;
2541 state =
2542 P::transition(mViewSource.get(),
2543 nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
2544 reconsume, pos);
2545 NS_HTML5_CONTINUE(stateloop);
2547 case '\0': {
2548 emitReplacementCharacter(buf, pos);
2549 continue;
2551 case '\r': {
2552 emitCarriageReturn<P>(buf, pos);
2553 NS_HTML5_BREAK(stateloop);
2555 case '\n': {
2556 P::silentLineFeed(this);
2557 [[fallthrough]];
2559 default: {
2560 continue;
2565 case RAWTEXT: {
2566 for (;;) {
2567 if (reconsume) {
2568 reconsume = false;
2569 } else {
2570 if (++pos == endPos) {
2571 NS_HTML5_BREAK(stateloop);
2573 c = P::checkChar(this, buf, pos);
2575 switch (c) {
2576 case '<': {
2577 flushChars(buf, pos);
2578 returnState = state;
2579 state =
2580 P::transition(mViewSource.get(),
2581 nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
2582 reconsume, pos);
2583 NS_HTML5_BREAK(rawtextloop);
2585 case '\0': {
2586 emitReplacementCharacter(buf, pos);
2587 continue;
2589 case '\r': {
2590 emitCarriageReturn<P>(buf, pos);
2591 NS_HTML5_BREAK(stateloop);
2593 case '\n': {
2594 P::silentLineFeed(this);
2595 [[fallthrough]];
2597 default: {
2598 continue;
2602 rawtextloop_end:;
2603 [[fallthrough]];
2605 case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
2606 for (;;) {
2607 if (++pos == endPos) {
2608 NS_HTML5_BREAK(stateloop);
2610 c = P::checkChar(this, buf, pos);
2611 switch (c) {
2612 case '/': {
2613 index = 0;
2614 clearStrBufBeforeUse();
2615 state = P::transition(mViewSource.get(),
2616 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
2617 reconsume, pos);
2618 NS_HTML5_BREAK(rawtextrcdatalessthansignloop);
2620 default: {
2621 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2622 cstart = pos;
2623 reconsume = true;
2624 state =
2625 P::transition(mViewSource.get(), returnState, reconsume, pos);
2626 NS_HTML5_CONTINUE(stateloop);
2630 rawtextrcdatalessthansignloop_end:;
2631 [[fallthrough]];
2633 case NON_DATA_END_TAG_NAME: {
2634 for (;;) {
2635 if (++pos == endPos) {
2636 NS_HTML5_BREAK(stateloop);
2638 c = P::checkChar(this, buf, pos);
2639 if (!endTagExpectationAsArray) {
2640 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2641 cstart = pos;
2642 reconsume = true;
2643 state =
2644 P::transition(mViewSource.get(), returnState, reconsume, pos);
2645 NS_HTML5_CONTINUE(stateloop);
2646 } else if (index < endTagExpectationAsArray.length) {
2647 char16_t e = endTagExpectationAsArray[index];
2648 char16_t folded = c;
2649 if (c >= 'A' && c <= 'Z') {
2650 folded += 0x20;
2652 if (folded != e) {
2653 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2654 emitStrBuf();
2655 cstart = pos;
2656 reconsume = true;
2657 state =
2658 P::transition(mViewSource.get(), returnState, reconsume, pos);
2659 NS_HTML5_CONTINUE(stateloop);
2661 appendStrBuf(c);
2662 index++;
2663 continue;
2664 } else {
2665 endTag = true;
2666 tagName = endTagExpectation;
2667 switch (c) {
2668 case '\r': {
2669 P::silentCarriageReturn(this);
2670 clearStrBufAfterUse();
2671 state = P::transition(mViewSource.get(),
2672 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
2673 reconsume, pos);
2674 NS_HTML5_BREAK(stateloop);
2676 case '\n': {
2677 P::silentLineFeed(this);
2678 [[fallthrough]];
2680 case ' ':
2681 case '\t':
2682 case '\f': {
2683 clearStrBufAfterUse();
2684 state = P::transition(mViewSource.get(),
2685 nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
2686 reconsume, pos);
2687 NS_HTML5_CONTINUE(stateloop);
2689 case '/': {
2690 clearStrBufAfterUse();
2691 state = P::transition(mViewSource.get(),
2692 nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
2693 reconsume, pos);
2694 NS_HTML5_CONTINUE(stateloop);
2696 case '>': {
2697 clearStrBufAfterUse();
2698 state = P::transition(mViewSource.get(),
2699 emitCurrentTagToken(false, pos),
2700 reconsume, pos);
2701 if (shouldSuspend) {
2702 NS_HTML5_BREAK(stateloop);
2704 NS_HTML5_CONTINUE(stateloop);
2706 default: {
2707 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
2708 emitStrBuf();
2709 cstart = pos;
2710 reconsume = true;
2711 state = P::transition(mViewSource.get(), returnState, reconsume,
2712 pos);
2713 NS_HTML5_CONTINUE(stateloop);
2719 case BOGUS_COMMENT: {
2720 for (;;) {
2721 if (reconsume) {
2722 reconsume = false;
2723 } else {
2724 if (++pos == endPos) {
2725 NS_HTML5_BREAK(stateloop);
2727 c = P::checkChar(this, buf, pos);
2729 switch (c) {
2730 case '>': {
2731 emitComment(0, pos);
2732 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2733 reconsume, pos);
2734 if (shouldSuspend) {
2735 NS_HTML5_BREAK(stateloop);
2737 NS_HTML5_CONTINUE(stateloop);
2739 case '-': {
2740 appendStrBuf(c);
2741 state = P::transition(mViewSource.get(),
2742 nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN,
2743 reconsume, pos);
2744 NS_HTML5_BREAK(boguscommentloop);
2746 case '\r': {
2747 appendStrBufCarriageReturn<P>();
2748 NS_HTML5_BREAK(stateloop);
2750 case '\n': {
2751 appendStrBufLineFeed<P>();
2752 continue;
2754 case '\0': {
2755 c = 0xfffd;
2756 [[fallthrough]];
2758 default: {
2759 appendStrBuf(c);
2760 continue;
2764 boguscommentloop_end:;
2765 [[fallthrough]];
2767 case BOGUS_COMMENT_HYPHEN: {
2768 boguscommenthyphenloop:
2769 for (;;) {
2770 if (++pos == endPos) {
2771 NS_HTML5_BREAK(stateloop);
2773 c = P::checkChar(this, buf, pos);
2774 switch (c) {
2775 case '>': {
2776 emitComment(0, pos);
2777 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
2778 reconsume, pos);
2779 if (shouldSuspend) {
2780 NS_HTML5_BREAK(stateloop);
2782 NS_HTML5_CONTINUE(stateloop);
2784 case '-': {
2785 appendSecondHyphenToBogusComment();
2786 NS_HTML5_CONTINUE(boguscommenthyphenloop);
2788 case '\r': {
2789 appendStrBufCarriageReturn<P>();
2790 state = P::transition(mViewSource.get(),
2791 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2792 pos);
2793 NS_HTML5_BREAK(stateloop);
2795 case '\n': {
2796 appendStrBufLineFeed<P>();
2797 state = P::transition(mViewSource.get(),
2798 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2799 pos);
2800 NS_HTML5_CONTINUE(stateloop);
2802 case '\0': {
2803 c = 0xfffd;
2804 [[fallthrough]];
2806 default: {
2807 appendStrBuf(c);
2808 state = P::transition(mViewSource.get(),
2809 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
2810 pos);
2811 NS_HTML5_CONTINUE(stateloop);
2816 case SCRIPT_DATA: {
2817 for (;;) {
2818 if (reconsume) {
2819 reconsume = false;
2820 } else {
2821 if (++pos == endPos) {
2822 NS_HTML5_BREAK(stateloop);
2824 c = P::checkChar(this, buf, pos);
2826 switch (c) {
2827 case '<': {
2828 flushChars(buf, pos);
2829 returnState = state;
2830 state = P::transition(
2831 mViewSource.get(),
2832 nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos);
2833 NS_HTML5_BREAK(scriptdataloop);
2835 case '\0': {
2836 emitReplacementCharacter(buf, pos);
2837 continue;
2839 case '\r': {
2840 emitCarriageReturn<P>(buf, pos);
2841 NS_HTML5_BREAK(stateloop);
2843 case '\n': {
2844 P::silentLineFeed(this);
2845 [[fallthrough]];
2847 default: {
2848 continue;
2852 scriptdataloop_end:;
2853 [[fallthrough]];
2855 case SCRIPT_DATA_LESS_THAN_SIGN: {
2856 for (;;) {
2857 if (++pos == endPos) {
2858 NS_HTML5_BREAK(stateloop);
2860 c = P::checkChar(this, buf, pos);
2861 switch (c) {
2862 case '/': {
2863 index = 0;
2864 clearStrBufBeforeUse();
2865 state = P::transition(mViewSource.get(),
2866 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
2867 reconsume, pos);
2868 NS_HTML5_CONTINUE(stateloop);
2870 case '!': {
2871 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2872 cstart = pos;
2873 state = P::transition(mViewSource.get(),
2874 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START,
2875 reconsume, pos);
2876 NS_HTML5_BREAK(scriptdatalessthansignloop);
2878 default: {
2879 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
2880 cstart = pos;
2881 reconsume = true;
2882 state =
2883 P::transition(mViewSource.get(),
2884 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2885 NS_HTML5_CONTINUE(stateloop);
2889 scriptdatalessthansignloop_end:;
2890 [[fallthrough]];
2892 case SCRIPT_DATA_ESCAPE_START: {
2893 for (;;) {
2894 if (++pos == endPos) {
2895 NS_HTML5_BREAK(stateloop);
2897 c = P::checkChar(this, buf, pos);
2898 switch (c) {
2899 case '-': {
2900 state =
2901 P::transition(mViewSource.get(),
2902 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START_DASH,
2903 reconsume, pos);
2904 NS_HTML5_BREAK(scriptdataescapestartloop);
2906 default: {
2907 reconsume = true;
2908 state =
2909 P::transition(mViewSource.get(),
2910 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2911 NS_HTML5_CONTINUE(stateloop);
2915 scriptdataescapestartloop_end:;
2916 [[fallthrough]];
2918 case SCRIPT_DATA_ESCAPE_START_DASH: {
2919 for (;;) {
2920 if (++pos == endPos) {
2921 NS_HTML5_BREAK(stateloop);
2923 c = P::checkChar(this, buf, pos);
2924 switch (c) {
2925 case '-': {
2926 state =
2927 P::transition(mViewSource.get(),
2928 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
2929 reconsume, pos);
2930 NS_HTML5_BREAK(scriptdataescapestartdashloop);
2932 default: {
2933 reconsume = true;
2934 state =
2935 P::transition(mViewSource.get(),
2936 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2937 NS_HTML5_CONTINUE(stateloop);
2941 scriptdataescapestartdashloop_end:;
2942 [[fallthrough]];
2944 case SCRIPT_DATA_ESCAPED_DASH_DASH: {
2945 for (;;) {
2946 if (++pos == endPos) {
2947 NS_HTML5_BREAK(stateloop);
2949 c = P::checkChar(this, buf, pos);
2950 switch (c) {
2951 case '-': {
2952 continue;
2954 case '<': {
2955 flushChars(buf, pos);
2956 state = P::transition(
2957 mViewSource.get(),
2958 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
2959 reconsume, pos);
2960 NS_HTML5_CONTINUE(stateloop);
2962 case '>': {
2963 state =
2964 P::transition(mViewSource.get(),
2965 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
2966 NS_HTML5_CONTINUE(stateloop);
2968 case '\0': {
2969 emitReplacementCharacter(buf, pos);
2970 state = P::transition(mViewSource.get(),
2971 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2972 reconsume, pos);
2973 NS_HTML5_BREAK(scriptdataescapeddashdashloop);
2975 case '\r': {
2976 emitCarriageReturn<P>(buf, pos);
2977 state = P::transition(mViewSource.get(),
2978 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2979 reconsume, pos);
2980 NS_HTML5_BREAK(stateloop);
2982 case '\n': {
2983 P::silentLineFeed(this);
2984 [[fallthrough]];
2986 default: {
2987 state = P::transition(mViewSource.get(),
2988 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
2989 reconsume, pos);
2990 NS_HTML5_BREAK(scriptdataescapeddashdashloop);
2994 scriptdataescapeddashdashloop_end:;
2995 [[fallthrough]];
2997 case SCRIPT_DATA_ESCAPED: {
2998 for (;;) {
2999 if (reconsume) {
3000 reconsume = false;
3001 } else {
3002 if (++pos == endPos) {
3003 NS_HTML5_BREAK(stateloop);
3005 c = P::checkChar(this, buf, pos);
3007 switch (c) {
3008 case '-': {
3009 state = P::transition(mViewSource.get(),
3010 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH,
3011 reconsume, pos);
3012 NS_HTML5_BREAK(scriptdataescapedloop);
3014 case '<': {
3015 flushChars(buf, pos);
3016 state = P::transition(
3017 mViewSource.get(),
3018 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
3019 reconsume, pos);
3020 NS_HTML5_CONTINUE(stateloop);
3022 case '\0': {
3023 emitReplacementCharacter(buf, pos);
3024 continue;
3026 case '\r': {
3027 emitCarriageReturn<P>(buf, pos);
3028 NS_HTML5_BREAK(stateloop);
3030 case '\n': {
3031 P::silentLineFeed(this);
3032 [[fallthrough]];
3034 default: {
3035 continue;
3039 scriptdataescapedloop_end:;
3040 [[fallthrough]];
3042 case SCRIPT_DATA_ESCAPED_DASH: {
3043 for (;;) {
3044 if (++pos == endPos) {
3045 NS_HTML5_BREAK(stateloop);
3047 c = P::checkChar(this, buf, pos);
3048 switch (c) {
3049 case '-': {
3050 state =
3051 P::transition(mViewSource.get(),
3052 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
3053 reconsume, pos);
3054 NS_HTML5_CONTINUE(stateloop);
3056 case '<': {
3057 flushChars(buf, pos);
3058 state = P::transition(
3059 mViewSource.get(),
3060 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
3061 reconsume, pos);
3062 NS_HTML5_BREAK(scriptdataescapeddashloop);
3064 case '\0': {
3065 emitReplacementCharacter(buf, pos);
3066 state = P::transition(mViewSource.get(),
3067 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3068 reconsume, pos);
3069 NS_HTML5_CONTINUE(stateloop);
3071 case '\r': {
3072 emitCarriageReturn<P>(buf, pos);
3073 state = P::transition(mViewSource.get(),
3074 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3075 reconsume, pos);
3076 NS_HTML5_BREAK(stateloop);
3078 case '\n': {
3079 P::silentLineFeed(this);
3080 [[fallthrough]];
3082 default: {
3083 state = P::transition(mViewSource.get(),
3084 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3085 reconsume, pos);
3086 NS_HTML5_CONTINUE(stateloop);
3090 scriptdataescapeddashloop_end:;
3091 [[fallthrough]];
3093 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
3094 for (;;) {
3095 if (++pos == endPos) {
3096 NS_HTML5_BREAK(stateloop);
3098 c = P::checkChar(this, buf, pos);
3099 switch (c) {
3100 case '/': {
3101 index = 0;
3102 clearStrBufBeforeUse();
3103 returnState = nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED;
3104 state = P::transition(mViewSource.get(),
3105 nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
3106 reconsume, pos);
3107 NS_HTML5_CONTINUE(stateloop);
3109 case 'S':
3110 case 's': {
3111 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
3112 cstart = pos;
3113 index = 1;
3114 state = P::transition(
3115 mViewSource.get(),
3116 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume,
3117 pos);
3118 NS_HTML5_BREAK(scriptdataescapedlessthanloop);
3120 default: {
3121 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
3122 cstart = pos;
3123 reconsume = true;
3124 state = P::transition(mViewSource.get(),
3125 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3126 reconsume, pos);
3127 NS_HTML5_CONTINUE(stateloop);
3131 scriptdataescapedlessthanloop_end:;
3132 [[fallthrough]];
3134 case SCRIPT_DATA_DOUBLE_ESCAPE_START: {
3135 for (;;) {
3136 if (++pos == endPos) {
3137 NS_HTML5_BREAK(stateloop);
3139 c = P::checkChar(this, buf, pos);
3140 MOZ_ASSERT(index > 0);
3141 if (index < 6) {
3142 char16_t folded = c;
3143 if (c >= 'A' && c <= 'Z') {
3144 folded += 0x20;
3146 if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
3147 reconsume = true;
3148 state = P::transition(mViewSource.get(),
3149 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3150 reconsume, pos);
3151 NS_HTML5_CONTINUE(stateloop);
3153 index++;
3154 continue;
3156 switch (c) {
3157 case '\r': {
3158 emitCarriageReturn<P>(buf, pos);
3159 state = P::transition(
3160 mViewSource.get(),
3161 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3162 NS_HTML5_BREAK(stateloop);
3164 case '\n': {
3165 P::silentLineFeed(this);
3166 [[fallthrough]];
3168 case ' ':
3169 case '\t':
3170 case '\f':
3171 case '/':
3172 case '>': {
3173 state = P::transition(
3174 mViewSource.get(),
3175 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3176 NS_HTML5_BREAK(scriptdatadoubleescapestartloop);
3178 default: {
3179 reconsume = true;
3180 state = P::transition(mViewSource.get(),
3181 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3182 reconsume, pos);
3183 NS_HTML5_CONTINUE(stateloop);
3187 scriptdatadoubleescapestartloop_end:;
3188 [[fallthrough]];
3190 case SCRIPT_DATA_DOUBLE_ESCAPED: {
3191 for (;;) {
3192 if (reconsume) {
3193 reconsume = false;
3194 } else {
3195 if (++pos == endPos) {
3196 NS_HTML5_BREAK(stateloop);
3198 c = P::checkChar(this, buf, pos);
3200 switch (c) {
3201 case '-': {
3202 state = P::transition(
3203 mViewSource.get(),
3204 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume,
3205 pos);
3206 NS_HTML5_BREAK(scriptdatadoubleescapedloop);
3208 case '<': {
3209 state = P::transition(
3210 mViewSource.get(),
3211 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3212 reconsume, pos);
3213 NS_HTML5_CONTINUE(stateloop);
3215 case '\0': {
3216 emitReplacementCharacter(buf, pos);
3217 continue;
3219 case '\r': {
3220 emitCarriageReturn<P>(buf, pos);
3221 NS_HTML5_BREAK(stateloop);
3223 case '\n': {
3224 P::silentLineFeed(this);
3225 [[fallthrough]];
3227 default: {
3228 continue;
3232 scriptdatadoubleescapedloop_end:;
3233 [[fallthrough]];
3235 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
3236 for (;;) {
3237 if (++pos == endPos) {
3238 NS_HTML5_BREAK(stateloop);
3240 c = P::checkChar(this, buf, pos);
3241 switch (c) {
3242 case '-': {
3243 state = P::transition(
3244 mViewSource.get(),
3245 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH,
3246 reconsume, pos);
3247 NS_HTML5_BREAK(scriptdatadoubleescapeddashloop);
3249 case '<': {
3250 state = P::transition(
3251 mViewSource.get(),
3252 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3253 reconsume, pos);
3254 NS_HTML5_CONTINUE(stateloop);
3256 case '\0': {
3257 emitReplacementCharacter(buf, pos);
3258 state = P::transition(
3259 mViewSource.get(),
3260 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3261 NS_HTML5_CONTINUE(stateloop);
3263 case '\r': {
3264 emitCarriageReturn<P>(buf, pos);
3265 state = P::transition(
3266 mViewSource.get(),
3267 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3268 NS_HTML5_BREAK(stateloop);
3270 case '\n': {
3271 P::silentLineFeed(this);
3272 [[fallthrough]];
3274 default: {
3275 state = P::transition(
3276 mViewSource.get(),
3277 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3278 NS_HTML5_CONTINUE(stateloop);
3282 scriptdatadoubleescapeddashloop_end:;
3283 [[fallthrough]];
3285 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
3286 for (;;) {
3287 if (++pos == endPos) {
3288 NS_HTML5_BREAK(stateloop);
3290 c = P::checkChar(this, buf, pos);
3291 switch (c) {
3292 case '-': {
3293 continue;
3295 case '<': {
3296 state = P::transition(
3297 mViewSource.get(),
3298 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
3299 reconsume, pos);
3300 NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop);
3302 case '>': {
3303 state =
3304 P::transition(mViewSource.get(),
3305 nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
3306 NS_HTML5_CONTINUE(stateloop);
3308 case '\0': {
3309 emitReplacementCharacter(buf, pos);
3310 state = P::transition(
3311 mViewSource.get(),
3312 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3313 NS_HTML5_CONTINUE(stateloop);
3315 case '\r': {
3316 emitCarriageReturn<P>(buf, pos);
3317 state = P::transition(
3318 mViewSource.get(),
3319 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3320 NS_HTML5_BREAK(stateloop);
3322 case '\n': {
3323 P::silentLineFeed(this);
3324 [[fallthrough]];
3326 default: {
3327 state = P::transition(
3328 mViewSource.get(),
3329 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3330 NS_HTML5_CONTINUE(stateloop);
3334 scriptdatadoubleescapeddashdashloop_end:;
3335 [[fallthrough]];
3337 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
3338 for (;;) {
3339 if (++pos == endPos) {
3340 NS_HTML5_BREAK(stateloop);
3342 c = P::checkChar(this, buf, pos);
3343 switch (c) {
3344 case '/': {
3345 index = 0;
3346 state =
3347 P::transition(mViewSource.get(),
3348 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_END,
3349 reconsume, pos);
3350 NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop);
3352 default: {
3353 reconsume = true;
3354 state = P::transition(
3355 mViewSource.get(),
3356 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3357 NS_HTML5_CONTINUE(stateloop);
3361 scriptdatadoubleescapedlessthanloop_end:;
3362 [[fallthrough]];
3364 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
3365 for (;;) {
3366 if (++pos == endPos) {
3367 NS_HTML5_BREAK(stateloop);
3369 c = P::checkChar(this, buf, pos);
3370 if (index < 6) {
3371 char16_t folded = c;
3372 if (c >= 'A' && c <= 'Z') {
3373 folded += 0x20;
3375 if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
3376 reconsume = true;
3377 state = P::transition(
3378 mViewSource.get(),
3379 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3380 NS_HTML5_CONTINUE(stateloop);
3382 index++;
3383 continue;
3385 switch (c) {
3386 case '\r': {
3387 emitCarriageReturn<P>(buf, pos);
3388 state = P::transition(mViewSource.get(),
3389 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3390 reconsume, pos);
3391 NS_HTML5_BREAK(stateloop);
3393 case '\n': {
3394 P::silentLineFeed(this);
3395 [[fallthrough]];
3397 case ' ':
3398 case '\t':
3399 case '\f':
3400 case '/':
3401 case '>': {
3402 state = P::transition(mViewSource.get(),
3403 nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
3404 reconsume, pos);
3405 NS_HTML5_CONTINUE(stateloop);
3407 default: {
3408 reconsume = true;
3409 state = P::transition(
3410 mViewSource.get(),
3411 nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
3412 NS_HTML5_CONTINUE(stateloop);
3417 case MARKUP_DECLARATION_OCTYPE: {
3418 for (;;) {
3419 if (++pos == endPos) {
3420 NS_HTML5_BREAK(stateloop);
3422 c = P::checkChar(this, buf, pos);
3423 if (index < 6) {
3424 char16_t folded = c;
3425 if (c >= 'A' && c <= 'Z') {
3426 folded += 0x20;
3428 if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
3429 appendStrBuf(c);
3430 } else {
3431 if (P::reportErrors) {
3432 errBogusComment();
3434 reconsume = true;
3435 state = P::transition(mViewSource.get(),
3436 nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
3437 pos);
3438 NS_HTML5_CONTINUE(stateloop);
3440 index++;
3441 continue;
3442 } else {
3443 reconsume = true;
3444 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DOCTYPE,
3445 reconsume, pos);
3446 NS_HTML5_BREAK(markupdeclarationdoctypeloop);
3449 markupdeclarationdoctypeloop_end:;
3450 [[fallthrough]];
3452 case DOCTYPE: {
3453 for (;;) {
3454 if (reconsume) {
3455 reconsume = false;
3456 } else {
3457 if (++pos == endPos) {
3458 NS_HTML5_BREAK(stateloop);
3460 c = P::checkChar(this, buf, pos);
3462 initDoctypeFields();
3463 switch (c) {
3464 case '\r': {
3465 P::silentCarriageReturn(this);
3466 state = P::transition(mViewSource.get(),
3467 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3468 reconsume, pos);
3469 NS_HTML5_BREAK(stateloop);
3471 case '\n': {
3472 P::silentLineFeed(this);
3473 [[fallthrough]];
3475 case ' ':
3476 case '\t':
3477 case '\f': {
3478 state = P::transition(mViewSource.get(),
3479 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3480 reconsume, pos);
3481 NS_HTML5_BREAK(doctypeloop);
3483 default: {
3484 if (P::reportErrors) {
3485 errMissingSpaceBeforeDoctypeName();
3487 reconsume = true;
3488 state = P::transition(mViewSource.get(),
3489 nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
3490 reconsume, pos);
3491 NS_HTML5_BREAK(doctypeloop);
3495 doctypeloop_end:;
3496 [[fallthrough]];
3498 case BEFORE_DOCTYPE_NAME: {
3499 for (;;) {
3500 if (reconsume) {
3501 reconsume = false;
3502 } else {
3503 if (++pos == endPos) {
3504 NS_HTML5_BREAK(stateloop);
3506 c = P::checkChar(this, buf, pos);
3508 switch (c) {
3509 case '\r': {
3510 P::silentCarriageReturn(this);
3511 NS_HTML5_BREAK(stateloop);
3513 case '\n': {
3514 P::silentLineFeed(this);
3515 [[fallthrough]];
3517 case ' ':
3518 case '\t':
3519 case '\f': {
3520 continue;
3522 case '>': {
3523 if (P::reportErrors) {
3524 errNamelessDoctype();
3526 forceQuirks = true;
3527 emitDoctypeToken(pos);
3528 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3529 reconsume, pos);
3530 if (shouldSuspend) {
3531 NS_HTML5_BREAK(stateloop);
3533 NS_HTML5_CONTINUE(stateloop);
3535 case '\0': {
3536 c = 0xfffd;
3537 [[fallthrough]];
3539 default: {
3540 if (c >= 'A' && c <= 'Z') {
3541 c += 0x20;
3543 clearStrBufBeforeUse();
3544 appendStrBuf(c);
3545 state =
3546 P::transition(mViewSource.get(),
3547 nsHtml5Tokenizer::DOCTYPE_NAME, reconsume, pos);
3548 NS_HTML5_BREAK(beforedoctypenameloop);
3552 beforedoctypenameloop_end:;
3553 [[fallthrough]];
3555 case DOCTYPE_NAME: {
3556 for (;;) {
3557 if (++pos == endPos) {
3558 NS_HTML5_BREAK(stateloop);
3560 c = P::checkChar(this, buf, pos);
3561 switch (c) {
3562 case '\r': {
3563 P::silentCarriageReturn(this);
3564 strBufToDoctypeName();
3565 state = P::transition(mViewSource.get(),
3566 nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
3567 reconsume, pos);
3568 NS_HTML5_BREAK(stateloop);
3570 case '\n': {
3571 P::silentLineFeed(this);
3572 [[fallthrough]];
3574 case ' ':
3575 case '\t':
3576 case '\f': {
3577 strBufToDoctypeName();
3578 state = P::transition(mViewSource.get(),
3579 nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
3580 reconsume, pos);
3581 NS_HTML5_BREAK(doctypenameloop);
3583 case '>': {
3584 strBufToDoctypeName();
3585 emitDoctypeToken(pos);
3586 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3587 reconsume, pos);
3588 if (shouldSuspend) {
3589 NS_HTML5_BREAK(stateloop);
3591 NS_HTML5_CONTINUE(stateloop);
3593 case '\0': {
3594 c = 0xfffd;
3595 [[fallthrough]];
3597 default: {
3598 if (c >= 'A' && c <= 'Z') {
3599 c += 0x0020;
3601 appendStrBuf(c);
3602 continue;
3606 doctypenameloop_end:;
3607 [[fallthrough]];
3609 case AFTER_DOCTYPE_NAME: {
3610 for (;;) {
3611 if (++pos == endPos) {
3612 NS_HTML5_BREAK(stateloop);
3614 c = P::checkChar(this, buf, pos);
3615 switch (c) {
3616 case '\r': {
3617 P::silentCarriageReturn(this);
3618 NS_HTML5_BREAK(stateloop);
3620 case '\n': {
3621 P::silentLineFeed(this);
3622 [[fallthrough]];
3624 case ' ':
3625 case '\t':
3626 case '\f': {
3627 continue;
3629 case '>': {
3630 emitDoctypeToken(pos);
3631 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3632 reconsume, pos);
3633 if (shouldSuspend) {
3634 NS_HTML5_BREAK(stateloop);
3636 NS_HTML5_CONTINUE(stateloop);
3638 case 'p':
3639 case 'P': {
3640 index = 0;
3641 state = P::transition(mViewSource.get(),
3642 nsHtml5Tokenizer::DOCTYPE_UBLIC, reconsume,
3643 pos);
3644 NS_HTML5_BREAK(afterdoctypenameloop);
3646 case 's':
3647 case 'S': {
3648 index = 0;
3649 state = P::transition(mViewSource.get(),
3650 nsHtml5Tokenizer::DOCTYPE_YSTEM, reconsume,
3651 pos);
3652 NS_HTML5_CONTINUE(stateloop);
3654 default: {
3655 bogusDoctype();
3656 state = P::transition(mViewSource.get(),
3657 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3658 pos);
3659 NS_HTML5_CONTINUE(stateloop);
3663 afterdoctypenameloop_end:;
3664 [[fallthrough]];
3666 case DOCTYPE_UBLIC: {
3667 for (;;) {
3668 if (++pos == endPos) {
3669 NS_HTML5_BREAK(stateloop);
3671 c = P::checkChar(this, buf, pos);
3672 if (index < 5) {
3673 char16_t folded = c;
3674 if (c >= 'A' && c <= 'Z') {
3675 folded += 0x20;
3677 if (folded != nsHtml5Tokenizer::UBLIC[index]) {
3678 bogusDoctype();
3679 reconsume = true;
3680 state = P::transition(mViewSource.get(),
3681 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3682 pos);
3683 NS_HTML5_CONTINUE(stateloop);
3685 index++;
3686 continue;
3687 } else {
3688 reconsume = true;
3689 state = P::transition(
3690 mViewSource.get(),
3691 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
3692 NS_HTML5_BREAK(doctypeublicloop);
3695 doctypeublicloop_end:;
3696 [[fallthrough]];
3698 case AFTER_DOCTYPE_PUBLIC_KEYWORD: {
3699 for (;;) {
3700 if (reconsume) {
3701 reconsume = false;
3702 } else {
3703 if (++pos == endPos) {
3704 NS_HTML5_BREAK(stateloop);
3706 c = P::checkChar(this, buf, pos);
3708 switch (c) {
3709 case '\r': {
3710 P::silentCarriageReturn(this);
3711 state = P::transition(
3712 mViewSource.get(),
3713 nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3714 pos);
3715 NS_HTML5_BREAK(stateloop);
3717 case '\n': {
3718 P::silentLineFeed(this);
3719 [[fallthrough]];
3721 case ' ':
3722 case '\t':
3723 case '\f': {
3724 state = P::transition(
3725 mViewSource.get(),
3726 nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3727 pos);
3728 NS_HTML5_BREAK(afterdoctypepublickeywordloop);
3730 case '\"': {
3731 if (P::reportErrors) {
3732 errNoSpaceBetweenDoctypePublicKeywordAndQuote();
3734 clearStrBufBeforeUse();
3735 state = P::transition(
3736 mViewSource.get(),
3737 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
3738 reconsume, pos);
3739 NS_HTML5_CONTINUE(stateloop);
3741 case '\'': {
3742 if (P::reportErrors) {
3743 errNoSpaceBetweenDoctypePublicKeywordAndQuote();
3745 clearStrBufBeforeUse();
3746 state = P::transition(
3747 mViewSource.get(),
3748 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
3749 reconsume, pos);
3750 NS_HTML5_CONTINUE(stateloop);
3752 case '>': {
3753 if (P::reportErrors) {
3754 errExpectedPublicId();
3756 forceQuirks = true;
3757 emitDoctypeToken(pos);
3758 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3759 reconsume, pos);
3760 if (shouldSuspend) {
3761 NS_HTML5_BREAK(stateloop);
3763 NS_HTML5_CONTINUE(stateloop);
3765 default: {
3766 bogusDoctype();
3767 state = P::transition(mViewSource.get(),
3768 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3769 pos);
3770 NS_HTML5_CONTINUE(stateloop);
3774 afterdoctypepublickeywordloop_end:;
3775 [[fallthrough]];
3777 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
3778 for (;;) {
3779 if (++pos == endPos) {
3780 NS_HTML5_BREAK(stateloop);
3782 c = P::checkChar(this, buf, pos);
3783 switch (c) {
3784 case '\r': {
3785 P::silentCarriageReturn(this);
3786 NS_HTML5_BREAK(stateloop);
3788 case '\n': {
3789 P::silentLineFeed(this);
3790 [[fallthrough]];
3792 case ' ':
3793 case '\t':
3794 case '\f': {
3795 continue;
3797 case '\"': {
3798 clearStrBufBeforeUse();
3799 state = P::transition(
3800 mViewSource.get(),
3801 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
3802 reconsume, pos);
3803 NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
3805 case '\'': {
3806 clearStrBufBeforeUse();
3807 state = P::transition(
3808 mViewSource.get(),
3809 nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
3810 reconsume, pos);
3811 NS_HTML5_CONTINUE(stateloop);
3813 case '>': {
3814 if (P::reportErrors) {
3815 errExpectedPublicId();
3817 forceQuirks = true;
3818 emitDoctypeToken(pos);
3819 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3820 reconsume, pos);
3821 if (shouldSuspend) {
3822 NS_HTML5_BREAK(stateloop);
3824 NS_HTML5_CONTINUE(stateloop);
3826 default: {
3827 bogusDoctype();
3828 state = P::transition(mViewSource.get(),
3829 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3830 pos);
3831 NS_HTML5_CONTINUE(stateloop);
3835 beforedoctypepublicidentifierloop_end:;
3836 [[fallthrough]];
3838 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
3839 for (;;) {
3840 if (++pos == endPos) {
3841 NS_HTML5_BREAK(stateloop);
3843 c = P::checkChar(this, buf, pos);
3844 switch (c) {
3845 case '\"': {
3846 publicIdentifier = strBufToString();
3847 state = P::transition(
3848 mViewSource.get(),
3849 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
3850 pos);
3851 NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
3853 case '>': {
3854 if (P::reportErrors) {
3855 errGtInPublicId();
3857 forceQuirks = true;
3858 publicIdentifier = strBufToString();
3859 emitDoctypeToken(pos);
3860 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3861 reconsume, pos);
3862 if (shouldSuspend) {
3863 NS_HTML5_BREAK(stateloop);
3865 NS_HTML5_CONTINUE(stateloop);
3867 case '\r': {
3868 appendStrBufCarriageReturn<P>();
3869 NS_HTML5_BREAK(stateloop);
3871 case '\n': {
3872 appendStrBufLineFeed<P>();
3873 continue;
3875 case '\0': {
3876 c = 0xfffd;
3877 [[fallthrough]];
3879 default: {
3880 appendStrBuf(c);
3881 continue;
3885 doctypepublicidentifierdoublequotedloop_end:;
3886 [[fallthrough]];
3888 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
3889 for (;;) {
3890 if (++pos == endPos) {
3891 NS_HTML5_BREAK(stateloop);
3893 c = P::checkChar(this, buf, pos);
3894 switch (c) {
3895 case '\r': {
3896 P::silentCarriageReturn(this);
3897 state = P::transition(
3898 mViewSource.get(),
3899 nsHtml5Tokenizer::
3900 BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
3901 reconsume, pos);
3902 NS_HTML5_BREAK(stateloop);
3904 case '\n': {
3905 P::silentLineFeed(this);
3906 [[fallthrough]];
3908 case ' ':
3909 case '\t':
3910 case '\f': {
3911 state = P::transition(
3912 mViewSource.get(),
3913 nsHtml5Tokenizer::
3914 BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
3915 reconsume, pos);
3916 NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
3918 case '>': {
3919 emitDoctypeToken(pos);
3920 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3921 reconsume, pos);
3922 if (shouldSuspend) {
3923 NS_HTML5_BREAK(stateloop);
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_DOUBLE_QUOTED,
3935 reconsume, pos);
3936 NS_HTML5_CONTINUE(stateloop);
3938 case '\'': {
3939 if (P::reportErrors) {
3940 errNoSpaceBetweenPublicAndSystemIds();
3942 clearStrBufBeforeUse();
3943 state = P::transition(
3944 mViewSource.get(),
3945 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
3946 reconsume, pos);
3947 NS_HTML5_CONTINUE(stateloop);
3949 default: {
3950 bogusDoctype();
3951 state = P::transition(mViewSource.get(),
3952 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
3953 pos);
3954 NS_HTML5_CONTINUE(stateloop);
3958 afterdoctypepublicidentifierloop_end:;
3959 [[fallthrough]];
3961 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
3962 for (;;) {
3963 if (++pos == endPos) {
3964 NS_HTML5_BREAK(stateloop);
3966 c = P::checkChar(this, buf, pos);
3967 switch (c) {
3968 case '\r': {
3969 P::silentCarriageReturn(this);
3970 NS_HTML5_BREAK(stateloop);
3972 case '\n': {
3973 P::silentLineFeed(this);
3974 [[fallthrough]];
3976 case ' ':
3977 case '\t':
3978 case '\f': {
3979 continue;
3981 case '>': {
3982 emitDoctypeToken(pos);
3983 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
3984 reconsume, pos);
3985 if (shouldSuspend) {
3986 NS_HTML5_BREAK(stateloop);
3988 NS_HTML5_CONTINUE(stateloop);
3990 case '\"': {
3991 clearStrBufBeforeUse();
3992 state = P::transition(
3993 mViewSource.get(),
3994 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
3995 reconsume, pos);
3996 NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop);
3998 case '\'': {
3999 clearStrBufBeforeUse();
4000 state = P::transition(
4001 mViewSource.get(),
4002 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
4003 reconsume, pos);
4004 NS_HTML5_CONTINUE(stateloop);
4006 default: {
4007 bogusDoctype();
4008 state = P::transition(mViewSource.get(),
4009 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4010 pos);
4011 NS_HTML5_CONTINUE(stateloop);
4015 betweendoctypepublicandsystemidentifiersloop_end:;
4016 [[fallthrough]];
4018 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
4019 for (;;) {
4020 if (++pos == endPos) {
4021 NS_HTML5_BREAK(stateloop);
4023 c = P::checkChar(this, buf, pos);
4024 switch (c) {
4025 case '\"': {
4026 systemIdentifier = strBufToString();
4027 state = P::transition(
4028 mViewSource.get(),
4029 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4030 pos);
4031 NS_HTML5_BREAK(doctypesystemidentifierdoublequotedloop);
4033 case '>': {
4034 if (P::reportErrors) {
4035 errGtInSystemId();
4037 forceQuirks = true;
4038 systemIdentifier = strBufToString();
4039 emitDoctypeToken(pos);
4040 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4041 reconsume, pos);
4042 if (shouldSuspend) {
4043 NS_HTML5_BREAK(stateloop);
4045 NS_HTML5_CONTINUE(stateloop);
4047 case '\r': {
4048 appendStrBufCarriageReturn<P>();
4049 NS_HTML5_BREAK(stateloop);
4051 case '\n': {
4052 appendStrBufLineFeed<P>();
4053 continue;
4055 case '\0': {
4056 c = 0xfffd;
4057 [[fallthrough]];
4059 default: {
4060 appendStrBuf(c);
4061 continue;
4065 doctypesystemidentifierdoublequotedloop_end:;
4066 [[fallthrough]];
4068 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
4069 for (;;) {
4070 if (++pos == endPos) {
4071 NS_HTML5_BREAK(stateloop);
4073 c = P::checkChar(this, buf, pos);
4074 switch (c) {
4075 case '\r': {
4076 P::silentCarriageReturn(this);
4077 NS_HTML5_BREAK(stateloop);
4079 case '\n': {
4080 P::silentLineFeed(this);
4081 [[fallthrough]];
4083 case ' ':
4084 case '\t':
4085 case '\f': {
4086 continue;
4088 case '>': {
4089 emitDoctypeToken(pos);
4090 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4091 reconsume, pos);
4092 if (shouldSuspend) {
4093 NS_HTML5_BREAK(stateloop);
4095 NS_HTML5_CONTINUE(stateloop);
4097 default: {
4098 bogusDoctypeWithoutQuirks();
4099 state = P::transition(mViewSource.get(),
4100 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4101 pos);
4102 NS_HTML5_BREAK(afterdoctypesystemidentifierloop);
4106 afterdoctypesystemidentifierloop_end:;
4107 [[fallthrough]];
4109 case BOGUS_DOCTYPE: {
4110 for (;;) {
4111 if (reconsume) {
4112 reconsume = false;
4113 } else {
4114 if (++pos == endPos) {
4115 NS_HTML5_BREAK(stateloop);
4117 c = P::checkChar(this, buf, pos);
4119 switch (c) {
4120 case '>': {
4121 emitDoctypeToken(pos);
4122 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4123 reconsume, pos);
4124 if (shouldSuspend) {
4125 NS_HTML5_BREAK(stateloop);
4127 NS_HTML5_CONTINUE(stateloop);
4129 case '\r': {
4130 P::silentCarriageReturn(this);
4131 NS_HTML5_BREAK(stateloop);
4133 case '\n': {
4134 P::silentLineFeed(this);
4135 [[fallthrough]];
4137 default: {
4138 continue;
4143 case DOCTYPE_YSTEM: {
4144 for (;;) {
4145 if (++pos == endPos) {
4146 NS_HTML5_BREAK(stateloop);
4148 c = P::checkChar(this, buf, pos);
4149 if (index < 5) {
4150 char16_t folded = c;
4151 if (c >= 'A' && c <= 'Z') {
4152 folded += 0x20;
4154 if (folded != nsHtml5Tokenizer::YSTEM[index]) {
4155 bogusDoctype();
4156 reconsume = true;
4157 state = P::transition(mViewSource.get(),
4158 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4159 pos);
4160 NS_HTML5_CONTINUE(stateloop);
4162 index++;
4163 NS_HTML5_CONTINUE(stateloop);
4164 } else {
4165 reconsume = true;
4166 state = P::transition(
4167 mViewSource.get(),
4168 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
4169 NS_HTML5_BREAK(doctypeystemloop);
4172 doctypeystemloop_end:;
4173 [[fallthrough]];
4175 case AFTER_DOCTYPE_SYSTEM_KEYWORD: {
4176 for (;;) {
4177 if (reconsume) {
4178 reconsume = false;
4179 } else {
4180 if (++pos == endPos) {
4181 NS_HTML5_BREAK(stateloop);
4183 c = P::checkChar(this, buf, pos);
4185 switch (c) {
4186 case '\r': {
4187 P::silentCarriageReturn(this);
4188 state = P::transition(
4189 mViewSource.get(),
4190 nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4191 pos);
4192 NS_HTML5_BREAK(stateloop);
4194 case '\n': {
4195 P::silentLineFeed(this);
4196 [[fallthrough]];
4198 case ' ':
4199 case '\t':
4200 case '\f': {
4201 state = P::transition(
4202 mViewSource.get(),
4203 nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4204 pos);
4205 NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
4207 case '\"': {
4208 if (P::reportErrors) {
4209 errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
4211 clearStrBufBeforeUse();
4212 state = P::transition(
4213 mViewSource.get(),
4214 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
4215 reconsume, pos);
4216 NS_HTML5_CONTINUE(stateloop);
4218 case '\'': {
4219 if (P::reportErrors) {
4220 errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
4222 clearStrBufBeforeUse();
4223 state = P::transition(
4224 mViewSource.get(),
4225 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
4226 reconsume, pos);
4227 NS_HTML5_CONTINUE(stateloop);
4229 case '>': {
4230 if (P::reportErrors) {
4231 errExpectedPublicId();
4233 forceQuirks = true;
4234 emitDoctypeToken(pos);
4235 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4236 reconsume, pos);
4237 if (shouldSuspend) {
4238 NS_HTML5_BREAK(stateloop);
4240 NS_HTML5_CONTINUE(stateloop);
4242 default: {
4243 bogusDoctype();
4244 state = P::transition(mViewSource.get(),
4245 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4246 pos);
4247 NS_HTML5_CONTINUE(stateloop);
4251 afterdoctypesystemkeywordloop_end:;
4252 [[fallthrough]];
4254 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
4255 for (;;) {
4256 if (++pos == endPos) {
4257 NS_HTML5_BREAK(stateloop);
4259 c = P::checkChar(this, buf, pos);
4260 switch (c) {
4261 case '\r': {
4262 P::silentCarriageReturn(this);
4263 NS_HTML5_BREAK(stateloop);
4265 case '\n': {
4266 P::silentLineFeed(this);
4267 [[fallthrough]];
4269 case ' ':
4270 case '\t':
4271 case '\f': {
4272 continue;
4274 case '\"': {
4275 clearStrBufBeforeUse();
4276 state = P::transition(
4277 mViewSource.get(),
4278 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
4279 reconsume, pos);
4280 NS_HTML5_CONTINUE(stateloop);
4282 case '\'': {
4283 clearStrBufBeforeUse();
4284 state = P::transition(
4285 mViewSource.get(),
4286 nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
4287 reconsume, pos);
4288 NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
4290 case '>': {
4291 if (P::reportErrors) {
4292 errExpectedSystemId();
4294 forceQuirks = true;
4295 emitDoctypeToken(pos);
4296 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4297 reconsume, pos);
4298 if (shouldSuspend) {
4299 NS_HTML5_BREAK(stateloop);
4301 NS_HTML5_CONTINUE(stateloop);
4303 default: {
4304 bogusDoctype();
4305 state = P::transition(mViewSource.get(),
4306 nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
4307 pos);
4308 NS_HTML5_CONTINUE(stateloop);
4312 beforedoctypesystemidentifierloop_end:;
4313 [[fallthrough]];
4315 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
4316 for (;;) {
4317 if (++pos == endPos) {
4318 NS_HTML5_BREAK(stateloop);
4320 c = P::checkChar(this, buf, pos);
4321 switch (c) {
4322 case '\'': {
4323 systemIdentifier = strBufToString();
4324 state = P::transition(
4325 mViewSource.get(),
4326 nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
4327 pos);
4328 NS_HTML5_CONTINUE(stateloop);
4330 case '>': {
4331 if (P::reportErrors) {
4332 errGtInSystemId();
4334 forceQuirks = true;
4335 systemIdentifier = strBufToString();
4336 emitDoctypeToken(pos);
4337 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4338 reconsume, pos);
4339 if (shouldSuspend) {
4340 NS_HTML5_BREAK(stateloop);
4342 NS_HTML5_CONTINUE(stateloop);
4344 case '\r': {
4345 appendStrBufCarriageReturn<P>();
4346 NS_HTML5_BREAK(stateloop);
4348 case '\n': {
4349 appendStrBufLineFeed<P>();
4350 continue;
4352 case '\0': {
4353 c = 0xfffd;
4354 [[fallthrough]];
4356 default: {
4357 appendStrBuf(c);
4358 continue;
4363 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
4364 for (;;) {
4365 if (++pos == endPos) {
4366 NS_HTML5_BREAK(stateloop);
4368 c = P::checkChar(this, buf, pos);
4369 switch (c) {
4370 case '\'': {
4371 publicIdentifier = strBufToString();
4372 state = P::transition(
4373 mViewSource.get(),
4374 nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
4375 pos);
4376 NS_HTML5_CONTINUE(stateloop);
4378 case '>': {
4379 if (P::reportErrors) {
4380 errGtInPublicId();
4382 forceQuirks = true;
4383 publicIdentifier = strBufToString();
4384 emitDoctypeToken(pos);
4385 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4386 reconsume, pos);
4387 if (shouldSuspend) {
4388 NS_HTML5_BREAK(stateloop);
4390 NS_HTML5_CONTINUE(stateloop);
4392 case '\r': {
4393 appendStrBufCarriageReturn<P>();
4394 NS_HTML5_BREAK(stateloop);
4396 case '\n': {
4397 appendStrBufLineFeed<P>();
4398 continue;
4400 case '\0': {
4401 c = 0xfffd;
4402 [[fallthrough]];
4404 default: {
4405 appendStrBuf(c);
4406 continue;
4411 case PROCESSING_INSTRUCTION: {
4412 for (;;) {
4413 if (++pos == endPos) {
4414 NS_HTML5_BREAK(stateloop);
4416 c = P::checkChar(this, buf, pos);
4417 switch (c) {
4418 case '\?': {
4419 state = P::transition(
4420 mViewSource.get(),
4421 nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK,
4422 reconsume, pos);
4423 NS_HTML5_BREAK(processinginstructionloop);
4425 default: {
4426 continue;
4430 processinginstructionloop_end:;
4431 [[fallthrough]];
4433 case PROCESSING_INSTRUCTION_QUESTION_MARK: {
4434 if (++pos == endPos) {
4435 NS_HTML5_BREAK(stateloop);
4437 c = P::checkChar(this, buf, pos);
4438 switch (c) {
4439 case '>': {
4440 state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
4441 reconsume, pos);
4442 suspendIfRequestedAfterCurrentNonTextToken();
4443 if (shouldSuspend) {
4444 NS_HTML5_BREAK(stateloop);
4446 NS_HTML5_CONTINUE(stateloop);
4448 default: {
4449 state = P::transition(mViewSource.get(),
4450 nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
4451 reconsume, pos);
4452 NS_HTML5_CONTINUE(stateloop);
4458 stateloop_end:;
4459 flushChars(buf, pos);
4460 stateSave = state;
4461 returnStateSave = returnState;
4462 return pos;
4465 void nsHtml5Tokenizer::initDoctypeFields() {
4466 clearStrBufAfterUse();
4467 doctypeName = nullptr;
4468 if (systemIdentifier) {
4469 systemIdentifier.Release();
4470 systemIdentifier = nullptr;
4472 if (publicIdentifier) {
4473 publicIdentifier.Release();
4474 publicIdentifier = nullptr;
4476 forceQuirks = false;
4479 template <class P>
4480 void nsHtml5Tokenizer::adjustDoubleHyphenAndAppendToStrBufCarriageReturn() {
4481 P::silentCarriageReturn(this);
4482 adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
4485 template <class P>
4486 void nsHtml5Tokenizer::adjustDoubleHyphenAndAppendToStrBufLineFeed() {
4487 P::silentLineFeed(this);
4488 adjustDoubleHyphenAndAppendToStrBufAndErr('\n', false);
4491 template <class P>
4492 void nsHtml5Tokenizer::appendStrBufLineFeed() {
4493 P::silentLineFeed(this);
4494 appendStrBuf('\n');
4497 template <class P>
4498 void nsHtml5Tokenizer::appendStrBufCarriageReturn() {
4499 P::silentCarriageReturn(this);
4500 appendStrBuf('\n');
4503 template <class P>
4504 void nsHtml5Tokenizer::emitCarriageReturn(char16_t* buf, int32_t pos) {
4505 P::silentCarriageReturn(this);
4506 flushChars(buf, pos);
4507 tokenHandler->characters(nsHtml5Tokenizer::LF, 0, 1);
4508 cstart = INT32_MAX;
4511 void nsHtml5Tokenizer::emitReplacementCharacter(char16_t* buf, int32_t pos) {
4512 flushChars(buf, pos);
4513 tokenHandler->zeroOriginatingReplacementCharacter();
4514 cstart = pos + 1;
4517 void nsHtml5Tokenizer::maybeEmitReplacementCharacter(char16_t* buf,
4518 int32_t pos) {
4519 flushChars(buf, pos);
4520 tokenHandler->zeroOrReplacementCharacter();
4521 cstart = pos + 1;
4524 void nsHtml5Tokenizer::emitPlaintextReplacementCharacter(char16_t* buf,
4525 int32_t pos) {
4526 flushChars(buf, pos);
4527 tokenHandler->characters(REPLACEMENT_CHARACTER, 0, 1);
4528 cstart = pos + 1;
4531 void nsHtml5Tokenizer::setAdditionalAndRememberAmpersandLocation(char16_t add) {
4532 additional = add;
4535 void nsHtml5Tokenizer::bogusDoctype() {
4536 errBogusDoctype();
4537 forceQuirks = true;
4540 void nsHtml5Tokenizer::bogusDoctypeWithoutQuirks() {
4541 errBogusDoctype();
4542 forceQuirks = false;
4545 void nsHtml5Tokenizer::handleNcrValue(int32_t returnState) {
4546 if (value <= 0xFFFF) {
4547 if (value >= 0x80 && value <= 0x9f) {
4548 errNcrInC1Range();
4549 char16_t* val = nsHtml5NamedCharacters::WINDOWS_1252[value - 0x80];
4550 emitOrAppendOne(val, returnState);
4551 } else if (value == 0x0) {
4552 errNcrZero();
4553 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4554 } else if ((value & 0xF800) == 0xD800) {
4555 errNcrSurrogate();
4556 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4557 } else {
4558 char16_t ch = (char16_t)value;
4559 bmpChar[0] = ch;
4560 emitOrAppendOne(bmpChar, returnState);
4562 } else if (value <= 0x10FFFF) {
4563 astralChar[0] = (char16_t)(nsHtml5Tokenizer::LEAD_OFFSET + (value >> 10));
4564 astralChar[1] = (char16_t)(0xDC00 + (value & 0x3FF));
4565 emitOrAppendTwo(astralChar, returnState);
4566 } else {
4567 errNcrOutOfRange();
4568 emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState);
4572 void nsHtml5Tokenizer::eof() {
4573 int32_t state = stateSave;
4574 int32_t returnState = returnStateSave;
4575 eofloop:
4576 for (;;) {
4577 switch (state) {
4578 case SCRIPT_DATA_LESS_THAN_SIGN:
4579 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
4580 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4581 NS_HTML5_BREAK(eofloop);
4583 case TAG_OPEN: {
4584 errEofAfterLt();
4585 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4586 NS_HTML5_BREAK(eofloop);
4588 case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
4589 tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
4590 NS_HTML5_BREAK(eofloop);
4592 case NON_DATA_END_TAG_NAME: {
4593 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
4594 emitStrBuf();
4595 NS_HTML5_BREAK(eofloop);
4597 case CLOSE_TAG_OPEN: {
4598 errEofAfterLt();
4599 tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
4600 NS_HTML5_BREAK(eofloop);
4602 case TAG_NAME: {
4603 errEofInTagName();
4604 NS_HTML5_BREAK(eofloop);
4606 case BEFORE_ATTRIBUTE_NAME:
4607 case AFTER_ATTRIBUTE_VALUE_QUOTED:
4608 case SELF_CLOSING_START_TAG: {
4609 errEofWithoutGt();
4610 NS_HTML5_BREAK(eofloop);
4612 case ATTRIBUTE_NAME: {
4613 errEofInAttributeName();
4614 NS_HTML5_BREAK(eofloop);
4616 case AFTER_ATTRIBUTE_NAME:
4617 case BEFORE_ATTRIBUTE_VALUE: {
4618 errEofWithoutGt();
4619 NS_HTML5_BREAK(eofloop);
4621 case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
4622 case ATTRIBUTE_VALUE_SINGLE_QUOTED:
4623 case ATTRIBUTE_VALUE_UNQUOTED: {
4624 errEofInAttributeValue();
4625 NS_HTML5_BREAK(eofloop);
4627 case BOGUS_COMMENT: {
4628 emitComment(0, 0);
4629 NS_HTML5_BREAK(eofloop);
4631 case BOGUS_COMMENT_HYPHEN: {
4632 emitComment(0, 0);
4633 NS_HTML5_BREAK(eofloop);
4635 case MARKUP_DECLARATION_OPEN: {
4636 errBogusComment();
4637 emitComment(0, 0);
4638 NS_HTML5_BREAK(eofloop);
4640 case MARKUP_DECLARATION_HYPHEN: {
4641 errBogusComment();
4642 emitComment(0, 0);
4643 NS_HTML5_BREAK(eofloop);
4645 case MARKUP_DECLARATION_OCTYPE: {
4646 if (index < 6) {
4647 errBogusComment();
4648 emitComment(0, 0);
4649 } else {
4650 errEofInDoctype();
4651 doctypeName = nullptr;
4652 if (systemIdentifier) {
4653 systemIdentifier.Release();
4654 systemIdentifier = nullptr;
4656 if (publicIdentifier) {
4657 publicIdentifier.Release();
4658 publicIdentifier = nullptr;
4660 forceQuirks = true;
4661 emitDoctypeToken(0);
4662 NS_HTML5_BREAK(eofloop);
4664 NS_HTML5_BREAK(eofloop);
4666 case COMMENT_START:
4667 case COMMENT:
4668 case COMMENT_LESSTHAN:
4669 case COMMENT_LESSTHAN_BANG: {
4670 errEofInComment();
4671 emitComment(0, 0);
4672 NS_HTML5_BREAK(eofloop);
4674 case COMMENT_END:
4675 case COMMENT_LESSTHAN_BANG_DASH_DASH: {
4676 errEofInComment();
4677 emitComment(2, 0);
4678 NS_HTML5_BREAK(eofloop);
4680 case COMMENT_END_DASH:
4681 case COMMENT_START_DASH:
4682 case COMMENT_LESSTHAN_BANG_DASH: {
4683 errEofInComment();
4684 emitComment(1, 0);
4685 NS_HTML5_BREAK(eofloop);
4687 case COMMENT_END_BANG: {
4688 errEofInComment();
4689 emitComment(3, 0);
4690 NS_HTML5_BREAK(eofloop);
4692 case DOCTYPE:
4693 case BEFORE_DOCTYPE_NAME: {
4694 errEofInDoctype();
4695 forceQuirks = true;
4696 emitDoctypeToken(0);
4697 NS_HTML5_BREAK(eofloop);
4699 case DOCTYPE_NAME: {
4700 errEofInDoctype();
4701 strBufToDoctypeName();
4702 forceQuirks = true;
4703 emitDoctypeToken(0);
4704 NS_HTML5_BREAK(eofloop);
4706 case DOCTYPE_UBLIC:
4707 case DOCTYPE_YSTEM:
4708 case AFTER_DOCTYPE_NAME:
4709 case AFTER_DOCTYPE_PUBLIC_KEYWORD:
4710 case AFTER_DOCTYPE_SYSTEM_KEYWORD:
4711 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
4712 errEofInDoctype();
4713 forceQuirks = true;
4714 emitDoctypeToken(0);
4715 NS_HTML5_BREAK(eofloop);
4717 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
4718 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
4719 errEofInPublicId();
4720 forceQuirks = true;
4721 publicIdentifier = strBufToString();
4722 emitDoctypeToken(0);
4723 NS_HTML5_BREAK(eofloop);
4725 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
4726 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
4727 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
4728 errEofInDoctype();
4729 forceQuirks = true;
4730 emitDoctypeToken(0);
4731 NS_HTML5_BREAK(eofloop);
4733 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
4734 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
4735 errEofInSystemId();
4736 forceQuirks = true;
4737 systemIdentifier = strBufToString();
4738 emitDoctypeToken(0);
4739 NS_HTML5_BREAK(eofloop);
4741 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
4742 errEofInDoctype();
4743 forceQuirks = true;
4744 emitDoctypeToken(0);
4745 NS_HTML5_BREAK(eofloop);
4747 case BOGUS_DOCTYPE: {
4748 emitDoctypeToken(0);
4749 NS_HTML5_BREAK(eofloop);
4751 case CONSUME_CHARACTER_REFERENCE: {
4752 emitOrAppendCharRefBuf(returnState);
4753 state = returnState;
4754 continue;
4756 case CHARACTER_REFERENCE_HILO_LOOKUP: {
4757 emitOrAppendCharRefBuf(returnState);
4758 state = returnState;
4759 continue;
4761 case CHARACTER_REFERENCE_TAIL: {
4762 for (;;) {
4763 char16_t c = '\0';
4764 entCol++;
4765 for (;;) {
4766 if (hi == -1) {
4767 NS_HTML5_BREAK(hiloop);
4769 if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
4770 NS_HTML5_BREAK(hiloop);
4772 if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
4773 NS_HTML5_BREAK(outer);
4774 } else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
4775 hi--;
4776 } else {
4777 NS_HTML5_BREAK(hiloop);
4780 hiloop_end:;
4781 for (;;) {
4782 if (hi < lo) {
4783 NS_HTML5_BREAK(outer);
4785 if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
4786 candidate = lo;
4787 charRefBufMark = charRefBufLen;
4788 lo++;
4789 } else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
4790 NS_HTML5_BREAK(outer);
4791 } else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
4792 lo++;
4793 } else {
4794 NS_HTML5_BREAK(loloop);
4797 loloop_end:;
4798 if (hi < lo) {
4799 NS_HTML5_BREAK(outer);
4801 continue;
4803 outer_end:;
4804 if (candidate == -1) {
4805 emitOrAppendCharRefBuf(returnState);
4806 state = returnState;
4807 NS_HTML5_CONTINUE(eofloop);
4808 } else {
4809 const nsHtml5CharacterName& candidateName =
4810 nsHtml5NamedCharacters::NAMES[candidate];
4811 if (!candidateName.length() ||
4812 candidateName.charAt(candidateName.length() - 1) != ';') {
4813 if ((returnState & DATA_AND_RCDATA_MASK)) {
4814 char16_t ch;
4815 if (charRefBufMark == charRefBufLen) {
4816 ch = '\0';
4817 } else {
4818 ch = charRefBuf[charRefBufMark];
4820 if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') ||
4821 (ch >= 'a' && ch <= 'z')) {
4822 appendCharRefBufToStrBuf();
4823 state = returnState;
4824 NS_HTML5_CONTINUE(eofloop);
4827 if ((returnState & DATA_AND_RCDATA_MASK)) {
4828 errUnescapedAmpersandInterpretedAsCharacterReference();
4829 } else {
4830 errNotSemicolonTerminated();
4833 const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
4834 if (!val[1]) {
4835 emitOrAppendOne(val, returnState);
4836 } else {
4837 emitOrAppendTwo(val, returnState);
4839 if (charRefBufMark < charRefBufLen) {
4840 if ((returnState & DATA_AND_RCDATA_MASK)) {
4841 appendStrBuf(charRefBuf, charRefBufMark,
4842 charRefBufLen - charRefBufMark);
4843 } else {
4844 tokenHandler->characters(charRefBuf, charRefBufMark,
4845 charRefBufLen - charRefBufMark);
4848 charRefBufLen = 0;
4849 state = returnState;
4850 NS_HTML5_CONTINUE(eofloop);
4853 case CONSUME_NCR:
4854 case DECIMAL_NRC_LOOP:
4855 case HEX_NCR_LOOP: {
4856 if (!seenDigits) {
4857 errNoDigitsInNCR();
4858 emitOrAppendCharRefBuf(returnState);
4859 state = returnState;
4860 continue;
4861 } else {
4862 errCharRefLacksSemicolon();
4864 handleNcrValue(returnState);
4865 state = returnState;
4866 continue;
4868 case CDATA_RSQB: {
4869 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
4870 NS_HTML5_BREAK(eofloop);
4872 case CDATA_RSQB_RSQB: {
4873 tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
4874 NS_HTML5_BREAK(eofloop);
4876 case DATA:
4877 default: {
4878 NS_HTML5_BREAK(eofloop);
4882 eofloop_end:;
4883 tokenHandler->eof();
4884 return;
4887 void nsHtml5Tokenizer::emitDoctypeToken(int32_t pos) {
4888 RememberGt(pos);
4889 cstart = pos + 1;
4890 tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier,
4891 forceQuirks);
4892 doctypeName = nullptr;
4893 publicIdentifier.Release();
4894 publicIdentifier = nullptr;
4895 systemIdentifier.Release();
4896 systemIdentifier = nullptr;
4897 suspendIfRequestedAfterCurrentNonTextToken();
4900 void nsHtml5Tokenizer::suspendIfRequestedAfterCurrentNonTextToken() {
4901 if (suspendAfterCurrentNonTextToken) {
4902 suspendAfterCurrentNonTextToken = false;
4903 shouldSuspend = true;
4907 void nsHtml5Tokenizer::suspendAfterCurrentTokenIfNotInText() {
4908 switch (stateSave) {
4909 case DATA:
4910 case RCDATA:
4911 case SCRIPT_DATA:
4912 case RAWTEXT:
4913 case SCRIPT_DATA_ESCAPED:
4914 case PLAINTEXT:
4915 case NON_DATA_END_TAG_NAME:
4916 case SCRIPT_DATA_LESS_THAN_SIGN:
4917 case SCRIPT_DATA_ESCAPE_START:
4918 case SCRIPT_DATA_ESCAPE_START_DASH:
4919 case SCRIPT_DATA_ESCAPED_DASH:
4920 case SCRIPT_DATA_ESCAPED_DASH_DASH:
4921 case RAWTEXT_RCDATA_LESS_THAN_SIGN:
4922 case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
4923 case SCRIPT_DATA_DOUBLE_ESCAPE_START:
4924 case SCRIPT_DATA_DOUBLE_ESCAPED:
4925 case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
4926 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
4927 case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
4928 case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
4929 return;
4931 case TAG_NAME:
4932 case BEFORE_ATTRIBUTE_NAME:
4933 case ATTRIBUTE_NAME:
4934 case AFTER_ATTRIBUTE_NAME:
4935 case BEFORE_ATTRIBUTE_VALUE:
4936 case AFTER_ATTRIBUTE_VALUE_QUOTED:
4937 case BOGUS_COMMENT:
4938 case MARKUP_DECLARATION_OPEN:
4939 case DOCTYPE:
4940 case BEFORE_DOCTYPE_NAME:
4941 case DOCTYPE_NAME:
4942 case AFTER_DOCTYPE_NAME:
4943 case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
4944 case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
4945 case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
4946 case AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
4947 case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
4948 case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
4949 case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
4950 case AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
4951 case BOGUS_DOCTYPE:
4952 case COMMENT_START:
4953 case COMMENT_START_DASH:
4954 case COMMENT:
4955 case COMMENT_END_DASH:
4956 case COMMENT_END:
4957 case COMMENT_END_BANG:
4958 case TAG_OPEN:
4959 case CLOSE_TAG_OPEN:
4960 case MARKUP_DECLARATION_HYPHEN:
4961 case MARKUP_DECLARATION_OCTYPE:
4962 case DOCTYPE_UBLIC:
4963 case DOCTYPE_YSTEM:
4964 case AFTER_DOCTYPE_PUBLIC_KEYWORD:
4965 case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
4966 case AFTER_DOCTYPE_SYSTEM_KEYWORD:
4967 case SELF_CLOSING_START_TAG:
4968 case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
4969 case ATTRIBUTE_VALUE_SINGLE_QUOTED:
4970 case ATTRIBUTE_VALUE_UNQUOTED:
4971 case BOGUS_COMMENT_HYPHEN:
4972 case COMMENT_LESSTHAN:
4973 case COMMENT_LESSTHAN_BANG:
4974 case COMMENT_LESSTHAN_BANG_DASH:
4975 case COMMENT_LESSTHAN_BANG_DASH_DASH:
4976 case CDATA_START:
4977 case CDATA_SECTION:
4978 case CDATA_RSQB:
4979 case CDATA_RSQB_RSQB:
4980 case PROCESSING_INSTRUCTION:
4981 case PROCESSING_INSTRUCTION_QUESTION_MARK: {
4982 break;
4984 case CONSUME_CHARACTER_REFERENCE:
4985 case CONSUME_NCR:
4986 case CHARACTER_REFERENCE_TAIL:
4987 case HEX_NCR_LOOP:
4988 case DECIMAL_NRC_LOOP:
4989 case HANDLE_NCR_VALUE:
4990 case HANDLE_NCR_VALUE_RECONSUME:
4991 case CHARACTER_REFERENCE_HILO_LOOKUP: {
4992 if (returnStateSave == DATA || returnStateSave == RCDATA) {
4993 return;
4995 break;
4997 default: {
4998 MOZ_ASSERT(false, "Incomplete switch");
4999 return;
5002 suspendAfterCurrentNonTextToken = true;
5005 bool nsHtml5Tokenizer::suspensionAfterCurrentNonTextTokenPending() {
5006 return suspendAfterCurrentNonTextToken;
5009 bool nsHtml5Tokenizer::internalEncodingDeclaration(
5010 nsHtml5String internalCharset) {
5011 if (encodingDeclarationHandler) {
5012 return encodingDeclarationHandler->internalEncodingDeclaration(
5013 internalCharset);
5015 return false;
5018 void nsHtml5Tokenizer::emitOrAppendTwo(const char16_t* val,
5019 int32_t returnState) {
5020 if ((returnState & DATA_AND_RCDATA_MASK)) {
5021 appendStrBuf(val[0]);
5022 appendStrBuf(val[1]);
5023 } else {
5024 tokenHandler->characters(val, 0, 2);
5028 void nsHtml5Tokenizer::emitOrAppendOne(const char16_t* val,
5029 int32_t returnState) {
5030 if ((returnState & DATA_AND_RCDATA_MASK)) {
5031 appendStrBuf(val[0]);
5032 } else {
5033 tokenHandler->characters(val, 0, 1);
5037 void nsHtml5Tokenizer::end() {
5038 if (!keepBuffer) {
5039 strBuf = nullptr;
5041 doctypeName = nullptr;
5042 if (systemIdentifier) {
5043 systemIdentifier.Release();
5044 systemIdentifier = nullptr;
5046 if (publicIdentifier) {
5047 publicIdentifier.Release();
5048 publicIdentifier = nullptr;
5050 tagName = nullptr;
5051 nonInternedTagName->setNameForNonInterned(nullptr, false);
5052 attributeName = nullptr;
5053 nonInternedAttributeName->setNameForNonInterned(nullptr);
5054 tokenHandler->endTokenization();
5055 if (attributes) {
5056 attributes->clear(0);
5060 void nsHtml5Tokenizer::requestSuspension() { shouldSuspend = true; }
5062 bool nsHtml5Tokenizer::isInDataState() { return (stateSave == DATA); }
5064 void nsHtml5Tokenizer::resetToDataState() {
5065 clearStrBufAfterUse();
5066 charRefBufLen = 0;
5067 stateSave = nsHtml5Tokenizer::DATA;
5068 lastCR = false;
5069 index = 0;
5070 forceQuirks = false;
5071 additional = '\0';
5072 entCol = -1;
5073 firstCharKey = -1;
5074 lo = 0;
5075 hi = 0;
5076 candidate = -1;
5077 charRefBufMark = 0;
5078 value = 0;
5079 seenDigits = false;
5080 suspendAfterCurrentNonTextToken = false;
5081 endTag = false;
5082 shouldSuspend = false;
5083 initDoctypeFields();
5084 containsHyphen = false;
5085 tagName = nullptr;
5086 attributeName = nullptr;
5087 if (newAttributesEachTime) {
5088 if (attributes) {
5089 delete attributes;
5090 attributes = nullptr;
5095 void nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other) {
5096 strBufLen = other->strBufLen;
5097 if (strBufLen > strBuf.length) {
5098 strBuf = jArray<char16_t, int32_t>::newJArray(strBufLen);
5100 nsHtml5ArrayCopy::arraycopy(other->strBuf, strBuf, strBufLen);
5101 charRefBufLen = other->charRefBufLen;
5102 nsHtml5ArrayCopy::arraycopy(other->charRefBuf, charRefBuf, charRefBufLen);
5103 stateSave = other->stateSave;
5104 returnStateSave = other->returnStateSave;
5105 endTagExpectation = other->endTagExpectation;
5106 endTagExpectationAsArray = other->endTagExpectationAsArray;
5107 lastCR = other->lastCR;
5108 index = other->index;
5109 forceQuirks = other->forceQuirks;
5110 additional = other->additional;
5111 entCol = other->entCol;
5112 firstCharKey = other->firstCharKey;
5113 lo = other->lo;
5114 hi = other->hi;
5115 candidate = other->candidate;
5116 charRefBufMark = other->charRefBufMark;
5117 value = other->value;
5118 seenDigits = other->seenDigits;
5119 endTag = other->endTag;
5120 shouldSuspend = false;
5121 suspendAfterCurrentNonTextToken = false;
5122 doctypeName = other->doctypeName;
5123 systemIdentifier.Release();
5124 if (!other->systemIdentifier) {
5125 systemIdentifier = nullptr;
5126 } else {
5127 systemIdentifier =
5128 nsHtml5Portability::newStringFromString(other->systemIdentifier);
5130 publicIdentifier.Release();
5131 if (!other->publicIdentifier) {
5132 publicIdentifier = nullptr;
5133 } else {
5134 publicIdentifier =
5135 nsHtml5Portability::newStringFromString(other->publicIdentifier);
5137 containsHyphen = other->containsHyphen;
5138 if (!other->tagName) {
5139 tagName = nullptr;
5140 } else if (other->tagName->isInterned()) {
5141 tagName = other->tagName;
5142 } else {
5143 nonInternedTagName->setNameForNonInterned(other->tagName->getName(),
5144 other->tagName->isCustom());
5145 tagName = nonInternedTagName;
5147 if (!other->attributeName) {
5148 attributeName = nullptr;
5149 } else if (other->attributeName->isInterned()) {
5150 attributeName = other->attributeName;
5151 } else {
5152 nonInternedAttributeName->setNameForNonInterned(
5153 other->attributeName->getLocal(nsHtml5AttributeName::HTML));
5154 attributeName = nonInternedAttributeName;
5156 delete attributes;
5157 if (!other->attributes) {
5158 attributes = nullptr;
5159 } else {
5160 attributes = other->attributes->cloneAttributes();
5164 void nsHtml5Tokenizer::initializeWithoutStarting() {
5165 confident = false;
5166 if (!keepBuffer) {
5167 strBuf = nullptr;
5169 line = 1;
5170 attributeLine = 1;
5171 resetToDataState();
5174 void nsHtml5Tokenizer::setEncodingDeclarationHandler(
5175 nsHtml5StreamParser* encodingDeclarationHandler) {
5176 this->encodingDeclarationHandler = encodingDeclarationHandler;
5179 nsHtml5Tokenizer::~nsHtml5Tokenizer() {
5180 MOZ_COUNT_DTOR(nsHtml5Tokenizer);
5181 delete nonInternedTagName;
5182 nonInternedTagName = nullptr;
5183 delete nonInternedAttributeName;
5184 nonInternedAttributeName = nullptr;
5185 delete attributes;
5186 attributes = nullptr;
5189 void nsHtml5Tokenizer::initializeStatics() {}
5191 void nsHtml5Tokenizer::releaseStatics() {}
5193 #include "nsHtml5TokenizerCppSupplement.h"