diff --git a/parser/html/javasrc/TreeBuilder.java b/parser/html/javasrc/TreeBuilder.java
index 32973e535d4d..3db2c69aef44 100644
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -868,6 +868,8 @@ public abstract class TreeBuilder implements TokenHandler,
*/
public final void characters(@Const @NoLength char[] buf, int start, int length)
throws SAXException {
+ // Note: Can't attach error messages to EOF in C++ yet
+
// CPPONLY: if (tokenizer.isViewingXmlSource()) {
// CPPONLY: return;
// CPPONLY: }
@@ -1271,6 +1273,7 @@ public abstract class TreeBuilder implements TokenHandler,
public final void eof() throws SAXException {
flushCharacters();
+ // Note: Can't attach error messages to EOF in C++ yet
eofloop: for (;;) {
if (isInForeign()) {
// [NOCPP[
diff --git a/parser/html/nsHtml5Highlighter.cpp b/parser/html/nsHtml5Highlighter.cpp
index 7e1f3102c378..68832fdc3153 100644
--- a/parser/html/nsHtml5Highlighter.cpp
+++ b/parser/html/nsHtml5Highlighter.cpp
@@ -205,10 +205,10 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
case NS_HTML5TOKENIZER_TAG_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
- EndInline(); // NS_HTML5TOKENIZER_TAG_NAME
+ EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
- EndInline(); // NS_HTML5TOKENIZER_TAG_NAME
+ EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
@@ -235,10 +235,10 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
switch (aState) {
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
- EndInline(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
+ EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
- EndInline(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
+ EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
@@ -266,7 +266,7 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
switch (aState) {
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
- EndInline();
+ EndSpanOrA();
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
StartSpan();
@@ -292,7 +292,7 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
}
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
- EndInline(); // end the slash highlight
+ EndSpanOrA(); // end the slash highlight
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
break;
@@ -304,7 +304,7 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
- EndInline();
+ EndSpanOrA();
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
StartSpan();
@@ -353,14 +353,14 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
}
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
- EndInline(); // the span for the ampersand
+ EndSpanOrA(); // the span for the ampersand
switch (aState) {
case NS_HTML5TOKENIZER_CONSUME_NCR:
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
break;
default:
// not actually a character reference
- EndInline();
+ EndSpanOrA();
break;
}
break;
@@ -369,13 +369,13 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
break;
}
// not actually a character reference
- EndInline();
+ EndSpanOrA();
break;
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL:
if (!aReconsume) {
FlushCurrent();
}
- EndInline();
+ EndSpanOrA();
break;
case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
@@ -388,7 +388,7 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
AddClass(sEntity);
break;
}
- EndInline();
+ EndSpanOrA();
break;
case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN:
switch (aState) {
@@ -406,18 +406,18 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
StartSpan(); // don't know if it is "end-tag" yet :-(
break;
}
- EndInline();
+ EndSpanOrA();
StartCharacters();
break;
case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
AddClass(sEndTag);
- EndInline();
+ EndSpanOrA();
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
AddClass(sEndTag);
- EndInline();
+ EndSpanOrA();
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
@@ -557,7 +557,7 @@ nsHtml5Highlighter::StartSpan(const PRUnichar* aClass)
}
void
-nsHtml5Highlighter::EndInline()
+nsHtml5Highlighter::EndSpanOrA()
{
FlushChars();
Pop();
@@ -596,10 +596,10 @@ void
nsHtml5Highlighter::FinishTag()
{
while (mInlinesOpen > 1) {
- EndInline();
+ EndSpanOrA();
}
FlushCurrent(); // >
- EndInline(); // DATA
+ EndSpanOrA(); // DATA
NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
StartCharacters();
}
@@ -685,14 +685,14 @@ void
nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsString* aValue)
{
- if (!(nsHtml5AttributeName::ATTR_HREF == aName
- || nsHtml5AttributeName::ATTR_SRC == aName
- || nsHtml5AttributeName::ATTR_ACTION == aName
- || nsHtml5AttributeName::ATTR_CITE == aName
- || nsHtml5AttributeName::ATTR_BACKGROUND == aName
- || nsHtml5AttributeName::ATTR_LONGDESC == aName
- || nsHtml5AttributeName::ATTR_XLINK_HREF == aName
- || nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
+ if (!(nsHtml5AttributeName::ATTR_HREF == aName ||
+ nsHtml5AttributeName::ATTR_SRC == aName ||
+ nsHtml5AttributeName::ATTR_ACTION == aName ||
+ nsHtml5AttributeName::ATTR_CITE == aName ||
+ nsHtml5AttributeName::ATTR_BACKGROUND == aName ||
+ nsHtml5AttributeName::ATTR_LONGDESC == aName ||
+ nsHtml5AttributeName::ATTR_XLINK_HREF == aName ||
+ nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
return;
}
AddViewSourceHref(*aValue);
diff --git a/parser/html/nsHtml5Highlighter.h b/parser/html/nsHtml5Highlighter.h
index 3def948c9d5d..b2b06b22e245 100644
--- a/parser/html/nsHtml5Highlighter.h
+++ b/parser/html/nsHtml5Highlighter.h
@@ -192,9 +192,9 @@ class nsHtml5Highlighter
void StartSpan(const PRUnichar* aClass);
/**
- * End the current or .
+ * End the current or in the highlighter output.
*/
- void EndInline();
+ void EndSpanOrA();
/**
* Starts a wrapper around a run of characters.
@@ -222,8 +222,10 @@ class nsHtml5Highlighter
void FlushCurrent();
/**
- * Finishes a source tag being highlighted by closing the open and
- * elements.
+ * Finishes highlighting a tag in the input data by closing the open
+ * and elements in the highlighter output and then starts
+ * another for potentially highlighting characters potentially
+ * appearing next.
*/
void FinishTag();
@@ -238,6 +240,9 @@ class nsHtml5Highlighter
/**
* Allocates a handle for an element.
*
+ * See the documentation for nsHtml5TreeBuilder::AllocateContentHandle()
+ * in nsHtml5TreeBuilderHSupplement.h.
+ *
* @return the handle
*/
nsIContent** AllocateContentHandle();
diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp
index f91fa98c4788..6b569f5b27a8 100644
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -516,6 +516,14 @@ nsHtml5StreamParser::FinalizeSniffing(const PRUint8* aFromSegment, // can be nul
XML_SetUserData(ud.mExpat, static_cast(&ud));
XML_Status status = XML_STATUS_OK;
+
+ // aFromSegment points to the data obtained from the current network
+ // event. mSniffingBuffer (if it exists) contains the data obtained before
+ // the current event. Thus, mSniffingLenth bytes of mSniffingBuffer
+ // followed by aCountToSniffingLimit bytes from aFromSegment are the
+ // first 1024 bytes of the file (or the file as a whole if the file is
+ // 1024 bytes long or shorter). Thus, we parse both buffers, but if the
+ // first call succeeds already, we skip parsing the second buffer.
if (mSniffingBuffer) {
status = XML_Parse(ud.mExpat,
reinterpret_cast(mSniffingBuffer.get()),
@@ -682,8 +690,8 @@ nsHtml5StreamParser::SniffStreamBytes(const PRUint8* aFromSegment,
PRUint32 countToSniffingLimit =
NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML) {
- nsHtml5ByteReadable readable(aFromSegment, aFromSegment
- + countToSniffingLimit);
+ nsHtml5ByteReadable readable(aFromSegment, aFromSegment +
+ countToSniffingLimit);
mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
if (mUnicodeDecoder) {
mUnicodeDecoder->SetInputErrorBehavior(
diff --git a/parser/html/nsHtml5Tokenizer.cpp b/parser/html/nsHtml5Tokenizer.cpp
index 6d120c94b69b..28428e320bcd 100644
--- a/parser/html/nsHtml5Tokenizer.cpp
+++ b/parser/html/nsHtml5Tokenizer.cpp
@@ -496,7 +496,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
state = P::transition(mViewSource, NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
}
- if (P::viewingSource) {
+ if (P::reportErrors) {
errProcessingInstruction();
}
clearLongStrBufAndAppend(c);
@@ -504,7 +504,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errLtGt();
}
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
@@ -513,7 +513,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
default: {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errBadCharAfterLt(c);
}
tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
@@ -617,7 +617,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
case '\'':
case '<':
case '=': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errBadCharBeforeAttributeNameOrNull(c);
}
}
@@ -682,7 +682,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
case '\"':
case '\'':
case '<': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errQuoteOrLtInAttributeNameOrNull(c);
}
}
@@ -734,7 +734,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errAttributeValueMissing();
}
addAttributeWithoutValue();
@@ -750,7 +750,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
case '<':
case '=':
case '`': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
}
}
@@ -839,7 +839,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
default: {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoSpaceBetweenAttributes();
}
state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
@@ -864,7 +864,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
default: {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errSlashNotFollowedByGt();
}
state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
@@ -923,7 +923,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
case '\'':
case '=':
case '`': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errUnquotedAttributeValOrNull(c);
}
}
@@ -977,7 +977,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
case '\"':
case '\'':
case '<': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errQuoteOrLtInAttributeNameOrNull(c);
}
}
@@ -1021,7 +1021,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
}
default: {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errBogusComment();
}
clearLongStrBuf();
@@ -1049,7 +1049,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_BREAK(markupdeclarationhyphenloop);
}
default: {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errBogusComment();
}
state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
@@ -1073,7 +1073,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errPrematureEndOfComment();
}
emitComment(0, pos);
@@ -1194,7 +1194,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '!': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errHyphenHyphenBang();
}
appendLongStrBuf(c);
@@ -1261,7 +1261,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errPrematureEndOfComment();
}
emitComment(1, pos);
@@ -1298,7 +1298,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
appendLongStrBuf(c);
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errBogusComment();
}
state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
@@ -1474,7 +1474,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
} else if (c >= 'A' && c <= 'Z') {
firstCharKey = c - 'A';
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoNamedCharacterMatch();
}
emitOrAppendStrBuf(returnState);
@@ -1507,7 +1507,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
}
if (!hilo) {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoNamedCharacterMatch();
}
emitOrAppendStrBuf(returnState);
@@ -1578,7 +1578,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
outer_end: ;
if (candidate == -1) {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoNamedCharacterMatch();
}
emitOrAppendStrBuf(returnState);
@@ -1599,7 +1599,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
ch = strBuf[strBufMark];
}
if (ch == '=' || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoNamedCharacterMatch();
}
appendStrBufToLongStrBuf();
@@ -1609,11 +1609,11 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
}
if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errUnescapedAmpersandInterpretedAsCharacterReference();
}
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNotSemicolonTerminated();
}
}
@@ -1690,7 +1690,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
NS_HTML5_BREAK(decimalloop);
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoDigitsInNCR();
}
appendStrBuf(';');
@@ -1703,7 +1703,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
} else {
if (!seenDigits) {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoDigitsInNCR();
}
emitOrAppendStrBuf(returnState);
@@ -1714,7 +1714,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
reconsume = true;
NS_HTML5_CONTINUE(stateloop);
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errCharRefLacksSemicolon();
}
if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
@@ -1766,7 +1766,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoDigitsInNCR();
}
appendStrBuf(';');
@@ -1779,7 +1779,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
} else {
if (!seenDigits) {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoDigitsInNCR();
}
emitOrAppendStrBuf(returnState);
@@ -1790,7 +1790,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
reconsume = true;
NS_HTML5_CONTINUE(stateloop);
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errCharRefLacksSemicolon();
}
if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
@@ -1839,7 +1839,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
c = checkChar(buf, pos);
switch(c) {
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errLtSlashGt();
}
cstart = pos + 1;
@@ -1848,7 +1848,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
case '\r': {
silentCarriageReturn();
- if (P::viewingSource) {
+ if (P::reportErrors) {
errGarbageAfterLtSlash();
}
clearLongStrBufAndAppend('\n');
@@ -1857,7 +1857,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
case '\n': {
silentLineFeed();
- if (P::viewingSource) {
+ if (P::reportErrors) {
errGarbageAfterLtSlash();
}
clearLongStrBufAndAppend('\n');
@@ -1877,7 +1877,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
state = P::transition(mViewSource, NS_HTML5TOKENIZER_TAG_NAME, reconsume, pos);
NS_HTML5_CONTINUE(stateloop);
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errGarbageAfterLtSlash();
}
clearLongStrBufAndAppend(c);
@@ -2625,7 +2625,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
appendLongStrBuf(c);
} else {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errBogusComment();
}
state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
@@ -2669,7 +2669,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_BREAK(doctypeloop);
}
default: {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errMissingSpaceBeforeDoctypeName();
}
state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME, reconsume, pos);
@@ -2704,7 +2704,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
continue;
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNamelessDoctype();
}
forceQuirks = true;
@@ -2868,7 +2868,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_BREAK(afterdoctypepublickeywordloop);
}
case '\"': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoSpaceBetweenDoctypePublicKeywordAndQuote();
}
clearLongStrBuf();
@@ -2876,7 +2876,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '\'': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoSpaceBetweenDoctypePublicKeywordAndQuote();
}
clearLongStrBuf();
@@ -2884,7 +2884,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errExpectedPublicId();
}
forceQuirks = true;
@@ -2931,7 +2931,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errExpectedPublicId();
}
forceQuirks = true;
@@ -2961,7 +2961,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errGtInPublicId();
}
forceQuirks = true;
@@ -3016,7 +3016,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '\"': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoSpaceBetweenPublicAndSystemIds();
}
clearLongStrBuf();
@@ -3024,7 +3024,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '\'': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoSpaceBetweenPublicAndSystemIds();
}
clearLongStrBuf();
@@ -3096,7 +3096,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errGtInSystemId();
}
forceQuirks = true;
@@ -3239,7 +3239,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
}
case '\"': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
}
clearLongStrBuf();
@@ -3247,7 +3247,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '\'': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
}
clearLongStrBuf();
@@ -3255,7 +3255,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errExpectedPublicId();
}
forceQuirks = true;
@@ -3302,7 +3302,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errExpectedSystemId();
}
forceQuirks = true;
@@ -3332,7 +3332,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errGtInSystemId();
}
forceQuirks = true;
@@ -3372,7 +3372,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
- if (P::viewingSource) {
+ if (P::reportErrors) {
errGtInPublicId();
}
forceQuirks = true;
diff --git a/parser/html/nsHtml5TokenizerCppSupplement.h b/parser/html/nsHtml5TokenizerCppSupplement.h
index e62481b38566..9b71c6db2bfe 100644
--- a/parser/html/nsHtml5TokenizerCppSupplement.h
+++ b/parser/html/nsHtml5TokenizerCppSupplement.h
@@ -64,67 +64,79 @@ nsHtml5Tokenizer::errWarnLtSlashInRcdata()
{
}
+// The null checks below annotated NS_LIKELY are not actually necessary.
+
void
nsHtml5Tokenizer::errUnquotedAttributeValOrNull(PRUnichar c)
{
- switch (c) {
- case '<':
- mViewSource->AddErrorToCurrentNode("errUnquotedAttributeLt");
- return;
- case '`':
- mViewSource->AddErrorToCurrentNode("errUnquotedAttributeGrave");
- return;
- case '\'':
- case '"':
- mViewSource->AddErrorToCurrentNode("errUnquotedAttributeQuote");
- return;
- case '=':
- mViewSource->AddErrorToCurrentNode("errUnquotedAttributeEquals");
- return;
+ if (NS_LIKELY(mViewSource)) {
+ switch (c) {
+ case '<':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeLt");
+ return;
+ case '`':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeGrave");
+ return;
+ case '\'':
+ case '"':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeQuote");
+ return;
+ case '=':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeEquals");
+ return;
+ }
}
}
void
nsHtml5Tokenizer::errLtOrEqualsOrGraveInUnquotedAttributeOrNull(PRUnichar c)
{
- switch (c) {
- case '=':
- mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartEquals");
- return;
- case '<':
- mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartLt");
- return;
- case '`':
- mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartGrave");
- return;
+ if (NS_LIKELY(mViewSource)) {
+ switch (c) {
+ case '=':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartEquals");
+ return;
+ case '<':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartLt");
+ return;
+ case '`':
+ mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartGrave");
+ return;
+ }
}
}
void
nsHtml5Tokenizer::errBadCharBeforeAttributeNameOrNull(PRUnichar c)
{
- if (c == '<') {
- mViewSource->AddErrorToCurrentNode("errBadCharBeforeAttributeNameLt");
- } else if (c == '=') {
- errEqualsSignBeforeAttributeName();
- } else if (c != 0xFFFD) {
- errQuoteBeforeAttributeName(c);
+ if (NS_LIKELY(mViewSource)) {
+ if (c == '<') {
+ mViewSource->AddErrorToCurrentNode("errBadCharBeforeAttributeNameLt");
+ } else if (c == '=') {
+ errEqualsSignBeforeAttributeName();
+ } else if (c != 0xFFFD) {
+ errQuoteBeforeAttributeName(c);
+ }
}
}
void
nsHtml5Tokenizer::errBadCharAfterLt(PRUnichar c)
{
- mViewSource->AddErrorToCurrentNode("errBadCharAfterLt");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errBadCharAfterLt");
+ }
}
void
nsHtml5Tokenizer::errQuoteOrLtInAttributeNameOrNull(PRUnichar c)
{
- if (c == '<') {
- mViewSource->AddErrorToCurrentNode("errLtInAttributeName");
- } else if (c != 0xFFFD) {
- mViewSource->AddErrorToCurrentNode("errQuoteInAttributeName");
+ if (NS_LIKELY(mViewSource)) {
+ if (c == '<') {
+ mViewSource->AddErrorToCurrentNode("errLtInAttributeName");
+ } else if (c != 0xFFFD) {
+ mViewSource->AddErrorToCurrentNode("errQuoteInAttributeName");
+ }
}
}
@@ -177,13 +189,17 @@ nsHtml5Tokenizer::errNcrControlChar(PRUnichar ch)
void
nsHtml5Tokenizer::errGarbageAfterLtSlash()
{
- mViewSource->AddErrorToCurrentNode("errGarbageAfterLtSlash");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errGarbageAfterLtSlash");
+ }
}
void
nsHtml5Tokenizer::errLtSlashGt()
{
- mViewSource->AddErrorToCurrentNode("errLtSlashGt");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errLtSlashGt");
+ }
}
void
@@ -205,19 +221,25 @@ nsHtml5Tokenizer::errNoDigitsInNCR()
void
nsHtml5Tokenizer::errGtInSystemId()
{
- mViewSource->AddErrorToCurrentNode("errGtInSystemId");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errGtInSystemId");
+ }
}
void
nsHtml5Tokenizer::errGtInPublicId()
{
- mViewSource->AddErrorToCurrentNode("errGtInPublicId");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errGtInPublicId");
+ }
}
void
nsHtml5Tokenizer::errNamelessDoctype()
{
- mViewSource->AddErrorToCurrentNode("errNamelessDoctype");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNamelessDoctype");
+ }
}
void
@@ -231,7 +253,9 @@ nsHtml5Tokenizer::errConsecutiveHyphens()
void
nsHtml5Tokenizer::errPrematureEndOfComment()
{
- mViewSource->AddErrorToCurrentNode("errPrematureEndOfComment");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errPrematureEndOfComment");
+ }
}
void
@@ -245,37 +269,49 @@ nsHtml5Tokenizer::errBogusComment()
void
nsHtml5Tokenizer::errSlashNotFollowedByGt()
{
- mViewSource->AddErrorToCurrentSlash("errSlashNotFollowedByGt");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentSlash("errSlashNotFollowedByGt");
+ }
}
void
nsHtml5Tokenizer::errNoSpaceBetweenAttributes()
{
- mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenAttributes");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenAttributes");
+ }
}
void
nsHtml5Tokenizer::errAttributeValueMissing()
{
- mViewSource->AddErrorToCurrentNode("errAttributeValueMissing");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errAttributeValueMissing");
+ }
}
void
nsHtml5Tokenizer::errEqualsSignBeforeAttributeName()
{
- mViewSource->AddErrorToCurrentNode("errEqualsSignBeforeAttributeName");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errEqualsSignBeforeAttributeName");
+ }
}
void
nsHtml5Tokenizer::errLtGt()
{
- mViewSource->AddErrorToCurrentNode("errLtGt");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errLtGt");
+ }
}
void
nsHtml5Tokenizer::errProcessingInstruction()
{
- mViewSource->AddErrorToCurrentNode("errProcessingInstruction");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errProcessingInstruction");
+ }
}
void
@@ -305,13 +341,17 @@ nsHtml5Tokenizer::errNoNamedCharacterMatch()
void
nsHtml5Tokenizer::errQuoteBeforeAttributeName(PRUnichar c)
{
- mViewSource->AddErrorToCurrentNode("errQuoteBeforeAttributeName");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errQuoteBeforeAttributeName");
+ }
}
void
nsHtml5Tokenizer::errExpectedPublicId()
{
- mViewSource->AddErrorToCurrentNode("errExpectedPublicId");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errExpectedPublicId");
+ }
}
void
@@ -453,19 +493,25 @@ nsHtml5Tokenizer::errEofInSystemId()
void
nsHtml5Tokenizer::errExpectedSystemId()
{
- mViewSource->AddErrorToCurrentNode("errExpectedSystemId");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errExpectedSystemId");
+ }
}
void
nsHtml5Tokenizer::errMissingSpaceBeforeDoctypeName()
{
- mViewSource->AddErrorToCurrentNode("errMissingSpaceBeforeDoctypeName");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errMissingSpaceBeforeDoctypeName");
+ }
}
void
nsHtml5Tokenizer::errHyphenHyphenBang()
{
- mViewSource->AddErrorToCurrentNode("errHyphenHyphenBang");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errHyphenHyphenBang");
+ }
}
void
@@ -487,17 +533,23 @@ nsHtml5Tokenizer::errNcrZero()
void
nsHtml5Tokenizer::errNoSpaceBetweenDoctypeSystemKeywordAndQuote()
{
- mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypeSystemKeywordAndQuote");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypeSystemKeywordAndQuote");
+ }
}
void
nsHtml5Tokenizer::errNoSpaceBetweenPublicAndSystemIds()
{
- mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenPublicAndSystemIds");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenPublicAndSystemIds");
+ }
}
void
nsHtml5Tokenizer::errNoSpaceBetweenDoctypePublicKeywordAndQuote()
{
- mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypePublicKeywordAndQuote");
+ if (NS_LIKELY(mViewSource)) {
+ mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypePublicKeywordAndQuote");
+ }
}
diff --git a/parser/html/nsHtml5TokenizerLoopPolicies.h b/parser/html/nsHtml5TokenizerLoopPolicies.h
index b098029216f2..70fae2fa396b 100644
--- a/parser/html/nsHtml5TokenizerLoopPolicies.h
+++ b/parser/html/nsHtml5TokenizerLoopPolicies.h
@@ -38,9 +38,13 @@
#ifndef nsHtml5TokenizerLoopPolicies_h_
#define nsHtml5TokenizerLoopPolicies_h_
+/**
+ * This policy does not report tokenizer transitions anywhere. To be used
+ * when _not_ viewing source.
+ */
struct nsHtml5SilentPolicy
{
- static const bool viewingSource = false;
+ static const bool reportErrors = false;
static PRInt32 transition(nsHtml5Highlighter* aHighlighter,
PRInt32 aState,
bool aReconsume,
@@ -51,9 +55,13 @@ struct nsHtml5SilentPolicy
}
};
+/**
+ * This policy reports the tokenizer transitions to a highlighter. To be used
+ * when viewing source.
+ */
struct nsHtml5ViewSourcePolicy
{
- static const bool viewingSource = true;
+ static const bool reportErrors = true;
static PRInt32 transition(nsHtml5Highlighter* aHighlighter,
PRInt32 aState,
bool aReconsume,
diff --git a/parser/html/nsHtml5TreeBuilderHSupplement.h b/parser/html/nsHtml5TreeBuilderHSupplement.h
index c0b5501aa588..0614e7c61b4f 100644
--- a/parser/html/nsHtml5TreeBuilderHSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderHSupplement.h
@@ -58,6 +58,29 @@
*/
void documentMode(nsHtml5DocumentMode m);
+ /**
+ * Using nsIContent** instead of nsIContent* is the parser deals with DOM
+ * nodes in a way that works off the main thread. Non-main-thread code
+ * can't refcount or otherwise touch nsIContent objects in any way.
+ * Yet, the off-the-main-thread code needs to have a way to hold onto a
+ * particular node and repeatedly operate on the same node.
+ *
+ * The way this works is that the off-the-main-thread code has an
+ * nsIContent** for each DOM node and a given nsIContent** is only ever
+ * actually dereferenced into an actual nsIContent* on the main thread.
+ * When the off-the-main-thread code requests a new node, it gets an
+ * nsIContent** immediately and a tree op is enqueued for later allocating
+ * an actual nsIContent object and writing a pointer to it into the memory
+ * location pointed to by the nsIContent**.
+ *
+ * Since tree ops are in a queue, the node creating tree op will always
+ * run before tree ops that try to further operate on the node that the
+ * nsIContent** is a handle to.
+ *
+ * On-the-main-thread parts of the parser use the same mechanism in order
+ * to avoid having to have duplicate code paths for on-the-main-thread and
+ * off-the-main-thread tree builder instances.)
+ */
nsIContent** AllocateContentHandle();
void accumulateCharactersForced(const PRUnichar* aBuf, PRInt32 aStart, PRInt32 aLength)
diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp
index df3c0447473a..b85e960deab2 100644
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -905,6 +905,8 @@ nsHtml5TreeOpExecutor::GetViewSourceBaseURI()
NS_ASSERTION(nested, "URI with scheme view-source didn't QI to nested!");
nested->GetInnerURI(getter_AddRefs(mViewSourceBaseURI));
} else {
+ // Fail gracefully if the base URL isn't a view-source: URL.
+ // Not sure if this can ever happen.
mViewSourceBaseURI = orig;
}
}
diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp
index 8507159a1d96..bfae5c444a6b 100644
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -715,6 +715,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
nsIContent* node = *(mOne.node);
PRUnichar* str = mTwo.unicharPtr;
nsDependentString depStr(str);
+ // See viewsource.css for the possible classes
nsAutoString klass;
node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
if (!klass.IsEmpty()) {
@@ -760,8 +761,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
rv = NS_URIChainHasFlags(uri,
nsIProtocolHandler::URI_OPENING_EXECUTES_SCRIPT,
&openingExecutesScript);
- NS_ENSURE_SUCCESS(rv, NS_OK);
- if (openingExecutesScript) {
+ if (NS_FAILED(rv) || openingExecutesScript) {
return NS_OK;
}
@@ -795,6 +795,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
char* msgId = mTwo.charPtr;
nsCOMPtr atom = Reget(mThree.atom);
nsCOMPtr otherAtom = Reget(mFour.atom);
+ // See viewsource.css for the possible classes in addition to "error".
nsAutoString klass;
node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
if (!klass.IsEmpty()) {