Decouple CSSMappedAttributeDeclaration from element completely.
<http://webkit.org/b/75187>

Reviewed by Darin Adler.

Let CSSMappedAttributeDeclaration inherit from CSSMutableDeclaration instead
of CSSElementStyleDeclaration. Add methods to CSSMappedAttributeDeclaration
for setting properties that also take a StyledElement* and use that mechanism
instead of temporarily associating an element with the declaration.

This reduces the size of mapped attributes by 4/8 bytes, but more importantly
opens a number of ways to simplify style declarations in future patches.

* css/CSSMutableStyleDeclaration.h:
* dom/CSSMappedAttributeDeclaration.cpp:
(WebCore::CSSMappedAttributeDeclaration::setNeedsStyleRecalc):
(WebCore::CSSMappedAttributeDeclaration::setMappedImageProperty):
(WebCore::CSSMappedAttributeDeclaration::setMappedLengthProperty):
(WebCore::CSSMappedAttributeDeclaration::setMappedProperty):
(WebCore::CSSMappedAttributeDeclaration::removeMappedProperty):
* dom/CSSMappedAttributeDeclaration.h:
(WebCore::CSSMappedAttributeDeclaration::CSSMappedAttributeDeclaration):

    Add/move methods to CSSMappedAttributeDeclaration for setting/removing
    properties that also take a StyledElement*. That element is used for
    scheduling style recalc and passing the right document to CSSParser.

* css/CSSParser.h:
* css/CSSParser.cpp:
(WebCore::parseColorValue):
(WebCore::parseSimpleLengthValue):
(WebCore::CSSParser::parseValue):
(WebCore::CSSParser::parseMappedAttributeValue):

    Added a parsedMappedAttributeValue() alternative to parseValue() that
    takes a StyledElement*.

* dom/StyledElement.h:
* html/HTMLElement.cpp:
(WebCore::HTMLElement::setContentEditable):

    Add (and use) a StyledElement::removeCSSProperty() complement to the
    addCSS*() functions.

* dom/StyledElement.cpp:
(WebCore::StyledElement::attributeChanged):
(WebCore::StyledElement::removeCSSProperty):
(WebCore::StyledElement::addCSSProperty):
(WebCore::StyledElement::addCSSImageProperty):
(WebCore::StyledElement::addCSSLength):
(WebCore::StyledElement::addCSSColor):
(WebCore::StyledElement::createMappedDecl):
* html/HTMLTableElement.cpp:
(WebCore::HTMLTableElement::additionalAttributeStyleDecls):
(WebCore::HTMLTableElement::addSharedCellBordersDecl):
(WebCore::HTMLTableElement::addSharedCellPaddingDecl):
(WebCore::HTMLTableElement::addSharedGroupDecls):

    Use the setMapped*Property() functions to plumb the element through.

* css/CSSElementStyleDeclaration.h:

    Update comment about CSSElementStyleDeclaration's subclasses.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@103663 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index f74859b..6abe93c 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,69 @@
