CSS 2.1 failure: table-columns-example-001 fails
[WebKit-https.git] / Source / WebCore / html / HTMLTableElement.cpp
index 84835dc..a22efa2 100644 (file)
@@ -30,6 +30,7 @@
 #include "CSSPropertyNames.h"
 #include "CSSStyleSheet.h"
 #include "CSSValueKeywords.h"
+#include "CSSValuePool.h"
 #include "ExceptionCode.h"
 #include "HTMLNames.h"
 #include "HTMLParserIdioms.h"
@@ -186,13 +187,15 @@ PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec
         return 0;
     }
 
-    HTMLTableRowElement* lastRow = 0;
-    HTMLTableRowElement* row = 0;
+    RefPtr<Node> protectFromMutationEvents(this);
+
+    RefPtr<HTMLTableRowElement> lastRow = 0;
+    RefPtr<HTMLTableRowElement> row = 0;
     if (index == -1)
         lastRow = HTMLTableRowsCollection::lastRow(this);
     else {
         for (int i = 0; i <= index; ++i) {
-            row = HTMLTableRowsCollection::rowAfter(this, lastRow);
+            row = HTMLTableRowsCollection::rowAfter(this, lastRow.get());
             if (!row) {
                 if (i != index) {
                     ec = INDEX_SIZE_ERR;
@@ -204,7 +207,7 @@ PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec
         }
     }
 
-    ContainerNode* parent;
+    RefPtr<ContainerNode> parent;
     if (lastRow)
         parent = row ? row->parentNode() : lastRow->parentNode();
     else {
@@ -219,7 +222,7 @@ PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionCode& ec
     }
 
     RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
-    parent->insertBefore(newRow, row, ec);
+    parent->insertBefore(newRow, row.get(), ec);
     return newRow.release();
 }
 
@@ -300,8 +303,8 @@ void HTMLTableElement::collectStyleForAttribute(Attribute* attr, StylePropertySe
     else if (attr->name() == heightAttr)
         addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     else if (attr->name() == borderAttr) {
-        int border = attr->isEmpty() ? 1 : attr->value().toInt();
-        addHTMLLengthToStyle(style, CSSPropertyBorderWidth, String::number(border)); // FIXME: Pass as integer.
+        int borderWidth = attr->isEmpty() ? 1 : attr->value().toInt();
+        addPropertyToAttributeStyle(style, CSSPropertyBorderWidth, borderWidth, CSSPrimitiveValue::CSS_PX);
     } else if (attr->name() == bordercolorAttr) {
         if (!attr->isEmpty())
             addHTMLColorToStyle(style, CSSPropertyBorderColor, attr->value());
@@ -313,7 +316,7 @@ void HTMLTableElement::collectStyleForAttribute(Attribute* attr, StylePropertySe
             style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document()->completeURL(url).string())));
     } else if (attr->name() == valignAttr) {
         if (!attr->isEmpty())
-            style->setProperty(CSSPropertyVerticalAlign, attr->value());
+            addPropertyToAttributeStyle(style, CSSPropertyVerticalAlign, attr->value());
     } else if (attr->name() == cellspacingAttr) {
         if (!attr->isEmpty())
             addHTMLLengthToStyle(style, CSSPropertyBorderSpacing, attr->value());
@@ -326,52 +329,52 @@ void HTMLTableElement::collectStyleForAttribute(Attribute* attr, StylePropertySe
     } else if (attr->name() == alignAttr) {
         if (!attr->value().isEmpty()) {
             if (equalIgnoringCase(attr->value(), "center")) {
-                style->setProperty(CSSPropertyWebkitMarginStart, CSSValueAuto);
-                style->setProperty(CSSPropertyWebkitMarginEnd, CSSValueAuto);
+                addPropertyToAttributeStyle(style, CSSPropertyWebkitMarginStart, CSSValueAuto);
+                addPropertyToAttributeStyle(style, CSSPropertyWebkitMarginEnd, CSSValueAuto);
             } else
-                style->setProperty(CSSPropertyFloat, attr->value());
+                addPropertyToAttributeStyle(style, CSSPropertyFloat, attr->value());
         }
     } else if (attr->name() == rulesAttr) {
         // The presence of a valid rules attribute causes border collapsing to be enabled.
         if (m_rulesAttr != UnsetRules)
-            style->setProperty(CSSPropertyBorderCollapse, CSSValueCollapse);
+            addPropertyToAttributeStyle(style, CSSPropertyBorderCollapse, CSSValueCollapse);
     } else if (attr->name() == frameAttr) {
         bool borderTop;
         bool borderRight;
         bool borderBottom;
         bool borderLeft;
         if (getBordersFromFrameAttributeValue(attr->value(), borderTop, borderRight, borderBottom, borderLeft)) {
-            style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
-            style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
-            style->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
-            style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
-            style->setProperty(CSSPropertyBorderTopStyle, borderTop ? CSSValueSolid : CSSValueHidden);
-            style->setProperty(CSSPropertyBorderBottomStyle, borderBottom ? CSSValueSolid : CSSValueHidden);
-            style->setProperty(CSSPropertyBorderLeftStyle, borderLeft ? CSSValueSolid : CSSValueHidden);
-            style->setProperty(CSSPropertyBorderRightStyle, borderRight ? CSSValueSolid : CSSValueHidden);
+            addPropertyToAttributeStyle(style, CSSPropertyBorderWidth, CSSValueThin);
+            addPropertyToAttributeStyle(style, CSSPropertyBorderTopStyle, borderTop ? CSSValueSolid : CSSValueHidden);
+            addPropertyToAttributeStyle(style, CSSPropertyBorderBottomStyle, borderBottom ? CSSValueSolid : CSSValueHidden);
+            addPropertyToAttributeStyle(style, CSSPropertyBorderLeftStyle, borderLeft ? CSSValueSolid : CSSValueHidden);
+            addPropertyToAttributeStyle(style, CSSPropertyBorderRightStyle, borderRight ? CSSValueSolid : CSSValueHidden);
         }
     } else
         HTMLElement::collectStyleForAttribute(attr, style);
 }
 
