Bug 897153 - Update parsing of template element to spec as of July 15, 2013. r=hsivonen

This commit is contained in:
William Chen 2013-08-12 14:46:12 -07:00
parent 33d6dd2ae8
commit 5dfa68445b
5 changed files with 156 additions and 145 deletions

View File

@ -726,7 +726,7 @@ public final class ElementName
public static final ElementName QUOTIENT = new ElementName("quotient", "quotient", TreeBuilder.OTHER); public static final ElementName QUOTIENT = new ElementName("quotient", "quotient", TreeBuilder.OTHER);
public static final ElementName SELECTOR = new ElementName("selector", "selector", TreeBuilder.OTHER); public static final ElementName SELECTOR = new ElementName("selector", "selector", TreeBuilder.OTHER);
public static final ElementName TEXTAREA = new ElementName("textarea", "textarea", TreeBuilder.TEXTAREA | SPECIAL); public static final ElementName TEXTAREA = new ElementName("textarea", "textarea", TreeBuilder.TEXTAREA | SPECIAL);
public static final ElementName TEMPLATE = new ElementName("template", "template", TreeBuilder.TEMPLATE | SPECIAL); public static final ElementName TEMPLATE = new ElementName("template", "template", TreeBuilder.TEMPLATE | SPECIAL | SCOPING);
public static final ElementName TEXTPATH = new ElementName("textpath", "textPath", TreeBuilder.OTHER); public static final ElementName TEXTPATH = new ElementName("textpath", "textPath", TreeBuilder.OTHER);
public static final ElementName VARIANCE = new ElementName("variance", "variance", TreeBuilder.OTHER); public static final ElementName VARIANCE = new ElementName("variance", "variance", TreeBuilder.OTHER);
public static final ElementName ANIMATION = new ElementName("animation", "animation", TreeBuilder.OTHER); public static final ElementName ANIMATION = new ElementName("animation", "animation", TreeBuilder.OTHER);

View File

