Refactor application of additional style attributes for table elements.
authorkling@webkit.org <kling@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Jan 2012 19:02:27 +0000 (19:02 +0000)
committerkling@webkit.org <kling@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Jan 2012 19:02:27 +0000 (19:02 +0000)
<http://webkit.org/b/77095>

Reviewed by Darin Adler.

The primary purpose of this change is to reduce usage of CSSMappedAttributeDeclaration.
Instead of using the mapped attribute decl table for additional table style, just use
regular CSSMutableStyleDeclarations. We cache them all globally, except for the style
that's shared between a table's cells. That one is cached per-table since it depends
on the table's border and padding.

* dom/CSSMappedAttributeDeclaration.cpp:
(WebCore::CSSMappedAttributeDeclaration::~CSSMappedAttributeDeclaration):
* dom/MappedAttributeEntry.h:

    Remove the concept of persistent CSSMappedAttributeDeclarations. The hunk in
    ~CSSMappedAttributeDeclaration was wildly wrong since it would leave stale pointers
    in the decl table, but unreachable since we always leaked one ref to those decls.

* dom/StyledElement.h:
(WebCore::StyledElement::additionalAttributeStyle):
* html/HTMLTableCellElement.cpp:
(WebCore::HTMLTableCellElement::additionalAttributeStyle):
* html/HTMLTableCellElement.h:
(HTMLTableCellElement):
* html/HTMLTableColElement.cpp:
(WebCore::HTMLTableColElement::additionalAttributeStyle):
* html/HTMLTableColElement.h:
(HTMLTableColElement):
* html/HTMLTableElement.cpp:
(WebCore::HTMLTableElement::parseMappedAttribute):
(WebCore::leakBorderStyle):
(WebCore::HTMLTableElement::additionalAttributeStyle):
(WebCore::HTMLTableElement::createSharedCellStyle):
(WebCore::HTMLTableElement::additionalCellStyle):
(WebCore::leakGroupBorderStyle):
(WebCore::HTMLTableElement::additionalGroupStyle):
* html/HTMLTableElement.h:
(HTMLTableElement):
* html/HTMLTableSectionElement.cpp:
(WebCore::HTMLTableSectionElement::additionalAttributeStyle):
* html/HTMLTableSectionElement.h:
(HTMLTableSectionElement):

    Instead of collecting additional style decls into a vector, switch over to a
    "PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle()".
    All style declarations that can be reused for all elements are cached at the return
    sites, leaving only the shared table cell style which we cache on HTMLTableElement.
    Also removed the canHaveAdditionalAttributeStyleDecls() virtual since the default
    additionalAttributeStyle() will just return 0.

* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::matchAllRules):

    Updated for the new additional style conventions.

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

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/css/CSSStyleSelector.cpp
Source/WebCore/dom/CSSMappedAttributeDeclaration.cpp
Source/WebCore/dom/MappedAttributeEntry.h
Source/WebCore/dom/StyledElement.h
Source/WebCore/html/HTMLTableCellElement.cpp
Source/WebCore/html/HTMLTableCellElement.h
Source/WebCore/html/HTMLTableColElement.cpp
Source/WebCore/html/HTMLTableColElement.h
Source/WebCore/html/HTMLTableElement.cpp
Source/WebCore/html/HTMLTableElement.h
Source/WebCore/html/HTMLTableSectionElement.cpp
Source/WebCore/html/HTMLTableSectionElement.h

