2010-08-22 Eric Seidel <eric@webkit.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 22 Aug 2010 18:38:38 +0000 (18:38 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 22 Aug 2010 18:38:38 +0000 (18:38 +0000)
        Reviewed by Adam Barth.

        HTML5 TreeBuilder builds wrong DOM for <a><svg><tr><input></a>
        https://bugs.webkit.org/show_bug.cgi?id=44390

        * html5lib/resources/adoption01.dat:
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):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@65785 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/html5lib/resources/adoption01.dat
WebCore/ChangeLog
WebCore/html/HTMLTreeBuilder.cpp

index f79cddd..4f7a024 100644 (file)
@@ -1,3 +1,12 @@
+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
+
+        * html5lib/resources/adoption01.dat:
+
 2010-08-22  Andreas Kling  <andreas.kling@nokia.com>
 
         Reviewed by Ariya Hidayat.
index 0c886d5..2ff6df3 100644 (file)
 |   <body>
 |     <a>
 |       <svg svg>
-|     <svg tr>
-|       <a>
-|   <svg input>
-|     <a>
+|         <svg tr>
+|           <svg input>
index b7976bd..8087148 100644 (file)
@@ -1,3 +1,25 @@
+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.
index f36b6ab..bdfe4be 100644 (file)
@@ -133,8 +133,11 @@ bool isTableBodyContextTag(const AtomicString& tagName)
 }
 
 // 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
@@ -241,22 +244,6 @@ bool isFormattingTag(const AtomicString& tagName)
     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) {
@@ -765,7 +752,7 @@ void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken& token)
             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();
     }
@@ -1726,7 +1713,7 @@ void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken& token)
             m_tree.openElements()->popUntilPopped(node);
             return;
         }
-        if (isNotFormattingAndNotPhrasing(node)) {
+        if (isSpecialNode(node)) {
             parseError(token);
             return;
         }
@@ -1742,7 +1729,7 @@ HTMLElementStack::ElementRecord* HTMLTreeBuilder::furthestBlockForFormattingElem
     for (; record; record = record->next()) {
         if (record->element() == formattingElement)
             return furthestBlock;
-        if (isNotFormattingAndNotPhrasing(record->element()))
+        if (isSpecialNode(record->element()))
             furthestBlock = record;
     }
     ASSERT_NOT_REACHED();
@@ -2494,30 +2481,19 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
         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;
     }