+2011-12-23  Andreas Kling  <awesomekling@apple.com>
+
+        Decouple CSSMappedAttributeDeclaration from element completely.
+        <http://webkit.org/b/75187>
+
+        Reviewed by Darin Adler.
+
+        Let CSSMappedAttributeDeclaration inherit from CSSMutableDeclaration instead
+        of CSSElementStyleDeclaration. Add methods to CSSMappedAttributeDeclaration
+        for setting properties that also take a StyledElement* and use that mechanism
+        instead of temporarily associating an element with the declaration.
+
+        This reduces the size of mapped attributes by 4/8 bytes, but more importantly
+        opens a number of ways to simplify style declarations in future patches.
+
+        * css/CSSMutableStyleDeclaration.h:
+        * dom/CSSMappedAttributeDeclaration.cpp:
+        (WebCore::CSSMappedAttributeDeclaration::setNeedsStyleRecalc):
+        (WebCore::CSSMappedAttributeDeclaration::setMappedImageProperty):
+        (WebCore::CSSMappedAttributeDeclaration::setMappedLengthProperty):
+        (WebCore::CSSMappedAttributeDeclaration::setMappedProperty):
+        (WebCore::CSSMappedAttributeDeclaration::removeMappedProperty):
+        * dom/CSSMappedAttributeDeclaration.h:
+        (WebCore::CSSMappedAttributeDeclaration::CSSMappedAttributeDeclaration):
+
+            Add/move methods to CSSMappedAttributeDeclaration for setting/removing
+            properties that also take a StyledElement*. That element is used for
+            scheduling style recalc and passing the right document to CSSParser.
+
+        * css/CSSParser.h:
+        * css/CSSParser.cpp:
+        (WebCore::parseColorValue):
+        (WebCore::parseSimpleLengthValue):
+        (WebCore::CSSParser::parseValue):
+        (WebCore::CSSParser::parseMappedAttributeValue):
+
+            Added a parsedMappedAttributeValue() alternative to parseValue() that
+            takes a StyledElement*.
+
+        * dom/StyledElement.h:
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::setContentEditable):
+
+            Add (and use) a StyledElement::removeCSSProperty() complement to the
+            addCSS*() functions.
+
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::attributeChanged):
+        (WebCore::StyledElement::removeCSSProperty):
+        (WebCore::StyledElement::addCSSProperty):
+        (WebCore::StyledElement::addCSSImageProperty):
+        (WebCore::StyledElement::addCSSLength):
+        (WebCore::StyledElement::addCSSColor):
+        (WebCore::StyledElement::createMappedDecl):
+        * html/HTMLTableElement.cpp:
+        (WebCore::HTMLTableElement::additionalAttributeStyleDecls):
+        (WebCore::HTMLTableElement::addSharedCellBordersDecl):
+        (WebCore::HTMLTableElement::addSharedCellPaddingDecl):
+        (WebCore::HTMLTableElement::addSharedGroupDecls):
+
+            Use the setMapped*Property() functions to plumb the element through.
+
+        * css/CSSElementStyleDeclaration.h:
+
+            Update comment about CSSElementStyleDeclaration's subclasses.
+
 2011-12-24  Jarred Nicholls  <jarred@sencha.com>
 
         Allow XMLHttpRequest withCredentials to be set prior to a call to open()
diff --git a/Source/WebCore/css/CSSElementStyleDeclaration.h b/Source/WebCore/css/CSSElementStyleDeclaration.h
index 12af9b5..4980cff 100644
--- a/Source/WebCore/css/CSSElementStyleDeclaration.h
+++ b/Source/WebCore/css/CSSElementStyleDeclaration.h
@@ -32,7 +32,7 @@
 
 class StyledElement;
 
-// Base class for CSSInlineStyleDeclaration and CSSMappedAttributeDeclaration.
+// Base class for CSSInlineStyleDeclaration and FontFaceStyleDeclaration (SVG).
 
 class CSSElementStyleDeclaration : public CSSMutableStyleDeclaration {
 public:
diff --git a/Source/WebCore/css/CSSMutableStyleDeclaration.cpp b/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
index 1686a56..c831b07 100644
--- a/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
+++ b/Source/WebCore/css/CSSMutableStyleDeclaration.cpp
@@ -768,14 +768,6 @@
     return true;
 }
 
-void CSSMutableStyleDeclaration::setImageProperty(int propertyId, const String& url, bool important)
-{
-    ASSERT(!m_iteratorCount);
-
-    setPropertyInternal(CSSProperty(propertyId, CSSImageValue::create(url), important));
-    setNeedsStyleRecalc();
-}
-
 void CSSMutableStyleDeclaration::parseDeclaration(const String& styleDeclaration)
 {
     ASSERT(!m_iteratorCount);
@@ -834,16 +826,6 @@
 #endif
 }
 