index bb72ccd..e4927df 100644 (file)
@@ -1,3 +1,61 @@
+2012-01-26  Andreas Kling  <awesomekling@apple.com>
+
+        Refactor application of additional style attributes for table elements.
+        <http://webkit.org/b/77095>
+
+        Reviewed by Darin Adler.
+
+        The primary purpose of this change is to reduce usage of CSSMappedAttributeDeclaration.
+        Instead of using the mapped attribute decl table for additional table style, just use
+        regular CSSMutableStyleDeclarations. We cache them all globally, except for the style
+        that's shared between a table's cells. That one is cached per-table since it depends
+        on the table's border and padding.
+
+        * dom/CSSMappedAttributeDeclaration.cpp:
+        (WebCore::CSSMappedAttributeDeclaration::~CSSMappedAttributeDeclaration):
+        * dom/MappedAttributeEntry.h:
+
+            Remove the concept of persistent CSSMappedAttributeDeclarations. The hunk in
+            ~CSSMappedAttributeDeclaration was wildly wrong since it would leave stale pointers
+            in the decl table, but unreachable since we always leaked one ref to those decls.
+
+        * dom/StyledElement.h:
+        (WebCore::StyledElement::additionalAttributeStyle):
+        * html/HTMLTableCellElement.cpp:
+        (WebCore::HTMLTableCellElement::additionalAttributeStyle):
+        * html/HTMLTableCellElement.h:
+        (HTMLTableCellElement):
+        * html/HTMLTableColElement.cpp:
+        (WebCore::HTMLTableColElement::additionalAttributeStyle):
+        * html/HTMLTableColElement.h:
+        (HTMLTableColElement):
+        * html/HTMLTableElement.cpp:
+        (WebCore::HTMLTableElement::parseMappedAttribute):
+        (WebCore::leakBorderStyle):
+        (WebCore::HTMLTableElement::additionalAttributeStyle):
+        (WebCore::HTMLTableElement::createSharedCellStyle):
+        (WebCore::HTMLTableElement::additionalCellStyle):
+        (WebCore::leakGroupBorderStyle):
+        (WebCore::HTMLTableElement::additionalGroupStyle):
+        * html/HTMLTableElement.h:
+        (HTMLTableElement):
+        * html/HTMLTableSectionElement.cpp:
+        (WebCore::HTMLTableSectionElement::additionalAttributeStyle):
+        * html/HTMLTableSectionElement.h:
+        (HTMLTableSectionElement):
+
+            Instead of collecting additional style decls into a vector, switch over to a
+            "PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle()".
+            All style declarations that can be reused for all elements are cached at the return
+            sites, leaving only the shared table cell style which we cache on HTMLTableElement.
+            Also removed the canHaveAdditionalAttributeStyleDecls() virtual since the default
+            additionalAttributeStyle() will just return 0.
+
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::matchAllRules):
+
+            Updated for the new additional style conventions.
+
 2012-01-26  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Web Inspector: Scripts panel editor container should be based on UISourceCode objects, not SourceFrames.
index f143423..e32b65b 100644 (file)
@@ -852,19 +852,14 @@ void CSSStyleSelector::matchAllRules(MatchResult& result)
         // Now we check additional mapped declarations.
         // Tables and table cells share an additional mapped rule that must be applied
         // after all attributes, since their mapped style depends on the values of multiple attributes.
