Bug 897143 - Update parser algorithms to be namespace aware. r=hsivonen

This commit is contained in:
William Chen 2013-08-12 14:46:12 -07:00
parent bcbcfbfe2f
commit d471fc9c9f
3 changed files with 79 additions and 55 deletions

View File

@ -1350,12 +1350,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
flushCharacters();
// Note: Can't attach error messages to EOF in C++ yet
eofloop: for (;;) {
if (isInForeign()) {
// [NOCPP[
err("End of file in a foreign namespace context.");
// ]NOCPP]
break eofloop;
}
switch (mode) {
case INITIAL:
/*
@ -2101,9 +2095,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
break;
} else if (node.isSpecial()
&& node.name != "p"
&& node.name != "address"
&& node.name != "div") {
&& (node.ns != "http://www.w3.org/1999/xhtml"
|| (node.name != "p"
&& node.name != "address"
&& node.name != "div"))) {
break;
}
eltPos--;
@ -3728,7 +3723,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
eltPos = currentPtr;
for (;;) {
StackNode<T> node = stack[eltPos];
if (node.name == name) {
if (node.ns == "http://www.w3.org/1999/xhtml" && node.name == name) {
generateImpliedEndTags();
if (errorHandler != null
&& !isCurrent(name)) {
@ -4052,7 +4047,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private int findLast(@Local String name) {
for (int i = currentPtr; i > 0; i--) {
if (stack[i].name == name) {
if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
return i;
}
}
@ -4061,10 +4056,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private int findLastInTableScope(@Local String name) {
for (int i = currentPtr; i > 0; i--) {
if (stack[i].name == name) {
return i;
} else if (stack[i].name == "table" || stack[i].name == "template") {
return TreeBuilder.NOT_FOUND_ON_STACK;
if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
if (stack[i].name == name) {
return i;
} else if (stack[i].name == "table" || stack[i].name == "template") {
return TreeBuilder.NOT_FOUND_ON_STACK;
}
}
}
return TreeBuilder.NOT_FOUND_ON_STACK;
@ -4072,9 +4069,15 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private int findLastInButtonScope(@Local String name) {
for (int i = currentPtr; i > 0; i--) {
if (stack[i].name == name) {
return i;
} else if (stack[i].isScoping() || stack[i].name == "button") {
if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
if (stack[i].name == name) {
return i;
} else if (stack[i].name == "button") {
return TreeBuilder.NOT_FOUND_ON_STACK;
}
}
if (stack[i].isScoping()) {
return TreeBuilder.NOT_FOUND_ON_STACK;
}
}
@ -4083,7 +4086,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private int findLastInScope(@Local String name) {
for (int i = currentPtr; i > 0; i--) {
if (stack[i].name == name) {
if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
return i;
} else if (stack[i].isScoping()) {
return TreeBuilder.NOT_FOUND_ON_STACK;
@ -4094,9 +4097,15 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private int findLastInListScope(@Local String name) {
for (int i = currentPtr; i > 0; i--) {
if (stack[i].name == name) {
return i;
} else if (stack[i].isScoping() || stack[i].name == "ul" || stack[i].name == "ol") {
if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
if (stack[i].name == name) {
return i;
} else if (stack[i].name == "ul" || stack[i].name == "ol") {
return TreeBuilder.NOT_FOUND_ON_STACK;
}
}
if (stack[i].isScoping()) {
return TreeBuilder.NOT_FOUND_ON_STACK;
}
}
@ -4125,7 +4134,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
case OPTION:
case OPTGROUP:
case RT_OR_RP:
if (node.name == name) {
if (node.ns == "http://www.w3.org/1999/xhtml" && node.name == name) {
return;
}
pop();
@ -4271,10 +4280,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private int findLastInTableScopeTdTh() {
for (int i = currentPtr; i > 0; i--) {
@Local String name = stack[i].name;
if ("td" == name || "th" == name) {
return i;
} else if (name == "table" || name == "template") {
return TreeBuilder.NOT_FOUND_ON_STACK;
if (stack[i].ns == "http://www.w3.org/1999/xhtml") {
if ("td" == name || "th" == name) {
return i;
} else if (name == "table" || name == "template") {
return TreeBuilder.NOT_FOUND_ON_STACK;
}
}
}
return TreeBuilder.NOT_FOUND_ON_STACK;
@ -4283,7 +4294,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private void clearStackBackTo(int eltPos) throws SAXException {
int eltGroup = stack[eltPos].getGroup();
while (currentPtr > eltPos) { // > not >= intentional
if (stack[currentPtr].getGroup() == TEMPLATE
if (stack[currentPtr].ns == "http://www.w3.org/1999/xhtml"
&& stack[currentPtr].getGroup() == TEMPLATE
&& (eltGroup == TABLE || eltGroup == TBODY_OR_THEAD_OR_TFOOT|| eltGroup == TR || eltGroup == HTML)) {
return;
}
@ -4454,7 +4466,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
@Inline private boolean isCurrent(@Local String name) {
return name == stack[currentPtr].name;
return stack[currentPtr].ns == "http://www.w3.org/1999/xhtml" &&
name == stack[currentPtr].name;
}
private void removeFromStack(int pos) throws SAXException {
@ -4737,7 +4750,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private int findLastOrRoot(@Local String name) {
for (int i = currentPtr; i > 0; i--) {
if (stack[i].name == name) {
if (stack[i].ns == "http://www.w3.org/1999/xhtml" && stack[i].name == name) {
return i;
}
}

View File

@ -450,9 +450,6 @@ nsHtml5TreeBuilder::eof()
{
flushCharacters();
for (; ; ) {
if (isInForeign()) {
NS_HTML5_BREAK(eofloop);
}
switch(mode) {
case NS_HTML5TREE_BUILDER_INITIAL: {
documentModeInternal(QUIRKS_MODE, nullptr, nullptr, false);
@ -1080,7 +1077,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
pop();
}
break;
} else if (node->isSpecial() && node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div) {
} else if (node->isSpecial() && (node->ns != kNameSpaceID_XHTML || (node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div))) {
break;
}
eltPos--;
@ -2662,7 +2659,7 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName)
eltPos = currentPtr;
for (; ; ) {
nsHtml5StackNode* node = stack[eltPos];
if (node->name == name) {
if (node->ns == kNameSpaceID_XHTML && node->name == name) {
generateImpliedEndTags();
if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
errUnclosedElements(eltPos, name);
@ -2992,7 +2989,7 @@ int32_t
nsHtml5TreeBuilder::findLast(nsIAtom* name)
{
for (int32_t i = currentPtr; i > 0; i--) {
if (stack[i]->name == name) {
if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
return i;
}
}
@ -3003,10 +3000,12 @@ int32_t
nsHtml5TreeBuilder::findLastInTableScope(nsIAtom* name)
{
for (int32_t i = currentPtr; i > 0; i--) {
if (stack[i]->name == name) {
return i;
} else if (stack[i]->name == nsHtml5Atoms::table || stack[i]->name == nsHtml5Atoms::template_) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
if (stack[i]->ns == kNameSpaceID_XHTML) {
if (stack[i]->name == name) {
return i;
} else if (stack[i]->name == nsHtml5Atoms::table || stack[i]->name == nsHtml5Atoms::template_) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
}
}
}
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
@ -3016,9 +3015,14 @@ int32_t
nsHtml5TreeBuilder::findLastInButtonScope(nsIAtom* name)
{
for (int32_t i = currentPtr; i > 0; i--) {
if (stack[i]->name == name) {
return i;
} else if (stack[i]->isScoping() || stack[i]->name == nsHtml5Atoms::button) {
if (stack[i]->ns == kNameSpaceID_XHTML) {
if (stack[i]->name == name) {
return i;
} else if (stack[i]->name == nsHtml5Atoms::button) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
}
}
if (stack[i]->isScoping()) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
}
}
@ -3029,7 +3033,7 @@ int32_t
nsHtml5TreeBuilder::findLastInScope(nsIAtom* name)
{
for (int32_t i = currentPtr; i > 0; i--) {
if (stack[i]->name == name) {
if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
return i;
} else if (stack[i]->isScoping()) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
@ -3042,9 +3046,14 @@ int32_t
nsHtml5TreeBuilder::findLastInListScope(nsIAtom* name)
{
for (int32_t i = currentPtr; i > 0; i--) {
if (stack[i]->name == name) {
return i;
} else if (stack[i]->isScoping() || stack[i]->name == nsHtml5Atoms::ul || stack[i]->name == nsHtml5Atoms::ol) {
if (stack[i]->ns == kNameSpaceID_XHTML) {
if (stack[i]->name == name) {
return i;
} else if (stack[i]->name == nsHtml5Atoms::ul || stack[i]->name == nsHtml5Atoms::ol) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
}
}
if (stack[i]->isScoping()) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
}
}
@ -3076,7 +3085,7 @@ nsHtml5TreeBuilder::generateImpliedEndTagsExceptFor(nsIAtom* name)
case NS_HTML5TREE_BUILDER_OPTION:
case NS_HTML5TREE_BUILDER_OPTGROUP:
case NS_HTML5TREE_BUILDER_RT_OR_RP: {
if (node->name == name) {
if (node->ns == kNameSpaceID_XHTML && node->name == name) {
return;
}
pop();
@ -3203,10 +3212,12 @@ nsHtml5TreeBuilder::findLastInTableScopeTdTh()
{
for (int32_t i = currentPtr; i > 0; i--) {
nsIAtom* name = stack[i]->name;
if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) {
return i;
} else if (name == nsHtml5Atoms::table || name == nsHtml5Atoms::template_) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
if (stack[i]->ns == kNameSpaceID_XHTML) {
if (nsHtml5Atoms::td == name || nsHtml5Atoms::th == name) {
return i;
} else if (name == nsHtml5Atoms::table || name == nsHtml5Atoms::template_) {
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
}
}
}
return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
@ -3217,7 +3228,7 @@ nsHtml5TreeBuilder::clearStackBackTo(int32_t eltPos)
{
int32_t eltGroup = stack[eltPos]->getGroup();
while (currentPtr > eltPos) {
if (stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE && (eltGroup == NS_HTML5TREE_BUILDER_TABLE || eltGroup == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || eltGroup == NS_HTML5TREE_BUILDER_TR || eltGroup == NS_HTML5TREE_BUILDER_HTML)) {
if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE && (eltGroup == NS_HTML5TREE_BUILDER_TABLE || eltGroup == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || eltGroup == NS_HTML5TREE_BUILDER_TR || eltGroup == NS_HTML5TREE_BUILDER_HTML)) {
return;
}
pop();
@ -3632,7 +3643,7 @@ int32_t
nsHtml5TreeBuilder::findLastOrRoot(nsIAtom* name)
{
for (int32_t i = currentPtr; i > 0; i--) {
if (stack[i]->name == name) {
if (stack[i]->ns == kNameSpaceID_XHTML && stack[i]->name == name) {
return i;
}
}

View File

@ -154,7 +154,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void clearTheListOfActiveFormattingElementsUpToTheLastMarker();
inline bool isCurrent(nsIAtom* name)
{
return name == stack[currentPtr]->name;
return stack[currentPtr]->ns == kNameSpaceID_XHTML && name == stack[currentPtr]->name;
}
void removeFromStack(int32_t pos);