Reviewed by Darin.
authoradele <adele@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 19 Feb 2005 01:13:01 +0000 (01:13 +0000)
committeradele <adele@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 19 Feb 2005 01:13:01 +0000 (01:13 +0000)
        Fix for <rdar://problem/3975568> REGRESSION(125-180)Australian Open pages have drawing problem

        This patch fixes two problems caused by our added support for custom tags.  First, the layout problem at the sites mentioned in the bug
        was caused by custom tags within tables.  In checkChild, we needed to treat these tags as spans so they get placed correctly in the DOM tree.
        Also, we were indexing the tagPriority and endTag arrays with id values from the custom tags that were greater than the size of the array.  So now
        we have functions to check for the custom tags, and again, treat them as spans.  To avoid confusion, we changed the names of the arrays to
        endTagArray and tagPriorityArray.

        * khtml/html/dtd.h: changed all uses of the endTag array to endTagArray for our new wrapper functions
        (DOM::tagPriority): added function to check array bounds and to treat custom tags as spans
        (DOM::endTagRequirement): added function to check array bounds and to treat custom tags as spans
        * khtml/html/dtd.cpp: changed name of endTag and tagPriority arrays to endTagArray and tagPriorityArray
        (DOM::checkChild): treat custom tags as spans during this check
        * khtml/html/html_elementimpl.cpp: changed all uses of the endTag array to the endTagRequirement function
        (HTMLElementImpl::createContextualFragment):
        (HTMLElementImpl::setInnerText):
        (HTMLElementImpl::setOuterText):
        (HTMLElementImpl::toString):
        * khtml/html/htmlparser.cpp: changed all uses of the endTag array to the endTagRequirement function and all uses of the tagPriority array to the tagPriority function.
        (KHTMLParser::parseToken):
        (KHTMLParser::insertNode):
        * khtml/html/htmltokenizer.cpp: (khtml::HTMLTokenizer::parseTag): changed all uses of the endTag array to the endTagRequirement function
       * khtml/editing/markup.cpp: changed all uses of the endTag array to the endTagRequirement function
        (khtml::endMarkup):
        (khtml::markup):

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

WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/markup.cpp
WebCore/khtml/html/dtd.cpp
WebCore/khtml/html/dtd.h
WebCore/khtml/html/html_elementimpl.cpp
WebCore/khtml/html/htmlparser.cpp
WebCore/khtml/html/htmltokenizer.cpp

index 77e97609d417c3e31131a19ffaba6688821ed555..4b8982b3a3c9bc50601647349a63598c62d0dfbc 100644 (file)
@@ -1,3 +1,33 @@
+2005-02-18  Adele Amchan  <adele@apple.com>
+
+        Reviewed by Darin.
+
+        Fix for <rdar://problem/3975568> REGRESSION(125-180)Australian Open pages have drawing problem
+
+        This patch fixes two problems caused by our added support for custom tags.  First, the layout problem at the sites mentioned in the bug
+        was caused by custom tags within tables.  In checkChild, we needed to treat these tags as spans so they get placed correctly in the DOM tree.
+        Also, we were indexing the tagPriority and endTag arrays with id values from the custom tags that were greater than the size of the array.  So now 
+        we have functions to check for the custom tags, and again, treat them as spans.  To avoid confusion, we changed the names of the arrays to
+        endTagArray and tagPriorityArray.
+
+        * khtml/html/dtd.h: changed all uses of the endTag array to endTagArray for our new wrapper functions
+        (DOM::tagPriority): added function to check array bounds and to treat custom tags as spans
+        (DOM::endTagRequirement): added function to check array bounds and to treat custom tags as spans
+        * khtml/html/dtd.cpp: changed name of endTag and tagPriority arrays to endTagArray and tagPriorityArray
+        (DOM::checkChild): treat custom tags as spans during this check
+        * khtml/html/html_elementimpl.cpp: changed all uses of the endTag array to the endTagRequirement function
+        (HTMLElementImpl::createContextualFragment):
+        (HTMLElementImpl::setInnerText):
+        (HTMLElementImpl::setOuterText):
+        (HTMLElementImpl::toString):
+        * khtml/html/htmlparser.cpp: changed all uses of the endTag array to the endTagRequirement function and all uses of the tagPriority array to the tagPriority function.
+        (KHTMLParser::parseToken):
+        (KHTMLParser::insertNode):
+        * khtml/html/htmltokenizer.cpp: (khtml::HTMLTokenizer::parseTag): changed all uses of the endTag array to the endTagRequirement function
+       * khtml/editing/markup.cpp: changed all uses of the endTag array to the endTagRequirement function
+        (khtml::endMarkup): 
+        (khtml::markup):
+
 2005-02-18  Jens Alfke  <jens@apple.com>
 
         Reviewed by Hyatt.
