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