+2010-08-22 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ HTML5 TreeBuilder builds wrong DOM for <a><svg><tr><input></a>
+ https://bugs.webkit.org/show_bug.cgi?id=44390
+
+ The HTML5 spec has changed since Adam and I original wrote
+ the HTMLTreeBuilder. Most important for this change was resolution of:
+ http://www.w3.org/Bugs/Public/show_bug.cgi?id=9580
+
+ I also removed our "phrasing" tag support since that was also removed
+ from the spec as part of other bug fixes.
+
+ This is tested by tonyg's <a><svg><tr><input></a> test in adoption01.dat.
+
+ * html/HTMLTreeBuilder.cpp:
+ (WebCore::HTMLTreeBuilder::processCloseWhenNestedTag):
+ (WebCore::HTMLTreeBuilder::processAnyOtherEndTagForInBody):
+ (WebCore::HTMLTreeBuilder::furthestBlockForFormattingElement):
+ (WebCore::HTMLTreeBuilder::processEndTag):
+
2010-08-22 Andreas Kling <andreas.kling@nokia.com>
Reviewed by Ariya Hidayat.
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
-bool isSpecialTag(const AtomicString& tagName)
+bool isSpecialNode(Node* node)
{
+ if (node->namespaceURI() != xhtmlNamespaceURI)
+ return false;
+ const AtomicString& tagName = node->localName();
return tagName == addressTag
|| tagName == articleTag
|| tagName == asideTag
return tagName == aTag || isNonAnchorFormattingTag(tagName);
}
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#phrasing
-bool isPhrasingTag(const AtomicString& tagName)
-{
- return !isSpecialTag(tagName) && !isScopingTag(tagName) && !isFormattingTag(tagName);
-}
-
-bool isNotFormattingAndNotPhrasing(const Element* element)
-{
- // The spec often says "node is not in the formatting category, and is not
- // in the phrasing category". !phrasing && !formatting == scoping || special
- // scoping || special is easier to compute.
- // FIXME: localName() is wrong for non-html content.
- const AtomicString& tagName = element->localName();
- return isScopingTag(tagName) || isSpecialTag(tagName);
-}
-
HTMLFormElement* closestFormAncestor(Element* element)
{
while (element) {
processFakeEndTag(node->tagQName());
break;
}
- if (isNotFormattingAndNotPhrasing(node) && !node->hasTagName(addressTag) && !node->hasTagName(divTag) && !node->hasTagName(pTag))
+ if (isSpecialNode(node) && !node->hasTagName(addressTag) && !node->hasTagName(divTag) && !node->hasTagName(pTag))
break;
nodeRecord = nodeRecord->next();
}
m_tree.openElements()->popUntilPopped(node);
return;
}
- if (isNotFormattingAndNotPhrasing(node)) {
+ if (isSpecialNode(node)) {
parseError(token);
return;
}
for (; record; record = record->next()) {
if (record->element() == formattingElement)
return furthestBlock;
- if (isNotFormattingAndNotPhrasing(record->element()))
+ if (isSpecialNode(record->element()))
furthestBlock = record;
}
ASSERT_NOT_REACHED();
if (m_tree.currentElement()->namespaceURI() != xhtmlNamespaceURI) {
// FIXME: This code just wants an Element* iterator, instead of an ElementRecord*
HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
- if (!nodeRecord->element()->hasLocalName(token.name())) {
+ if (!nodeRecord->element()->hasLocalName(token.name()))
parseError(token);
- // FIXME: This return is not in the spec but it needed for now
- // to prevent walking off the bottom of the stack.
- // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10118
- if (!m_tree.openElements()->contains(token.name()))
- return;
- }
while (1) {
if (nodeRecord->element()->hasLocalName(token.name())) {
m_tree.openElements()->popUntilPopped(nodeRecord->element());
- return;
+ break;
}
nodeRecord = nodeRecord->next();
- if (nodeRecord->element()->namespaceURI() == xhtmlNamespaceURI) {
- processUsingSecondaryInsertionModeAndAdjustInsertionMode(token);
- // FIXME: This is a hack around a spec bug and is likely wrong.
- // http://www.w3.org/Bugs/Public/show_bug.cgi?id=9581
- if (nodeRecord != m_tree.openElements()->topRecord())
- return;
- }
+ if (nodeRecord->element()->namespaceURI() == xhtmlNamespaceURI)
+ break;
}
- return;
}
+ // Any other end tag (also the last two steps of "An end tag, if the current node is not an element in the HTML namespace."
processUsingSecondaryInsertionModeAndAdjustInsertionMode(token);
break;
}