Bug 482921 part 3 - Highlight tree builder-level errors in View Source. r=Olli.Pettay.

This commit is contained in:
Henri Sivonen 2011-11-01 13:33:11 +02:00
parent d55e46aa36
commit f55328bb86
12 changed files with 1368 additions and 399 deletions

View File

@ -39,6 +39,7 @@
# http://hg.mozilla.org/projects/htmlparser/file/1f633cef7de7/src/nu/validator/htmlparser/impl/ErrorReportingTokenizer.java
# which is available under the MIT license.
# Tokenizer errors
errGarbageAfterLtSlash=Garbage after \u201C</\u201D.
errLtSlashGt=Saw \u201C</>\u201D. Probable causes: Unescaped \u201C<\u201D (escape as \u201C&lt;\u201D) or mistyped end tag.
errCharRefLacksSemicolon=Character reference was not terminated by a semicolon.
@ -100,4 +101,52 @@ errNcrControlChar=Character reference expands to a control character.
errNcrZero=Character reference expands to zero.
errNoSpaceBetweenDoctypeSystemKeywordAndQuote=No space between the doctype \u201CSYSTEM\u201D keyword and the quote.
errNoSpaceBetweenPublicAndSystemIds=No space between the doctype public and system identifiers.
errNoSpaceBetweenDoctypePublicKeywordAndQuote=No space between the doctype \u201CPUBLIC\u201D keyword and the quote.
errNoSpaceBetweenDoctypePublicKeywordAndQuote=No space between the doctype \u201CPUBLIC\u201D keyword and the quote.
# Tree builder errors
errStrayStartTag=Stray end tag \u201C%1$S\u201D.
errStrayEndTag=Stray end tag \u201C%1$S\u201D.
errUnclosedElements=End tag \u201C%1$S\u201D seen, but there were open elements.
errUnclosedElementsImplied=End tag \u201C%1$S\u201D implied, but there were open elements.
errUnclosedElementsCell=A table cell was implicitly closed, but there were open elements.
errStrayDoctype=Stray doctype.
errAlmostStandardsDoctype=Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D.
errQuirkyDoctype=Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D.
errNonSpaceInTrailer=Non-space character in page trailer.
errNonSpaceAfterFrameset=Non-space after \u201Cframeset\u201D.
errNonSpaceInFrameset=Non-space in \u201Cframeset\u201D.
errNonSpaceAfterBody=Non-space character after body.
errNonSpaceInColgroupInFragment=Non-space in \u201Ccolgroup\u201D when parsing fragment.
errNonSpaceInNoscriptInHead=Non-space character inside \u201Cnoscript\u201D inside \u201Chead\u201D.
errFooBetweenHeadAndBody=\u201C%1$S\u201D element between \u201Chead\u201D and \u201Cbody\u201D.
errStartTagWithoutDoctype=Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.
errNoSelectInTableScope=No \u201Cselect\u201D in table scope.
errStartSelectWhereEndSelectExpected=\u201Cselect\u201D start tag where end tag expected.
errStartTagWithSelectOpen=\u201C%1$S\u201D start tag with \u201Cselect\u201D open.
errBadStartTagInHead=Bad start tag in \u201C%1$S\u201D in \u201Chead\u201D.
errImage=Saw a start tag \u201Cimage\u201D.
errIsindex=\u201Cisindex\u201D seen.
errFooSeenWhenFooOpen=An \u201C%1$S\u201D start tag seen but an element of the same type was already open.
errHeadingWhenHeadingOpen=Heading cannot be a child of another heading.
errFramesetStart=\u201Cframeset\u201D start tag seen.
errNoCellToClose=No cell to close.
errStartTagInTable=Start tag \u201C%1$S\u201D seen in \u201Ctable\u201D.
errFormWhenFormOpen=Saw a \u201Cform\u201D start tag, but there was already an active \u201Cform\u201D element. Nested forms are not allowed. Ignoring the tag.
errTableSeenWhileTableOpen=Start tag for \u201Ctable\u201D seen but the previous \u201Ctable\u201D is still open.
errStartTagInTableBody=\u201C%1$S\u201D start tag in table body.
errEndTagSeenWithoutDoctype=End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.
errEndTagAfterBody=Saw an end tag after \u201Cbody\u201D had been closed.
errEndTagSeenWithSelectOpen=\u201C%1$S\u201D end tag with \u201Cselect\u201D open.
errGarbageInColgroup=Garbage in \u201Ccolgroup\u201D fragment.
errEndTagBr=End tag \u201Cbr\u201D.
errNoElementToCloseButEndTagSeen=No \u201C%1$S\u201D element in scope but a \u201C%1$S\u201D end tag seen.
errHtmlStartTagInForeignContext=HTML start tag \u201C%1$S\u201D in a foreign namespace context.
errTableClosedWhileCaptionOpen=\u201Ctable\u201D closed but \u201Ccaption\u201D was still open.
errNoTableRowToClose=No table row to close.
errNonSpaceInTable=Misplaced non-space characters insided a table.
errUnclosedChildrenInRuby=Unclosed children in \u201Cruby\u201D.
errStartTagSeenWithoutRuby=Start tag \u201C%1$S\u201D seen without a \u201Cruby\u201D element being open.
errSelfClosing=Self-closing syntax (\u201C/>\u201D) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
errNoCheckUnclosedElementsOnStack=Unclosed elements on stack.
errEndTagDidNotMatchCurrentOpenElement=End tag \u201C%1$S\u201D did not match the name of the current open element (\u201C%2$S\u201D).
errEndTagViolatesNestingRules=End tag \u201C%1$S\u201D violates nesting rules.

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ HTML5_ATOM(noframes, "noframes")
HTML5_ATOM(noscript, "noscript")
HTML5_ATOM(plaintext, "plaintext")
HTML5_ATOM(script, "script")
HTML5_ATOM(table, "table")
HTML5_ATOM(caption, "caption")
HTML5_ATOM(p, "p")
HTML5_ATOM(address, "address")
@ -42,7 +43,6 @@ HTML5_ATOM(option, "option")
HTML5_ATOM(ruby, "ruby")
HTML5_ATOM(select, "select")
HTML5_ATOM(optgroup, "optgroup")
HTML5_ATOM(table, "table")
HTML5_ATOM(frameset, "frameset")
HTML5_ATOM(button, "button")
HTML5_ATOM(ul, "ul")

