CSSStyleDeclaration: Remove ability to have style sheet as parent.
authorandreas.kling@nokia.com <andreas.kling@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Nov 2011 12:37:44 +0000 (12:37 +0000)
committerandreas.kling@nokia.com <andreas.kling@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Nov 2011 12:37:44 +0000 (12:37 +0000)
<http://webkit.org/b/73199>

Reviewed by Antti Koivisto.

Refactor so we don't have to support style sheets as parents of style declarations.
The users of this mechanism were mapped attributes and inline styles, which instead
now know how to find the relevant style sheet via their document().

* css/CSSMutableStyleDeclaration.h:
* css/CSSMutableStyleDeclaration.cpp:
(WebCore::CSSElementStyleDeclaration::styleSheet):

    Added CSSElementStyleDeclaration::styleSheet(). The default implementation
    returns the associated element's document()->elementSheet(). It is virtual
    because SVGFontFaceElement needs document()->mappedElementSheet() instead.

* css/CSSStyleDeclaration.h:
(WebCore::CSSStyleDeclaration::parentRule):
(WebCore::CSSStyleDeclaration::setParentRule):
* css/CSSStyleDeclaration.cpp:
(WebCore::CSSStyleDeclaration::CSSStyleDeclaration):

    Remove m_parentIsRule and m_parentStyleSheet, leaving only m_parentRule.

* css/CSSStyleDeclaration.cpp:
(WebCore::CSSStyleDeclaration::parentStyleSheet):

    Out-of-lined so it can return the CSSElementStyleDeclaration::styleSheet() for
    declarations with an associated element.

* css/WebKitCSSKeyframeRule.cpp:
(WebCore::WebKitCSSKeyframeRule::~WebKitCSSKeyframeRule):
(WebCore::WebKitCSSKeyframeRule::setDeclaration):

    Use setParentRule() instead of setParentStyleSheet() on the internal
    CSSMutableStyleDeclaration in keyframe rules.

* dom/StyledElement.h:

    Removed StyledElement::didMoveToNewOwnerDocument() since we no longer need to
    manually keep the inline style's parent style sheet pointer up-to-date.

* dom/StyledElement.cpp:
(WebCore::StyledElement::createInlineStyleDecl):
(WebCore::StyledElement::destroyInlineStyleDecl):
(WebCore::StyledElement::attributeChanged):
(WebCore::StyledElement::createMappedDecl):
* html/HTMLTableElement.cpp:
(WebCore::HTMLTableElement::additionalAttributeStyleDecls):
(WebCore::HTMLTableElement::addSharedCellBordersDecl):
(WebCore::HTMLTableElement::addSharedCellPaddingDecl):
(WebCore::HTMLTableElement::addSharedGroupDecls):
* svg/SVGFontFaceElement.cpp:
(WebCore::SVGFontFaceElement::SVGFontFaceElement):

    Remove setParentStyleSheet() calls on mapped attributes and inline styles.
    They now find the relevant style sheet by following the associated element ptr.

* svg/SVGFontFaceElement.cpp:
(WebCore::FontFaceStyleDeclaration::FontFaceStyleDeclaration):
(WebCore::FontFaceStyleDeclaration::~FontFaceStyleDeclaration):
(WebCore::FontFaceStyleDeclaration::styleSheet):

    Subclass CSSElementStyleDeclaration for SVG's font-face elment in order to
    override styleSheet(). This is necessary because they operate on the document's
    mappedElementSheet() rather than the elementSheet().

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

Source/WebCore/ChangeLog
Source/WebCore/css/CSSMutableStyleDeclaration.cpp
Source/WebCore/css/CSSMutableStyleDeclaration.h
Source/WebCore/css/CSSStyleDeclaration.cpp
Source/WebCore/css/CSSStyleDeclaration.h
Source/WebCore/css/WebKitCSSKeyframeRule.cpp
Source/WebCore/dom/StyledElement.cpp
Source/WebCore/dom/StyledElement.h
Source/WebCore/html/HTMLTableElement.cpp
Source/WebCore/svg/SVGFontFaceElement.cpp

