in parser/html/nsHtml5Tokenizer.cpp [473:4463]
int32_t nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos,
char16_t* buf, bool reconsume,
int32_t returnState, int32_t endPos) {
bool reportedConsecutiveHyphens = false;
stateloop:
for (;;) {
switch (state) {
case DATA: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '&': {
flushChars(buf, pos);
MOZ_ASSERT(!charRefBufLen,
"charRefBufLen not reset after previous use!");
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('\0');
returnState = state;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '<': {
flushChars(buf, pos);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::TAG_OPEN, reconsume, pos);
NS_HTML5_BREAK(dataloop);
}
case '\0': {
maybeEmitReplacementCharacter(buf, pos);
continue;
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
dataloop_end:;
[[fallthrough]];
}
case TAG_OPEN: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
if (c >= 'A' && c <= 'Z') {
endTag = false;
clearStrBufBeforeUse();
appendStrBuf((char16_t)(c + 0x20));
containsHyphen = false;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
reconsume, pos);
NS_HTML5_BREAK(tagopenloop);
} else if (c >= 'a' && c <= 'z') {
endTag = false;
clearStrBufBeforeUse();
appendStrBuf(c);
containsHyphen = false;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
reconsume, pos);
NS_HTML5_BREAK(tagopenloop);
}
switch (c) {
case '!': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::MARKUP_DECLARATION_OPEN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '/': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::CLOSE_TAG_OPEN, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\?': {
if (viewingXmlSource) {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
if (P::reportErrors) {
errProcessingInstruction();
}
clearStrBufBeforeUse();
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errLtGt();
}
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
cstart = pos + 1;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
default: {
if (P::reportErrors) {
errBadCharAfterLt(c);
}
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
cstart = pos;
reconsume = true;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
tagopenloop_end:;
[[fallthrough]];
}
case TAG_NAME: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
strBufToElementNameString();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
strBufToElementNameString();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_BREAK(tagnameloop);
}
case '/': {
strBufToElementNameString();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
strBufToElementNameString();
state = P::transition(mViewSource.get(),
emitCurrentTagToken(false, pos), reconsume,
pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
if (c >= 'A' && c <= 'Z') {
c += 0x20;
} else if (c == '-') {
containsHyphen = true;
}
appendStrBuf(c);
continue;
}
}
}
tagnameloop_end:;
[[fallthrough]];
}
case BEFORE_ATTRIBUTE_NAME: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '/': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
state = P::transition(mViewSource.get(),
emitCurrentTagToken(false, pos), reconsume,
pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
case '\"':
case '\'':
case '<':
case '=': {
if (P::reportErrors) {
errBadCharBeforeAttributeNameOrNull(c);
}
[[fallthrough]];
}
default: {
if (c >= 'A' && c <= 'Z') {
c += 0x20;
}
attributeLine = line;
clearStrBufBeforeUse();
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
pos);
NS_HTML5_BREAK(beforeattributenameloop);
}
}
}
beforeattributenameloop_end:;
[[fallthrough]];
}
case ATTRIBUTE_NAME: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
attributeNameComplete();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
attributeNameComplete();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '/': {
attributeNameComplete();
addAttributeWithoutValue();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '=': {
attributeNameComplete();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
reconsume, pos);
NS_HTML5_BREAK(attributenameloop);
}
case '>': {
attributeNameComplete();
addAttributeWithoutValue();
state = P::transition(mViewSource.get(),
emitCurrentTagToken(false, pos), reconsume,
pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
case '\"':
case '\'':
case '<': {
if (P::reportErrors) {
errQuoteOrLtInAttributeNameOrNull(c);
}
[[fallthrough]];
}
default: {
if (c >= 'A' && c <= 'Z') {
c += 0x20;
}
appendStrBuf(c);
continue;
}
}
}
attributenameloop_end:;
[[fallthrough]];
}
case BEFORE_ATTRIBUTE_VALUE: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '\"': {
attributeLine = line;
clearStrBufBeforeUse();
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED,
reconsume, pos);
NS_HTML5_BREAK(beforeattributevalueloop);
}
case '&': {
attributeLine = line;
clearStrBufBeforeUse();
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\'': {
attributeLine = line;
clearStrBufBeforeUse();
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errAttributeValueMissing();
}
addAttributeWithoutValue();
state = P::transition(mViewSource.get(),
emitCurrentTagToken(false, pos), reconsume,
pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
case '<':
case '=':
case '`': {
if (P::reportErrors) {
errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
}
[[fallthrough]];
}
default: {
attributeLine = line;
clearStrBufBeforeUse();
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
beforeattributevalueloop_end:;
[[fallthrough]];
}
case ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '\"': {
addAttributeWithValue();
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
reconsume, pos);
NS_HTML5_BREAK(attributevaluedoublequotedloop);
}
case '&': {
MOZ_ASSERT(!charRefBufLen,
"charRefBufLen not reset after previous use!");
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('\"');
returnState = state;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
continue;
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
attributevaluedoublequotedloop_end:;
[[fallthrough]];
}
case AFTER_ATTRIBUTE_VALUE_QUOTED: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '/': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
reconsume, pos);
NS_HTML5_BREAK(afterattributevaluequotedloop);
}
case '>': {
state = P::transition(mViewSource.get(),
emitCurrentTagToken(false, pos), reconsume,
pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
if (P::reportErrors) {
errNoSpaceBetweenAttributes();
}
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
afterattributevaluequotedloop_end:;
[[fallthrough]];
}
case SELF_CLOSING_START_TAG: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '>': {
state =
P::transition(mViewSource.get(), emitCurrentTagToken(true, pos),
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
if (P::reportErrors) {
errSlashNotFollowedByGt();
}
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
case ATTRIBUTE_VALUE_UNQUOTED: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
addAttributeWithValue();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
addAttributeWithValue();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '&': {
MOZ_ASSERT(!charRefBufLen,
"charRefBufLen not reset after previous use!");
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('>');
returnState = state;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
addAttributeWithValue();
state = P::transition(mViewSource.get(),
emitCurrentTagToken(false, pos), reconsume,
pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
case '<':
case '\"':
case '\'':
case '=':
case '`': {
if (P::reportErrors) {
errUnquotedAttributeValOrNull(c);
}
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
}
case AFTER_ATTRIBUTE_NAME: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '/': {
addAttributeWithoutValue();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '=': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
addAttributeWithoutValue();
state = P::transition(mViewSource.get(),
emitCurrentTagToken(false, pos), reconsume,
pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
case '\"':
case '\'':
case '<': {
if (P::reportErrors) {
errQuoteOrLtInAttributeNameOrNull(c);
}
[[fallthrough]];
}
default: {
addAttributeWithoutValue();
if (c >= 'A' && c <= 'Z') {
c += 0x20;
}
clearStrBufBeforeUse();
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case MARKUP_DECLARATION_OPEN: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
clearStrBufBeforeUse();
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::MARKUP_DECLARATION_HYPHEN,
reconsume, pos);
NS_HTML5_BREAK(markupdeclarationopenloop);
}
case 'd':
case 'D': {
clearStrBufBeforeUse();
appendStrBuf(c);
index = 0;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::MARKUP_DECLARATION_OCTYPE,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '[': {
if (tokenHandler->cdataSectionAllowed()) {
clearStrBufBeforeUse();
appendStrBuf(c);
index = 0;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::CDATA_START, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
[[fallthrough]];
}
default: {
if (P::reportErrors) {
errBogusComment();
}
clearStrBufBeforeUse();
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
markupdeclarationopenloop_end:;
[[fallthrough]];
}
case MARKUP_DECLARATION_HYPHEN: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
clearStrBufAfterOneHyphen();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_START, reconsume,
pos);
NS_HTML5_BREAK(markupdeclarationhyphenloop);
}
default: {
if (P::reportErrors) {
errBogusComment();
}
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
markupdeclarationhyphenloop_end:;
[[fallthrough]];
}
case COMMENT_START: {
reportedConsecutiveHyphens = false;
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_START_DASH,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errPrematureEndOfComment();
}
emitComment(0, pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '<': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_BREAK(commentstartloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_BREAK(commentstartloop);
}
}
}
commentstartloop_end:;
[[fallthrough]];
}
case COMMENT: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_END_DASH,
reconsume, pos);
NS_HTML5_BREAK(commentloop);
}
case '<': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
continue;
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
commentloop_end:;
[[fallthrough]];
}
case COMMENT_END_DASH: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
appendStrBuf(c);
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_END, reconsume, pos);
NS_HTML5_BREAK(commentenddashloop);
}
case '<': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
commentenddashloop_end:;
[[fallthrough]];
}
case COMMENT_END: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '>': {
emitComment(2, pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '-': {
adjustDoubleHyphenAndAppendToStrBufAndErr(
c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
continue;
}
case '<': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
adjustDoubleHyphenAndAppendToStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
adjustDoubleHyphenAndAppendToStrBufLineFeed<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '!': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_END_BANG,
reconsume, pos);
NS_HTML5_BREAK(commentendloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
adjustDoubleHyphenAndAppendToStrBufAndErr(
c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
commentendloop_end:;
[[fallthrough]];
}
case COMMENT_END_BANG: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '>': {
emitComment(3, pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '-': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_END_DASH,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case COMMENT_LESSTHAN: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '!': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG,
reconsume, pos);
NS_HTML5_BREAK(commentlessthanloop);
}
case '<': {
appendStrBuf(c);
continue;
}
case '-': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_END_DASH,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
commentlessthanloop_end:;
[[fallthrough]];
}
case COMMENT_LESSTHAN_BANG: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
appendStrBuf(c);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH, reconsume, pos);
NS_HTML5_BREAK(commentlessthanbangloop);
}
case '<': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
commentlessthanbangloop_end:;
[[fallthrough]];
}
case COMMENT_LESSTHAN_BANG_DASH: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
appendStrBuf(c);
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH,
reconsume, pos);
break;
}
case '<': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
[[fallthrough]];
}
case COMMENT_LESSTHAN_BANG_DASH_DASH: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '>': {
appendStrBuf(c);
emitComment(3, pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '-': {
if (P::reportErrors) {
errNestedComment();
}
adjustDoubleHyphenAndAppendToStrBufAndErr(
c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state =
P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
c = '\n';
P::silentCarriageReturn(this);
if (P::reportErrors) {
errNestedComment();
}
adjustDoubleHyphenAndAppendToStrBufAndErr(
c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
if (P::reportErrors) {
errNestedComment();
}
adjustDoubleHyphenAndAppendToStrBufAndErr(
c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '!': {
if (P::reportErrors) {
errNestedComment();
}
adjustDoubleHyphenAndAppendToStrBufAndErr(
c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_END_BANG, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
if (P::reportErrors) {
errNestedComment();
}
adjustDoubleHyphenAndAppendToStrBufAndErr(
c, reportedConsecutiveHyphens);
reportedConsecutiveHyphens = true;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
case COMMENT_START_DASH: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
appendStrBuf(c);
state =
P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errPrematureEndOfComment();
}
emitComment(1, pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '<': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
case CDATA_START: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
if (index < 6) {
if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
appendStrBuf(c);
} else {
if (P::reportErrors) {
errBogusComment();
}
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
index++;
continue;
} else {
clearStrBufAfterUse();
cstart = pos;
reconsume = true;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
break;
}
}
[[fallthrough]];
}
case CDATA_SECTION: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case ']': {
flushChars(buf, pos);
state =
P::transition(mViewSource.get(), nsHtml5Tokenizer::CDATA_RSQB,
reconsume, pos);
NS_HTML5_BREAK(cdatasectionloop);
}
case '\0': {
maybeEmitReplacementCharacter(buf, pos);
continue;
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
cdatasectionloop_end:;
[[fallthrough]];
}
case CDATA_RSQB: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case ']': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::CDATA_RSQB_RSQB, reconsume,
pos);
break;
}
default: {
tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
cstart = pos;
reconsume = true;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
[[fallthrough]];
}
case CDATA_RSQB_RSQB: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case ']': {
tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
continue;
}
case '>': {
cstart = pos + 1;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
suspendIfRequestedAfterCurrentNonTextToken();
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 2);
cstart = pos;
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::CDATA_SECTION, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case ATTRIBUTE_VALUE_SINGLE_QUOTED: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '\'': {
addAttributeWithValue();
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '&': {
MOZ_ASSERT(!charRefBufLen,
"charRefBufLen not reset after previous use!");
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('\'');
returnState = state;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
reconsume, pos);
NS_HTML5_BREAK(attributevaluesinglequotedloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
continue;
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
attributevaluesinglequotedloop_end:;
[[fallthrough]];
}
case CONSUME_CHARACTER_REFERENCE: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case ' ':
case '\t':
case '\n':
case '\r':
case '\f':
case '<':
case '&':
case '\0':
case ';': {
emitOrAppendCharRefBuf(returnState);
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos;
}
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '#': {
appendCharRefBuf('#');
state =
P::transition(mViewSource.get(), nsHtml5Tokenizer::CONSUME_NCR,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
default: {
if (c == additional) {
emitOrAppendCharRefBuf(returnState);
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
if (c >= 'a' && c <= 'z') {
firstCharKey = c - 'a' + 26;
} else if (c >= 'A' && c <= 'Z') {
firstCharKey = c - 'A';
} else {
if (c == ';') {
if (P::reportErrors) {
errNoNamedCharacterMatch();
}
}
emitOrAppendCharRefBuf(returnState);
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos;
}
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
appendCharRefBuf(c);
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP,
reconsume, pos);
break;
}
}
[[fallthrough]];
}
case CHARACTER_REFERENCE_HILO_LOOKUP: {
{
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
int32_t hilo = 0;
if (c <= 'z') {
const int32_t* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c];
if (row) {
hilo = row[firstCharKey];
}
}
if (!hilo) {
if (c == ';') {
if (P::reportErrors) {
errNoNamedCharacterMatch();
}
}
emitOrAppendCharRefBuf(returnState);
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos;
}
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
appendCharRefBuf(c);
lo = hilo & 0xFFFF;
hi = hilo >> 16;
entCol = -1;
candidate = -1;
charRefBufMark = 0;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL,
reconsume, pos);
}
[[fallthrough]];
}
case CHARACTER_REFERENCE_TAIL: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
entCol++;
for (;;) {
if (hi < lo) {
NS_HTML5_BREAK(outer);
}
if (entCol == nsHtml5NamedCharacters::NAMES[lo].length()) {
candidate = lo;
charRefBufMark = charRefBufLen;
lo++;
} else if (entCol > nsHtml5NamedCharacters::NAMES[lo].length()) {
NS_HTML5_BREAK(outer);
} else if (c > nsHtml5NamedCharacters::NAMES[lo].charAt(entCol)) {
lo++;
} else {
NS_HTML5_BREAK(loloop);
}
}
loloop_end:;
for (;;) {
if (hi < lo) {
NS_HTML5_BREAK(outer);
}
if (entCol == nsHtml5NamedCharacters::NAMES[hi].length()) {
NS_HTML5_BREAK(hiloop);
}
if (entCol > nsHtml5NamedCharacters::NAMES[hi].length()) {
NS_HTML5_BREAK(outer);
} else if (c < nsHtml5NamedCharacters::NAMES[hi].charAt(entCol)) {
hi--;
} else {
NS_HTML5_BREAK(hiloop);
}
}
hiloop_end:;
if (c == ';') {
if (entCol + 1 == nsHtml5NamedCharacters::NAMES[lo].length()) {
candidate = lo;
charRefBufMark = charRefBufLen;
}
NS_HTML5_BREAK(outer);
}
if (hi < lo) {
NS_HTML5_BREAK(outer);
}
appendCharRefBuf(c);
continue;
}
outer_end:;
if (candidate == -1) {
if (c == ';') {
if (P::reportErrors) {
errNoNamedCharacterMatch();
}
}
emitOrAppendCharRefBuf(returnState);
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos;
}
reconsume = true;
state = P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
} else {
const nsHtml5CharacterName& candidateName =
nsHtml5NamedCharacters::NAMES[candidate];
if (!candidateName.length() ||
candidateName.charAt(candidateName.length() - 1) != ';') {
if ((returnState & DATA_AND_RCDATA_MASK)) {
char16_t ch;
if (charRefBufMark == charRefBufLen) {
ch = c;
} else {
ch = charRefBuf[charRefBufMark];
}
if (ch == '=' || (ch >= '0' && ch <= '9') ||
(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
if (c == ';') {
if (P::reportErrors) {
errNoNamedCharacterMatch();
}
}
appendCharRefBufToStrBuf();
reconsume = true;
state = P::transition(mViewSource.get(), returnState, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
if ((returnState & DATA_AND_RCDATA_MASK)) {
if (P::reportErrors) {
errUnescapedAmpersandInterpretedAsCharacterReference();
}
} else {
if (P::reportErrors) {
errNotSemicolonTerminated();
}
}
}
P::completedNamedCharacterReference(mViewSource.get());
const char16_t* val = nsHtml5NamedCharacters::VALUES[candidate];
if (!val[1]) {
emitOrAppendOne(val, returnState);
} else {
emitOrAppendTwo(val, returnState);
}
if (charRefBufMark < charRefBufLen) {
if ((returnState & DATA_AND_RCDATA_MASK)) {
appendStrBuf(charRefBuf, charRefBufMark,
charRefBufLen - charRefBufMark);
} else {
tokenHandler->characters(charRefBuf, charRefBufMark,
charRefBufLen - charRefBufMark);
}
}
bool earlyBreak = (c == ';' && charRefBufMark == charRefBufLen);
charRefBufLen = 0;
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = earlyBreak ? pos + 1 : pos;
}
reconsume = !earlyBreak;
state = P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
case CONSUME_NCR: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
value = 0;
seenDigits = false;
switch (c) {
case 'x':
case 'X': {
appendCharRefBuf(c);
state =
P::transition(mViewSource.get(), nsHtml5Tokenizer::HEX_NCR_LOOP,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
default: {
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::DECIMAL_NRC_LOOP, reconsume,
pos);
break;
}
}
[[fallthrough]];
}
case DECIMAL_NRC_LOOP: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
MOZ_ASSERT(value >= 0, "value must not become negative.");
if (c >= '0' && c <= '9') {
seenDigits = true;
if (value <= 0x10FFFF) {
value *= 10;
value += c - '0';
}
continue;
} else if (c == ';') {
if (seenDigits) {
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos + 1;
}
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::HANDLE_NCR_VALUE,
reconsume, pos);
NS_HTML5_BREAK(decimalloop);
} else {
if (P::reportErrors) {
errNoDigitsInNCR();
}
appendCharRefBuf(';');
emitOrAppendCharRefBuf(returnState);
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos + 1;
}
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
} else {
if (!seenDigits) {
if (P::reportErrors) {
errNoDigitsInNCR();
}
emitOrAppendCharRefBuf(returnState);
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos;
}
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
} else {
if (P::reportErrors) {
errCharRefLacksSemicolon();
}
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos;
}
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::HANDLE_NCR_VALUE,
reconsume, pos);
NS_HTML5_BREAK(decimalloop);
}
}
}
decimalloop_end:;
[[fallthrough]];
}
case HANDLE_NCR_VALUE: {
charRefBufLen = 0;
handleNcrValue(returnState);
state = P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case HEX_NCR_LOOP: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
MOZ_ASSERT(value >= 0, "value must not become negative.");
if (c >= '0' && c <= '9') {
seenDigits = true;
if (value <= 0x10FFFF) {
value *= 16;
value += c - '0';
}
continue;
} else if (c >= 'A' && c <= 'F') {
seenDigits = true;
if (value <= 0x10FFFF) {
value *= 16;
value += c - 'A' + 10;
}
continue;
} else if (c >= 'a' && c <= 'f') {
seenDigits = true;
if (value <= 0x10FFFF) {
value *= 16;
value += c - 'a' + 10;
}
continue;
} else if (c == ';') {
if (seenDigits) {
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos + 1;
}
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::HANDLE_NCR_VALUE,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
} else {
if (P::reportErrors) {
errNoDigitsInNCR();
}
appendCharRefBuf(';');
emitOrAppendCharRefBuf(returnState);
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos + 1;
}
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
} else {
if (!seenDigits) {
if (P::reportErrors) {
errNoDigitsInNCR();
}
emitOrAppendCharRefBuf(returnState);
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos;
}
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
} else {
if (P::reportErrors) {
errCharRefLacksSemicolon();
}
if (!(returnState & DATA_AND_RCDATA_MASK)) {
cstart = pos;
}
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::HANDLE_NCR_VALUE,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case PLAINTEXT: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '\0': {
emitPlaintextReplacementCharacter(buf, pos);
continue;
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
}
case CLOSE_TAG_OPEN: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '>': {
if (P::reportErrors) {
errLtSlashGt();
}
cstart = pos + 1;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
P::silentCarriageReturn(this);
if (P::reportErrors) {
errGarbageAfterLtSlash();
}
clearStrBufBeforeUse();
appendStrBuf('\n');
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
if (P::reportErrors) {
errGarbageAfterLtSlash();
}
clearStrBufBeforeUse();
appendStrBuf(c);
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
if (c >= 'A' && c <= 'Z') {
c += 0x20;
}
if (c >= 'a' && c <= 'z') {
endTag = true;
clearStrBufBeforeUse();
appendStrBuf(c);
containsHyphen = false;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::TAG_NAME, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
} else {
if (P::reportErrors) {
errGarbageAfterLtSlash();
}
clearStrBufBeforeUse();
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case RCDATA: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '&': {
flushChars(buf, pos);
MOZ_ASSERT(!charRefBufLen,
"charRefBufLen not reset after previous use!");
appendCharRefBuf(c);
setAdditionalAndRememberAmpersandLocation('\0');
returnState = state;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '<': {
flushChars(buf, pos);
returnState = state;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
continue;
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
}
case RAWTEXT: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '<': {
flushChars(buf, pos);
returnState = state;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN,
reconsume, pos);
NS_HTML5_BREAK(rawtextloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
continue;
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
rawtextloop_end:;
[[fallthrough]];
}
case RAWTEXT_RCDATA_LESS_THAN_SIGN: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '/': {
index = 0;
clearStrBufBeforeUse();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
reconsume, pos);
NS_HTML5_BREAK(rawtextrcdatalessthansignloop);
}
default: {
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
cstart = pos;
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
rawtextrcdatalessthansignloop_end:;
[[fallthrough]];
}
case NON_DATA_END_TAG_NAME: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
if (!endTagExpectationAsArray) {
tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
cstart = pos;
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
} else if (index < endTagExpectationAsArray.length) {
char16_t e = endTagExpectationAsArray[index];
char16_t folded = c;
if (c >= 'A' && c <= 'Z') {
folded += 0x20;
}
if (folded != e) {
tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
emitStrBuf();
cstart = pos;
reconsume = true;
state =
P::transition(mViewSource.get(), returnState, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
appendStrBuf(c);
index++;
continue;
} else {
endTag = true;
tagName = endTagExpectation;
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
clearStrBufAfterUse();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
clearStrBufAfterUse();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '/': {
clearStrBufAfterUse();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
clearStrBufAfterUse();
state = P::transition(mViewSource.get(),
emitCurrentTagToken(false, pos),
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
emitStrBuf();
cstart = pos;
reconsume = true;
state = P::transition(mViewSource.get(), returnState, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
}
case BOGUS_COMMENT: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '>': {
emitComment(0, pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '-': {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN,
reconsume, pos);
NS_HTML5_BREAK(boguscommentloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
continue;
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
boguscommentloop_end:;
[[fallthrough]];
}
case BOGUS_COMMENT_HYPHEN: {
boguscommenthyphenloop:
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '>': {
emitComment(0, pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '-': {
appendSecondHyphenToBogusComment();
NS_HTML5_CONTINUE(boguscommenthyphenloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case SCRIPT_DATA: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '<': {
flushChars(buf, pos);
returnState = state;
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN, reconsume, pos);
NS_HTML5_BREAK(scriptdataloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
continue;
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
scriptdataloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_LESS_THAN_SIGN: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '/': {
index = 0;
clearStrBufBeforeUse();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '!': {
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
cstart = pos;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START,
reconsume, pos);
NS_HTML5_BREAK(scriptdatalessthansignloop);
}
default: {
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
cstart = pos;
reconsume = true;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdatalessthansignloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_ESCAPE_START: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPE_START_DASH,
reconsume, pos);
NS_HTML5_BREAK(scriptdataescapestartloop);
}
default: {
reconsume = true;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdataescapestartloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_ESCAPE_START_DASH: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
reconsume, pos);
NS_HTML5_BREAK(scriptdataescapestartdashloop);
}
default: {
reconsume = true;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdataescapestartdashloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_ESCAPED_DASH_DASH: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
continue;
}
case '<': {
flushChars(buf, pos);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_BREAK(scriptdataescapeddashdashloop);
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_BREAK(scriptdataescapeddashdashloop);
}
}
}
scriptdataescapeddashdashloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_ESCAPED: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '-': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH,
reconsume, pos);
NS_HTML5_BREAK(scriptdataescapedloop);
}
case '<': {
flushChars(buf, pos);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
continue;
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
scriptdataescapedloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_ESCAPED_DASH: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '<': {
flushChars(buf, pos);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN,
reconsume, pos);
NS_HTML5_BREAK(scriptdataescapeddashloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdataescapeddashloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '/': {
index = 0;
clearStrBufBeforeUse();
returnState = nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::NON_DATA_END_TAG_NAME,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case 'S':
case 's': {
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
cstart = pos;
index = 1;
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_START, reconsume,
pos);
NS_HTML5_BREAK(scriptdataescapedlessthanloop);
}
default: {
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
cstart = pos;
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdataescapedlessthanloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_DOUBLE_ESCAPE_START: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
MOZ_ASSERT(index > 0);
if (index < 6) {
char16_t folded = c;
if (c >= 'A' && c <= 'Z') {
folded += 0x20;
}
if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
index++;
continue;
}
switch (c) {
case '\r': {
emitCarriageReturn<P>(buf, pos);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f':
case '/':
case '>': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_BREAK(scriptdatadoubleescapestartloop);
}
default: {
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdatadoubleescapestartloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_DOUBLE_ESCAPED: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '-': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH, reconsume,
pos);
NS_HTML5_BREAK(scriptdatadoubleescapedloop);
}
case '<': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
continue;
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
scriptdatadoubleescapedloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH,
reconsume, pos);
NS_HTML5_BREAK(scriptdatadoubleescapeddashloop);
}
case '<': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdatadoubleescapeddashloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '-': {
continue;
}
case '<': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN,
reconsume, pos);
NS_HTML5_BREAK(scriptdatadoubleescapeddashdashloop);
}
case '>': {
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
emitReplacementCharacter(buf, pos);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
emitCarriageReturn<P>(buf, pos);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdatadoubleescapeddashdashloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '/': {
index = 0;
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPE_END,
reconsume, pos);
NS_HTML5_BREAK(scriptdatadoubleescapedlessthanloop);
}
default: {
reconsume = true;
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
scriptdatadoubleescapedlessthanloop_end:;
[[fallthrough]];
}
case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
if (index < 6) {
char16_t folded = c;
if (c >= 'A' && c <= 'Z') {
folded += 0x20;
}
if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) {
reconsume = true;
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
index++;
continue;
}
switch (c) {
case '\r': {
emitCarriageReturn<P>(buf, pos);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f':
case '/':
case '>': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
default: {
reconsume = true;
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::SCRIPT_DATA_DOUBLE_ESCAPED, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case MARKUP_DECLARATION_OCTYPE: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
if (index < 6) {
char16_t folded = c;
if (c >= 'A' && c <= 'Z') {
folded += 0x20;
}
if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
appendStrBuf(c);
} else {
if (P::reportErrors) {
errBogusComment();
}
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
index++;
continue;
} else {
reconsume = true;
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DOCTYPE,
reconsume, pos);
NS_HTML5_BREAK(markupdeclarationdoctypeloop);
}
}
markupdeclarationdoctypeloop_end:;
[[fallthrough]];
}
case DOCTYPE: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
initDoctypeFields();
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
reconsume, pos);
NS_HTML5_BREAK(doctypeloop);
}
default: {
if (P::reportErrors) {
errMissingSpaceBeforeDoctypeName();
}
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME,
reconsume, pos);
NS_HTML5_BREAK(doctypeloop);
}
}
}
doctypeloop_end:;
[[fallthrough]];
}
case BEFORE_DOCTYPE_NAME: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '>': {
if (P::reportErrors) {
errNamelessDoctype();
}
forceQuirks = true;
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
if (c >= 'A' && c <= 'Z') {
c += 0x20;
}
clearStrBufBeforeUse();
appendStrBuf(c);
state =
P::transition(mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_NAME, reconsume, pos);
NS_HTML5_BREAK(beforedoctypenameloop);
}
}
}
beforedoctypenameloop_end:;
[[fallthrough]];
}
case DOCTYPE_NAME: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
strBufToDoctypeName();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
strBufToDoctypeName();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::AFTER_DOCTYPE_NAME,
reconsume, pos);
NS_HTML5_BREAK(doctypenameloop);
}
case '>': {
strBufToDoctypeName();
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
if (c >= 'A' && c <= 'Z') {
c += 0x0020;
}
appendStrBuf(c);
continue;
}
}
}
doctypenameloop_end:;
[[fallthrough]];
}
case AFTER_DOCTYPE_NAME: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '>': {
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case 'p':
case 'P': {
index = 0;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_UBLIC, reconsume,
pos);
NS_HTML5_BREAK(afterdoctypenameloop);
}
case 's':
case 'S': {
index = 0;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_YSTEM, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
default: {
bogusDoctype();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
afterdoctypenameloop_end:;
[[fallthrough]];
}
case DOCTYPE_UBLIC: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
if (index < 5) {
char16_t folded = c;
if (c >= 'A' && c <= 'Z') {
folded += 0x20;
}
if (folded != nsHtml5Tokenizer::UBLIC[index]) {
bogusDoctype();
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
index++;
continue;
} else {
reconsume = true;
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD, reconsume, pos);
NS_HTML5_BREAK(doctypeublicloop);
}
}
doctypeublicloop_end:;
[[fallthrough]];
}
case AFTER_DOCTYPE_PUBLIC_KEYWORD: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
pos);
NS_HTML5_BREAK(afterdoctypepublickeywordloop);
}
case '\"': {
if (P::reportErrors) {
errNoSpaceBetweenDoctypePublicKeywordAndQuote();
}
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\'': {
if (P::reportErrors) {
errNoSpaceBetweenDoctypePublicKeywordAndQuote();
}
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errExpectedPublicId();
}
forceQuirks = true;
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
bogusDoctype();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
afterdoctypepublickeywordloop_end:;
[[fallthrough]];
}
case BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '\"': {
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED,
reconsume, pos);
NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
}
case '\'': {
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errExpectedPublicId();
}
forceQuirks = true;
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
bogusDoctype();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
beforedoctypepublicidentifierloop_end:;
[[fallthrough]];
}
case DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\"': {
publicIdentifier = strBufToString();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
pos);
NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
}
case '>': {
if (P::reportErrors) {
errGtInPublicId();
}
forceQuirks = true;
publicIdentifier = strBufToString();
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
continue;
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
doctypepublicidentifierdoublequotedloop_end:;
[[fallthrough]];
}
case AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::
BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
reconsume, pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::
BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS,
reconsume, pos);
NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
}
case '>': {
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\"': {
if (P::reportErrors) {
errNoSpaceBetweenPublicAndSystemIds();
}
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\'': {
if (P::reportErrors) {
errNoSpaceBetweenPublicAndSystemIds();
}
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
default: {
bogusDoctype();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
afterdoctypepublicidentifierloop_end:;
[[fallthrough]];
}
case BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '>': {
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\"': {
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
reconsume, pos);
NS_HTML5_BREAK(betweendoctypepublicandsystemidentifiersloop);
}
case '\'': {
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
default: {
bogusDoctype();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
betweendoctypepublicandsystemidentifiersloop_end:;
[[fallthrough]];
}
case DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\"': {
systemIdentifier = strBufToString();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
pos);
NS_HTML5_BREAK(doctypesystemidentifierdoublequotedloop);
}
case '>': {
if (P::reportErrors) {
errGtInSystemId();
}
forceQuirks = true;
systemIdentifier = strBufToString();
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
continue;
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
doctypesystemidentifierdoublequotedloop_end:;
[[fallthrough]];
}
case AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '>': {
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
bogusDoctypeWithoutQuirks();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_BREAK(afterdoctypesystemidentifierloop);
}
}
}
afterdoctypesystemidentifierloop_end:;
[[fallthrough]];
}
case BOGUS_DOCTYPE: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '>': {
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
default: {
continue;
}
}
}
}
case DOCTYPE_YSTEM: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
if (index < 5) {
char16_t folded = c;
if (c >= 'A' && c <= 'Z') {
folded += 0x20;
}
if (folded != nsHtml5Tokenizer::YSTEM[index]) {
bogusDoctype();
reconsume = true;
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
index++;
NS_HTML5_CONTINUE(stateloop);
} else {
reconsume = true;
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD, reconsume, pos);
NS_HTML5_BREAK(doctypeystemloop);
}
}
doctypeystemloop_end:;
[[fallthrough]];
}
case AFTER_DOCTYPE_SYSTEM_KEYWORD: {
for (;;) {
if (reconsume) {
reconsume = false;
} else {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
}
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
pos);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
pos);
NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
}
case '\"': {
if (P::reportErrors) {
errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
}
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\'': {
if (P::reportErrors) {
errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
}
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errExpectedPublicId();
}
forceQuirks = true;
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
bogusDoctype();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
afterdoctypesystemkeywordloop_end:;
[[fallthrough]];
}
case BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\r': {
P::silentCarriageReturn(this);
NS_HTML5_BREAK(stateloop);
}
case '\n': {
P::silentLineFeed(this);
[[fallthrough]];
}
case ' ':
case '\t':
case '\f': {
continue;
}
case '\"': {
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
case '\'': {
clearStrBufBeforeUse();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED,
reconsume, pos);
NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
}
case '>': {
if (P::reportErrors) {
errExpectedSystemId();
}
forceQuirks = true;
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
bogusDoctype();
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::BOGUS_DOCTYPE, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
beforedoctypesystemidentifierloop_end:;
[[fallthrough]];
}
case DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\'': {
systemIdentifier = strBufToString();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errGtInSystemId();
}
forceQuirks = true;
systemIdentifier = strBufToString();
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
continue;
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
}
case DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\'': {
publicIdentifier = strBufToString();
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume,
pos);
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (P::reportErrors) {
errGtInPublicId();
}
forceQuirks = true;
publicIdentifier = strBufToString();
emitDoctypeToken(pos);
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
case '\r': {
appendStrBufCarriageReturn<P>();
NS_HTML5_BREAK(stateloop);
}
case '\n': {
appendStrBufLineFeed<P>();
continue;
}
case '\0': {
c = 0xfffd;
[[fallthrough]];
}
default: {
appendStrBuf(c);
continue;
}
}
}
}
case PROCESSING_INSTRUCTION: {
for (;;) {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '\?': {
state = P::transition(
mViewSource.get(),
nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK,
reconsume, pos);
NS_HTML5_BREAK(processinginstructionloop);
}
default: {
continue;
}
}
}
processinginstructionloop_end:;
[[fallthrough]];
}
case PROCESSING_INSTRUCTION_QUESTION_MARK: {
if (++pos == endPos) {
NS_HTML5_BREAK(stateloop);
}
c = P::checkChar(this, buf, pos);
switch (c) {
case '>': {
state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
reconsume, pos);
suspendIfRequestedAfterCurrentNonTextToken();
if (shouldSuspend) {
NS_HTML5_BREAK(stateloop);
}
NS_HTML5_CONTINUE(stateloop);
}
default: {
state = P::transition(mViewSource.get(),
nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
}
stateloop_end:;
flushChars(buf, pos);
stateSave = state;
returnStateSave = returnState;
return pos;
}