+bool HTMLTableElement::isPresentationAttribute(const QualifiedName& name) const
+{
+    if (name == widthAttr || name == heightAttr || name == bgcolorAttr || name == backgroundAttr || name == valignAttr || name == vspaceAttr || name == hspaceAttr || name == alignAttr || name == cellspacingAttr || name == borderAttr || name == bordercolorAttr || name == frameAttr || name == rulesAttr)
+        return true;
+    return HTMLElement::isPresentationAttribute(name);
+}
+
 void HTMLTableElement::parseAttribute(Attribute* attr)
 {
     CellBorders bordersBefore = cellBorders();
     unsigned short oldPadding = m_padding;
 
-    if (attr->name() == widthAttr || attr->name() == heightAttr || attr->name() == bgcolorAttr || attr->name() == backgroundAttr || attr->name() == valignAttr || attr->name() == vspaceAttr || attr->name() == hspaceAttr || attr->name() == alignAttr || attr->name() == cellspacingAttr)
-        setNeedsAttributeStyleUpdate();
-    else if (attr->name() == borderAttr)  {
+    if (attr->name() == borderAttr)  {
         // FIXME: This attribute is a mess.
         m_borderAttr = true;
         if (!attr->isNull()) {
             int border = attr->isEmpty() ? 1 : attr->value().toInt();
             m_borderAttr = border;
         }
-        setNeedsAttributeStyleUpdate();
     } else if (attr->name() == bordercolorAttr) {
         m_borderColorAttr = !attr->isEmpty();
-        setNeedsAttributeStyleUpdate();
     } else if (attr->name() == frameAttr) {
         // FIXME: This attribute is a mess.
         bool borderTop;
@@ -379,7 +382,6 @@ void HTMLTableElement::parseAttribute(Attribute* attr)
         bool borderBottom;
         bool borderLeft;
         m_frameAttr = getBordersFromFrameAttributeValue(attr->value(), borderTop, borderRight, borderBottom, borderLeft);
-        setNeedsAttributeStyleUpdate();
     } else if (attr->name() == rulesAttr) {
         m_rulesAttr = UnsetRules;
         if (equalIgnoringCase(attr->value(), "none"))
@@ -392,8 +394,6 @@ void HTMLTableElement::parseAttribute(Attribute* attr)
             m_rulesAttr = ColsRules;
         if (equalIgnoringCase(attr->value(), "all"))
             m_rulesAttr = AllRules;
-
-        setNeedsAttributeStyleUpdate();
     } else if (attr->name() == cellpaddingAttr) {
         if (!attr->value().isEmpty())
             m_padding = max(0, attr->value().toInt());
@@ -426,8 +426,18 @@ static StylePropertySet* leakBorderStyle(int value)
 
 StylePropertySet* HTMLTableElement::additionalAttributeStyle()
 {
-    if ((!m_borderAttr && !m_borderColorAttr) || m_frameAttr)
+    if (m_frameAttr)
+        return 0;
+    
+    if (!m_borderAttr && !m_borderColorAttr) {
+        // Setting the border to 'hidden' allows it to win over any border
+        // set on the table's cells during border-conflict resolution.
+        if (m_rulesAttr != UnsetRules) {
+            static StylePropertySet* solidBorderStyle = leakBorderStyle(CSSValueHidden);
+            return solidBorderStyle;
+        }
         return 0;
+    }
 
     if (m_borderColorAttr) {
         static StylePropertySet* solidBorderStyle = leakBorderStyle(CSSValueSolid);
@@ -470,43 +480,32 @@ PassRefPtr<StylePropertySet> HTMLTableElement::createSharedCellStyle()
         style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
         style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
         style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
-        style->setProperty(CSSPropertyBorderColor, "inherit");
+        style->setProperty(CSSPropertyBorderColor, cssValuePool().createInheritedValue());
         break;
     case SolidBordersRowsOnly:
         style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
         style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
         style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
         style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
-        style->setProperty(CSSPropertyBorderColor, "inherit");
+        style->setProperty(CSSPropertyBorderColor, cssValuePool().createInheritedValue());
         break;
     case SolidBorders:
-        style->setProperty(CSSPropertyBorderWidth, "1px");
-        style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
-        style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
-        style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
-        style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
-        style->setProperty(CSSPropertyBorderColor, "inherit");
+        style->setProperty(CSSPropertyBorderWidth, cssValuePool().createValue(1, CSSPrimitiveValue::CSS_PX));
+        style->setProperty(CSSPropertyBorderStyle, cssValuePool().createIdentifierValue(CSSValueSolid));
+        style->setProperty(CSSPropertyBorderColor, cssValuePool().createInheritedValue());
         break;
     case InsetBorders:
-        style->setProperty(CSSPropertyBorderWidth, "1px");
-        style->setProperty(CSSPropertyBorderTopStyle, CSSValueInset);
-        style->setProperty(CSSPropertyBorderBottomStyle, CSSValueInset);
-        style->setProperty(CSSPropertyBorderLeftStyle, CSSValueInset);
-        style->setProperty(CSSPropertyBorderRightStyle, CSSValueInset);
-        style->setProperty(CSSPropertyBorderColor, "inherit");
+        style->setProperty(CSSPropertyBorderWidth, cssValuePool().createValue(1, CSSPrimitiveValue::CSS_PX));
+        style->setProperty(CSSPropertyBorderStyle, cssValuePool().createIdentifierValue(CSSValueInset));
+        style->setProperty(CSSPropertyBorderColor, cssValuePool().createInheritedValue());
         break;
     case NoBorders:
-        style->setProperty(CSSPropertyBorderWidth, "0");
+        style->setProperty(CSSPropertyBorderWidth, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX));
         break;
     }
 
-    if (m_padding) {
-        String value = String::number(m_padding) + "px";
-        style->setProperty(CSSPropertyPaddingTop, value);
-        style->setProperty(CSSPropertyPaddingBottom, value);
-        style->setProperty(CSSPropertyPaddingLeft, value);
-        style->setProperty(CSSPropertyPaddingRight, value);
-    }
+    if (m_padding)
+        style->setProperty(CSSPropertyPadding, cssValuePool().createValue(m_padding, CSSPrimitiveValue::CSS_PX));
 
     return style.release();
 }
@@ -548,12 +547,6 @@ StylePropertySet* HTMLTableElement::additionalGroupStyle(bool rows)
     return columnBorderStyle;
 }
 
-void HTMLTableElement::attach()
-{
-    ASSERT(!attached());
-    HTMLElement::attach();
-}
-
 bool HTMLTableElement::isURLAttribute(Attribute *attr) const
 {
     return attr->name() == backgroundAttr || HTMLElement::isURLAttribute(attr);