-        if (m_styledElement->canHaveAdditionalAttributeStyleDecls()) {
-            Vector<CSSMutableStyleDeclaration*> additionalAttributeStyleDecls;
-            m_styledElement->additionalAttributeStyleDecls(additionalAttributeStyleDecls);
-            if (!additionalAttributeStyleDecls.isEmpty()) {
-                unsigned additionalDeclsSize = additionalAttributeStyleDecls.size();
-                if (result.ranges.firstAuthorRule == -1)
-                    result.ranges.firstAuthorRule = m_matchedDecls.size();
-                result.ranges.lastAuthorRule = m_matchedDecls.size() + additionalDeclsSize - 1;
-                for (unsigned i = 0; i < additionalDeclsSize; ++i)
-                    addMatchedDeclaration(additionalAttributeStyleDecls[i]);
-                result.isCacheable = false;
-            }
+        if (RefPtr<CSSMutableStyleDeclaration> additionalStyle = m_styledElement->additionalAttributeStyle()) {
+            if (result.ranges.firstAuthorRule == -1)
+                result.ranges.firstAuthorRule = m_matchedDecls.size();
+            result.ranges.lastAuthorRule = m_matchedDecls.size();
+            addMatchedDeclaration(additionalStyle.get());
+            result.isCacheable = false;
         }
+
         if (m_styledElement->isHTMLElement()) {
             bool isAuto;
             TextDirection textDirection = toHTMLElement(m_styledElement)->directionalityIfhasDirAutoAttribute(isAuto);
index 536992d..1585f80 100644 (file)
@@ -38,8 +38,7 @@ inline void CSSMappedAttributeDeclaration::setNeedsStyleRecalc(StyledElement* el
 
 CSSMappedAttributeDeclaration::~CSSMappedAttributeDeclaration()
 {
-    if (m_entryType != ePersistent)
-        StyledElement::removeMappedAttributeDecl(m_entryType, m_attrName, m_attrValue);
+    StyledElement::removeMappedAttributeDecl(m_entryType, m_attrName, m_attrValue);
 }
 
 void CSSMappedAttributeDeclaration::setMappedImageProperty(StyledElement* element, int propertyId, const String& url)
index b31d513..4de4927 100644 (file)
@@ -31,7 +31,6 @@ namespace WebCore {
 enum MappedAttributeEntry {
       eNone
     , eUniversal
-    , ePersistent
     , eReplaced
     , eBlock
     , eHR
index c434988..932c847 100644 (file)
@@ -55,8 +55,7 @@ public:
     static CSSMappedAttributeDeclaration* getMappedAttributeDecl(MappedAttributeEntry, Attribute*);
     static void setMappedAttributeDecl(MappedAttributeEntry, Attribute*, CSSMappedAttributeDeclaration*);
 
-    virtual bool canHaveAdditionalAttributeStyleDecls() const { return false; }
-    virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&) { }
+    virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() { return 0; }
     void invalidateStyleAttribute();
 
     CSSMutableStyleDeclaration* inlineStyleDecl() const { return attributeMap() ? attributeMap()->inlineStyleDecl() : 0; }
index 7e205d9..9a96a36 100644 (file)
@@ -118,15 +118,14 @@ void HTMLTableCellElement::parseMappedAttribute(Attribute* attr)
         HTMLTablePartElement::parseMappedAttribute(attr);
 }
 
-// used by table cells to share style decls created by the enclosing table.
-void HTMLTableCellElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableCellElement::additionalAttributeStyle()
 {
     ContainerNode* p = parentNode();
     while (p && !p->hasTagName(tableTag))
         p = p->parentNode();
     if (!p)
-        return;
-    static_cast<HTMLTableElement*>(p)->addSharedCellDecls(results);
+        return 0;
+    return static_cast<HTMLTableElement*>(p)->additionalCellStyle();
 }
 
 bool HTMLTableCellElement::isURLAttribute(Attribute *attr) const
index 5a47272..d7ddc86 100644 (file)
@@ -56,10 +56,8 @@ private:
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
     virtual void parseMappedAttribute(Attribute*);
 
-    // used by table cells to share style decls created by the enclosing table.
-    virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
-    virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
-    
+    virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() OVERRIDE;
+
     virtual bool isURLAttribute(Attribute*) const;
 
     virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
index 96af708..10657e6 100644 (file)
@@ -77,17 +77,16 @@ void HTMLTableColElement::parseMappedAttribute(Attribute* attr)
         HTMLTablePartElement::parseMappedAttribute(attr);
 }
 
-// used by table columns and column groups to share style decls created by the enclosing table.
-void HTMLTableColElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableColElement::additionalAttributeStyle()
 {
     if (!hasLocalName(colgroupTag))
-        return;
+        return 0;
     ContainerNode* p = parentNode();
     while (p && !p->hasTagName(tableTag))
         p = p->parentNode();
     if (!p)
-        return;
-    static_cast<HTMLTableElement*>(p)->addSharedGroupDecls(false, results);
+        return 0;
+    return static_cast<HTMLTableElement*>(p)->additionalGroupStyle(false);
 }
 
 void HTMLTableColElement::setSpan(int n)
index c7517d1..36180c7 100644 (file)
@@ -44,9 +44,8 @@ private:
 
     virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
     virtual void parseMappedAttribute(Attribute*);
-    virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
-    virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
-   
+    virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() OVERRIDE;
+
     int m_span;
 };
 
index 342cff2..cac8b4d 100644 (file)
@@ -436,8 +436,7 @@ void HTMLTableElement::parseMappedAttribute(Attribute* attr)
         HTMLElement::parseMappedAttribute(attr);
 
     if (bordersBefore != cellBorders() || oldPadding != m_padding) {
-        if (oldPadding != m_padding)
-            m_paddingDecl = 0;
+        m_sharedCellStyle = 0;
         bool cellChanged = false;
         for (Node* child = firstChild(); child; child = child->nextSibling())
             cellChanged |= setTableCellsChanged(child);
@@ -446,28 +445,27 @@ void HTMLTableElement::parseMappedAttribute(Attribute* attr)
     }
 }
 
