diff --git a/parser/html/javasrc/TreeBuilder.java b/parser/html/javasrc/TreeBuilder.java index 8fb2b37459c7..494ce2b3073e 100644 --- a/parser/html/javasrc/TreeBuilder.java +++ b/parser/html/javasrc/TreeBuilder.java @@ -203,49 +203,71 @@ public abstract class TreeBuilder implements TokenHandler, // start insertion modes - private static final int INITIAL = 0; + private static final int IN_ROW = 0; - private static final int BEFORE_HTML = 1; + private static final int IN_TABLE_BODY = 1; - private static final int BEFORE_HEAD = 2; + private static final int IN_TABLE = 2; - private static final int IN_HEAD = 3; + private static final int IN_CAPTION = 3; - private static final int IN_HEAD_NOSCRIPT = 4; + private static final int IN_CELL = 4; - private static final int AFTER_HEAD = 5; + private static final int FRAMESET_OK = 5; private static final int IN_BODY = 6; - private static final int IN_TABLE = 7; + private static final int IN_HEAD = 7; - private static final int IN_CAPTION = 8; + private static final int IN_HEAD_NOSCRIPT = 8; + // no fall-through + private static final int IN_COLUMN_GROUP = 9; - private static final int IN_TABLE_BODY = 10; + // no fall-through + + private static final int IN_SELECT_IN_TABLE = 10; - private static final int IN_ROW = 11; + private static final int IN_SELECT = 11; - private static final int IN_CELL = 12; + // no fall-through + + private static final int AFTER_BODY = 12; - private static final int IN_SELECT = 13; + // no fall-through + + private static final int IN_FRAMESET = 13; - private static final int IN_SELECT_IN_TABLE = 14; + private static final int AFTER_FRAMESET = 14; - private static final int AFTER_BODY = 15; + // no fall-through + + private static final int INITIAL = 15; + + // could add fall-through - private static final int IN_FRAMESET = 16; + private static final int BEFORE_HTML = 16; - private static final int AFTER_FRAMESET = 17; + // could add fall-through - private static final int AFTER_AFTER_BODY = 18; + private static final int BEFORE_HEAD = 17; - private static final int AFTER_AFTER_FRAMESET = 19; + // no fall-through + + private static final int AFTER_HEAD = 18; - private static final int TEXT = 20; + // no fall-through + + private static final int AFTER_AFTER_BODY = 19; - private static final int FRAMESET_OK = 21; + // no fall-through + + private static final int AFTER_AFTER_FRAMESET = 20; + + // no fall-through + + private static final int TEXT = 21; // start charset states @@ -614,232 +636,214 @@ public abstract class TreeBuilder implements TokenHandler, public final void doctype(@Local String name, String publicIdentifier, String systemIdentifier, boolean forceQuirks) throws SAXException { needToDropLF = false; - if (!isInForeign()) { - switch (mode) { - case INITIAL: - // [NOCPP[ - if (reportingDoctype) { - // ]NOCPP] - String emptyString = Portability.newEmptyString(); - appendDoctypeToDocument(name == null ? "" : name, - publicIdentifier == null ? emptyString - : publicIdentifier, - systemIdentifier == null ? emptyString - : systemIdentifier); - Portability.releaseString(emptyString); - // [NOCPP[ - } - switch (doctypeExpectation) { - case HTML: - // ]NOCPP] - if (isQuirky(name, publicIdentifier, - systemIdentifier, forceQuirks)) { - errQuirkyDoctype(); - documentModeInternal(DocumentMode.QUIRKS_MODE, - publicIdentifier, systemIdentifier, - false); - } else if (isAlmostStandards(publicIdentifier, - systemIdentifier)) { - // [NOCPP[ - if (firstCommentLocation != null) { - warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); - } - // ]NOCPP] - errAlmostStandardsDoctype(); - documentModeInternal( - DocumentMode.ALMOST_STANDARDS_MODE, - publicIdentifier, systemIdentifier, - false); - } else { - // [NOCPP[ - if (firstCommentLocation != null) { - warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); - } - if ((Portability.literalEqualsString( - "-//W3C//DTD HTML 4.0//EN", - publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString( - "http://www.w3.org/TR/REC-html40/strict.dtd", - systemIdentifier))) - || (Portability.literalEqualsString( - "-//W3C//DTD HTML 4.01//EN", - publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString( - "http://www.w3.org/TR/html4/strict.dtd", - systemIdentifier))) - || (Portability.literalEqualsString( - "-//W3C//DTD XHTML 1.0 Strict//EN", - publicIdentifier) && Portability.literalEqualsString( - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", - systemIdentifier)) - || (Portability.literalEqualsString( - "-//W3C//DTD XHTML 1.1//EN", - publicIdentifier) && Portability.literalEqualsString( - "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd", - systemIdentifier)) - - ) { - warn("Obsolete doctype. Expected \u201C\u201D."); - } else if (!((systemIdentifier == null || Portability.literalEqualsString( - "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) { - err("Legacy doctype. Expected \u201C\u201D."); - } - // ]NOCPP] - documentModeInternal( - DocumentMode.STANDARDS_MODE, - publicIdentifier, systemIdentifier, - false); - } - // [NOCPP[ - break; - case HTML401_STRICT: - html4 = true; - tokenizer.turnOnAdditionalHtml4Errors(); - if (isQuirky(name, publicIdentifier, - systemIdentifier, forceQuirks)) { - err("Quirky doctype. Expected \u201C\u201D."); - documentModeInternal(DocumentMode.QUIRKS_MODE, - publicIdentifier, systemIdentifier, - true); - } else if (isAlmostStandards(publicIdentifier, - systemIdentifier)) { - if (firstCommentLocation != null) { - warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); - } - err("Almost standards mode doctype. Expected \u201C\u201D."); - documentModeInternal( - DocumentMode.ALMOST_STANDARDS_MODE, - publicIdentifier, systemIdentifier, - true); - } else { - if (firstCommentLocation != null) { - warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); - } - if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) { - if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) { - warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C\u201D."); - } - } else { - err("The doctype was not the HTML 4.01 Strict doctype. Expected \u201C\u201D."); - } - documentModeInternal( - DocumentMode.STANDARDS_MODE, - publicIdentifier, systemIdentifier, - true); - } - break; - case HTML401_TRANSITIONAL: - html4 = true; - tokenizer.turnOnAdditionalHtml4Errors(); - if (isQuirky(name, publicIdentifier, - systemIdentifier, forceQuirks)) { - err("Quirky doctype. Expected \u201C\u201D."); - documentModeInternal(DocumentMode.QUIRKS_MODE, - publicIdentifier, systemIdentifier, - true); - } else if (isAlmostStandards(publicIdentifier, - systemIdentifier)) { - if (firstCommentLocation != null) { - warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); - } - if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier) - && systemIdentifier != null) { - if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) { - warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C\u201D."); - } - } else { - err("The doctype was not a non-quirky HTML 4.01 Transitional doctype. Expected \u201C\u201D."); - } - documentModeInternal( - DocumentMode.ALMOST_STANDARDS_MODE, - publicIdentifier, systemIdentifier, - true); - } else { - if (firstCommentLocation != null) { - warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); - } - err("The doctype was not the HTML 4.01 Transitional doctype. Expected \u201C\u201D."); - documentModeInternal( - DocumentMode.STANDARDS_MODE, - publicIdentifier, systemIdentifier, - true); - } - break; - case AUTO: - html4 = isHtml4Doctype(publicIdentifier); - if (html4) { - tokenizer.turnOnAdditionalHtml4Errors(); - } - if (isQuirky(name, publicIdentifier, - systemIdentifier, forceQuirks)) { - err("Quirky doctype. Expected e.g. \u201C\u201D."); - documentModeInternal(DocumentMode.QUIRKS_MODE, - publicIdentifier, systemIdentifier, - html4); - } else if (isAlmostStandards(publicIdentifier, - systemIdentifier)) { - if (firstCommentLocation != null) { - warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); - } - if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier)) { - if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) { - warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C\u201D."); - } - } else { - err("Almost standards mode doctype. Expected e.g. \u201C\u201D."); - } - documentModeInternal( - DocumentMode.ALMOST_STANDARDS_MODE, - publicIdentifier, systemIdentifier, - html4); - } else { - if (firstCommentLocation != null) { - warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", firstCommentLocation); - } - if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) { - if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) { - warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C\u201D."); - } - } else if (!((systemIdentifier == null || Portability.literalEqualsString( - "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) { - err("Legacy doctype. Expected e.g. \u201C\u201D."); - } - documentModeInternal( - DocumentMode.STANDARDS_MODE, - publicIdentifier, systemIdentifier, - html4); - } - break; - case NO_DOCTYPE_ERRORS: - if (isQuirky(name, publicIdentifier, - systemIdentifier, forceQuirks)) { - documentModeInternal(DocumentMode.QUIRKS_MODE, - publicIdentifier, systemIdentifier, - false); - } else if (isAlmostStandards(publicIdentifier, - systemIdentifier)) { - documentModeInternal( - DocumentMode.ALMOST_STANDARDS_MODE, - publicIdentifier, systemIdentifier, - false); - } else { - documentModeInternal( - DocumentMode.STANDARDS_MODE, - publicIdentifier, systemIdentifier, - false); - } - break; - } + if (!isInForeign() && mode == INITIAL) { + // [NOCPP[ + if (reportingDoctype) { + // ]NOCPP] + String emptyString = Portability.newEmptyString(); + appendDoctypeToDocument(name == null ? "" : name, + publicIdentifier == null ? emptyString + : publicIdentifier, + systemIdentifier == null ? emptyString + : systemIdentifier); + Portability.releaseString(emptyString); + // [NOCPP[ + } + switch (doctypeExpectation) { + case HTML: // ]NOCPP] + if (isQuirky(name, publicIdentifier, systemIdentifier, + forceQuirks)) { + errQuirkyDoctype(); + documentModeInternal(DocumentMode.QUIRKS_MODE, + publicIdentifier, systemIdentifier, false); + } else if (isAlmostStandards(publicIdentifier, + systemIdentifier)) { + // [NOCPP[ + if (firstCommentLocation != null) { + warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", + firstCommentLocation); + } + // ]NOCPP] + errAlmostStandardsDoctype(); + documentModeInternal( + DocumentMode.ALMOST_STANDARDS_MODE, + publicIdentifier, systemIdentifier, false); + } else { + // [NOCPP[ + if (firstCommentLocation != null) { + warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", + firstCommentLocation); + } + if ((Portability.literalEqualsString( + "-//W3C//DTD HTML 4.0//EN", publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString( + "http://www.w3.org/TR/REC-html40/strict.dtd", + systemIdentifier))) + || (Portability.literalEqualsString( + "-//W3C//DTD HTML 4.01//EN", + publicIdentifier) && (systemIdentifier == null || Portability.literalEqualsString( + "http://www.w3.org/TR/html4/strict.dtd", + systemIdentifier))) + || (Portability.literalEqualsString( + "-//W3C//DTD XHTML 1.0 Strict//EN", + publicIdentifier) && Portability.literalEqualsString( + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", + systemIdentifier)) + || (Portability.literalEqualsString( + "-//W3C//DTD XHTML 1.1//EN", + publicIdentifier) && Portability.literalEqualsString( + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd", + systemIdentifier)) - /* - * - * Then, switch to the root element mode of the tree - * construction stage. - */ - mode = BEFORE_HTML; - return; - default: + ) { + warn("Obsolete doctype. Expected \u201C\u201D."); + } else if (!((systemIdentifier == null || Portability.literalEqualsString( + "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) { + err("Legacy doctype. Expected \u201C\u201D."); + } + // ]NOCPP] + documentModeInternal(DocumentMode.STANDARDS_MODE, + publicIdentifier, systemIdentifier, false); + } + // [NOCPP[ + break; + case HTML401_STRICT: + html4 = true; + tokenizer.turnOnAdditionalHtml4Errors(); + if (isQuirky(name, publicIdentifier, systemIdentifier, + forceQuirks)) { + err("Quirky doctype. Expected \u201C\u201D."); + documentModeInternal(DocumentMode.QUIRKS_MODE, + publicIdentifier, systemIdentifier, true); + } else if (isAlmostStandards(publicIdentifier, + systemIdentifier)) { + if (firstCommentLocation != null) { + warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", + firstCommentLocation); + } + err("Almost standards mode doctype. Expected \u201C\u201D."); + documentModeInternal( + DocumentMode.ALMOST_STANDARDS_MODE, + publicIdentifier, systemIdentifier, true); + } else { + if (firstCommentLocation != null) { + warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", + firstCommentLocation); + } + if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) { + if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) { + warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C\u201D."); + } + } else { + err("The doctype was not the HTML 4.01 Strict doctype. Expected \u201C\u201D."); + } + documentModeInternal(DocumentMode.STANDARDS_MODE, + publicIdentifier, systemIdentifier, true); + } + break; + case HTML401_TRANSITIONAL: + html4 = true; + tokenizer.turnOnAdditionalHtml4Errors(); + if (isQuirky(name, publicIdentifier, systemIdentifier, + forceQuirks)) { + err("Quirky doctype. Expected \u201C\u201D."); + documentModeInternal(DocumentMode.QUIRKS_MODE, + publicIdentifier, systemIdentifier, true); + } else if (isAlmostStandards(publicIdentifier, + systemIdentifier)) { + if (firstCommentLocation != null) { + warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", + firstCommentLocation); + } + if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier) + && systemIdentifier != null) { + if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) { + warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C\u201D."); + } + } else { + err("The doctype was not a non-quirky HTML 4.01 Transitional doctype. Expected \u201C\u201D."); + } + documentModeInternal( + DocumentMode.ALMOST_STANDARDS_MODE, + publicIdentifier, systemIdentifier, true); + } else { + if (firstCommentLocation != null) { + warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", + firstCommentLocation); + } + err("The doctype was not the HTML 4.01 Transitional doctype. Expected \u201C\u201D."); + documentModeInternal(DocumentMode.STANDARDS_MODE, + publicIdentifier, systemIdentifier, true); + } + break; + case AUTO: + html4 = isHtml4Doctype(publicIdentifier); + if (html4) { + tokenizer.turnOnAdditionalHtml4Errors(); + } + if (isQuirky(name, publicIdentifier, systemIdentifier, + forceQuirks)) { + err("Quirky doctype. Expected e.g. \u201C\u201D."); + documentModeInternal(DocumentMode.QUIRKS_MODE, + publicIdentifier, systemIdentifier, html4); + } else if (isAlmostStandards(publicIdentifier, + systemIdentifier)) { + if (firstCommentLocation != null) { + warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", + firstCommentLocation); + } + if ("-//W3C//DTD HTML 4.01 Transitional//EN".equals(publicIdentifier)) { + if (!"http://www.w3.org/TR/html4/loose.dtd".equals(systemIdentifier)) { + warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C\u201D."); + } + } else { + err("Almost standards mode doctype. Expected e.g. \u201C\u201D."); + } + documentModeInternal( + DocumentMode.ALMOST_STANDARDS_MODE, + publicIdentifier, systemIdentifier, html4); + } else { + if (firstCommentLocation != null) { + warn("Comments seen before doctype. Internet Explorer will go into the quirks mode.", + firstCommentLocation); + } + if ("-//W3C//DTD HTML 4.01//EN".equals(publicIdentifier)) { + if (!"http://www.w3.org/TR/html4/strict.dtd".equals(systemIdentifier)) { + warn("The doctype did not contain the system identifier prescribed by the HTML 4.01 specification. Expected \u201C\u201D."); + } + } else if (!((systemIdentifier == null || Portability.literalEqualsString( + "about:legacy-compat", systemIdentifier)) && publicIdentifier == null)) { + err("Legacy doctype. Expected e.g. \u201C\u201D."); + } + documentModeInternal(DocumentMode.STANDARDS_MODE, + publicIdentifier, systemIdentifier, html4); + } + break; + case NO_DOCTYPE_ERRORS: + if (isQuirky(name, publicIdentifier, systemIdentifier, + forceQuirks)) { + documentModeInternal(DocumentMode.QUIRKS_MODE, + publicIdentifier, systemIdentifier, false); + } else if (isAlmostStandards(publicIdentifier, + systemIdentifier)) { + documentModeInternal( + DocumentMode.ALMOST_STANDARDS_MODE, + publicIdentifier, systemIdentifier, false); + } else { + documentModeInternal(DocumentMode.STANDARDS_MODE, + publicIdentifier, systemIdentifier, false); + } break; } + // ]NOCPP] + + /* + * + * Then, switch to the root element mode of the tree construction + * stage. + */ + mode = BEFORE_HTML; + return; } /* * A DOCTYPE token Parse error. @@ -1611,6 +1615,35 @@ public abstract class TreeBuilder implements TokenHandler, } // foreignObject / annotation-xml } switch (mode) { + case IN_ROW: + switch (group) { + case TD_OR_TH: + clearStackBackTo(findLastOrRoot(TreeBuilder.TR)); + appendToCurrentNodeAndPushElement( + elementName, + attributes); + mode = IN_CELL; + insertMarker(); + attributes = null; // CPP + break starttagloop; + case CAPTION: + case COL: + case COLGROUP: + case TBODY_OR_THEAD_OR_TFOOT: + case TR: + eltPos = findLastOrRoot(TreeBuilder.TR); + if (eltPos == 0) { + assert fragment; + errNoTableRowToClose(); + break starttagloop; + } + clearStackBackTo(eltPos); + pop(); + mode = IN_TABLE_BODY; + continue; + default: + // fall through to IN_TABLE + } case IN_TABLE_BODY: switch (group) { case TR: @@ -1646,35 +1679,6 @@ public abstract class TreeBuilder implements TokenHandler, default: // fall through to IN_TABLE } - case IN_ROW: - switch (group) { - case TD_OR_TH: - clearStackBackTo(findLastOrRoot(TreeBuilder.TR)); - appendToCurrentNodeAndPushElement( - elementName, - attributes); - mode = IN_CELL; - insertMarker(); - attributes = null; // CPP - break starttagloop; - case CAPTION: - case COL: - case COLGROUP: - case TBODY_OR_THEAD_OR_TFOOT: - case TR: - eltPos = findLastOrRoot(TreeBuilder.TR); - if (eltPos == 0) { - assert fragment; - errNoTableRowToClose(); - break starttagloop; - } - clearStackBackTo(eltPos); - pop(); - mode = IN_TABLE_BODY; - continue; - default: - // fall through to IN_TABLE - } case IN_TABLE: intableloop: for (;;) { switch (group) { @@ -3606,6 +3610,37 @@ public abstract class TreeBuilder implements TokenHandler, eltPos--; } } + case IN_HEAD: + switch (group) { + case HEAD: + pop(); + mode = AFTER_HEAD; + break endtagloop; + case BR: + case HTML: + case BODY: + pop(); + mode = AFTER_HEAD; + continue; + default: + errStrayEndTag(name); + break endtagloop; + } + case IN_HEAD_NOSCRIPT: + switch (group) { + case NOSCRIPT: + pop(); + mode = IN_HEAD; + break endtagloop; + case BR: + errStrayEndTag(name); + pop(); + mode = IN_HEAD; + continue; + default: + errStrayEndTag(name); + break endtagloop; + } case IN_COLUMN_GROUP: switch (group) { case COLGROUP: @@ -3806,37 +3841,6 @@ public abstract class TreeBuilder implements TokenHandler, errStrayEndTag(name); break endtagloop; } - case IN_HEAD: - switch (group) { - case HEAD: - pop(); - mode = AFTER_HEAD; - break endtagloop; - case BR: - case HTML: - case BODY: - pop(); - mode = AFTER_HEAD; - continue; - default: - errStrayEndTag(name); - break endtagloop; - } - case IN_HEAD_NOSCRIPT: - switch (group) { - case NOSCRIPT: - pop(); - mode = IN_HEAD; - break endtagloop; - case BR: - errStrayEndTag(name); - pop(); - mode = IN_HEAD; - continue; - default: - errStrayEndTag(name); - break endtagloop; - } case AFTER_HEAD: switch (group) { case HTML: diff --git a/parser/html/nsHtml5TreeBuilder.cpp b/parser/html/nsHtml5TreeBuilder.cpp index f353a02eb73d..671f902f4a14 100644 --- a/parser/html/nsHtml5TreeBuilder.cpp +++ b/parser/html/nsHtml5TreeBuilder.cpp @@ -51,6 +51,7 @@ #include "nsAHtml5TreeBuilderState.h" #include "nsHtml5Highlighter.h" #include "nsHtml5ViewSourceUtils.h" +#include "mozilla/Likely.h" #include "nsHtml5Tokenizer.h" #include "nsHtml5MetaScanner.h" @@ -64,8 +65,6 @@ #include "nsHtml5TreeBuilder.h" -#include "mozilla/Likely.h" - PRUnichar nsHtml5TreeBuilder::REPLACEMENT_CHARACTER[] = { 0xfffd }; static const char* const QUIRKY_PUBLIC_IDS_DATA[] = { "+//silmaril//dtd html pro v0r11 19970101//", "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", "-//as//dtd html 3.0 aswedit + extensions//", "-//ietf//dtd html 2.0 level 1//", "-//ietf//dtd html 2.0 level 2//", "-//ietf//dtd html 2.0 strict level 1//", "-//ietf//dtd html 2.0 strict level 2//", "-//ietf//dtd html 2.0 strict//", "-//ietf//dtd html 2.0//", "-//ietf//dtd html 2.1e//", "-//ietf//dtd html 3.0//", "-//ietf//dtd html 3.2 final//", "-//ietf//dtd html 3.2//", "-//ietf//dtd html 3//", "-//ietf//dtd html level 0//", "-//ietf//dtd html level 1//", "-//ietf//dtd html level 2//", "-//ietf//dtd html level 3//", "-//ietf//dtd html strict level 0//", "-//ietf//dtd html strict level 1//", "-//ietf//dtd html strict level 2//", "-//ietf//dtd html strict level 3//", "-//ietf//dtd html strict//", "-//ietf//dtd html//", "-//metrius//dtd metrius presentational//", "-//microsoft//dtd internet explorer 2.0 html strict//", "-//microsoft//dtd internet explorer 2.0 html//", "-//microsoft//dtd internet explorer 2.0 tables//", "-//microsoft//dtd internet explorer 3.0 html strict//", "-//microsoft//dtd internet explorer 3.0 html//", "-//microsoft//dtd internet explorer 3.0 tables//", "-//netscape comm. corp.//dtd html//", "-//netscape comm. corp.//dtd strict html//", "-//o'reilly and associates//dtd html 2.0//", "-//o'reilly and associates//dtd html extended 1.0//", "-//o'reilly and associates//dtd html extended relaxed 1.0//", "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", "-//spyglass//dtd html 2.0 extended//", "-//sq//dtd html 2.0 hotmetal + extensions//", "-//sun microsystems corp.//dtd hotjava html//", "-//sun microsystems corp.//dtd hotjava strict html//", "-//w3c//dtd html 3 1995-03-24//", "-//w3c//dtd html 3.2 draft//", "-//w3c//dtd html 3.2 final//", "-//w3c//dtd html 3.2//", "-//w3c//dtd html 3.2s draft//", "-//w3c//dtd html 4.0 frameset//", "-//w3c//dtd html 4.0 transitional//", "-//w3c//dtd html experimental 19960712//", "-//w3c//dtd html experimental 970421//", "-//w3c//dtd w3 html//", "-//w3o//dtd w3 html 3.0//", "-//webtechs//dtd mozilla html 2.0//", "-//webtechs//dtd mozilla html//" }; staticJArray nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS = { QUIRKY_PUBLIC_IDS_DATA, NS_ARRAY_LENGTH(QUIRKY_PUBLIC_IDS_DATA) }; @@ -125,28 +124,21 @@ void nsHtml5TreeBuilder::doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks) { needToDropLF = false; - if (!isInForeign()) { - switch(mode) { - case NS_HTML5TREE_BUILDER_INITIAL: { - nsString* emptyString = nsHtml5Portability::newEmptyString(); - appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier); - nsHtml5Portability::releaseString(emptyString); - if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) { - errQuirkyDoctype(); - documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, false); - } else if (isAlmostStandards(publicIdentifier, systemIdentifier)) { - errAlmostStandardsDoctype(); - documentModeInternal(ALMOST_STANDARDS_MODE, publicIdentifier, systemIdentifier, false); - } else { - documentModeInternal(STANDARDS_MODE, publicIdentifier, systemIdentifier, false); - } - mode = NS_HTML5TREE_BUILDER_BEFORE_HTML; - return; - } - default: { - break; - } + if (!isInForeign() && mode == NS_HTML5TREE_BUILDER_INITIAL) { + nsString* emptyString = nsHtml5Portability::newEmptyString(); + appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier); + nsHtml5Portability::releaseString(emptyString); + if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) { + errQuirkyDoctype(); + documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, false); + } else if (isAlmostStandards(publicIdentifier, systemIdentifier)) { + errAlmostStandardsDoctype(); + documentModeInternal(ALMOST_STANDARDS_MODE, publicIdentifier, systemIdentifier, false); + } else { + documentModeInternal(STANDARDS_MODE, publicIdentifier, systemIdentifier, false); } + mode = NS_HTML5TREE_BUILDER_BEFORE_HTML; + return; } errStrayDoctype(); return; @@ -637,6 +629,36 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu } } switch(mode) { + case NS_HTML5TREE_BUILDER_IN_ROW: { + switch(group) { + case NS_HTML5TREE_BUILDER_TD_OR_TH: { + clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TR)); + appendToCurrentNodeAndPushElement(elementName, attributes); + mode = NS_HTML5TREE_BUILDER_IN_CELL; + insertMarker(); + attributes = nullptr; + NS_HTML5_BREAK(starttagloop); + } + case NS_HTML5TREE_BUILDER_CAPTION: + case NS_HTML5TREE_BUILDER_COL: + case NS_HTML5TREE_BUILDER_COLGROUP: + case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: + case NS_HTML5TREE_BUILDER_TR: { + eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR); + if (!eltPos) { + MOZ_ASSERT(fragment); + errNoTableRowToClose(); + NS_HTML5_BREAK(starttagloop); + } + clearStackBackTo(eltPos); + pop(); + mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; + continue; + } + default: + ; // fall through + } + } case NS_HTML5TREE_BUILDER_IN_TABLE_BODY: { switch(group) { case NS_HTML5TREE_BUILDER_TR: { @@ -672,36 +694,6 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu ; // fall through } } - case NS_HTML5TREE_BUILDER_IN_ROW: { - switch(group) { - case NS_HTML5TREE_BUILDER_TD_OR_TH: { - clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TR)); - appendToCurrentNodeAndPushElement(elementName, attributes); - mode = NS_HTML5TREE_BUILDER_IN_CELL; - insertMarker(); - attributes = nullptr; - NS_HTML5_BREAK(starttagloop); - } - case NS_HTML5TREE_BUILDER_CAPTION: - case NS_HTML5TREE_BUILDER_COL: - case NS_HTML5TREE_BUILDER_COLGROUP: - case NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT: - case NS_HTML5TREE_BUILDER_TR: { - eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TR); - if (!eltPos) { - MOZ_ASSERT(fragment); - errNoTableRowToClose(); - NS_HTML5_BREAK(starttagloop); - } - clearStackBackTo(eltPos); - pop(); - mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; - continue; - } - default: - ; // fall through - } - } case NS_HTML5TREE_BUILDER_IN_TABLE: { for (; ; ) { switch(group) { @@ -2534,6 +2526,45 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) } } } + case NS_HTML5TREE_BUILDER_IN_HEAD: { + switch(group) { + case NS_HTML5TREE_BUILDER_HEAD: { + pop(); + mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; + NS_HTML5_BREAK(endtagloop); + } + case NS_HTML5TREE_BUILDER_BR: + case NS_HTML5TREE_BUILDER_HTML: + case NS_HTML5TREE_BUILDER_BODY: { + pop(); + mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; + continue; + } + default: { + errStrayEndTag(name); + NS_HTML5_BREAK(endtagloop); + } + } + } + case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: { + switch(group) { + case NS_HTML5TREE_BUILDER_NOSCRIPT: { + pop(); + mode = NS_HTML5TREE_BUILDER_IN_HEAD; + NS_HTML5_BREAK(endtagloop); + } + case NS_HTML5TREE_BUILDER_BR: { + errStrayEndTag(name); + pop(); + mode = NS_HTML5TREE_BUILDER_IN_HEAD; + continue; + } + default: { + errStrayEndTag(name); + NS_HTML5_BREAK(endtagloop); + } + } + } case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: { switch(group) { case NS_HTML5TREE_BUILDER_COLGROUP: { @@ -2718,45 +2749,6 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) } } } - case NS_HTML5TREE_BUILDER_IN_HEAD: { - switch(group) { - case NS_HTML5TREE_BUILDER_HEAD: { - pop(); - mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; - NS_HTML5_BREAK(endtagloop); - } - case NS_HTML5TREE_BUILDER_BR: - case NS_HTML5TREE_BUILDER_HTML: - case NS_HTML5TREE_BUILDER_BODY: { - pop(); - mode = NS_HTML5TREE_BUILDER_AFTER_HEAD; - continue; - } - default: { - errStrayEndTag(name); - NS_HTML5_BREAK(endtagloop); - } - } - } - case NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT: { - switch(group) { - case NS_HTML5TREE_BUILDER_NOSCRIPT: { - pop(); - mode = NS_HTML5TREE_BUILDER_IN_HEAD; - NS_HTML5_BREAK(endtagloop); - } - case NS_HTML5TREE_BUILDER_BR: { - errStrayEndTag(name); - pop(); - mode = NS_HTML5TREE_BUILDER_IN_HEAD; - continue; - } - default: { - errStrayEndTag(name); - NS_HTML5_BREAK(endtagloop); - } - } - } case NS_HTML5TREE_BUILDER_AFTER_HEAD: { switch(group) { case NS_HTML5TREE_BUILDER_HTML: diff --git a/parser/html/nsHtml5TreeBuilder.h b/parser/html/nsHtml5TreeBuilder.h index c31cb666942d..0063958223c8 100644 --- a/parser/html/nsHtml5TreeBuilder.h +++ b/parser/html/nsHtml5TreeBuilder.h @@ -52,6 +52,7 @@ #include "nsAHtml5TreeBuilderState.h" #include "nsHtml5Highlighter.h" #include "nsHtml5ViewSourceUtils.h" +#include "mozilla/Likely.h" class nsHtml5StreamParser; @@ -318,28 +319,28 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState #define NS_HTML5TREE_BUILDER_FONT 64 #define NS_HTML5TREE_BUILDER_KEYGEN 65 #define NS_HTML5TREE_BUILDER_MENUITEM 66 -#define NS_HTML5TREE_BUILDER_INITIAL 0 -#define NS_HTML5TREE_BUILDER_BEFORE_HTML 1 -#define NS_HTML5TREE_BUILDER_BEFORE_HEAD 2 -#define NS_HTML5TREE_BUILDER_IN_HEAD 3 -#define NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT 4 -#define NS_HTML5TREE_BUILDER_AFTER_HEAD 5 +#define NS_HTML5TREE_BUILDER_IN_ROW 0 +#define NS_HTML5TREE_BUILDER_IN_TABLE_BODY 1 +#define NS_HTML5TREE_BUILDER_IN_TABLE 2 +#define NS_HTML5TREE_BUILDER_IN_CAPTION 3 +#define NS_HTML5TREE_BUILDER_IN_CELL 4 +#define NS_HTML5TREE_BUILDER_FRAMESET_OK 5 #define NS_HTML5TREE_BUILDER_IN_BODY 6 -#define NS_HTML5TREE_BUILDER_IN_TABLE 7 -#define NS_HTML5TREE_BUILDER_IN_CAPTION 8 +#define NS_HTML5TREE_BUILDER_IN_HEAD 7 +#define NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT 8 #define NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP 9 -#define NS_HTML5TREE_BUILDER_IN_TABLE_BODY 10 -#define NS_HTML5TREE_BUILDER_IN_ROW 11 -#define NS_HTML5TREE_BUILDER_IN_CELL 12 -#define NS_HTML5TREE_BUILDER_IN_SELECT 13 -#define NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE 14 -#define NS_HTML5TREE_BUILDER_AFTER_BODY 15 -#define NS_HTML5TREE_BUILDER_IN_FRAMESET 16 -#define NS_HTML5TREE_BUILDER_AFTER_FRAMESET 17 -#define NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY 18 -#define NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET 19 -#define NS_HTML5TREE_BUILDER_TEXT 20 -#define NS_HTML5TREE_BUILDER_FRAMESET_OK 21 +#define NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE 10 +#define NS_HTML5TREE_BUILDER_IN_SELECT 11 +#define NS_HTML5TREE_BUILDER_AFTER_BODY 12 +#define NS_HTML5TREE_BUILDER_IN_FRAMESET 13 +#define NS_HTML5TREE_BUILDER_AFTER_FRAMESET 14 +#define NS_HTML5TREE_BUILDER_INITIAL 15 +#define NS_HTML5TREE_BUILDER_BEFORE_HTML 16 +#define NS_HTML5TREE_BUILDER_BEFORE_HEAD 17 +#define NS_HTML5TREE_BUILDER_AFTER_HEAD 18 +#define NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY 19 +#define NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET 20 +#define NS_HTML5TREE_BUILDER_TEXT 21 #define NS_HTML5TREE_BUILDER_CHARSET_INITIAL 0 #define NS_HTML5TREE_BUILDER_CHARSET_C 1 #define NS_HTML5TREE_BUILDER_CHARSET_H 2