Bug 590498 - Change popping condition when forcibly breaking out of foreign content in HTML5 parser. rs=jonas, a=blocking2.0-betaN.

--HG--
extra : rebase_source : 4b673ba39fd24d120347b9752ba04a4904f764cd
This commit is contained in:
Henri Sivonen 2010-09-15 11:37:55 +03:00
parent e63b49975a
commit 66cd476432
3 changed files with 54 additions and 22 deletions

View File

@ -1233,14 +1233,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
public final void eof() throws SAXException { public final void eof() throws SAXException {
flushCharacters(); flushCharacters();
if (inForeign) {
err("End of file in a foreign namespace context.");
while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") {
popOnEof();
}
inForeign = false;
}
eofloop: for (;;) { eofloop: for (;;) {
if (inForeign) {
err("End of file in a foreign namespace context.");
break eofloop;
}
switch (mode) { switch (mode) {
case INITIAL: case INITIAL:
/* /*
@ -1485,10 +1482,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
err("HTML start tag \u201C" err("HTML start tag \u201C"
+ name + name
+ "\u201D in a foreign namespace context."); + "\u201D in a foreign namespace context.");
while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") { while (!isSpecialParentInForeign(stack[currentPtr])) {
pop(); pop();
} }
inForeign = false; if (!hasForeignInScope()) {
inForeign = false;
}
continue starttagloop; continue starttagloop;
case FONT: case FONT:
if (attributes.contains(AttributeName.COLOR) if (attributes.contains(AttributeName.COLOR)
@ -1497,10 +1496,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
err("HTML start tag \u201C" err("HTML start tag \u201C"
+ name + name
+ "\u201D in a foreign namespace context."); + "\u201D in a foreign namespace context.");
while (stack[currentPtr].ns != "http://www.w3.org/1999/xhtml") { while (!isSpecialParentInForeign(stack[currentPtr])) {
pop(); pop();
} }
inForeign = false; if (!hasForeignInScope()) {
inForeign = false;
}
continue starttagloop; continue starttagloop;
} }
// else fall thru // else fall thru
@ -2915,6 +2916,19 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
} }
private boolean isSpecialParentInForeign(StackNode<T> stackNode) {
@NsUri String ns = stackNode.ns;
if ("http://www.w3.org/1999/xhtml" == ns) {
return true;
}
if (ns == "http://www.w3.org/2000/svg") {
return stackNode.group == FOREIGNOBJECT_OR_DESC
|| stackNode.group == TITLE;
}
assert ns == "http://www.w3.org/1998/Math/MathML" : "Unexpected namespace.";
return stackNode.group == MI_MO_MN_MS_MTEXT;
}
/** /**
* *
* <p> * <p>

View File

@ -430,14 +430,11 @@ void
nsHtml5TreeBuilder::eof() nsHtml5TreeBuilder::eof()
{ {
flushCharacters(); flushCharacters();
if (inForeign) {
while (stack[currentPtr]->ns != kNameSpaceID_XHTML) {
popOnEof();
}
inForeign = PR_FALSE;
}
for (; ; ) { for (; ; ) {
if (inForeign) {
NS_HTML5_BREAK(eofloop);
}
switch(mode) { switch(mode) {
case NS_HTML5TREE_BUILDER_INITIAL: { case NS_HTML5TREE_BUILDER_INITIAL: {
documentModeInternal(QUIRKS_MODE, nsnull, nsnull, PR_FALSE); documentModeInternal(QUIRKS_MODE, nsnull, nsnull, PR_FALSE);
@ -596,19 +593,23 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: case NS_HTML5TREE_BUILDER_PRE_OR_LISTING:
case NS_HTML5TREE_BUILDER_TABLE: { case NS_HTML5TREE_BUILDER_TABLE: {
while (stack[currentPtr]->ns != kNameSpaceID_XHTML) { while (!isSpecialParentInForeign(stack[currentPtr])) {
pop(); pop();
} }
inForeign = PR_FALSE; if (!hasForeignInScope()) {
inForeign = PR_FALSE;
}
NS_HTML5_CONTINUE(starttagloop); NS_HTML5_CONTINUE(starttagloop);
} }
case NS_HTML5TREE_BUILDER_FONT: { case NS_HTML5TREE_BUILDER_FONT: {
if (attributes->contains(nsHtml5AttributeName::ATTR_COLOR) || attributes->contains(nsHtml5AttributeName::ATTR_FACE) || attributes->contains(nsHtml5AttributeName::ATTR_SIZE)) { if (attributes->contains(nsHtml5AttributeName::ATTR_COLOR) || attributes->contains(nsHtml5AttributeName::ATTR_FACE) || attributes->contains(nsHtml5AttributeName::ATTR_SIZE)) {
while (stack[currentPtr]->ns != kNameSpaceID_XHTML) { while (!isSpecialParentInForeign(stack[currentPtr])) {
pop(); pop();
} }
inForeign = PR_FALSE; if (!hasForeignInScope()) {
inForeign = PR_FALSE;
}
NS_HTML5_CONTINUE(starttagloop); NS_HTML5_CONTINUE(starttagloop);
} }
} }
@ -1797,6 +1798,20 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
} }
PRBool
nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode* stackNode)
{
PRInt32 ns = stackNode->ns;
if (kNameSpaceID_XHTML == ns) {
return PR_TRUE;
}
if (ns == kNameSpaceID_SVG) {
return stackNode->group == NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC || stackNode->group == NS_HTML5TREE_BUILDER_TITLE;
}
return stackNode->group == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT;
}
nsString* nsString*
nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue) nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue)
{ {

View File

@ -105,6 +105,9 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void eof(); void eof();
void endTokenization(); void endTokenization();
void startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, PRBool selfClosing); void startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, PRBool selfClosing);
private:
PRBool isSpecialParentInForeign(nsHtml5StackNode* stackNode);
public:
static nsString* extractCharsetFromContent(nsString* attributeValue); static nsString* extractCharsetFromContent(nsString* attributeValue);
private: private:
void checkMetaCharset(nsHtml5HtmlAttributes* attributes); void checkMetaCharset(nsHtml5HtmlAttributes* attributes);