-void HTMLTableElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+static CSSMutableStyleDeclaration* leakBorderStyle(int value)
 {
-    if ((!m_borderAttr && !m_borderColorAttr) || m_frameAttr)
-        return;
-
-    AtomicString borderValue = m_borderColorAttr ? "solid" : "outset";
-    CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, tableborderAttr, borderValue);
-    if (!decl) {
-        decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
-        ASSERT(!decl->useStrictParsing());
+    RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
+    style->setProperty(CSSPropertyBorderTopStyle, value);
+    style->setProperty(CSSPropertyBorderBottomStyle, value);
+    style->setProperty(CSSPropertyBorderLeftStyle, value);
+    style->setProperty(CSSPropertyBorderRightStyle, value);
+    return style.release().leakRef();
+}
 
-        int value = m_borderColorAttr ? CSSValueSolid : CSSValueOutset;
-        decl->setMappedProperty(this, CSSPropertyBorderTopStyle, value);
-        decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, value);
-        decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, value);
-        decl->setMappedProperty(this, CSSPropertyBorderRightStyle, value);
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableElement::additionalAttributeStyle()
+{
+    if ((!m_borderAttr && !m_borderColorAttr) || m_frameAttr)
+        return 0;
 
-        setMappedAttributeDecl(ePersistent, tableborderAttr, borderValue, decl);
-        decl->setMappedState(ePersistent, tableborderAttr, borderValue);
+    if (m_borderColorAttr) {
+        static CSSMutableStyleDeclaration* solidBorderStyle = leakBorderStyle(CSSValueSolid);
+        return solidBorderStyle;
     }
-
-    results.append(decl);
+    static CSSMutableStyleDeclaration* outsetBorderStyle = leakBorderStyle(CSSValueOutset);
+    return outsetBorderStyle;
 }
 
 HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
@@ -493,118 +491,92 @@ HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
     return NoBorders;
 }
 