@ -273,7 +273,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private static final int TEXT = 21; private static final int TEXT = 21;
private static final int TEMPLATE_CONTENTS = 22; private static final int IN_TEMPLATE = 22;
// start charset states // start charset states
@ -619,7 +619,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
currentPtr++; currentPtr++;
stack[currentPtr] = node; stack[currentPtr] = node;
if ("template" == contextName) { if ("template" == contextName) {
pushTemplateMode(TEMPLATE_CONTENTS); pushTemplateMode(IN_TEMPLATE);
} }
resetTheInsertionMode(); resetTheInsertionMode();
if ("title" == contextName || "textarea" == contextName) { if ("title" == contextName || "textarea" == contextName) {
@ -1011,7 +1011,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
*/ */
continue; continue;
case FRAMESET_OK: case FRAMESET_OK:
case TEMPLATE_CONTENTS: case IN_TEMPLATE:
case IN_BODY: case IN_BODY:
case IN_CELL: case IN_CELL:
case IN_CAPTION: case IN_CAPTION:
@ -1210,7 +1210,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
mode = IN_BODY; mode = IN_BODY;
i--; i--;
continue; continue;
case TEMPLATE_CONTENTS: case IN_TEMPLATE:
case IN_BODY: case IN_BODY:
case IN_CELL: case IN_CELL:
case IN_CAPTION: case IN_CAPTION:
@ -1428,15 +1428,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
appendToCurrentNodeAndPushBodyElement(); appendToCurrentNodeAndPushBodyElement();
mode = IN_BODY; mode = IN_BODY;
continue; continue;
case IN_TABLE_BODY:
case IN_ROW:
case IN_TABLE:
case IN_SELECT_IN_TABLE:
case IN_SELECT:
case IN_COLUMN_GROUP: case IN_COLUMN_GROUP:
if (currentPtr == 0) {
assert fragment;
break eofloop;
} else {
popOnEof();
mode = IN_TABLE;
continue;
}
case FRAMESET_OK: case FRAMESET_OK:
case IN_CAPTION: case IN_CAPTION:
case IN_CELL: case IN_CELL:
@ -1459,7 +1456,30 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
} }
// ]NOCPP] // ]NOCPP]
if (isTemplateModeStackEmpty()) {
break eofloop; break eofloop;
}
// fall through to IN_TEMPLATE
case IN_TEMPLATE:
int eltPos = findLast("template");
if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
assert fragment;
break eofloop;
}
if (errorHandler != null) {
errUnclosedElements(eltPos, "template");
}
while (currentPtr >= eltPos) {
pop();
}
clearTheListOfActiveFormattingElementsUpToTheLastMarker();
popTemplateMode();
resetTheInsertionMode();
// Reprocess token.
continue;
case TEXT: case TEXT:
// [NOCPP[ // [NOCPP[
if (errorHandler != null) { if (errorHandler != null) {
@ -1474,11 +1494,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
popOnEof(); popOnEof();
mode = originalMode; mode = originalMode;
continue; continue;
case IN_TABLE_BODY:
case IN_ROW:
case IN_TABLE:
case IN_SELECT:
case IN_SELECT_IN_TABLE:
case IN_FRAMESET: case IN_FRAMESET:
// [NOCPP[ // [NOCPP[
if (errorHandler != null && currentPtr > 0) { if (errorHandler != null && currentPtr > 0) {
@ -1486,17 +1501,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
// ]NOCPP] // ]NOCPP]
break eofloop; break eofloop;
case TEMPLATE_CONTENTS:
if (currentPtr == 0) {
assert fragment;
break eofloop;
}
// TODO: Parse error. Add error reporting.
popOnEof();
resetTheInsertionMode();
// Reprocess token.
continue;
case AFTER_BODY: case AFTER_BODY:
case AFTER_FRAMESET: case AFTER_FRAMESET:
case AFTER_AFTER_BODY: case AFTER_AFTER_BODY:
@ -1648,14 +1652,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} // foreignObject / annotation-xml } // foreignObject / annotation-xml
} }
switch (mode) { switch (mode) {
case TEMPLATE_CONTENTS: case IN_TEMPLATE:
switch (group) { switch (group) {
case FRAME:
popTemplateMode();
pushTemplateMode(IN_FRAMESET);
mode = IN_FRAMESET;
// Reprocess token.
continue;
case COL: case COL:
popTemplateMode(); popTemplateMode();
pushTemplateMode(IN_COLUMN_GROUP); pushTemplateMode(IN_COLUMN_GROUP);
@ -1690,6 +1688,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
selfClosing = false; selfClosing = false;
attributes = null; // CPP attributes = null; // CPP
break starttagloop; break starttagloop;
case TITLE:
startTagTitleInHead(elementName, attributes);
attributes = null; // CPP
break starttagloop;
case BASE:
case LINK_OR_BASEFONT_OR_BGSOUND: case LINK_OR_BASEFONT_OR_BGSOUND:
appendVoidElementToCurrentMayFoster( appendVoidElementToCurrentMayFoster(
elementName, elementName,
@ -1701,6 +1704,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
startTagScriptInHead(elementName, attributes); startTagScriptInHead(elementName, attributes);
attributes = null; // CPP attributes = null; // CPP
break starttagloop; break starttagloop;
case NOFRAMES:
case STYLE: case STYLE:
startTagGenericRawText(elementName, attributes); startTagGenericRawText(elementName, attributes);
attributes = null; // CPP attributes = null; // CPP
@ -2469,6 +2473,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
break starttagloop; break starttagloop;
case BASE: case BASE:
case COMMAND: case COMMAND:
case LINK_OR_BASEFONT_OR_BGSOUND:
appendVoidElementToCurrentMayFoster( appendVoidElementToCurrentMayFoster(
elementName, elementName,
attributes); attributes);
@ -2476,17 +2481,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
attributes = null; // CPP attributes = null; // CPP
break starttagloop; break starttagloop;
case META: case META:
case LINK_OR_BASEFONT_OR_BGSOUND:
// Fall through to IN_HEAD_NOSCRIPT // Fall through to IN_HEAD_NOSCRIPT
break inheadloop; break inheadloop;
case TITLE: case TITLE:
appendToCurrentNodeAndPushElementMayFoster( startTagTitleInHead(elementName, attributes);
elementName,
attributes);
originalMode = mode;
mode = TEXT;
tokenizer.setStateAndEndTagExpectation(
Tokenizer.RCDATA, elementName);
attributes = null; // CPP attributes = null; // CPP
break starttagloop; break starttagloop;
case NOSCRIPT: case NOSCRIPT:
@ -2729,10 +2727,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
selfClosing = false; selfClosing = false;
attributes = null; // CPP attributes = null; // CPP
break starttagloop; break starttagloop;
case TEMPLATE:
startTagTemplateInHead(elementName, attributes);
attributes = null; // CPP
break starttagloop;
default: default:
// fall through to AFTER_FRAMESET // fall through to AFTER_FRAMESET
} }
@ -3028,6 +3022,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
} }
private void startTagTitleInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {
appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
originalMode = mode;
mode = TEXT;
tokenizer.setStateAndEndTagExpectation(Tokenizer.RCDATA, elementName);
}
private void startTagGenericRawText(ElementName elementName, HtmlAttributes attributes) throws SAXException { private void startTagGenericRawText(ElementName elementName, HtmlAttributes attributes) throws SAXException {
appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
originalMode = mode; originalMode = mode;
@ -3044,17 +3045,22 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
private void startTagTemplateInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException { private void startTagTemplateInHead(ElementName elementName, HtmlAttributes attributes) throws SAXException {
insertMarker();
appendToCurrentNodeAndPushElement(elementName, attributes); appendToCurrentNodeAndPushElement(elementName, attributes);
insertMarker();
framesetOk = false;
originalMode = mode; originalMode = mode;
mode = TEMPLATE_CONTENTS; mode = IN_TEMPLATE;
pushTemplateMode(TEMPLATE_CONTENTS); pushTemplateMode(IN_TEMPLATE);
} }
private boolean isTemplateContents() { private boolean isTemplateContents() {
return TreeBuilder.NOT_FOUND_ON_STACK != findLast("template"); return TreeBuilder.NOT_FOUND_ON_STACK != findLast("template");
} }
private boolean isTemplateModeStackEmpty() {
return templateModePtr == -1;
}
private boolean isSpecialParentInForeign(StackNode<T> stackNode) { private boolean isSpecialParentInForeign(StackNode<T> stackNode) {
@NsUri String ns = stackNode.ns; @NsUri String ns = stackNode.ns;
return ("http://www.w3.org/1999/xhtml" == ns) return ("http://www.w3.org/1999/xhtml" == ns)
@ -3281,7 +3287,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
} }
switch (mode) { switch (mode) {
case TEMPLATE_CONTENTS: case IN_TEMPLATE:
switch (group) { switch (group) {
case TEMPLATE: case TEMPLATE:
// fall through to IN_HEAD // fall through to IN_HEAD
@ -3753,7 +3759,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
mode = AFTER_HEAD; mode = AFTER_HEAD;
continue; continue;
case TEMPLATE: case TEMPLATE:
endTagTemplateInHead(name); endTagTemplateInHead();
break endtagloop; break endtagloop;
default: default:
errStrayEndTag(name); errStrayEndTag(name);
@ -3790,7 +3796,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
errStrayEndTag(name); errStrayEndTag(name);
break endtagloop; break endtagloop;
case TEMPLATE: case TEMPLATE:
endTagTemplateInHead(name); endTagTemplateInHead();
break endtagloop; break endtagloop;
default: default:
if (currentPtr == 0 || stack[currentPtr].getGroup() == if (currentPtr == 0 || stack[currentPtr].getGroup() ==
@ -3862,7 +3868,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
resetTheInsertionMode(); resetTheInsertionMode();
break endtagloop; break endtagloop;
case TEMPLATE: case TEMPLATE:
endTagTemplateInHead(name); endTagTemplateInHead();
break endtagloop; break endtagloop;
default: default:
errStrayEndTag(name); errStrayEndTag(name);
@ -3886,8 +3892,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
case IN_FRAMESET: case IN_FRAMESET:
switch (group) { switch (group) {
case FRAMESET: case FRAMESET:
if (currentPtr == 0 || isTemplateContents()) { if (currentPtr == 0) {
assert fragment || isTemplateContents(); assert fragment;
errStrayEndTag(name); errStrayEndTag(name);
break endtagloop; break endtagloop;
} }
@ -3896,9 +3902,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
mode = AFTER_FRAMESET; mode = AFTER_FRAMESET;
} }
break endtagloop; break endtagloop;
case TEMPLATE:
endTagTemplateInHead(name);
break endtagloop;
default: default:
errStrayEndTag(name); errStrayEndTag(name);
break endtagloop; break endtagloop;
@ -4017,15 +4020,15 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} // endtagloop } // endtagloop
} }
private void endTagTemplateInHead(@Local String name) throws SAXException { private void endTagTemplateInHead() throws SAXException {
int eltPos = findLast(name); int eltPos = findLast("template");
if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) { if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
errStrayEndTag(name); errStrayEndTag("template");
return; return;
} }
generateImpliedEndTags(); generateImpliedEndTags();
if (errorHandler != null && !isCurrent(name)) { if (errorHandler != null && !isCurrent("template")) {
errUnclosedElements(eltPos, name); errUnclosedElements(eltPos, "template");
} }
while (currentPtr >= eltPos) { while (currentPtr >= eltPos) {
pop(); pop();
@ -4320,11 +4323,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
return; return;
} }
} }
if ("template" == name) { if ("select" == name) {
assert templateModePtr >= 0;
mode = templateModeStack[templateModePtr];
return;
} else if ("select" == name) {
// TODO: Fragment case. Add error reporting. // TODO: Fragment case. Add error reporting.
mode = IN_SELECT; mode = IN_SELECT;
return; return;
@ -4350,6 +4349,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} else if ("http://www.w3.org/1999/xhtml" != ns) { } else if ("http://www.w3.org/1999/xhtml" != ns) {
mode = framesetOk ? FRAMESET_OK : IN_BODY; mode = framesetOk ? FRAMESET_OK : IN_BODY;
return; return;
} else if ("template" == name) {
assert templateModePtr >= 0;
mode = templateModeStack[templateModePtr];
return;
} else if ("head" == name) { } else if ("head" == name) {
if (name == contextName) { if (name == contextName) {
// TODO: Fragment case. Add error reporting. // TODO: Fragment case. Add error reporting.

View File

@ -852,7 +852,7 @@ nsHtml5ElementName::initializeStatics()
ELT_QUOTIENT = new nsHtml5ElementName(nsHtml5Atoms::quotient, nsHtml5Atoms::quotient, NS_HTML5TREE_BUILDER_OTHER); ELT_QUOTIENT = new nsHtml5ElementName(nsHtml5Atoms::quotient, nsHtml5Atoms::quotient, NS_HTML5TREE_BUILDER_OTHER);
ELT_SELECTOR = new nsHtml5ElementName(nsHtml5Atoms::selector, nsHtml5Atoms::selector, NS_HTML5TREE_BUILDER_OTHER); ELT_SELECTOR = new nsHtml5ElementName(nsHtml5Atoms::selector, nsHtml5Atoms::selector, NS_HTML5TREE_BUILDER_OTHER);
ELT_TEXTAREA = new nsHtml5ElementName(nsHtml5Atoms::textarea, nsHtml5Atoms::textarea, NS_HTML5TREE_BUILDER_TEXTAREA | NS_HTML5ELEMENT_NAME_SPECIAL); ELT_TEXTAREA = new nsHtml5ElementName(nsHtml5Atoms::textarea, nsHtml5Atoms::textarea, NS_HTML5TREE_BUILDER_TEXTAREA | NS_HTML5ELEMENT_NAME_SPECIAL);
ELT_TEMPLATE = new nsHtml5ElementName(nsHtml5Atoms::template_, nsHtml5Atoms::template_, NS_HTML5TREE_BUILDER_TEMPLATE | NS_HTML5ELEMENT_NAME_SPECIAL); ELT_TEMPLATE = new nsHtml5ElementName(nsHtml5Atoms::template_, nsHtml5Atoms::template_, NS_HTML5TREE_BUILDER_TEMPLATE | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
ELT_TEXTPATH = new nsHtml5ElementName(nsHtml5Atoms::textpath, nsHtml5Atoms::textPath, NS_HTML5TREE_BUILDER_OTHER); ELT_TEXTPATH = new nsHtml5ElementName(nsHtml5Atoms::textpath, nsHtml5Atoms::textPath, NS_HTML5TREE_BUILDER_OTHER);
ELT_VARIANCE = new nsHtml5ElementName(nsHtml5Atoms::variance, nsHtml5Atoms::variance, NS_HTML5TREE_BUILDER_OTHER); ELT_VARIANCE = new nsHtml5ElementName(nsHtml5Atoms::variance, nsHtml5Atoms::variance, NS_HTML5TREE_BUILDER_OTHER);
ELT_ANIMATION = new nsHtml5ElementName(nsHtml5Atoms::animation, nsHtml5Atoms::animation, NS_HTML5TREE_BUILDER_OTHER); ELT_ANIMATION = new nsHtml5ElementName(nsHtml5Atoms::animation, nsHtml5Atoms::animation, NS_HTML5TREE_BUILDER_OTHER);

View File

@ -99,7 +99,7 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
currentPtr++; currentPtr++;
stack[currentPtr] = node; stack[currentPtr] = node;
if (nsHtml5Atoms::template_ == contextName) { if (nsHtml5Atoms::template_ == contextName) {
pushTemplateMode(NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS); pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TEMPLATE);
} }
resetTheInsertionMode(); resetTheInsertionMode();
if (nsHtml5Atoms::title == contextName || nsHtml5Atoms::textarea == contextName) { if (nsHtml5Atoms::title == contextName || nsHtml5Atoms::textarea == contextName) {
@ -237,7 +237,7 @@ nsHtml5TreeBuilder::characters(const PRUnichar* buf, int32_t start, int32_t leng
continue; continue;
} }
case NS_HTML5TREE_BUILDER_FRAMESET_OK: case NS_HTML5TREE_BUILDER_FRAMESET_OK:
case NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS: case NS_HTML5TREE_BUILDER_IN_TEMPLATE:
case NS_HTML5TREE_BUILDER_IN_BODY: case NS_HTML5TREE_BUILDER_IN_BODY:
case NS_HTML5TREE_BUILDER_IN_CELL: case NS_HTML5TREE_BUILDER_IN_CELL:
case NS_HTML5TREE_BUILDER_IN_CAPTION: { case NS_HTML5TREE_BUILDER_IN_CAPTION: {
@ -340,7 +340,7 @@ nsHtml5TreeBuilder::characters(const PRUnichar* buf, int32_t start, int32_t leng
i--; i--;
continue; continue;
} }
case NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS: case NS_HTML5TREE_BUILDER_IN_TEMPLATE:
case NS_HTML5TREE_BUILDER_IN_BODY: case NS_HTML5TREE_BUILDER_IN_BODY:
case NS_HTML5TREE_BUILDER_IN_CELL: case NS_HTML5TREE_BUILDER_IN_CELL:
case NS_HTML5TREE_BUILDER_IN_CAPTION: { case NS_HTML5TREE_BUILDER_IN_CAPTION: {
@ -485,22 +485,37 @@ nsHtml5TreeBuilder::eof()
mode = NS_HTML5TREE_BUILDER_IN_BODY; mode = NS_HTML5TREE_BUILDER_IN_BODY;
continue; continue;
} }
case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP: { case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
if (!currentPtr) { case NS_HTML5TREE_BUILDER_IN_ROW:
MOZ_ASSERT(fragment); case NS_HTML5TREE_BUILDER_IN_TABLE:
NS_HTML5_BREAK(eofloop); case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE:
} else { case NS_HTML5TREE_BUILDER_IN_SELECT:
popOnEof(); case NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP:
mode = NS_HTML5TREE_BUILDER_IN_TABLE;
continue;
}
}
case NS_HTML5TREE_BUILDER_FRAMESET_OK: case NS_HTML5TREE_BUILDER_FRAMESET_OK:
case NS_HTML5TREE_BUILDER_IN_CAPTION: case NS_HTML5TREE_BUILDER_IN_CAPTION:
case NS_HTML5TREE_BUILDER_IN_CELL: case NS_HTML5TREE_BUILDER_IN_CELL:
case NS_HTML5TREE_BUILDER_IN_BODY: { case NS_HTML5TREE_BUILDER_IN_BODY: {
if (isTemplateModeStackEmpty()) {
NS_HTML5_BREAK(eofloop); NS_HTML5_BREAK(eofloop);
} }
}
case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
int32_t eltPos = findLast(nsHtml5Atoms::template_);
if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
MOZ_ASSERT(fragment);
NS_HTML5_BREAK(eofloop);
}
if (MOZ_UNLIKELY(mViewSource)) {
errUnclosedElements(eltPos, nsHtml5Atoms::template_);
}
while (currentPtr >= eltPos) {
pop();
}
clearTheListOfActiveFormattingElementsUpToTheLastMarker();
popTemplateMode();
resetTheInsertionMode();
continue;
}
case NS_HTML5TREE_BUILDER_TEXT: { case NS_HTML5TREE_BUILDER_TEXT: {
if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) { if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) {
popOnEof(); popOnEof();
@ -509,23 +524,9 @@ nsHtml5TreeBuilder::eof()
mode = originalMode; mode = originalMode;
continue; continue;
} }
case NS_HTML5TREE_BUILDER_IN_TABLE_BODY:
case NS_HTML5TREE_BUILDER_IN_ROW:
case NS_HTML5TREE_BUILDER_IN_TABLE:
case NS_HTML5TREE_BUILDER_IN_SELECT:
case NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE:
case NS_HTML5TREE_BUILDER_IN_FRAMESET: { case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
NS_HTML5_BREAK(eofloop); NS_HTML5_BREAK(eofloop);
} }
case NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS: {
if (!currentPtr) {
MOZ_ASSERT(fragment);
NS_HTML5_BREAK(eofloop);
}
popOnEof();
resetTheInsertionMode();
continue;
}
case NS_HTML5TREE_BUILDER_AFTER_BODY: case NS_HTML5TREE_BUILDER_AFTER_BODY:
case NS_HTML5TREE_BUILDER_AFTER_FRAMESET: case NS_HTML5TREE_BUILDER_AFTER_FRAMESET:
case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY: case NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY:
@ -645,14 +646,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
} }
switch(mode) { switch(mode) {
case NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS: { case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
switch(group) { switch(group) {
case NS_HTML5TREE_BUILDER_FRAME: {
popTemplateMode();
pushTemplateMode(NS_HTML5TREE_BUILDER_IN_FRAMESET);
mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
continue;
}
case NS_HTML5TREE_BUILDER_COL: { case NS_HTML5TREE_BUILDER_COL: {
popTemplateMode(); popTemplateMode();
pushTemplateMode(NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP); pushTemplateMode(NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP);
@ -686,6 +681,12 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
attributes = nullptr; attributes = nullptr;
NS_HTML5_BREAK(starttagloop); NS_HTML5_BREAK(starttagloop);
} }
case NS_HTML5TREE_BUILDER_TITLE: {
startTagTitleInHead(elementName, attributes);
attributes = nullptr;
NS_HTML5_BREAK(starttagloop);
}
case NS_HTML5TREE_BUILDER_BASE:
case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: { case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
appendVoidElementToCurrentMayFoster(elementName, attributes); appendVoidElementToCurrentMayFoster(elementName, attributes);
selfClosing = false; selfClosing = false;
@ -697,6 +698,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
attributes = nullptr; attributes = nullptr;
NS_HTML5_BREAK(starttagloop); NS_HTML5_BREAK(starttagloop);
} }
case NS_HTML5TREE_BUILDER_NOFRAMES:
case NS_HTML5TREE_BUILDER_STYLE: { case NS_HTML5TREE_BUILDER_STYLE: {
startTagGenericRawText(elementName, attributes); startTagGenericRawText(elementName, attributes);
attributes = nullptr; attributes = nullptr;
@ -1394,21 +1396,18 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
NS_HTML5_BREAK(starttagloop); NS_HTML5_BREAK(starttagloop);
} }
case NS_HTML5TREE_BUILDER_BASE: case NS_HTML5TREE_BUILDER_BASE:
case NS_HTML5TREE_BUILDER_COMMAND: { case NS_HTML5TREE_BUILDER_COMMAND:
case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
appendVoidElementToCurrentMayFoster(elementName, attributes); appendVoidElementToCurrentMayFoster(elementName, attributes);
selfClosing = false; selfClosing = false;
attributes = nullptr; attributes = nullptr;
NS_HTML5_BREAK(starttagloop); NS_HTML5_BREAK(starttagloop);
} }
case NS_HTML5TREE_BUILDER_META: case NS_HTML5TREE_BUILDER_META: {
case NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND: {
NS_HTML5_BREAK(inheadloop); NS_HTML5_BREAK(inheadloop);
} }
case NS_HTML5TREE_BUILDER_TITLE: { case NS_HTML5TREE_BUILDER_TITLE: {
appendToCurrentNodeAndPushElementMayFoster(elementName, attributes); startTagTitleInHead(elementName, attributes);
originalMode = mode;
mode = NS_HTML5TREE_BUILDER_TEXT;
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName);
attributes = nullptr; attributes = nullptr;
NS_HTML5_BREAK(starttagloop); NS_HTML5_BREAK(starttagloop);
} }
@ -1663,11 +1662,6 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
attributes = nullptr; attributes = nullptr;
NS_HTML5_BREAK(starttagloop); NS_HTML5_BREAK(starttagloop);
} }
case NS_HTML5TREE_BUILDER_TEMPLATE: {
startTagTemplateInHead(elementName, attributes);
attributes = nullptr;
NS_HTML5_BREAK(starttagloop);
}
default: default:
; // fall through ; // fall through
} }
@ -1895,6 +1889,15 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
} }
void
nsHtml5TreeBuilder::startTagTitleInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
originalMode = mode;
mode = NS_HTML5TREE_BUILDER_TEXT;
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, elementName);
}
void void
nsHtml5TreeBuilder::startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{ {
@ -1916,11 +1919,12 @@ nsHtml5TreeBuilder::startTagScriptInHead(nsHtml5ElementName* elementName, nsHtml
void void
nsHtml5TreeBuilder::startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{ {
insertMarker();
appendToCurrentNodeAndPushElement(elementName, attributes); appendToCurrentNodeAndPushElement(elementName, attributes);
insertMarker();
framesetOk = false;
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS; mode = NS_HTML5TREE_BUILDER_IN_TEMPLATE;
pushTemplateMode(NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS); pushTemplateMode(NS_HTML5TREE_BUILDER_IN_TEMPLATE);
} }
bool bool
@ -1929,6 +1933,12 @@ nsHtml5TreeBuilder::isTemplateContents()
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLast(nsHtml5Atoms::template_); return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK != findLast(nsHtml5Atoms::template_);
} }
bool
nsHtml5TreeBuilder::isTemplateModeStackEmpty()
{
return templateModePtr == -1;
}
bool bool
nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode* stackNode) nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode* stackNode)
{ {
@ -2184,7 +2194,7 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
} }
} }
switch(mode) { switch(mode) {
case NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS: { case NS_HTML5TREE_BUILDER_IN_TEMPLATE: {
switch(group) { switch(group) {
case NS_HTML5TREE_BUILDER_TEMPLATE: { case NS_HTML5TREE_BUILDER_TEMPLATE: {
break; break;
@ -2692,7 +2702,7 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
continue; continue;
} }
case NS_HTML5TREE_BUILDER_TEMPLATE: { case NS_HTML5TREE_BUILDER_TEMPLATE: {
endTagTemplateInHead(name); endTagTemplateInHead();
NS_HTML5_BREAK(endtagloop); NS_HTML5_BREAK(endtagloop);
} }
default: { default: {
@ -2737,7 +2747,7 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
NS_HTML5_BREAK(endtagloop); NS_HTML5_BREAK(endtagloop);
} }
case NS_HTML5TREE_BUILDER_TEMPLATE: { case NS_HTML5TREE_BUILDER_TEMPLATE: {
endTagTemplateInHead(name); endTagTemplateInHead();
NS_HTML5_BREAK(endtagloop); NS_HTML5_BREAK(endtagloop);
} }
default: { default: {
@ -2815,7 +2825,7 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
NS_HTML5_BREAK(endtagloop); NS_HTML5_BREAK(endtagloop);
} }
case NS_HTML5TREE_BUILDER_TEMPLATE: { case NS_HTML5TREE_BUILDER_TEMPLATE: {
endTagTemplateInHead(name); endTagTemplateInHead();
NS_HTML5_BREAK(endtagloop); NS_HTML5_BREAK(endtagloop);
} }
default: { default: {
@ -2845,8 +2855,8 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
case NS_HTML5TREE_BUILDER_IN_FRAMESET: { case NS_HTML5TREE_BUILDER_IN_FRAMESET: {
switch(group) { switch(group) {
case NS_HTML5TREE_BUILDER_FRAMESET: { case NS_HTML5TREE_BUILDER_FRAMESET: {
if (!currentPtr || isTemplateContents()) { if (!currentPtr) {
MOZ_ASSERT(fragment || isTemplateContents()); MOZ_ASSERT(fragment);
errStrayEndTag(name); errStrayEndTag(name);
NS_HTML5_BREAK(endtagloop); NS_HTML5_BREAK(endtagloop);
} }
@ -2856,10 +2866,6 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
} }
NS_HTML5_BREAK(endtagloop); NS_HTML5_BREAK(endtagloop);
} }
case NS_HTML5TREE_BUILDER_TEMPLATE: {
endTagTemplateInHead(name);
NS_HTML5_BREAK(endtagloop);
}
default: { default: {
errStrayEndTag(name); errStrayEndTag(name);
NS_HTML5_BREAK(endtagloop); NS_HTML5_BREAK(endtagloop);
@ -2955,16 +2961,16 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
} }
void void
nsHtml5TreeBuilder::endTagTemplateInHead(nsIAtom* name) nsHtml5TreeBuilder::endTagTemplateInHead()
{ {
int32_t eltPos = findLast(name); int32_t eltPos = findLast(nsHtml5Atoms::template_);
if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) {
errStrayEndTag(name); errStrayEndTag(nsHtml5Atoms::template_);
return; return;
} }
generateImpliedEndTags(); generateImpliedEndTags();
if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) { if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(nsHtml5Atoms::template_)) {
errUnclosedElements(eltPos, name); errUnclosedElements(eltPos, nsHtml5Atoms::template_);
} }
while (currentPtr >= eltPos) { while (currentPtr >= eltPos) {
pop(); pop();
@ -3254,11 +3260,7 @@ nsHtml5TreeBuilder::resetTheInsertionMode()
return; return;
} }
} }
if (nsHtml5Atoms::template_ == name) { if (nsHtml5Atoms::select == name) {
MOZ_ASSERT(templateModePtr >= 0);
mode = templateModeStack[templateModePtr];
return;
} else if (nsHtml5Atoms::select == name) {
mode = NS_HTML5TREE_BUILDER_IN_SELECT; mode = NS_HTML5TREE_BUILDER_IN_SELECT;
return; return;
} else if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) { } else if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) {
@ -3282,6 +3284,10 @@ nsHtml5TreeBuilder::resetTheInsertionMode()
} else if (kNameSpaceID_XHTML != ns) { } else if (kNameSpaceID_XHTML != ns) {
mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;
return; return;
} else if (nsHtml5Atoms::template_ == name) {
MOZ_ASSERT(templateModePtr >= 0);
mode = templateModeStack[templateModePtr];
return;
} else if (nsHtml5Atoms::head == name) { } else if (nsHtml5Atoms::head == name) {
if (name == contextName) { if (name == contextName) {
mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY; mode = framesetOk ? NS_HTML5TREE_BUILDER_FRAMESET_OK : NS_HTML5TREE_BUILDER_IN_BODY;

View File

@ -109,10 +109,12 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void endTokenization(); void endTokenization();
void startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, bool selfClosing); void startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, bool selfClosing);
private: private:
void startTagTitleInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void startTagScriptInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void startTagScriptInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
bool isTemplateContents(); bool isTemplateContents();
bool isTemplateModeStackEmpty();
bool isSpecialParentInForeign(nsHtml5StackNode* stackNode); bool isSpecialParentInForeign(nsHtml5StackNode* stackNode);
public: public:
static nsString* extractCharsetFromContent(nsString* attributeValue); static nsString* extractCharsetFromContent(nsString* attributeValue);
@ -121,7 +123,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
public: public:
void endTag(nsHtml5ElementName* elementName); void endTag(nsHtml5ElementName* elementName);
private: private:
void endTagTemplateInHead(nsIAtom* name); void endTagTemplateInHead();
int32_t findLastInTableScopeOrRootTemplateTbodyTheadTfoot(); int32_t findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
int32_t findLast(nsIAtom* name); int32_t findLast(nsIAtom* name);
int32_t findLastInTableScope(nsIAtom* name); int32_t findLastInTableScope(nsIAtom* name);
@ -357,7 +359,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
#define NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY 19 #define NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY 19
#define NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET 20 #define NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET 20
#define NS_HTML5TREE_BUILDER_TEXT 21 #define NS_HTML5TREE_BUILDER_TEXT 21
#define NS_HTML5TREE_BUILDER_TEMPLATE_CONTENTS 22 #define NS_HTML5TREE_BUILDER_IN_TEMPLATE 22
#define NS_HTML5TREE_BUILDER_CHARSET_INITIAL 0 #define NS_HTML5TREE_BUILDER_CHARSET_INITIAL 0
#define NS_HTML5TREE_BUILDER_CHARSET_C 1 #define NS_HTML5TREE_BUILDER_CHARSET_C 1
#define NS_HTML5TREE_BUILDER_CHARSET_H 2 #define NS_HTML5TREE_BUILDER_CHARSET_H 2