View File

@ -75,12 +75,16 @@ nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
, mCStart(PR_INT32_MAX)
, mPos(0)
, mInlinesOpen(0)
, mInCharacters(false)
, mBuffer(nsnull)
, mSyntaxHighlight(Preferences::GetBool("view_source.syntax_highlight",
true))
, mWrapLongLines(Preferences::GetBool("view_source.wrap_long_lines", true))
, mTabSize(Preferences::GetInt("view_source.tab_size", 4))
, mOpSink(aOpSink)
, mCurrentRun(nsnull)
, mAmpersand(nsnull)
, mSlash(nsnull)
, mHandles(new nsIContent*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH])
, mHandlesUsed(0)
{
@ -149,6 +153,8 @@ nsHtml5Highlighter::Start()
preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId);
Push(nsGkAtoms::pre, preAttrs);
StartCharacters();
mOpQueue.AppendElement()->Init(eTreeOpStartLayout);
}
@ -163,13 +169,15 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
case NS_HTML5TOKENIZER_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.
StartSpan();
if (aState == NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE) {
StartSpan();
// Start another span for highlighting the ampersand
StartSpan();
mAmpersand = CurrentNode();
} else {
mMarkupDecl = CurrentNode();
EndCharacters();
StartSpan();
mCurrentRun = CurrentNode();
}
break;
case NS_HTML5TOKENIZER_TAG_OPEN:
@ -178,7 +186,7 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
StartSpan(sStartTag);
break;
case NS_HTML5TOKENIZER_DATA:
EndInline(); // DATA
FinishTag(); // DATA
break;
}
break;
@ -387,6 +395,7 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
break;
}
EndInline();
StartCharacters();
break;
case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME:
switch (aState) {
@ -420,6 +429,7 @@ nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED:
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH:
if (aState == NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN) {
EndCharacters();
StartSpan();
}
break;
@ -537,6 +547,25 @@ nsHtml5Highlighter::EndInline()
--mInlinesOpen;
}
void
nsHtml5Highlighter::StartCharacters()
{
NS_PRECONDITION(!mInCharacters, "Already in characters!");
FlushChars();
Push(nsGkAtoms::span, nsnull);
mCurrentRun = CurrentNode();
mInCharacters = true;
}
void
nsHtml5Highlighter::EndCharacters()
{
NS_PRECONDITION(mInCharacters, "Not in characters!");
FlushChars();
Pop();
mInCharacters = false;
}
void
nsHtml5Highlighter::StartA()
{
@ -555,6 +584,7 @@ nsHtml5Highlighter::FinishTag()
FlushCurrent(); // >
EndInline(); // DATA
NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
StartCharacters();
}
void
@ -703,12 +733,33 @@ nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId)
}
void
nsHtml5Highlighter::AddErrorToCurrentMarkupDecl(const char* aMsgId)
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId)
{
NS_PRECONDITION(mMarkupDecl, "Adding error to markup decl without one!");
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mMarkupDecl, aMsgId);
treeOp->Init(mCurrentRun, aMsgId);
}
void
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
nsIAtom* aName)
{
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mCurrentRun, aMsgId);
}
void
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
nsIAtom* aName,
nsIAtom* aOther)
{
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mCurrentRun, aMsgId);
}
void