-void HTMLTableElement::addSharedCellDecls(Vector<CSSMutableStyleDeclaration*>& results)
-{
-    addSharedCellBordersDecl(results);
-    addSharedCellPaddingDecl(results);
-}
-
-void HTMLTableElement::addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaration*>& results)
-{
-    CellBorders borders = cellBorders();
-
-    static const AtomicString* cellBorderNames[] = { new AtomicString("none"), new AtomicString("solid"), new AtomicString("inset"), new AtomicString("solid-cols"), new AtomicString("solid-rows") };
-    const AtomicString& cellborderValue = *cellBorderNames[borders];
-    CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, cellborderAttr, cellborderValue);
-    if (!decl) {
-        decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
-        ASSERT(!decl->useStrictParsing());
-
-        switch (borders) {
-            case SolidBordersColsOnly:
-                decl->setMappedProperty(this, CSSPropertyBorderLeftWidth, CSSValueThin);
-                decl->setMappedProperty(this, CSSPropertyBorderRightWidth, CSSValueThin);
-                decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueSolid);
-                decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueSolid);
-                decl->setMappedProperty(this, CSSPropertyBorderColor, "inherit");
-                break;
-            case SolidBordersRowsOnly:
-                decl->setMappedProperty(this, CSSPropertyBorderTopWidth, CSSValueThin);
-                decl->setMappedProperty(this, CSSPropertyBorderBottomWidth, CSSValueThin);
-                decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueSolid);
-                decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueSolid);
-                decl->setMappedProperty(this, CSSPropertyBorderColor, "inherit");
-                break;
-            case SolidBorders:
-                decl->setMappedProperty(this, CSSPropertyBorderWidth, "1px");
-                decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueSolid);
-                decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueSolid);
-                decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueSolid);
-                decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueSolid);
-                decl->setMappedProperty(this, CSSPropertyBorderColor, "inherit");
-                break;
-            case InsetBorders:
-                decl->setMappedProperty(this, CSSPropertyBorderWidth, "1px");
-                decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueInset);
-                decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueInset);
-                decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueInset);
-                decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueInset);
-                decl->setMappedProperty(this, CSSPropertyBorderColor, "inherit");
-                break;
-            case NoBorders:
-                decl->setMappedProperty(this, CSSPropertyBorderWidth, "0");
-                break;
-        }
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableElement::createSharedCellStyle()
+{
+    RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
+
+    switch (cellBorders()) {
+    case SolidBordersColsOnly:
+        style->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
+        style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
+        style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
+        style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
+        style->setProperty(CSSPropertyBorderColor, "inherit");
+        break;
+    case SolidBordersRowsOnly:
+        style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
+        style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
+        style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
+        style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
+        style->setProperty(CSSPropertyBorderColor, "inherit");
+        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");
+        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");
+        break;
+    case NoBorders:
+        style->setProperty(CSSPropertyBorderWidth, "0");
+        break;
+    }
 
-        setMappedAttributeDecl(ePersistent, cellborderAttr, *cellBorderNames[borders], decl);
-        decl->setMappedState(ePersistent, cellborderAttr, cellborderValue);
+    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);
     }
 
-    results.append(decl);
+    return style.release();
 }
 
-void HTMLTableElement::addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableElement::additionalCellStyle()
 {
-    if (m_padding == 0)
-        return;
+    if (!m_sharedCellStyle)
+        m_sharedCellStyle = createSharedCellStyle();
+    return m_sharedCellStyle;
+}
 
-    if (!m_paddingDecl) {
-        String paddingValue = String::number(m_padding);
-        m_paddingDecl = getMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue);
-        if (!m_paddingDecl) {
-            m_paddingDecl = CSSMappedAttributeDeclaration::create();
-            ASSERT(!m_paddingDecl->useStrictParsing());
-
-            m_paddingDecl->setMappedProperty(this, CSSPropertyPaddingTop, paddingValue);
-            m_paddingDecl->setMappedProperty(this, CSSPropertyPaddingRight, paddingValue);
-            m_paddingDecl->setMappedProperty(this, CSSPropertyPaddingBottom, paddingValue);
-            m_paddingDecl->setMappedProperty(this, CSSPropertyPaddingLeft, paddingValue);
-        }
-        setMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue, m_paddingDecl.get());
-        m_paddingDecl->setMappedState(eUniversal, cellpaddingAttr, paddingValue);
+static CSSMutableStyleDeclaration* leakGroupBorderStyle(int rows)
+{
+    RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
+    if (rows) {
+        style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
+        style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
+        style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
+        style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
+    } else {
+        style->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
+        style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
+        style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
+        style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
     }
-
-    results.append(m_paddingDecl.get());
+    return style.release().leakRef();
 }
 
-void HTMLTableElement::addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableElement::additionalGroupStyle(bool rows)
 {
     if (m_rulesAttr != GroupsRules)
-        return;
-
-    AtomicString rulesValue = rows ? "rowgroups" : "colgroups";
-    CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, rulesAttr, rulesValue);
-    if (!decl) {
-        decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
-        ASSERT(!decl->useStrictParsing());
-
-        if (rows) {
-            decl->setMappedProperty(this, CSSPropertyBorderTopWidth, CSSValueThin);
-            decl->setMappedProperty(this, CSSPropertyBorderBottomWidth, CSSValueThin);
-            decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueSolid);
-            decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueSolid);
-        } else {
-            decl->setMappedProperty(this, CSSPropertyBorderLeftWidth, CSSValueThin);
-            decl->setMappedProperty(this, CSSPropertyBorderRightWidth, CSSValueThin);
-            decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueSolid);
-            decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueSolid);
-        }
+        return 0;
 