index c939335..734a409 100644 (file)
@@ -1,3 +1,73 @@
+2011-11-28  Andreas Kling  <kling@webkit.org>
+
+        CSSStyleDeclaration: Remove ability to have style sheet as parent.
+        <http://webkit.org/b/73199>
+
+        Reviewed by Antti Koivisto.
+
+        Refactor so we don't have to support style sheets as parents of style declarations.
+        The users of this mechanism were mapped attributes and inline styles, which instead
+        now know how to find the relevant style sheet via their document().
+
+        * css/CSSMutableStyleDeclaration.h:
+        * css/CSSMutableStyleDeclaration.cpp:
+        (WebCore::CSSElementStyleDeclaration::styleSheet):
+
+            Added CSSElementStyleDeclaration::styleSheet(). The default implementation
+            returns the associated element's document()->elementSheet(). It is virtual
+            because SVGFontFaceElement needs document()->mappedElementSheet() instead.
+
+        * css/CSSStyleDeclaration.h:
+        (WebCore::CSSStyleDeclaration::parentRule):
+        (WebCore::CSSStyleDeclaration::setParentRule):
+        * css/CSSStyleDeclaration.cpp:
+        (WebCore::CSSStyleDeclaration::CSSStyleDeclaration):
+
+            Remove m_parentIsRule and m_parentStyleSheet, leaving only m_parentRule.
+
+        * css/CSSStyleDeclaration.cpp:
+        (WebCore::CSSStyleDeclaration::parentStyleSheet):
+
+            Out-of-lined so it can return the CSSElementStyleDeclaration::styleSheet() for
+            declarations with an associated element.
+
+        * css/WebKitCSSKeyframeRule.cpp:
+        (WebCore::WebKitCSSKeyframeRule::~WebKitCSSKeyframeRule):
+        (WebCore::WebKitCSSKeyframeRule::setDeclaration):
+
+            Use setParentRule() instead of setParentStyleSheet() on the internal
+            CSSMutableStyleDeclaration in keyframe rules.
+
+        * dom/StyledElement.h:
+
+            Removed StyledElement::didMoveToNewOwnerDocument() since we no longer need to
+            manually keep the inline style's parent style sheet pointer up-to-date.
+
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::createInlineStyleDecl):
+        (WebCore::StyledElement::destroyInlineStyleDecl):
+        (WebCore::StyledElement::attributeChanged):
+        (WebCore::StyledElement::createMappedDecl):
+        * html/HTMLTableElement.cpp:
+        (WebCore::HTMLTableElement::additionalAttributeStyleDecls):
+        (WebCore::HTMLTableElement::addSharedCellBordersDecl):
+        (WebCore::HTMLTableElement::addSharedCellPaddingDecl):
+        (WebCore::HTMLTableElement::addSharedGroupDecls):
+        * svg/SVGFontFaceElement.cpp:
+        (WebCore::SVGFontFaceElement::SVGFontFaceElement):
+
+            Remove setParentStyleSheet() calls on mapped attributes and inline styles.
+            They now find the relevant style sheet by following the associated element ptr.
+
+        * svg/SVGFontFaceElement.cpp:
+        (WebCore::FontFaceStyleDeclaration::FontFaceStyleDeclaration):
+        (WebCore::FontFaceStyleDeclaration::~FontFaceStyleDeclaration):
+        (WebCore::FontFaceStyleDeclaration::styleSheet):
+
+            Subclass CSSElementStyleDeclaration for SVG's font-face elment in order to
+            override styleSheet(). This is necessary because they operate on the document's
+            mappedElementSheet() rather than the elementSheet().
+
 2011-11-28  Peter Rybin  <peter.rybin@gmail.com>
 
         Web Inspector: [protocol] generate C++ classes for protocol JSON named types
index fc66be7..b6289f5 100644 (file)
@@ -1044,4 +1044,11 @@ CSSProperty* CSSMutableStyleDeclaration::findPropertyWithId(int propertyID)
     return 0;
 }
 
+CSSStyleSheet* CSSElementStyleDeclaration::styleSheet() const
+{
+    if (m_element && m_element->document())
+        return m_element->document()->elementSheet();
+    return 0;
+}
+
 } // namespace WebCore
index 32fa239..058ec0b 100644 (file)
@@ -180,6 +180,8 @@ public:
     StyledElement* element() const { return m_element; }
     void setElement(StyledElement* element) { m_element = element; }
 
+    virtual CSSStyleSheet* styleSheet() const;
+
 protected:
     CSSElementStyleDeclaration(bool isInline)
         : CSSMutableStyleDeclaration()
index 84a8322..2b74b24 100644 (file)
@@ -45,11 +45,19 @@ CSSStyleDeclaration::CSSStyleDeclaration(CSSRule* parent)
 #endif
     , m_isElementStyleDeclaration(false)
     , m_isInlineStyleDeclaration(false)
-    , m_parentIsRule(true)
     , m_parentRule(parent)
 {
 }
 