View File

@ -123,24 +123,56 @@ class nsHtml5Highlighter
/**
* Adds an error annotation to the node that's currently on top of
* mStack.
*
* @param aMsgId the id of the message in the property file
*/
void AddErrorToCurrentNode(const char* aMsgId);
/**
* Adds an error annotation to the node that corresponds to the most
* recently opened markup declaration/tag span.
* recently opened markup declaration/tag span, character reference or
* run of text.
*
* @param aMsgId the id of the message in the property file
*/
void AddErrorToCurrentMarkupDecl(const char* aMsgId);
void AddErrorToCurrentRun(const char* aMsgId);
/**
* Adds an error annotation to the node that corresponds to the most
* recently opened markup declaration/tag span, character reference or
* run of text with one atom to use when formatting the message.
*
* @param aMsgId the id of the message in the property file
* @param aName the atom
*/
void AddErrorToCurrentRun(const char* aMsgId, nsIAtom* aName);
/**
* Adds an error annotation to the node that corresponds to the most
* recently opened markup declaration/tag span, character reference or
* run of text with two atoms to use when formatting the message.
*
* @param aMsgId the id of the message in the property file
* @param aName the first atom
* @param aOther the second atom
*/
void AddErrorToCurrentRun(const char* aMsgId,
nsIAtom* aName,
nsIAtom* aOther);
/**
* Adds an error annotation to the node that corresponds to the most
* recent potentially character reference-starting ampersand.
*
* @param aMsgId the id of the message in the property file
*/
void AddErrorToCurrentAmpersand(const char* aMsgId);
/**
* Adds an error annotation to the node that corresponds to the most
* recent potentially self-closing slash.
*
* @param aMsgId the id of the message in the property file
*/
void AddErrorToCurrentSlash(const char* aMsgId);
@ -164,6 +196,16 @@ class nsHtml5Highlighter
*/
void EndInline();
/**
* Starts a wrapper around a run of characters.
*/
void StartCharacters();
/**
* Ends a wrapper around a run of characters.
*/
void EndCharacters();
/**
* Starts an <a>.
*/
@ -270,10 +312,17 @@ class nsHtml5Highlighter
PRInt32 mPos;
/**
* The number of inline elements open inside the <pre>.
* The number of inline elements open inside the <pre> excluding the
* span potentially wrapping a run of characters.
*/
PRInt32 mInlinesOpen;
/**
* Whether there's a span wrapping a run of characters (excluding CDATA
* section) open.
*/
bool mInCharacters;
/**
* The current buffer being tokenized.
*/
@ -310,9 +359,9 @@ class nsHtml5Highlighter
nsAHtml5TreeOpSink* mOpSink;
/**
* The most recently opened markup declaration/tag.
* The most recently opened markup declaration/tag or run of characters.
*/
nsIContent** mMarkupDecl;
nsIContent** mCurrentRun;
/**
* The most recent ampersand in a place where character references were

View File

@ -206,7 +206,10 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
mTokenizer->setEncodingDeclarationHandler(this);
if (aMode == VIEW_SOURCE_HTML || aMode == VIEW_SOURCE_XML) {
mTokenizer->EnableViewSource(new nsHtml5Highlighter(mExecutor->GetStage()));
nsHtml5Highlighter* highlighter =
new nsHtml5Highlighter(mExecutor->GetStage());
mTokenizer->EnableViewSource(highlighter); // takes ownership
mTreeBuilder->EnableViewSource(highlighter); // doesn't own
}
// Chardet instantiation adapted from nsDOMFile.

View File

@ -1537,7 +1537,11 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
NS_HTML5_CONTINUE(stateloop);
}
}
if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
} else {
}
}
const PRUnichar* val = nsHtml5NamedCharacters::VALUES[candidate];
@ -4419,7 +4423,11 @@ nsHtml5Tokenizer::stateLoopReportTransitions(PRInt32 state, PRUnichar c, PRInt32
NS_HTML5_CONTINUE(stateloop);
}
}
if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
errUnescapedAmpersandInterpretedAsCharacterReference();
} else {
errNotSemicolonTerminated();
}
}
mViewSource->CompletedNamedCharacterReference();
const PRUnichar* val = nsHtml5NamedCharacters::VALUES[candidate];
@ -6509,7 +6517,11 @@ nsHtml5Tokenizer::eof()
NS_HTML5_CONTINUE(eofloop);
}
}
if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
errUnescapedAmpersandInterpretedAsCharacterReference();
} else {
errNotSemicolonTerminated();
}
}
const PRUnichar* val = nsHtml5NamedCharacters::VALUES[candidate];
if (!val[1]) {
@ -6538,6 +6550,8 @@ nsHtml5Tokenizer::eof()
emitOrAppendStrBuf(returnState);
state = returnState;
continue;
} else {
errCharRefLacksSemicolon();
}
handleNcrValue(returnState);
state = returnState;

View File

@ -136,7 +136,7 @@ nsHtml5Tokenizer::maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs)
* When an end tag token is emitted with attributes, that is a parse
* error.
*/
mViewSource->AddErrorToCurrentMarkupDecl("maybeErrAttributesOnEndTag");
mViewSource->AddErrorToCurrentRun("maybeErrAttributesOnEndTag");
}
}
@ -151,7 +151,7 @@ nsHtml5Tokenizer::maybeErrSlashInEndTag(bool selfClosing)
PRUnichar
nsHtml5Tokenizer::errNcrNonCharacter(PRUnichar ch)
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrNonCharacter");
}
return ch;
@ -160,7 +160,7 @@ nsHtml5Tokenizer::errNcrNonCharacter(PRUnichar ch)
void
nsHtml5Tokenizer::errAstralNonCharacter(int ch)
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errAstralNonCharacter");
}
}
@ -168,7 +168,7 @@ nsHtml5Tokenizer::errAstralNonCharacter(int ch)
PRUnichar
nsHtml5Tokenizer::errNcrControlChar(PRUnichar ch)
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrControlChar");
}
return ch;
@ -189,13 +189,15 @@ nsHtml5Tokenizer::errLtSlashGt()
void
nsHtml5Tokenizer::errCharRefLacksSemicolon()
{
mViewSource->AddErrorToCurrentNode("errCharRefLacksSemicolon");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errCharRefLacksSemicolon");
}
}
void
nsHtml5Tokenizer::errNoDigitsInNCR()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNoDigitsInNCR");
}
}
@ -221,7 +223,7 @@ nsHtml5Tokenizer::errNamelessDoctype()
void
nsHtml5Tokenizer::errConsecutiveHyphens()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errConsecutiveHyphens");
}
}
@ -235,7 +237,7 @@ nsHtml5Tokenizer::errPrematureEndOfComment()
void
nsHtml5Tokenizer::errBogusComment()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errBogusComment");
}
}
@ -279,19 +281,23 @@ nsHtml5Tokenizer::errProcessingInstruction()
void
nsHtml5Tokenizer::errUnescapedAmpersandInterpretedAsCharacterReference()
{
mViewSource->AddErrorToCurrentAmpersand("errUnescapedAmpersandInterpretedAsCharacterReference");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentAmpersand("errUnescapedAmpersandInterpretedAsCharacterReference");
}
}
void
nsHtml5Tokenizer::errNotSemicolonTerminated()
{
mViewSource->AddErrorToCurrentNode("errNotSemicolonTerminated");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNotSemicolonTerminated");
}
}
void
nsHtml5Tokenizer::errNoNamedCharacterMatch()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentAmpersand("errNoNamedCharacterMatch");
}
}
@ -311,7 +317,7 @@ nsHtml5Tokenizer::errExpectedPublicId()
void
nsHtml5Tokenizer::errBogusDoctype()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errBogusDoctype");
}
}
@ -319,7 +325,7 @@ nsHtml5Tokenizer::errBogusDoctype()
void
nsHtml5Tokenizer::errNcrSurrogate()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrSurrogate");
}
}
@ -327,7 +333,7 @@ nsHtml5Tokenizer::errNcrSurrogate()
void
nsHtml5Tokenizer::errNcrCr()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrCr");
}
}
@ -335,7 +341,7 @@ nsHtml5Tokenizer::errNcrCr()
void
nsHtml5Tokenizer::errNcrInC1Range()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrInC1Range");
}
}
@ -343,79 +349,79 @@ nsHtml5Tokenizer::errNcrInC1Range()
void
nsHtml5Tokenizer::errEofInPublicId()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofInPublicId");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInPublicId");
}
}
void
nsHtml5Tokenizer::errEofInComment()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofInComment");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInComment");
}
}
void
nsHtml5Tokenizer::errEofInDoctype()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofInDoctype");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInDoctype");
}
}
void
nsHtml5Tokenizer::errEofInAttributeValue()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofInAttributeValue");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInAttributeValue");
}
}
void
nsHtml5Tokenizer::errEofInAttributeName()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofInAttributeName");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInAttributeName");
}
}
void
nsHtml5Tokenizer::errEofWithoutGt()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofWithoutGt");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofWithoutGt");
}
}
void
nsHtml5Tokenizer::errEofInTagName()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofInTagName");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInTagName");
}
}
void
nsHtml5Tokenizer::errEofInEndTag()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofInEndTag");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInEndTag");
}
}
void
nsHtml5Tokenizer::errEofAfterLt()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofAfterLt");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofAfterLt");
}
}
void
nsHtml5Tokenizer::errNcrOutOfRange()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrOutOfRange");
}
}
@ -423,7 +429,7 @@ nsHtml5Tokenizer::errNcrOutOfRange()
void
nsHtml5Tokenizer::errNcrUnassigned()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrUnassigned");
}
}
@ -431,7 +437,7 @@ nsHtml5Tokenizer::errNcrUnassigned()
void
nsHtml5Tokenizer::errDuplicateAttribute()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errDuplicateAttribute");
}
}
@ -439,8 +445,8 @@ nsHtml5Tokenizer::errDuplicateAttribute()
void
nsHtml5Tokenizer::errEofInSystemId()
{
if (mViewSource) {
mViewSource->AddErrorToCurrentMarkupDecl("errEofInSystemId");
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInSystemId");
}
}
@ -465,7 +471,7 @@ nsHtml5Tokenizer::errHyphenHyphenBang()
void
nsHtml5Tokenizer::errNcrControlChar()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrControlChar");
}
}
@ -473,7 +479,7 @@ nsHtml5Tokenizer::errNcrControlChar()
void
nsHtml5Tokenizer::errNcrZero()
{
if (mViewSource) {
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrZero");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -52,6 +52,7 @@
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5StreamParser.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Highlighter.h"
class nsHtml5StreamParser;

View File

@ -57,6 +57,7 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
, contextNode(nsnull)
, formPointer(nsnull)
, headPointer(nsnull)
, mViewSource(nsnull)
, mOpSink(aOpSink)
, mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])
, mHandlesUsed(0)
@ -707,3 +708,396 @@ nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m)
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(m);
}
// Error reporting
void
nsHtml5TreeBuilder::EnableViewSource(nsHtml5Highlighter* aHighlighter)
{
mViewSource = aHighlighter;
}
void
nsHtml5TreeBuilder::errStrayStartTag(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errStrayStartTag", aName);
}
}
void
nsHtml5TreeBuilder::errStrayEndTag(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errStrayEndTag", aName);
}
}
void
nsHtml5TreeBuilder::errUnclosedElements(PRInt32 aIndex, nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errUnclosedElements", aName);
}
}
void
nsHtml5TreeBuilder::errUnclosedElementsImplied(PRInt32 aIndex, nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errUnclosedElementsImplied",
aName);
}
}
void
nsHtml5TreeBuilder::errUnclosedElementsCell(PRInt32 aIndex)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errUnclosedElementsCell");
}
}
void
nsHtml5TreeBuilder::errStrayDoctype()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errStrayDoctype");
}
}
void
nsHtml5TreeBuilder::errAlmostStandardsDoctype()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errAlmostStandardsDoctype");
}
}
void
nsHtml5TreeBuilder::errQuirkyDoctype()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errQuirkyDoctype");
}
}
void
nsHtml5TreeBuilder::errNonSpaceInTrailer()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNonSpaceInTrailer");
}
}
void
nsHtml5TreeBuilder::errNonSpaceAfterFrameset()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNonSpaceAfterFrameset");
}
}
void
nsHtml5TreeBuilder::errNonSpaceInFrameset()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNonSpaceInFrameset");
}
}
void
nsHtml5TreeBuilder::errNonSpaceAfterBody()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNonSpaceAfterBody");
}
}
void
nsHtml5TreeBuilder::errNonSpaceInColgroupInFragment()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNonSpaceInColgroupInFragment");
}
}
void
nsHtml5TreeBuilder::errNonSpaceInNoscriptInHead()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNonSpaceInNoscriptInHead");
}
}
void
nsHtml5TreeBuilder::errFooBetweenHeadAndBody(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errFooBetweenHeadAndBody", aName);
}
}
void
nsHtml5TreeBuilder::errStartTagWithoutDoctype()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errStartTagWithoutDoctype");
}
}
void
nsHtml5TreeBuilder::errNoSelectInTableScope()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNoSelectInTableScope");
}
}
void
nsHtml5TreeBuilder::errStartSelectWhereEndSelectExpected()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun(
"errStartSelectWhereEndSelectExpected");
}
}
void
nsHtml5TreeBuilder::errStartTagWithSelectOpen(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errStartTagWithSelectOpen", aName);
}
}
void
nsHtml5TreeBuilder::errBadStartTagInHead(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errBadStartTagInHead", aName);
}
}
void
nsHtml5TreeBuilder::errImage()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errImage");
}
}
void
nsHtml5TreeBuilder::errIsindex()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errIsindex");
}
}
void
nsHtml5TreeBuilder::errFooSeenWhenFooOpen(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errFooSeenWhenFooOpen", aName);
}
}
void
nsHtml5TreeBuilder::errHeadingWhenHeadingOpen()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errHeadingWhenHeadingOpen");
}
}
void
nsHtml5TreeBuilder::errFramesetStart()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errFramesetStart");
}
}
void
nsHtml5TreeBuilder::errNoCellToClose()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNoCellToClose");
}
}
void
nsHtml5TreeBuilder::errStartTagInTable(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errStartTagInTable", aName);
}
}
void
nsHtml5TreeBuilder::errFormWhenFormOpen()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errFormWhenFormOpen");
}
}
void
nsHtml5TreeBuilder::errTableSeenWhileTableOpen()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errTableSeenWhileTableOpen");
}
}
void
nsHtml5TreeBuilder::errStartTagInTableBody(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errStartTagInTableBody", aName);
}
}
void
nsHtml5TreeBuilder::errEndTagSeenWithoutDoctype()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEndTagSeenWithoutDoctype");
}
}
void
nsHtml5TreeBuilder::errEndTagAfterBody()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEndTagAfterBody");
}
}
void
nsHtml5TreeBuilder::errEndTagSeenWithSelectOpen(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEndTagSeenWithSelectOpen",
aName);
}
}
void
nsHtml5TreeBuilder::errGarbageInColgroup()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errGarbageInColgroup");
}
}
void
nsHtml5TreeBuilder::errEndTagBr()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEndTagBr");
}
}
void
nsHtml5TreeBuilder::errNoElementToCloseButEndTagSeen(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun(
"errNoElementToCloseButEndTagSeen", aName);
}
}
void
nsHtml5TreeBuilder::errHtmlStartTagInForeignContext(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errHtmlStartTagInForeignContext",
aName);
}
}
void
nsHtml5TreeBuilder::errTableClosedWhileCaptionOpen()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errTableClosedWhileCaptionOpen");
}
}
void
nsHtml5TreeBuilder::errNoTableRowToClose()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNoTableRowToClose");
}
}
void
nsHtml5TreeBuilder::errNonSpaceInTable()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errNonSpaceInTable");
}
}
void
nsHtml5TreeBuilder::errUnclosedChildrenInRuby()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errUnclosedChildrenInRuby");
}
}
void
nsHtml5TreeBuilder::errStartTagSeenWithoutRuby(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errStartTagSeenWithoutRuby",
aName);
}
}
void
nsHtml5TreeBuilder::errSelfClosing()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentSlash("errSelfClosing");
}
}
void
nsHtml5TreeBuilder::errNoCheckUnclosedElementsOnStack()
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun(
"errNoCheckUnclosedElementsOnStack");
}
}
void
nsHtml5TreeBuilder::errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName,
nsIAtom* aOther)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun(
"errEndTagDidNotMatchCurrentOpenElement", aName, aOther);
}
}
void
nsHtml5TreeBuilder::errEndTagViolatesNestingRules(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEndTagViolatesNestingRules", aName);
}
}
void
nsHtml5TreeBuilder::errEndWithUnclosedElements(nsIAtom* aName)
{
if (NS_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEndWithUnclosedElements", aName);
}
}