-        setMappedAttributeDecl(ePersistent, rulesAttr, rulesValue, decl);
-        decl->setMappedState(ePersistent, rulesAttr, rulesValue);
+    if (rows) {
+        static CSSMutableStyleDeclaration* rowBorderStyle = leakGroupBorderStyle(true);
+        return rowBorderStyle;
     }
-
-    results.append(decl);
+    static CSSMutableStyleDeclaration* columnBorderStyle = leakGroupBorderStyle(false);
+    return columnBorderStyle;
 }
 
 void HTMLTableElement::attach()
index deed951..cfde1df 100644 (file)
@@ -66,8 +66,8 @@ public:
 
     virtual void attach();
 
-    void addSharedCellDecls(Vector<CSSMutableStyleDeclaration*>&);
-    void addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDeclaration*>&);
+    PassRefPtr<CSSMutableStyleDeclaration> additionalCellStyle();
+    PassRefPtr<CSSMutableStyleDeclaration> additionalGroupStyle(bool rows);
 
 private:
     HTMLTableElement(const QualifiedName&, Document*);
@@ -76,21 +76,18 @@ private:
     virtual void parseMappedAttribute(Attribute*);
     virtual bool isURLAttribute(Attribute*) const;
 
-    // Used to obtain either a solid or outset border decl and to deal with the frame
-    // and rules attributes.
-    virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
-    virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
+    // Used to obtain either a solid or outset border decl and to deal with the frame and rules attributes.
+    virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() OVERRIDE;
 
     virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
 
-    void addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaration*>&);
-    void addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaration*>&);
-    
     enum TableRules { UnsetRules, NoneRules, GroupsRules, RowsRules, ColsRules, AllRules };
     enum CellBorders { NoBorders, SolidBorders, InsetBorders, SolidBordersColsOnly, SolidBordersRowsOnly };
 
     CellBorders cellBorders() const;
 
+    PassRefPtr<CSSMutableStyleDeclaration> createSharedCellStyle();
+
     HTMLTableSectionElement* lastBody() const;
 
     bool m_borderAttr;          // Sets a precise border width and creates an outset border for the table and for its cells.
@@ -100,8 +97,8 @@ private:
                                 // are present, to none otherwise).
 
     unsigned short m_padding;
-    RefPtr<CSSMappedAttributeDeclaration> m_paddingDecl;
     OwnPtr<HTMLTableRowsCollection> m_rowsCollection;
+    RefPtr<CSSMutableStyleDeclaration> m_sharedCellStyle;
 };
 
 } //namespace
index 3297ad6..ef6e9f2 100644 (file)
@@ -47,15 +47,14 @@ PassRefPtr<HTMLTableSectionElement> HTMLTableSectionElement::create(const Qualif
     return adoptRef(new HTMLTableSectionElement(tagName, document));
 }
 
-// used by table row groups to share style decls created by the enclosing table.
-void HTMLTableSectionElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableSectionElement::additionalAttributeStyle()
 {
     ContainerNode* p = parentNode();
     while (p && !p->hasTagName(tableTag))
         p = p->parentNode();
     if (!p)
-        return;
-    static_cast<HTMLTableElement*>(p)->addSharedGroupDecls(true, results);
+        return 0;
+    return static_cast<HTMLTableElement*>(p)->additionalGroupStyle(true);
 }
 
 // these functions are rather slow, since we need to get the row at
index 295904c..b1680c4 100644 (file)
@@ -56,8 +56,7 @@ public:
 private:
     HTMLTableSectionElement(const QualifiedName& tagName, Document*);
 
-    virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
-    virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
+    virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() OVERRIDE;
 };
 
 } //namespace