/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Don't call StartBodyContents here in order to be able to put it in a // speculation.
mOpQueue.AppendElement()->Init(mozilla::AsVariant(opStartLayout()));
}
int32_t nsHtml5Highlighter::Transition(int32_t aState, bool aReconsume,
int32_t aPos) {
mPos = aPos; switch (mState) { case nsHtml5Tokenizer::SCRIPT_DATA: case nsHtml5Tokenizer::RAWTEXT: case nsHtml5Tokenizer::RCDATA: case nsHtml5Tokenizer::DATA: // We can transition on < and on &. Either way, we don't yet know the // role of the token, so open a span without class. if (aState == nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE) {
StartSpan(); // Start another span for highlighting the ampersand
StartSpan();
mAmpersand = CurrentNode();
} else {
EndCharactersAndStartMarkupRun();
} break; case nsHtml5Tokenizer::TAG_OPEN: switch (aState) { case nsHtml5Tokenizer::TAG_NAME:
StartSpan(u"start-tag"); break; case nsHtml5Tokenizer::DATA:
FinishTag(); // DATA break; case nsHtml5Tokenizer::PROCESSING_INSTRUCTION:
AddClass(u"pi"); break;
} break; case nsHtml5Tokenizer::TAG_NAME: switch (aState) { case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
EndSpanOrA(); // nsHtml5Tokenizer::TAG_NAME break; case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
EndSpanOrA(); // nsHtml5Tokenizer::TAG_NAME
StartSpan(); // for highlighting the slash
mSlash = CurrentNode(); break; default:
FinishTag(); break;
} break; case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME: switch (aState) { case nsHtml5Tokenizer::ATTRIBUTE_NAME:
StartSpan(u"attribute-name"); break; case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
mSlash = CurrentNode(); break; default:
FinishTag(); break;
} break; case nsHtml5Tokenizer::ATTRIBUTE_NAME: switch (aState) { case nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME: case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE:
EndSpanOrA(); // nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME break; case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
EndSpanOrA(); // nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
StartSpan(); // for highlighting the slash
mSlash = CurrentNode(); break; default:
FinishTag(); break;
} break; case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE: switch (aState) { case nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED: case nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED:
FlushCurrent();
StartA(); break; case nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED:
StartA(); break; default:
FinishTag(); break;
} break; case nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED: case nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED: switch (aState) { case nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED:
EndSpanOrA(); break; case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE:
StartSpan();
StartSpan(); // for ampersand itself
mAmpersand = CurrentNode(); break; default:
MOZ_ASSERT_UNREACHABLE("Impossible transition."); break;
} break; case nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED: switch (aState) { case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME: break; case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
mSlash = CurrentNode(); break; default:
FinishTag(); break;
} break; case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
EndSpanOrA(); // end the slash highlight switch (aState) { case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME: break; default:
FinishTag(); break;
} break; case nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED: switch (aState) { case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
EndSpanOrA(); break; case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE:
StartSpan();
StartSpan(); // for ampersand itself
mAmpersand = CurrentNode(); break; default:
FinishTag(); break;
} break; case nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME: switch (aState) { case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
mSlash = CurrentNode(); break; case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE: break; case nsHtml5Tokenizer::ATTRIBUTE_NAME:
StartSpan(u"attribute-name"); break; default:
FinishTag(); break;
} break; // most comment states are omitted, because they don't matter to // highlighting case nsHtml5Tokenizer::COMMENT_START: case nsHtml5Tokenizer::BOGUS_COMMENT:
AddClass(u"comment");
[[fallthrough]]; case nsHtml5Tokenizer::COMMENT_END: case nsHtml5Tokenizer::COMMENT_END_BANG: case nsHtml5Tokenizer::COMMENT_START_DASH: case nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN: case nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH: if (aState == nsHtml5Tokenizer::DATA) {
FinishTag();
} break; // most cdata states are omitted, because they don't matter to // highlighting case nsHtml5Tokenizer::CDATA_RSQB_RSQB: if (aState == nsHtml5Tokenizer::DATA) {
AddClass(u"cdata");
FinishTag();
} break; case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE:
EndSpanOrA(); // the span for the ampersand switch (aState) { case nsHtml5Tokenizer::CONSUME_NCR: case nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP: break; default: // not actually a character reference
EndSpanOrA(); break;
} break; case nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP: if (aState == nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL) { break;
} // not actually a character reference
EndSpanOrA(); break; case nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL: if (!aReconsume) {
FlushCurrent();
}
EndSpanOrA(); break; case nsHtml5Tokenizer::DECIMAL_NRC_LOOP: case nsHtml5Tokenizer::HEX_NCR_LOOP: switch (aState) { case nsHtml5Tokenizer::HANDLE_NCR_VALUE:
AddClass(u"entity");
FlushCurrent(); break; case nsHtml5Tokenizer::HANDLE_NCR_VALUE_RECONSUME:
AddClass(u"entity"); break;
}
EndSpanOrA(); break; case nsHtml5Tokenizer::CLOSE_TAG_OPEN: switch (aState) { case nsHtml5Tokenizer::DATA:
FinishTag(); break; case nsHtml5Tokenizer::TAG_NAME:
StartSpan(u"end-tag"); break;
} break; case nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN: if (aState == nsHtml5Tokenizer::NON_DATA_END_TAG_NAME) {
FlushCurrent();
StartSpan(); // don't know if it is "end-tag" yet :-( break;
}
EndSpanOrA();
StartCharacters(); break; case nsHtml5Tokenizer::NON_DATA_END_TAG_NAME: switch (aState) { case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
AddClass(u"end-tag");
EndSpanOrA(); break; case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
AddClass(u"end-tag");
EndSpanOrA();
StartSpan(); // for highlighting the slash
mSlash = CurrentNode(); break; case nsHtml5Tokenizer::DATA: // yes, as a result of emitting the token
AddClass(u"end-tag");
FinishTag(); break; default:
FinishTag(); break;
} break; case nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN: case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: if (aState == nsHtml5Tokenizer::NON_DATA_END_TAG_NAME) {
FlushCurrent();
StartSpan(); // don't know if it is "end-tag" yet :-( break;
}
FinishTag(); break; case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH: case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED: case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH: if (aState == nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN) {
EndCharactersAndStartMarkupRun();
} break; // Lots of double escape states omitted, because they don't highlight. // Likewise, only doctype states that can emit the doctype are of // interest. Otherwise, the transition out of bogus comment deals. case nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME: case nsHtml5Tokenizer::DOCTYPE_NAME: case nsHtml5Tokenizer::AFTER_DOCTYPE_NAME: case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD: case nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER: case nsHtml5Tokenizer::BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER: case nsHtml5Tokenizer::BOGUS_DOCTYPE: case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD: case nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: if (aState == nsHtml5Tokenizer::DATA) {
AddClass(u"doctype");
FinishTag();
} break; case nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK: if (aState == nsHtml5Tokenizer::DATA) {
FinishTag();
} break; default: break;
}
mState = aState; return aState;
}
[[nodiscard]] bool nsHtml5Highlighter::End() { switch (mState) { case nsHtml5Tokenizer::COMMENT_END: case nsHtml5Tokenizer::COMMENT_END_BANG: case nsHtml5Tokenizer::COMMENT_START_DASH: case nsHtml5Tokenizer::BOGUS_COMMENT: case nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN:
AddClass(u"comment"); break; case nsHtml5Tokenizer::CDATA_RSQB_RSQB:
AddClass(u"cdata"); break; case nsHtml5Tokenizer::DECIMAL_NRC_LOOP: case nsHtml5Tokenizer::HEX_NCR_LOOP: // XXX need tokenizer help here break; case nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME: case nsHtml5Tokenizer::DOCTYPE_NAME: case nsHtml5Tokenizer::AFTER_DOCTYPE_NAME: case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD: case nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER: case nsHtml5Tokenizer::BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER: case nsHtml5Tokenizer::BOGUS_DOCTYPE: case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD: case nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
AddClass(u"doctype"); break; default: break;
}
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mozilla::AsVariant(opStreamEnded())); return FlushOps().isOk();
}
void nsHtml5Highlighter::FinishTag() { while (mInlinesOpen > 1) {
EndSpanOrA();
}
FlushCurrent(); // >
EndSpanOrA(); // DATA
NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
StartCharacters();
}
void nsHtml5Highlighter::FlushChars() { if (mCStart < mPos) {
char16_t* buf = mBuffer->getBuffer();
int32_t i = mCStart; while (i < mPos) {
char16_t c = buf[i]; switch (c) { case'\r': // The input this code sees has been normalized so that there are // CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF // to show consistent LF line breaks to layout. It is OK to mutate // the input data, because there are no reparses in the View Source // case, so we won't need the original data in the buffer anymore.
buf[i] = '\n';
[[fallthrough]]; case'\n': {
++i; if (mCStart < i) {
int32_t len = i - mCStart;
AppendCharacters(buf, mCStart, len);
mCStart = i;
}
NewLine(); break;
} default:
++i; break;
}
} if (mCStart < mPos) {
int32_t len = mPos - mCStart;
AppendCharacters(buf, mCStart, len);
mCStart = mPos;
}
}
}
bool nsHtml5Highlighter::ShouldFlushOps() { // Arbitrary threshold that doesn't have an exact justification. // The general idea is to flush much, much sooner than reaching // the maximum size of `nsTArray`. return mOpQueue.Length() > 100000;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.