-void CSSMutableStyleDeclaration::setLengthProperty(int propertyId, const String& value, bool important)
-{
-    ASSERT(!m_iteratorCount);
-
-    bool parseMode = useStrictParsing();
-    setStrictParsing(false);
-    setProperty(propertyId, value, important);
-    setStrictParsing(parseMode);
-}
-
 unsigned CSSMutableStyleDeclaration::virtualLength() const
 {
     return length();
diff --git a/Source/WebCore/css/CSSMutableStyleDeclaration.h b/Source/WebCore/css/CSSMutableStyleDeclaration.h
index 9740877..54e08ed 100644
--- a/Source/WebCore/css/CSSMutableStyleDeclaration.h
+++ b/Source/WebCore/css/CSSMutableStyleDeclaration.h
@@ -107,10 +107,6 @@
 
     void removeProperty(int propertyID) { removeProperty(propertyID, true, false); }
 
-    // setLengthProperty treats integers as pixels! (Needed for conversion of HTML attributes.)
-    void setLengthProperty(int propertyId, const String& value, bool important);
-    void setImageProperty(int propertyId, const String& url, bool important = false);
-
     // The following parses an entire new style declaration.
     void parseDeclaration(const String& styleDeclaration);
 
@@ -137,6 +133,9 @@
     CSSMutableStyleDeclaration(CSSRule* parentRule);
     CSSMutableStyleDeclaration();
 
+    void setPropertyInternal(const CSSProperty&, CSSProperty* slot = 0);
+    String removeProperty(int propertyID, bool notifyChanged, bool returnText);
+
 private:
     CSSMutableStyleDeclaration(CSSRule* parentRule, const Vector<CSSProperty>&);
     CSSMutableStyleDeclaration(CSSRule* parentRule, const CSSProperty* const *, int numProperties);
@@ -160,8 +159,6 @@
     bool setProperty(int propertyID, int value, bool important, bool notifyChanged);
     bool setProperty(int propertyId, double value, CSSPrimitiveValue::UnitTypes, bool important, bool notifyChanged);
     bool setProperty(int propertyID, const String& value, bool important, bool notifyChanged);
-    void setPropertyInternal(const CSSProperty&, CSSProperty* slot = 0);
-    String removeProperty(int propertyID, bool notifyChanged, bool returnText);
     bool removeShorthandProperty(int propertyID, bool notifyChanged);
     bool removePropertiesInSet(const int* set, unsigned length, bool notifyChanged);
 
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index 3bff12c..ac977c4 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -332,7 +332,7 @@
     }
 }
 
-static bool parseColorValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
+static bool parseColorValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict, CSSStyleSheet* contextStyleSheet = 0)
 {
     if (!string.length())
         return false;
@@ -352,7 +352,7 @@
         validPrimitive = true;
     }
 
-    CSSStyleSheet* styleSheet = declaration->parentStyleSheet();
+    CSSStyleSheet* styleSheet = contextStyleSheet ? contextStyleSheet : declaration->parentStyleSheet();
     if (!styleSheet)
         return false;
     Document* document = styleSheet->findDocument();
@@ -415,7 +415,7 @@
     }
 }
 
-static bool parseSimpleLengthValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
+static bool parseSimpleLengthValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict, CSSStyleSheet* contextStyleSheet = 0)
 {
     const UChar* characters = string.characters();
     unsigned length = string.length();
@@ -449,7 +449,7 @@
     if (number < 0 && !acceptsNegativeNumbers)
         return false;
 
-    CSSStyleSheet* styleSheet = declaration->parentStyleSheet();
+    CSSStyleSheet* styleSheet = contextStyleSheet ? contextStyleSheet : declaration->parentStyleSheet();
     if (!styleSheet)
         return false;
     Document* document = styleSheet->findDocument();
@@ -460,6 +460,20 @@
     return true;
 }
 
+bool CSSParser::parseMappedAttributeValue(CSSMappedAttributeDeclaration* declaration, StyledElement* element, int propertyId, const String& value)
+{
+    ASSERT(declaration);
+    ASSERT(element);
+    ASSERT(element->document());
+    CSSStyleSheet* elementSheet = element->document()->elementSheet();
+    if (parseSimpleLengthValue(declaration, propertyId, value, false, false, elementSheet))
+        return true;
+    if (parseColorValue(declaration, propertyId, value, false, false, elementSheet))
+        return true;
+    CSSParser parser(false);
+    return parser.parseValue(declaration, propertyId, value, false, elementSheet);
+}
+
 bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, bool strict)
 {
     if (parseSimpleLengthValue(declaration, propertyId, string, important, strict))
@@ -470,9 +484,12 @@
     return parser.parseValue(declaration, propertyId, string, important);
 }
 
-bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important)
+bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int propertyId, const String& string, bool important, CSSStyleSheet* contextStyleSheet)
 {
-    setStyleSheet(declaration->parentStyleSheet());
+    if (contextStyleSheet)
+        setStyleSheet(contextStyleSheet);
+    else
+        setStyleSheet(declaration->parentStyleSheet());
 
     setupParser("@-webkit-value{", string, "} ");
 
diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h
index 88a2eb4..dbb7e8f 100644
--- a/Source/WebCore/css/CSSParser.h
+++ b/Source/WebCore/css/CSSParser.h
@@ -40,6 +40,7 @@
 namespace WebCore {
 
 class CSSBorderImageSliceValue;
+class CSSMappedAttributeDeclaration;
 class CSSMutableStyleDeclaration;
 class CSSPrimitiveValue;
 class CSSValuePool;
@@ -50,12 +51,13 @@
 class CSSStyleSheet;
 class CSSValue;
 class CSSValueList;
+class CSSWrapShape;
 class Document;
 class MediaList;
 class MediaQueryExp;
+class StyledElement;
 class WebKitCSSKeyframeRule;
 class WebKitCSSKeyframesRule;
-class CSSWrapShape;
 
 class CSSParser {
 public:
@@ -72,6 +74,8 @@
     bool parseDeclaration(CSSMutableStyleDeclaration*, const String&, RefPtr<CSSStyleSourceData>* = 0, CSSStyleSheet* contextStyleSheet = 0);
     bool parseMediaQuery(MediaList*, const String&);
 
+    static bool parseMappedAttributeValue(CSSMappedAttributeDeclaration*, StyledElement*, int propertyId, const String&);
+
     Document* findDocument() const;
 
     CSSValuePool* cssValuePool() const { return m_cssValuePool.get(); }
@@ -331,7 +335,7 @@
     bool isGeneratedImageValue(CSSParserValue*) const;
     bool parseGeneratedImage(CSSParserValueList*, RefPtr<CSSValue>&);
 
-    bool parseValue(CSSMutableStyleDeclaration*, int propId, const String&, bool important);
+    bool parseValue(CSSMutableStyleDeclaration*, int propId, const String&, bool important, CSSStyleSheet* contextStyleSheet = 0);
 
     enum SizeParameterType {
         None,
diff --git a/Source/WebCore/dom/CSSMappedAttributeDeclaration.cpp b/Source/WebCore/dom/CSSMappedAttributeDeclaration.cpp
index 9ee6474..536992d 100644
--- a/Source/WebCore/dom/CSSMappedAttributeDeclaration.cpp
+++ b/Source/WebCore/dom/CSSMappedAttributeDeclaration.cpp
@@ -3,7 +3,7 @@
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Peter Kelly (pmk@post.com)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006, 2011 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,14 +23,60 @@
 #include "config.h"
 #include "CSSMappedAttributeDeclaration.h"
 
+#include "CSSImageValue.h"
+#include "CSSParser.h"
+#include "CSSValuePool.h"
 #include "StyledElement.h"
 
 namespace WebCore {
 
+inline void CSSMappedAttributeDeclaration::setNeedsStyleRecalc(StyledElement* element)
+{
+    ASSERT(element);
+    element->setNeedsStyleRecalc(FullStyleChange);
+}
+
 CSSMappedAttributeDeclaration::~CSSMappedAttributeDeclaration()
 {
     if (m_entryType != ePersistent)
         StyledElement::removeMappedAttributeDecl(m_entryType, m_attrName, m_attrValue);
 }
 
+void CSSMappedAttributeDeclaration::setMappedImageProperty(StyledElement* element, int propertyId, const String& url)
+{
+    setPropertyInternal(CSSProperty(propertyId, CSSImageValue::create(url)));
+    setNeedsStyleRecalc(element);
+}
+
+void CSSMappedAttributeDeclaration::setMappedLengthProperty(StyledElement* element, int propertyId, const String& value)
+{
+    setMappedProperty(element, propertyId, value);
+}
+
+void CSSMappedAttributeDeclaration::setMappedProperty(StyledElement* element, int propertyId, int value)
+{
+    ASSERT(element->document());
+    setPropertyInternal(CSSProperty(propertyId, element->document()->cssValuePool()->createIdentifierValue(value)));
+    setNeedsStyleRecalc(element);
+}
+
+void CSSMappedAttributeDeclaration::setMappedProperty(StyledElement* element, int propertyId, const String& value)
+{
+    if (value.isEmpty()) {
+        removeMappedProperty(element, propertyId);
+        return;
+    }
+
+    if (!CSSParser::parseMappedAttributeValue(this, element, propertyId, value))
+        return;
+
+    setNeedsStyleRecalc(element);
+}
+
+void CSSMappedAttributeDeclaration::removeMappedProperty(StyledElement* element, int propertyId)
+{
+    removeProperty(propertyId, false, false);
+    setNeedsStyleRecalc(element);
+}
+
 }
diff --git a/Source/WebCore/dom/CSSMappedAttributeDeclaration.h b/Source/WebCore/dom/CSSMappedAttributeDeclaration.h
index 71ccf54..a5b7551 100644
--- a/Source/WebCore/dom/CSSMappedAttributeDeclaration.h
+++ b/Source/WebCore/dom/CSSMappedAttributeDeclaration.h
@@ -3,7 +3,7 @@
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Peter Kelly (pmk@post.com)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2011 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -25,13 +25,15 @@
 #ifndef CSSMappedAttributeDeclaration_h
 #define CSSMappedAttributeDeclaration_h
 
-#include "CSSElementStyleDeclaration.h"
+#include "CSSMutableStyleDeclaration.h"
 #include "MappedAttributeEntry.h"
 #include "QualifiedName.h"
 
 namespace WebCore {
 
-class CSSMappedAttributeDeclaration : public CSSElementStyleDeclaration {
+class StyledElement;
+
+class CSSMappedAttributeDeclaration : public CSSMutableStyleDeclaration {
 public:
     static PassRefPtr<CSSMappedAttributeDeclaration> create()
     {
@@ -47,14 +49,25 @@
         m_attrValue = val;
     }
 
+    void setMappedProperty(StyledElement*, int propertyId, int value);
+    void setMappedProperty(StyledElement*, int propertyId, const String& value);
+    void setMappedImageProperty(StyledElement*, int propertyId, const String& url);
+
+    // NOTE: setMappedLengthProperty() treats integers as pixels! (Needed for conversion of HTML attributes.)
+    void setMappedLengthProperty(StyledElement*, int propertyId, const String& value);
+
+    void removeMappedProperty(StyledElement*, int propertyId);
+
 private:
     CSSMappedAttributeDeclaration()
-        : CSSElementStyleDeclaration(/* isInline */ false)
+        : CSSMutableStyleDeclaration()
         , m_entryType(eNone)
         , m_attrName(anyQName())
     {
     }
 
+    void setNeedsStyleRecalc(StyledElement*);
+
     MappedAttributeEntry m_entryType;
     QualifiedName m_attrName;
     AtomicString m_attrValue;
diff --git a/Source/WebCore/dom/StyledElement.cpp b/Source/WebCore/dom/StyledElement.cpp
index c7ee147..77a8ef9 100644
--- a/Source/WebCore/dom/StyledElement.cpp
+++ b/Source/WebCore/dom/StyledElement.cpp
@@ -197,7 +197,6 @@
         // Add the decl to the table in the appropriate spot.
         setMappedAttributeDecl(entry, attr, attr->decl());
         attr->decl()->setMappedState(entry, attr->name(), attr->value());
-        attr->decl()->setElement(0);
         if (attributeMap())
             attributeMap()->declAdded();
     }
@@ -262,33 +261,40 @@
     return ensureInlineStyleDecl();
 }
 
+void StyledElement::removeCSSProperty(Attribute* attribute, int id)
+{
+    if (!attribute->decl())
+        createMappedDecl(attribute);
+    attribute->decl()->removeMappedProperty(this, id);
+}
+
 void StyledElement::addCSSProperty(Attribute* attribute, int id, const String &value)
 {
     if (!attribute->decl())
         createMappedDecl(attribute);
-    attribute->decl()->setProperty(id, value, false);
+    attribute->decl()->setMappedProperty(this, id, value);
 }
 
 void StyledElement::addCSSProperty(Attribute* attribute, int id, int value)
 {
     if (!attribute->decl())
         createMappedDecl(attribute);
-    attribute->decl()->setProperty(id, value, false);
+    attribute->decl()->setMappedProperty(this, id, value);
 }
 
 void StyledElement::addCSSImageProperty(Attribute* attribute, int id, const String& url)
 {
     if (!attribute->decl())
         createMappedDecl(attribute);
-    attribute->decl()->setImageProperty(id, url, false);
+    attribute->decl()->setMappedImageProperty(this, id, url);
 }
 
-void StyledElement::addCSSLength(Attribute* attr, int id, const String &value)
+void StyledElement::addCSSLength(Attribute* attribute, int id, const String &value)
 {
     // FIXME: This function should not spin up the CSS parser, but should instead just figure out the correct
     // length unit and make the appropriate parsed value.
-    if (!attr->decl())
-        createMappedDecl(attr);
+    if (!attribute->decl())
+        createMappedDecl(attribute);
 
     // strip attribute garbage..
     StringImpl* v = value.impl();
@@ -311,12 +317,12 @@
         }
 
         if (l != v->length()) {
-            attr->decl()->setLengthProperty(id, v->substring(0, l), false);
+            attribute->decl()->setMappedLengthProperty(this, id, v->substring(0, l));
             return;
         }
     }
-    
-    attr->decl()->setLengthProperty(id, value, false);
+
+    attribute->decl()->setMappedLengthProperty(this, id, value);
 }
 
 static String parseColorStringWithCrazyLegacyRules(const String& colorString)
@@ -390,18 +396,17 @@
     // If the string is a named CSS color or a 3/6-digit hex color, use that.
     Color parsedColor(colorString);
     if (parsedColor.isValid()) {
-        attribute->decl()->setProperty(id, colorString, false);
+        attribute->decl()->setMappedProperty(this, id, colorString);
         return;
     }
 
-    attribute->decl()->setProperty(id, parseColorStringWithCrazyLegacyRules(colorString), false);
+    attribute->decl()->setMappedProperty(this, id, parseColorStringWithCrazyLegacyRules(colorString));
 }
 
 void StyledElement::createMappedDecl(Attribute* attr)
 {
     RefPtr<CSSMappedAttributeDeclaration> decl = CSSMappedAttributeDeclaration::create();
     attr->setDecl(decl);
-    decl->setElement(this);
     ASSERT(!decl->useStrictParsing());
 }
 
diff --git a/Source/WebCore/dom/StyledElement.h b/Source/WebCore/dom/StyledElement.h
index f553d86..3e62926 100644
--- a/Source/WebCore/dom/StyledElement.h
+++ b/Source/WebCore/dom/StyledElement.h
@@ -46,6 +46,7 @@
     void addCSSProperty(Attribute*, int id, int value);
     void addCSSImageProperty(Attribute*, int propertyID, const String& url);
     void addCSSColor(Attribute*, int id, const String& color);
+    void removeCSSProperty(Attribute*, int id);
 
     static CSSMappedAttributeDeclaration* getMappedAttributeDecl(MappedAttributeEntry, const QualifiedName& name, const AtomicString& value);
     static void setMappedAttributeDecl(MappedAttributeEntry, const QualifiedName& name, const AtomicString& value, CSSMappedAttributeDeclaration*);
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
index 95fe4af..23e2945 100644
--- a/Source/WebCore/html/HTMLElement.cpp
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -752,9 +752,9 @@
         addCSSProperty(attr, CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
     } else if (equalIgnoringCase(enabled, "false")) {
         addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadOnly);
-        attr->decl()->removeProperty(CSSPropertyWordWrap);
-        attr->decl()->removeProperty(CSSPropertyWebkitNbspMode);
-        attr->decl()->removeProperty(CSSPropertyWebkitLineBreak);
+        removeCSSProperty(attr, CSSPropertyWordWrap);
+        removeCSSProperty(attr, CSSPropertyWebkitNbspMode);
+        removeCSSProperty(attr, CSSPropertyWebkitLineBreak);
     } else if (equalIgnoringCase(enabled, "plaintext-only")) {
         addCSSProperty(attr, CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);
         addCSSProperty(attr, CSSPropertyWordWrap, CSSValueBreakWord);
diff --git a/Source/WebCore/html/HTMLTableElement.cpp b/Source/WebCore/html/HTMLTableElement.cpp
index 9ca7dab..7a84a99 100644
--- a/Source/WebCore/html/HTMLTableElement.cpp
+++ b/Source/WebCore/html/HTMLTableElement.cpp
@@ -4,7 +4,7 @@
  *           (C) 1998 Waldo Bastian (bastian@kde.org)
  *           (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2010, 2011 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -455,21 +455,18 @@
     CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, tableborderAttr, borderValue);
     if (!decl) {
         decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
-        decl->setElement(this);
         ASSERT(!decl->useStrictParsing());
-        
-        int v = m_borderColorAttr ? CSSValueSolid : CSSValueOutset;
-        decl->setProperty(CSSPropertyBorderTopStyle, v, false);
-        decl->setProperty(CSSPropertyBorderBottomStyle, v, false);
-        decl->setProperty(CSSPropertyBorderLeftStyle, v, false);
-        decl->setProperty(CSSPropertyBorderRightStyle, v, false);
+
+        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);
 
         setMappedAttributeDecl(ePersistent, tableborderAttr, borderValue, decl);
-        decl->setElement(0);
         decl->setMappedState(ePersistent, tableborderAttr, borderValue);
     }
-    
-    
+
     results.append(decl);
 }
 