index 25d3730e5a8f1beca9dce74cceec0654c9f215b6..35b2e96ea3217ad0982991551ecc846b3e59f438 100644 (file)
@@ -45,8 +45,8 @@ using DOM::DocumentFragmentImpl;
 using DOM::DocumentImpl;
 using DOM::DOMString;
 using DOM::ElementImpl;
-using DOM::endTag;
 using DOM::FORBIDDEN;
+using DOM::endTagRequirement;
 using DOM::HTMLElementImpl;
 using DOM::NamedAttrMapImpl;
 using DOM::Node;
@@ -230,7 +230,7 @@ static QString startMarkup(const NodeImpl *node, const RangeImpl *range, EAnnota
 
 static QString endMarkup(const NodeImpl *node)
 {
-    if ((!node->isHTMLElement() || endTag[node->id()] != FORBIDDEN) && node->nodeType() != Node::TEXT_NODE && node->nodeType() != Node::DOCUMENT_NODE) {
+    if ((!node->isHTMLElement() || endTagRequirement(node->id()) != FORBIDDEN) && node->nodeType() != Node::TEXT_NODE && node->nodeType() != Node::DOCUMENT_NODE) {
         return "</" + node->nodeName().string() + ">";
     }
     return "";
@@ -248,7 +248,7 @@ static QString markup(const NodeImpl *startNode, bool onlyIncludeChildren, bool
             }
             me += startMarkup(current, 0, DoNotAnnotateForInterchange, 0);
         }        
-        if (!current->isHTMLElement() || endTag[current->id()] != FORBIDDEN) {
+        if (!current->isHTMLElement() || endTagRequirement(current->id()) != FORBIDDEN) {
             // print children
             if (NodeImpl *n = current->firstChild()) {
                 me += markup(n, false, true, nodes);
index 74e869059bfe2e3c3de08ddadda112e11dcf8ede..efe10658571e612d96764ddde4da3351693ce0e4 100644 (file)
@@ -44,7 +44,7 @@ using namespace DOM;
 // 8 table
 // 9 body frameset
 // 10 html
-const unsigned short DOM::tagPriority[] = {
+const unsigned short DOM::tagPriorityArray[] = {
     0, // 0
     1, // ID_A == 1
     1, // ID_ABBR
@@ -151,7 +151,7 @@ const unsigned short DOM::tagPriority[] = {
     0, // ID_TEXT
 };
 
-const tagStatus DOM::endTag[] = {
+const tagStatus DOM::endTagArray[] = {
     REQUIRED,  // 0
     REQUIRED,  // ID_A == 1
     REQUIRED,  // ID_ABBR
@@ -559,8 +559,11 @@ bool DOM::checkChild(ushort tagID, ushort childID)
 
     // ### allow comments inside ANY node that can contain children
 
-    if (tagID > ID_LAST_TAG || childID > ID_LAST_TAG)
-        return true; // one or both of the elements is an XML element; just allow for now
+    // Treat custom elements the same as <span>.
+    if (tagID > ID_LAST_TAG)
+        tagID = ID_SPAN;
+    if (childID > ID_LAST_TAG)
+        childID = ID_SPAN;
 
     switch(tagID)
     {
index 7e5a6c0ee0bc594af4a995f39f179a20f808d08e..37ce8ce6c6b64c9030ba831c58f767289d9f3365 100644 (file)
@@ -23,6 +23,7 @@
 #define _DOM_dtd_h_
 
 #include "dom/dom_string.h"
+#include "misc/htmltags.h"
 
 namespace DOM
 {
@@ -34,8 +35,24 @@ enum tagStatus { OPTIONAL, REQUIRED, FORBIDDEN };
 
 bool checkChild(ushort tagID, ushort childID);
 
-extern const unsigned short tagPriority[];
-extern const tagStatus endTag[];
+extern const unsigned short tagPriorityArray[];
+extern const tagStatus endTagArray[];
+
+inline unsigned short tagPriority(Q_UINT32 tagId)
+{
+    // Treat custom elements the same as <span>; also don't read past the end of the array.
+    if (tagId > ID_LAST_TAG)
+        return tagPriorityArray[ID_SPAN];
+    return tagPriorityArray[tagId];
+}
+
+inline tagStatus endTagRequirement(Q_UINT32 tagId)
+{
+    // Treat custom elements the same as <span>; also don't read past the end of the array.
+    if (tagId > ID_LAST_TAG)
+        return endTagArray[ID_SPAN];
+    return endTagArray[tagId];
+}
 
 } //namespace DOM
 #endif
index dbb0127602ecb257c598a6100e9ac9dca79236d1..0eeba82bd151e0fd70ae5ed2f92a9717b794d1dd 100644 (file)
@@ -741,7 +741,7 @@ DOMString HTMLElementImpl::outerText() const
 DocumentFragmentImpl *HTMLElementImpl::createContextualFragment(const DOMString &html)
 {
     // the following is in accordance with the definition as used by IE
-    if( endTag[id()] == FORBIDDEN )
+    if( endTagRequirement(id()) == FORBIDDEN )
         return NULL;
     // IE disallows innerHTML on inline elements. I don't see why we should have this restriction, as our
     // dhtml engine can cope with it. Lars
@@ -847,7 +847,7 @@ bool HTMLElementImpl::setOuterHTML( const DOMString &html )
 bool HTMLElementImpl::setInnerText( const DOMString &text )
 {
     // following the IE specs.
-    if( endTag[id()] == FORBIDDEN )
+    if( endTagRequirement(id()) == FORBIDDEN )
         return false;
     // IE disallows innerText on inline elements. I don't see why we should have this restriction, as our
     // dhtml engine can cope with it. Lars
@@ -881,7 +881,7 @@ bool HTMLElementImpl::setInnerText( const DOMString &text )
 bool HTMLElementImpl::setOuterText( const DOMString &text )
 {
     // following the IE specs.
-    if( endTag[id()] == FORBIDDEN )
+    if( endTagRequirement(id()) == FORBIDDEN )
         return false;
     switch( id() ) {
         case ID_COL:
@@ -1072,7 +1072,7 @@ DOMString HTMLElementImpl::toString() const
        DOMString result = openTagStartToString();
        result += ">";
 
-       if (endTag[id()] == REQUIRED) {
+       if (endTagRequirement(id()) == REQUIRED) {
            result += "</";
            result += tagName();
            result += ">";
index 725b8b2fe269575399daaf25ee57d5a7790380c9..878668d0050d620a5088a45bb908e0df4d7fd7df 100644 (file)
@@ -247,7 +247,7 @@ void KHTMLParser::parseToken(Token *t)
         e->setAttributeMap(t->attrs);
 
         // take care of optional close tags
-        if(endTag[e->id()] == DOM::OPTIONAL)
+        if(endTagRequirement(e->id()) == DOM::OPTIONAL)
             popBlock(t->id);
             
         if (isHeaderTag(t->id))
@@ -317,9 +317,9 @@ bool KHTMLParser::insertNode(NodeImpl *n, bool flat)
         kdDebug( 6035 ) << "added " << n->nodeName().string() << " to " << tmp->nodeName().string() << ", new current=" << newNode->nodeName().string() << endl;
 #endif
         // don't push elements without end tag on the stack
-        if(tagPriority[id] != 0 && !flat)
+        if(tagPriority(id) != 0 && !flat)
         {
-            pushBlock(id, tagPriority[id]);
+            pushBlock(id, tagPriority(id));
             if (newNode == current)
                 popBlock(id);
             else
@@ -415,7 +415,7 @@ bool KHTMLParser::insertNode(NodeImpl *n, bool flat)
             if ( head ) {
                 DOM::NodeImpl *newNode = head->addChild(n);
                 if ( newNode ) {
-                    pushBlock(id, tagPriority[id]);
+                    pushBlock(id, tagPriority(id));
                     setCurrent(newNode);
 #if SPEED_DEBUG < 2
                    if(!n->attached() && HTMLWidget)
@@ -523,7 +523,7 @@ bool KHTMLParser::insertNode(NodeImpl *n, bool flat)
                     NodeImpl* table = tsection->parent();
                     int exceptioncode = 0;
                     table->insertBefore(n, tsection, exceptioncode);
-                    pushBlock(id, tagPriority[id]);
+                    pushBlock(id, tagPriority(id));
                     setCurrent(n);
                     inStrayTableContent++;
                     blockStack->strayTableContent = true;
@@ -663,10 +663,10 @@ bool KHTMLParser::insertNode(NodeImpl *n, bool flat)
 #endif
                         break;
                     }
-                    if (n->isElementNode() && tagPriority[id] != 0 && 
-                        !flat && endTag[id] != DOM::FORBIDDEN)
+                    if (n->isElementNode() && tagPriority(id) != 0 && 
+                        !flat && endTagRequirement(id) != DOM::FORBIDDEN)
                     {
-                        pushBlock(id, tagPriority[id]);
+                        pushBlock(id, tagPriority(id));
                         setCurrent(n);
                         inStrayTableContent++;
                         blockStack->strayTableContent = true;
index 3c97ab22677a06f2320e434b680c7d10b634676e..210c2210f85b045f5a4aab5aa01fb3b5eaf0a073 100644 (file)
@@ -65,7 +65,7 @@ using DOM::DocumentImpl;
 using DOM::FORBIDDEN;
 using DOM::Node;
 using DOM::emptyAtom;
-using DOM::endTag;
+using DOM::endTagRequirement;
 
 // turn off inlining to void warning with newer gcc
 #undef __inline
@@ -1460,7 +1460,7 @@ void HTMLTokenizer::parseTag(TokenizerString &src)
                 break;
             }
             
-            if (beginTag && endTag[tagID] == FORBIDDEN)
+            if (beginTag && endTagRequirement(tagID) == FORBIDDEN)
                 // Don't discard LFs since this element has no end tag.
                 discard = NoneDiscard;