View File

@ -38,7 +38,7 @@
#define NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH 512
private:
nsHtml5Highlighter* mViewSource;
nsTArray<nsHtml5TreeOperation> mOpQueue;
nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
nsAHtml5TreeOpSink* mOpSink;
@ -96,4 +96,100 @@
void DropHandles();
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
void errStrayStartTag(nsIAtom* aName);
void errStrayEndTag(nsIAtom* aName);
void errUnclosedElements(PRInt32 aIndex, nsIAtom* aName);
void errUnclosedElementsImplied(PRInt32 aIndex, nsIAtom* aName);
void errUnclosedElementsCell(PRInt32 aIndex);
void errStrayDoctype();
void errAlmostStandardsDoctype();
void errQuirkyDoctype();
void errNonSpaceInTrailer();
void errNonSpaceAfterFrameset();
void errNonSpaceInFrameset();
void errNonSpaceAfterBody();
void errNonSpaceInColgroupInFragment();
void errNonSpaceInNoscriptInHead();
void errFooBetweenHeadAndBody(nsIAtom* aName);
void errStartTagWithoutDoctype();
void errNoSelectInTableScope();
void errStartSelectWhereEndSelectExpected();
void errStartTagWithSelectOpen(nsIAtom* aName);
void errBadStartTagInHead(nsIAtom* aName);
void errImage();
void errIsindex();
void errFooSeenWhenFooOpen(nsIAtom* aName);
void errHeadingWhenHeadingOpen();
void errFramesetStart();
void errNoCellToClose();
void errStartTagInTable(nsIAtom* aName);
void errFormWhenFormOpen();
void errTableSeenWhileTableOpen();
void errStartTagInTableBody(nsIAtom* aName);
void errEndTagSeenWithoutDoctype();
void errEndTagAfterBody();
void errEndTagSeenWithSelectOpen(nsIAtom* aName);
void errGarbageInColgroup();
void errEndTagBr();
void errNoElementToCloseButEndTagSeen(nsIAtom* aName);
void errHtmlStartTagInForeignContext(nsIAtom* aName);
void errTableClosedWhileCaptionOpen();
void errNoTableRowToClose();
void errNonSpaceInTable();
void errUnclosedChildrenInRuby();
void errStartTagSeenWithoutRuby(nsIAtom* aName);
void errSelfClosing();
void errNoCheckUnclosedElementsOnStack();
void errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName, nsIAtom* aOther);
void errEndTagViolatesNestingRules(nsIAtom* aName);
void errEndWithUnclosedElements(nsIAtom* aName);
void MarkAsBroken();