+CSSStyleSheet* CSSStyleDeclaration::parentStyleSheet() const
+{
+    if (parentRule())
+        return parentRule()->parentStyleSheet();
+    if (isElementStyleDeclaration())
+        return static_cast<const CSSElementStyleDeclaration*>(this)->styleSheet();
+    return 0;
+}
+
 PassRefPtr<CSSValue> CSSStyleDeclaration::getPropertyCSSValue(const String& propertyName)
 {
     int propID = cssPropertyID(propertyName);
index 33edc74..7fb6d6d 100644 (file)
@@ -39,31 +39,10 @@ public:
 
     static bool isPropertyName(const String&);
 
-    // FIXME: Refactor so CSSStyleDeclaration never needs to have a style sheet parent.
-
-    CSSRule* parentRule() const
-    {
-        return m_parentIsRule ? m_parentRule : 0;
-    }
-
-    void setParentRule(CSSRule* rule)
-    {
-        m_parentIsRule = true;
-        m_parentRule = rule;
-    }
-
-    void setParentStyleSheet(CSSStyleSheet* styleSheet)
-    {
-        m_parentIsRule = false;
-        m_parentStyleSheet = styleSheet;
-    }
-
-    CSSStyleSheet* parentStyleSheet() const
-    {
-        if (!m_parentIsRule)
-            return m_parentStyleSheet;
-        return m_parentRule ? m_parentRule->parentStyleSheet() : 0;
-    }
+    CSSRule* parentRule() const { return m_parentRule; }
+    void setParentRule(CSSRule* rule) { m_parentRule = rule; }
+
+    CSSStyleSheet* parentStyleSheet() const;
 
     virtual String cssText() const = 0;
     virtual void setCssText(const String&, ExceptionCode&) = 0;
@@ -124,11 +103,7 @@ protected:
     bool m_isInlineStyleDeclaration : 1;
 
 private:
-    bool m_parentIsRule : 1;
-    union {
-        CSSRule* m_parentRule;
-        CSSStyleSheet* m_parentStyleSheet;
-    };
+    CSSRule* m_parentRule;
 };
 
 } // namespace WebCore
index 7fd29f8..e9a2c6f 100644 (file)
@@ -38,7 +38,7 @@ WebKitCSSKeyframeRule::WebKitCSSKeyframeRule(CSSStyleSheet* parent)
 WebKitCSSKeyframeRule::~WebKitCSSKeyframeRule()
 {
     if (m_style)
-        m_style->setParentStyleSheet(0);
+        m_style->setParentRule(0);
 }
 
 String WebKitCSSKeyframeRule::cssText() const
@@ -55,7 +55,7 @@ String WebKitCSSKeyframeRule::cssText() const
 void WebKitCSSKeyframeRule::setDeclaration(PassRefPtr<CSSMutableStyleDeclaration> style)
 {
     m_style = style;
-    m_style->setParentStyleSheet(parentStyleSheet());
+    m_style->setParentRule(this);
 }
 
 /* static */
index 949d4fa..83b9b00 100644 (file)
@@ -130,7 +130,6 @@ PassRefPtr<Attribute> StyledElement::createAttribute(const QualifiedName& name,
 void StyledElement::createInlineStyleDecl()
 {
     m_inlineStyleDecl = CSSInlineStyleDeclaration::create();
-    m_inlineStyleDecl->setParentStyleSheet(document()->elementSheet());
     m_inlineStyleDecl->setElement(this);
     m_inlineStyleDecl->setStrictParsing(isHTMLElement() && !document()->inQuirksMode());
 }
@@ -139,7 +138,6 @@ void StyledElement::destroyInlineStyleDecl()
 {
     if (m_inlineStyleDecl) {
         m_inlineStyleDecl->setElement(0);
-        m_inlineStyleDecl->setParentStyleSheet(0);
         m_inlineStyleDecl = 0;
     }
 }
@@ -195,7 +193,6 @@ void StyledElement::attributeChanged(Attribute* attr, bool preserveDecls)
         // 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()->setParentStyleSheet(0);
         attr->decl()->setElement(0);
         if (attributeMap())
             attributeMap()->declAdded();
@@ -405,7 +402,6 @@ void StyledElement::createMappedDecl(Attribute* attr)
 {
     RefPtr<CSSMappedAttributeDeclaration> decl = CSSMappedAttributeDeclaration::create();
     attr->setDecl(decl);
-    decl->setParentStyleSheet(document()->elementSheet());
     decl->setElement(this);
     ASSERT(!decl->useStrictParsing());
 }
@@ -450,13 +446,4 @@ void StyledElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
         style->addSubresourceStyleURLs(urls);
 }
 
-
-void StyledElement::didMoveToNewOwnerDocument()
-{
-    if (m_inlineStyleDecl)
-        m_inlineStyleDecl->setParentStyleSheet(document()->elementSheet());
-
-    Element::didMoveToNewOwnerDocument();
-}
-
 }
index 8282c29..f85b9a9 100644 (file)
@@ -83,8 +83,6 @@ protected:
     // parseMappedAttribute (called via setAttribute()) and
     // svgAttributeChanged (called when element.className.baseValue is set)
     void classAttributeChanged(const AtomicString& newClassString);