@@ -511,50 +508,48 @@
     CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, cellborderAttr, cellborderValue);
     if (!decl) {
         decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
-        decl->setElement(this);
         ASSERT(!decl->useStrictParsing());
-        
+
         switch (borders) {
             case SolidBordersColsOnly:
-                decl->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin, false);
-                decl->setProperty(CSSPropertyBorderRightWidth, CSSValueThin, false);
-                decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
-                decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
-                decl->setProperty(CSSPropertyBorderColor, "inherit", false);
+                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->setProperty(CSSPropertyBorderTopWidth, CSSValueThin, false);
-                decl->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin, false);
-                decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
-                decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
-                decl->setProperty(CSSPropertyBorderColor, "inherit", false);
+                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->setProperty(CSSPropertyBorderWidth, "1px", false);
-                decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
-                decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
-                decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
-                decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
-                decl->setProperty(CSSPropertyBorderColor, "inherit", false);
+                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->setProperty(CSSPropertyBorderWidth, "1px", false);
-                decl->setProperty(CSSPropertyBorderTopStyle, CSSValueInset, false);
-                decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueInset, false);
-                decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueInset, false);
-                decl->setProperty(CSSPropertyBorderRightStyle, CSSValueInset, false);
-                decl->setProperty(CSSPropertyBorderColor, "inherit", false);
+                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->setProperty(CSSPropertyBorderWidth, "0", false);
+                decl->setMappedProperty(this, CSSPropertyBorderWidth, "0");
                 break;
         }
 
         setMappedAttributeDecl(ePersistent, cellborderAttr, *cellBorderNames[borders], decl);
-        decl->setElement(0);
         decl->setMappedState(ePersistent, cellborderAttr, cellborderValue);
     }
-    
+
     results.append(decl);
 }
 
@@ -568,19 +563,17 @@
         m_paddingDecl = getMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue);
         if (!m_paddingDecl) {
             m_paddingDecl = CSSMappedAttributeDeclaration::create();
-            m_paddingDecl->setElement(this);
             ASSERT(!m_paddingDecl->useStrictParsing());
-            
-            m_paddingDecl->setProperty(CSSPropertyPaddingTop, paddingValue, false);
-            m_paddingDecl->setProperty(CSSPropertyPaddingRight, paddingValue, false);
-            m_paddingDecl->setProperty(CSSPropertyPaddingBottom, paddingValue, false);
-            m_paddingDecl->setProperty(CSSPropertyPaddingLeft, paddingValue, false);
+
+            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->setElement(0);
         m_paddingDecl->setMappedState(eUniversal, cellpaddingAttr, paddingValue);
     }
-    
+
     results.append(m_paddingDecl.get());
 }
 
@@ -593,23 +586,21 @@
     CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, rulesAttr, rulesValue);
     if (!decl) {
         decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
-        decl->setElement(this);
         ASSERT(!decl->useStrictParsing());
-        
+
         if (rows) {
-            decl->setProperty(CSSPropertyBorderTopWidth, CSSValueThin, false);
-            decl->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin, false);
-            decl->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid, false);
-            decl->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid, false);
+            decl->setMappedProperty(this, CSSPropertyBorderTopWidth, CSSValueThin);
+            decl->setMappedProperty(this, CSSPropertyBorderBottomWidth, CSSValueThin);
+            decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueSolid);
+            decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueSolid);
         } else {
-            decl->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin, false);
-            decl->setProperty(CSSPropertyBorderRightWidth, CSSValueThin, false);
-            decl->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid, false);
-            decl->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid, false);
+            decl->setMappedProperty(this, CSSPropertyBorderLeftWidth, CSSValueThin);
+            decl->setMappedProperty(this, CSSPropertyBorderRightWidth, CSSValueThin);
+            decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueSolid);
+            decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueSolid);
         }
 
         setMappedAttributeDecl(ePersistent, rulesAttr, rulesValue, decl);
-        decl->setElement(0);
         decl->setMappedState(ePersistent, rulesAttr, rulesValue);
     }