-    
-    virtual void didMoveToNewOwnerDocument();
 
 private:
     void createMappedDecl(Attribute*);
index 02cb617..9ca7dab 100644 (file)
@@ -455,7 +455,6 @@ void HTMLTableElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDecla
     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->setParentStyleSheet(document()->elementSheet());
         decl->setElement(this);
         ASSERT(!decl->useStrictParsing());
         
@@ -466,7 +465,6 @@ void HTMLTableElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDecla
         decl->setProperty(CSSPropertyBorderRightStyle, v, false);
 
         setMappedAttributeDecl(ePersistent, tableborderAttr, borderValue, decl);
-        decl->setParentStyleSheet(0);
         decl->setElement(0);
         decl->setMappedState(ePersistent, tableborderAttr, borderValue);
     }
@@ -513,7 +511,6 @@ void HTMLTableElement::addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaratio
     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->setParentStyleSheet(document()->elementSheet());
         decl->setElement(this);
         ASSERT(!decl->useStrictParsing());
         
@@ -554,7 +551,6 @@ void HTMLTableElement::addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaratio
         }
 
         setMappedAttributeDecl(ePersistent, cellborderAttr, *cellBorderNames[borders], decl);
-        decl->setParentStyleSheet(0);
         decl->setElement(0);
         decl->setMappedState(ePersistent, cellborderAttr, cellborderValue);
     }
@@ -572,7 +568,6 @@ void HTMLTableElement::addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaratio
         m_paddingDecl = getMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue);
         if (!m_paddingDecl) {
             m_paddingDecl = CSSMappedAttributeDeclaration::create();
-            m_paddingDecl->setParentStyleSheet(document()->elementSheet());
             m_paddingDecl->setElement(this);
             ASSERT(!m_paddingDecl->useStrictParsing());
             
@@ -582,7 +577,6 @@ void HTMLTableElement::addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaratio
             m_paddingDecl->setProperty(CSSPropertyPaddingLeft, paddingValue, false);
         }
         setMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue, m_paddingDecl.get());
-        m_paddingDecl->setParentStyleSheet(0);
         m_paddingDecl->setElement(0);
         m_paddingDecl->setMappedState(eUniversal, cellpaddingAttr, paddingValue);
     }
@@ -599,7 +593,6 @@ void HTMLTableElement::addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDecl
     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->setParentStyleSheet(document()->elementSheet());
         decl->setElement(this);
         ASSERT(!decl->useStrictParsing());
         
@@ -616,7 +609,6 @@ void HTMLTableElement::addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDecl
         }
 
         setMappedAttributeDecl(ePersistent, rulesAttr, rulesValue, decl);
-        decl->setParentStyleSheet(0);
         decl->setElement(0);
         decl->setMappedState(ePersistent, rulesAttr, rulesValue);
     }
index 8885ad8..9ba7d46 100644 (file)
@@ -46,13 +46,40 @@ namespace WebCore {
 
 using namespace SVGNames;
 
+// FIXME: This class is needed because CSSElementStyleDeclaration normally resolves
+//        the parentStyleSheet() to its document's elementSheet(). For SVG font-face
+//        elements however, we want the mappedElementSheet().
+//        With the planned refactoring to decouple WebKit's internal CSS structures
+//        from the CSSOM, the need for parent style sheet pointers, and thus also this
+//        class, goes away.
+class FontFaceStyleDeclaration : public CSSElementStyleDeclaration {
+public:
+    static PassRefPtr<FontFaceStyleDeclaration> create(SVGFontFaceElement* element)
+    {
+        return adoptRef(new FontFaceStyleDeclaration(element));
+    }
+
+    virtual ~FontFaceStyleDeclaration() { }
+
+    virtual CSSStyleSheet* styleSheet() const
+    {
+        return element()->document() ? element()->document()->mappedElementSheet() : 0;
+    }
+
+private:
+    FontFaceStyleDeclaration(SVGFontFaceElement* element)
+        : CSSElementStyleDeclaration(/* isInline */ false)
+    {
+        setElement(element);
+    }
+};
+
 inline SVGFontFaceElement::SVGFontFaceElement(const QualifiedName& tagName, Document* document)
     : SVGElement(tagName, document)
     , m_fontFaceRule(CSSFontFaceRule::create())
-    , m_styleDeclaration(CSSMutableStyleDeclaration::create())
+    , m_styleDeclaration(FontFaceStyleDeclaration::create(this))
 {
     ASSERT(hasTagName(font_faceTag));
-    m_styleDeclaration->setParentStyleSheet(document->mappedElementSheet());
     m_styleDeclaration->setStrictParsing(true);
     m_fontFaceRule->setDeclaration(m_styleDeclaration.get());
 }