https://bugs.webkit.org/show_bug.cgi?id=80370
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Mar 2012 20:15:16 +0000 (20:15 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 8 Mar 2012 20:15:16 +0000 (20:15 +0000)
Enable matched declaration caching for elements with a style attribute

Reviewed by Andreas Kling

Make the property set for style attribute immutable as long as there is no CSSOM
wrapper for it. If the style attribute changes we create a new property set instead
of recycling the old one. This way the property sets can be made cacheable as long
as there is no CSSOM wrapper that would allow uncontrolled modifications. Constructing
the wrapper disables caching.

Made StyledElement::inlineStyle() and StyledElement::ensureInlineStyle() return a const
StylePropertySet so making accidental modifications difficult. Also dropped *Decl from
the names.

Fixed two unrelated bugs that this exposed.

* css/CSSStyleSelector.cpp:

    Don't allow caching of document element style if writingModeSetOnDocumentElement() bit is set.
    Tested by fast/multicol/vertical-rl/break-properties.html.

(WebCore::CSSStyleSelector::collectMatchingRulesForList):
* css/StylePropertySet.h:
(StylePropertySet):
(WebCore::StylePropertySet::hasCSSOMWrapper):
* dom/Element.cpp:
(WebCore::Element::recalcStyle):

    Invalidate the matched properties cache if the document has rem units and the root font changes.
    Tested by fast/css/rem-dynamic-scaling.html.

* dom/ElementAttributeData.cpp:
(WebCore):
(WebCore::ElementAttributeData::ensureInlineStyle):
(WebCore::ElementAttributeData::ensureMutableInlineStyle):
(WebCore::ElementAttributeData::updateInlineStyleAvoidingMutation):
(WebCore::ElementAttributeData::destroyInlineStyle):
* dom/ElementAttributeData.h:
(WebCore::ElementAttributeData::inlineStyle):
(ElementAttributeData):
* dom/StyledElement.cpp:
(WebCore::StyledElement::updateStyleAttribute):
(WebCore::StyledElement::~StyledElement):
(WebCore):
(WebCore::StyledElement::style):
(WebCore::StyledElement::parseAttribute):
(WebCore::StyledElement::setInlineStyleProperty):
(WebCore::StyledElement::removeInlineStyleProperty):
(WebCore::StyledElement::addSubresourceAttributeURLs):
* dom/StyledElement.h:
(WebCore::StyledElement::inlineStyle):
(WebCore::StyledElement::ensureInlineStyle):
(StyledElement):
(WebCore::StyledElement::destroyInlineStyle):
* editing/ApplyStyleCommand.cpp:
(WebCore::hasNoAttributeOrOnlyStyleAttribute):
(WebCore::ApplyStyleCommand::applyRelativeFontStyleChange):
(WebCore::ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock):
(WebCore::ApplyStyleCommand::applyInlineStyleToNodeRange):
(WebCore::ApplyStyleCommand::removeCSSStyle):
(WebCore::ApplyStyleCommand::applyInlineStyleToPushDown):
(WebCore::ApplyStyleCommand::addBlockStyle):
(WebCore::ApplyStyleCommand::addInlineStyleIfNeeded):
* editing/EditingStyle.cpp:
(WebCore::HTMLElementEquivalent::propertyExistsInStyle):
(HTMLTextDecorationEquivalent):
(WebCore::HTMLTextDecorationEquivalent::propertyExistsInStyle):
(WebCore::EditingStyle::conflictsWithInlineStyleOfElement):
(WebCore::EditingStyle::elementIsStyledSpanOrHTMLEquivalent):
(WebCore::EditingStyle::mergeInlineStyleOfElement):
(WebCore::elementMatchesAndPropertyIsNotInInlineStyleDecl):
(WebCore::EditingStyle::mergeStyle):
* editing/EditingStyle.h:
(EditingStyle):
* editing/RemoveCSSPropertyCommand.cpp:
(WebCore::RemoveCSSPropertyCommand::doApply):
* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline):
(WebCore::ReplaceSelectionCommand::handleStyleSpans):
* editing/markup.cpp:
(WebCore::StyledMarkupAccumulator::appendElement):
(WebCore::styleFromMatchedRulesAndInlineDecl):
* html/HTMLElement.cpp:
(WebCore::StyledElement::copyNonAttributeProperties):
* html/canvas/CanvasStyle.cpp:
(WebCore::currentColor):
* page/PageSerializer.cpp:
(WebCore::PageSerializer::serializeFrame):
(WebCore::PageSerializer::retrieveResourcesForProperties):
* page/PageSerializer.h:
(PageSerializer):
* rendering/RenderTreeAsText.cpp:
(WebCore::isEmptyOrUnstyledAppleStyleSpan):

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

19 files changed:
Source/WebCore/ChangeLog
Source/WebCore/css/CSSStyleSelector.cpp
Source/WebCore/css/StylePropertySet.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/ElementAttributeData.cpp
Source/WebCore/dom/ElementAttributeData.h
Source/WebCore/dom/StyledElement.cpp
Source/WebCore/dom/StyledElement.h
Source/WebCore/editing/ApplyStyleCommand.cpp
Source/WebCore/editing/EditingStyle.cpp
Source/WebCore/editing/EditingStyle.h
Source/WebCore/editing/RemoveCSSPropertyCommand.cpp
Source/WebCore/editing/ReplaceSelectionCommand.cpp
Source/WebCore/editing/markup.cpp
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/canvas/CanvasStyle.cpp
Source/WebCore/page/PageSerializer.cpp
Source/WebCore/page/PageSerializer.h
Source/WebCore/rendering/RenderTreeAsText.cpp

index cf99523..91826ed 100644 (file)
@@ -1,3 +1,100 @@
+2012-03-08  Antti Koivisto  <antti@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=80370
+        Enable matched declaration caching for elements with a style attribute
+
+        Reviewed by Andreas Kling
+
+        Make the property set for style attribute immutable as long as there is no CSSOM
+        wrapper for it. If the style attribute changes we create a new property set instead
+        of recycling the old one. This way the property sets can be made cacheable as long
+        as there is no CSSOM wrapper that would allow uncontrolled modifications. Constructing
+        the wrapper disables caching.
+        
+        Made StyledElement::inlineStyle() and StyledElement::ensureInlineStyle() return a const
+        StylePropertySet so making accidental modifications difficult. Also dropped *Decl from
+        the names.
+        
+        Fixed two unrelated bugs that this exposed.
+
+        * css/CSSStyleSelector.cpp:
+        
+            Don't allow caching of document element style if writingModeSetOnDocumentElement() bit is set.
+            Tested by fast/multicol/vertical-rl/break-properties.html.
+        
+        (WebCore::CSSStyleSelector::collectMatchingRulesForList):
+        * css/StylePropertySet.h:
+        (StylePropertySet):
+        (WebCore::StylePropertySet::hasCSSOMWrapper):
+        * dom/Element.cpp:
+        (WebCore::Element::recalcStyle):
+        
+            Invalidate the matched properties cache if the document has rem units and the root font changes.
+            Tested by fast/css/rem-dynamic-scaling.html.
+        
+        * dom/ElementAttributeData.cpp:
+        (WebCore):
+        (WebCore::ElementAttributeData::ensureInlineStyle):
+        (WebCore::ElementAttributeData::ensureMutableInlineStyle):
+        (WebCore::ElementAttributeData::updateInlineStyleAvoidingMutation):
+        (WebCore::ElementAttributeData::destroyInlineStyle):
+        * dom/ElementAttributeData.h:
+        (WebCore::ElementAttributeData::inlineStyle):
+        (ElementAttributeData):
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::updateStyleAttribute):
+        (WebCore::StyledElement::~StyledElement):
+        (WebCore):
+        (WebCore::StyledElement::style):
+        (WebCore::StyledElement::parseAttribute):
+        (WebCore::StyledElement::setInlineStyleProperty):
+        (WebCore::StyledElement::removeInlineStyleProperty):
+        (WebCore::StyledElement::addSubresourceAttributeURLs):
+        * dom/StyledElement.h:
+        (WebCore::StyledElement::inlineStyle):
+        (WebCore::StyledElement::ensureInlineStyle):
+        (StyledElement):
+        (WebCore::StyledElement::destroyInlineStyle):
+        * editing/ApplyStyleCommand.cpp:
+        (WebCore::hasNoAttributeOrOnlyStyleAttribute):
+        (WebCore::ApplyStyleCommand::applyRelativeFontStyleChange):
+        (WebCore::ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock):
+        (WebCore::ApplyStyleCommand::applyInlineStyleToNodeRange):
+        (WebCore::ApplyStyleCommand::removeCSSStyle):
+        (WebCore::ApplyStyleCommand::applyInlineStyleToPushDown):
+        (WebCore::ApplyStyleCommand::addBlockStyle):
+        (WebCore::ApplyStyleCommand::addInlineStyleIfNeeded):
+        * editing/EditingStyle.cpp:
+        (WebCore::HTMLElementEquivalent::propertyExistsInStyle):
+        (HTMLTextDecorationEquivalent):
+        (WebCore::HTMLTextDecorationEquivalent::propertyExistsInStyle):
+        (WebCore::EditingStyle::conflictsWithInlineStyleOfElement):
+        (WebCore::EditingStyle::elementIsStyledSpanOrHTMLEquivalent):
+        (WebCore::EditingStyle::mergeInlineStyleOfElement):
+        (WebCore::elementMatchesAndPropertyIsNotInInlineStyleDecl):
+        (WebCore::EditingStyle::mergeStyle):
+        * editing/EditingStyle.h:
+        (EditingStyle):
+        * editing/RemoveCSSPropertyCommand.cpp:
+        (WebCore::RemoveCSSPropertyCommand::doApply):
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline):
+        (WebCore::ReplaceSelectionCommand::handleStyleSpans):
+        * editing/markup.cpp:
+        (WebCore::StyledMarkupAccumulator::appendElement):
+        (WebCore::styleFromMatchedRulesAndInlineDecl):
+        * html/HTMLElement.cpp:
+        (WebCore::StyledElement::copyNonAttributeProperties):
+        * html/canvas/CanvasStyle.cpp:
+        (WebCore::currentColor):
+        * page/PageSerializer.cpp:
+        (WebCore::PageSerializer::serializeFrame):
+        (WebCore::PageSerializer::retrieveResourcesForProperties):
+        * page/PageSerializer.h:
+        (PageSerializer):
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::isEmptyOrUnstyledAppleStyleSpan):
+
 2012-03-08  Scott Byer  <scottbyer@chromium.org>
 
         Have ScrollAnimatorNone use requestAnimationFrame
index 59f615a..e9823d5 100644 (file)
@@ -1088,8 +1088,13 @@ void CSSStyleSelector::matchAllRules(MatchResult& result)
         matchAuthorRules(result, false);
 
     // Now check our inline style attribute.
-    if (m_matchAuthorAndUserStyles && m_styledElement)
-        addElementStyleProperties(result, m_styledElement->inlineStyleDecl(), false /* isCacheable */);
+    if (m_matchAuthorAndUserStyles && m_styledElement && m_styledElement->inlineStyle()) {
+        // Inline style is immutable as long as there is no CSSOM wrapper.
+        // FIXME: Media control shadow trees seem to have problems with caching.
+        bool isInlineStyleCacheable = !m_styledElement->inlineStyle()->hasCSSOMWrapper() && !m_styledElement->isInShadowTree();
+        // FIXME: Constify.
+        addElementStyleProperties(result, const_cast<StylePropertySet*>(m_styledElement->inlineStyle()), isInlineStyleCacheable);
+    }
 
 #if ENABLE(SVG)
     // Now check SMIL animation override style.
@@ -1149,7 +1154,7 @@ Node* CSSStyleSelector::locateCousinList(Element* parent, unsigned& visitedNodeC
         return 0;
 #endif
     StyledElement* p = static_cast<StyledElement*>(parent);
-    if (p->inlineStyleDecl())
+    if (p->inlineStyle())
         return 0;
 #if ENABLE(SVG)
     if (p->isSVGElement() && static_cast<SVGElement*>(p)->animatedSMILStyleProperties())
@@ -1294,7 +1299,7 @@ bool CSSStyleSelector::canShareStyleWithElement(StyledElement* element) const
         return false;
     if (element->hasClass() != m_element->hasClass())
         return false;
-    if (element->inlineStyleDecl())
+    if (element->inlineStyle())
         return false;
 #if ENABLE(SVG)
     if (element->isSVGElement() && static_cast<SVGElement*>(element)->animatedSMILStyleProperties())
@@ -1408,7 +1413,7 @@ RenderStyle* CSSStyleSelector::locateSharedStyle()
     if (!m_styledElement || !m_parentStyle)
         return 0;
     // If the element has inline style it is probably unique.
-    if (m_styledElement->inlineStyleDecl())
+    if (m_styledElement->inlineStyle())
         return 0;
 #if ENABLE(SVG)
     if (m_styledElement->isSVGElement() && static_cast<SVGElement*>(m_styledElement)->animatedSMILStyleProperties())
@@ -2705,8 +2710,11 @@ void CSSStyleSelector::invalidateMatchedPropertiesCache()
     m_matchedPropertiesCache.clear();
 }
 
-static bool isCacheableInMatchedPropertiesCache(const RenderStyle* style, const RenderStyle* parentStyle)
+static bool isCacheableInMatchedPropertiesCache(const Element* element, const RenderStyle* style, const RenderStyle* parentStyle)
 {
+    // FIXME: CSSPropertyWebkitWritingMode modifies state when applying to document element. We can't skip the applying by caching.
+    if (element == element->document()->documentElement() && element->document()->writingModeSetOnDocumentElement())
+        return false;
     if (style->unique() || (style->styleType() != NOPSEUDO && parentStyle->unique()))
         return false;
     if (style->hasAppearance())
@@ -2788,7 +2796,7 @@ void CSSStyleSelector::applyMatchedProperties(const MatchResult& matchResult)
     
     if (cacheItem || !cacheHash)
         return;
-    if (!isCacheableInMatchedPropertiesCache(m_style.get(), m_parentStyle))
+    if (!isCacheableInMatchedPropertiesCache(m_element, m_style.get(), m_parentStyle))
         return;
     addToMatchedPropertiesCache(m_style.get(), m_parentStyle, cacheHash, matchResult);
 }
@@ -3727,6 +3735,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
     // CSS Text Layout Module Level 3: Vertical writing support
     case CSSPropertyWebkitWritingMode: {
         HANDLE_INHERIT_AND_INITIAL_AND_PRIMITIVE(writingMode, WritingMode)
+        // FIXME: It is not ok to modify document state while applying style.
         if (!isInherit && !isInitial && m_element && m_element == m_element->document()->documentElement())
             m_element->document()->setWritingModeSetOnDocumentElement(true);
         FontDescription fontDescription = m_style->fontDescription();
index 9aeb2e4..d5c5e6f 100644 (file)
@@ -107,6 +107,8 @@ public:
     CSSStyleDeclaration* ensureCSSStyleDeclaration() const;
     CSSStyleDeclaration* ensureRuleCSSStyleDeclaration(const CSSRule* parentRule) const;
     CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(const StyledElement* parentElement) const;
+    
+    bool hasCSSOMWrapper() const { return m_hasCSSOMWrapper; }
 
 private:
     StylePropertySet();
index 3d5c5ce..c925749 100644 (file)
@@ -1109,12 +1109,16 @@ void Element::recalcStyle(StyleChange change)
         } else if (styleChangeType() == SyntheticStyleChange)
              setRenderStyle(newStyle);
 
+        // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
+        // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
+        if (document()->usesRemUnits() && document()->documentElement() == this && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
+            // Cached RenderStyles may depend on the rem units.
+            document()->styleSelector()->invalidateMatchedPropertiesCache();
+            change = Force;
+        }
+
         if (change != Force) {
-            // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
-            // all the way down the tree.  This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
-            if (document()->usesRemUnits() && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize() && document()->documentElement() == this)
-                change = Force;
-            else if (styleChangeType() >= FullStyleChange)
+            if (styleChangeType() >= FullStyleChange)
                 change = Force;
             else
                 change = ch;
index 59c3ece..601c34b 100644 (file)
@@ -51,8 +51,8 @@ void ElementAttributeData::setClass(const String& className, bool shouldFoldCase
 {
     m_classNames.set(className, shouldFoldCase);
 }
-
-StylePropertySet* ElementAttributeData::ensureInlineStyleDecl(StyledElement* element)
+    
+StylePropertySet* ElementAttributeData::ensureInlineStyle(StyledElement* element)
 {
     if (!m_inlineStyleDecl) {
         ASSERT(element->isStyledElement());
@@ -62,7 +62,30 @@ StylePropertySet* ElementAttributeData::ensureInlineStyleDecl(StyledElement* ele
     return m_inlineStyleDecl.get();
 }
 
-void ElementAttributeData::destroyInlineStyleDecl(StyledElement* element)
+StylePropertySet* ElementAttributeData::ensureMutableInlineStyle(StyledElement* element)
+{
+    if (m_inlineStyleDecl && !m_inlineStyleDecl->hasCSSOMWrapper()) {
+        m_inlineStyleDecl = m_inlineStyleDecl->copy();
+        m_inlineStyleDecl->setStrictParsing(element->isHTMLElement() && !element->document()->inQuirksMode());
+        return m_inlineStyleDecl.get();
+    }
+    return ensureInlineStyle(element);
+}
+    
+void ElementAttributeData::updateInlineStyleAvoidingMutation(StyledElement* element, const String& text)
+{
+    // We reconstruct the property set instead of mutating if there is no CSSOM wrapper.
+    // This makes wrapperless property sets immutable and so cacheable.
+    if (m_inlineStyleDecl && !m_inlineStyleDecl->hasCSSOMWrapper())
+        m_inlineStyleDecl.clear();
+    if (!m_inlineStyleDecl) {
+        m_inlineStyleDecl = StylePropertySet::create();
+        m_inlineStyleDecl->setStrictParsing(element->isHTMLElement() && !element->document()->inQuirksMode());
+    }
+    m_inlineStyleDecl->parseDeclaration(text, element->document()->elementSheet());
+}
+
+void ElementAttributeData::destroyInlineStyle(StyledElement* element)
 {
     if (!m_inlineStyleDecl)
         return;
index 1fbf3ee..e0866b2 100644 (file)
@@ -96,9 +96,11 @@ public:
     const AtomicString& idForStyleResolution() const { return m_idForStyleResolution; }
     void setIdForStyleResolution(const AtomicString& newId) { m_idForStyleResolution = newId; }
 
-    StylePropertySet* inlineStyleDecl() { return m_inlineStyleDecl.get(); }
-    StylePropertySet* ensureInlineStyleDecl(StyledElement*);
-    void destroyInlineStyleDecl(StyledElement* element);
+    StylePropertySet* inlineStyle() { return m_inlineStyleDecl.get(); }
+    StylePropertySet* ensureInlineStyle(StyledElement*);
+    StylePropertySet* ensureMutableInlineStyle(StyledElement*);
+    void updateInlineStyleAvoidingMutation(StyledElement*, const String& text);
+    void destroyInlineStyle(StyledElement*);
 
     StylePropertySet* attributeStyle() const { return m_attributeStyle.get(); }
     void setAttributeStyle(PassRefPtr<StylePropertySet> style) { m_attributeStyle = style; }
index 106c228..26ea896 100644 (file)
@@ -50,13 +50,18 @@ void StyledElement::updateStyleAttribute() const
 {
     ASSERT(!isStyleAttributeValid());
     setIsStyleAttributeValid();
-    if (StylePropertySet* inlineStyle = inlineStyleDecl())
+    if (const StylePropertySet* inlineStyle = this->inlineStyle())
         const_cast<StyledElement*>(this)->setAttribute(styleAttr, inlineStyle->asText(), /*notifyChanged*/ false);
 }
 
 StyledElement::~StyledElement()
 {
-    destroyInlineStyleDecl();
+    destroyInlineStyle();
+}
+
+CSSStyleDeclaration* StyledElement::style() 
+{ 
+    return ensureAttributeData()->ensureMutableInlineStyle(this)->ensureInlineCSSStyleDeclaration(this); 
 }
 
 void StyledElement::attributeChanged(Attribute* attr)
@@ -97,9 +102,9 @@ void StyledElement::parseAttribute(Attribute* attr)
         classAttributeChanged(attr->value());
     else if (attr->name() == styleAttr) {
         if (attr->isNull())
-            destroyInlineStyleDecl();
+            destroyInlineStyle();
         else if (document()->contentSecurityPolicy()->allowInlineStyle())
-            ensureInlineStyleDecl()->parseDeclaration(attr->value(), document()->elementSheet());
+            ensureAttributeData()->updateInlineStyleAvoidingMutation(this, attr->value());
         setIsStyleAttributeValid();
         setNeedsStyleRecalc();
         InspectorInstrumentation::didInvalidateStyleAttr(document(), this);
@@ -115,21 +120,21 @@ void StyledElement::inlineStyleChanged()
     
 bool StyledElement::setInlineStyleProperty(int propertyID, int identifier, bool important)
 {
-    ensureInlineStyleDecl()->setProperty(propertyID, document()->cssValuePool()->createIdentifierValue(identifier), important);
+    ensureAttributeData()->ensureMutableInlineStyle(this)->setProperty(propertyID, document()->cssValuePool()->createIdentifierValue(identifier), important);
     inlineStyleChanged();
     return true;
 }
 
 bool StyledElement::setInlineStyleProperty(int propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important)
 {
-    ensureInlineStyleDecl()->setProperty(propertyID, document()->cssValuePool()->createValue(value, unit), important);
+    ensureAttributeData()->ensureMutableInlineStyle(this)->setProperty(propertyID, document()->cssValuePool()->createValue(value, unit), important);
     inlineStyleChanged();
     return true;
 }
 
 bool StyledElement::setInlineStyleProperty(int propertyID, const String& value, bool important)
 {
-    bool changes = ensureInlineStyleDecl()->setProperty(propertyID, value, important, document()->elementSheet());
+    bool changes = ensureAttributeData()->ensureMutableInlineStyle(this)->setProperty(propertyID, value, important, document()->elementSheet());
     if (changes)
         inlineStyleChanged();
     return changes;
@@ -137,7 +142,10 @@ bool StyledElement::setInlineStyleProperty(int propertyID, const String& value,
 
 bool StyledElement::removeInlineStyleProperty(int propertyID)
 {
-    bool changes = ensureInlineStyleDecl()->removeProperty(propertyID);
+    StylePropertySet* inlineStyle = attributeData() ? attributeData()->inlineStyle() : 0;
+    if (!inlineStyle)
+        return false;
+    bool changes = inlineStyle->removeProperty(propertyID);
     if (changes)
         inlineStyleChanged();
     return changes;
@@ -145,7 +153,7 @@ bool StyledElement::removeInlineStyleProperty(int propertyID)
 
 void StyledElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
 {
-    if (StylePropertySet* inlineStyle = inlineStyleDecl())
+    if (StylePropertySet* inlineStyle = attributeData() ? attributeData()->inlineStyle() : 0)
         inlineStyle->addSubresourceStyleURLs(urls, document()->elementSheet());
 }
 
index 5900e9d..7f9b280 100644 (file)
@@ -39,8 +39,8 @@ public:
     virtual StylePropertySet* additionalAttributeStyle() { return 0; }
     void invalidateStyleAttribute();
 
-    StylePropertySet* inlineStyleDecl() const { return attributeData() ? attributeData()->inlineStyleDecl() : 0; }
-    StylePropertySet* ensureInlineStyleDecl() { return ensureAttributeData()->ensureInlineStyleDecl(this); }
+    const StylePropertySet* inlineStyle() const { return attributeData() ? attributeData()->inlineStyle() : 0; }
+    const StylePropertySet* ensureInlineStyle() { return ensureAttributeData()->ensureInlineStyle(this); }
     
     // Unlike StylePropertySet setters, these implement invalidation.
     bool setInlineStyleProperty(int propertyID, int identifier, bool important = false);
@@ -48,7 +48,7 @@ public:
     bool setInlineStyleProperty(int propertyID, const String& value, bool important = false);
     bool removeInlineStyleProperty(int propertyID);
     
-    virtual CSSStyleDeclaration* style() OVERRIDE { return ensureInlineStyleDecl()->ensureInlineCSSStyleDeclaration(this); }
+    virtual CSSStyleDeclaration* style() OVERRIDE;
 
     StylePropertySet* attributeStyle();
 
@@ -84,10 +84,10 @@ private:
 
     void updateAttributeStyle();
 
-    void destroyInlineStyleDecl()
+    void destroyInlineStyle()
     {
         if (attributeData())
-            attributeData()->destroyInlineStyleDecl(this);
+            attributeData()->destroyInlineStyle(this);
     }
 };
 
index 25444bb..7c6347c 100644 (file)
@@ -80,7 +80,7 @@ static bool hasNoAttributeOrOnlyStyleAttribute(const StyledElement* element, Sho
     if (element->getAttribute(classAttr) == styleSpanClassString())
         matchedAttributes++;
     if (element->hasAttribute(styleAttr) && (shouldStyleAttributeBeEmpty == AllowNonEmptyStyleAttribute
-        || !element->inlineStyleDecl() || element->inlineStyleDecl()->isEmpty()))
+        || !element->inlineStyle() || element->inlineStyle()->isEmpty()))
         matchedAttributes++;
 
     ASSERT(matchedAttributes <= element->attributeCount());
@@ -382,7 +382,7 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style)
         }
         lastStyledNode = node;
 
-        StylePropertySet* inlineStyleDecl = element->ensureInlineStyleDecl();
+        RefPtr<StylePropertySet> inlineStyleDecl = element->ensureInlineStyle()->copy();
         float currentFontSize = computedFontSize(node);
         float desiredFontSize = max(MinimumFontSize, startingFontSizes.get(node) + style->fontSizeDelta());
         RefPtr<CSSValue> value = inlineStyleDecl->getPropertyCSSValue(CSSPropertyFontSize);
@@ -509,7 +509,7 @@ void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, Node* unsp
             // other attributes, like we (should) do with B and I elements.
             removeNodeAttribute(element, dirAttr);
         } else {
-            RefPtr<StylePropertySet> inlineStyle = element->ensureInlineStyleDecl()->copy();
+            RefPtr<StylePropertySet> inlineStyle = element->ensureInlineStyle()->copy();
             inlineStyle->setProperty(CSSPropertyUnicodeBidi, CSSValueNormal);
             inlineStyle->removeProperty(CSSPropertyDirection);
             setNodeAttribute(element, styleAttr, inlineStyle->asText());
@@ -723,7 +723,7 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, Node* n
                 break;
             // Add to this element's inline style and skip over its contents.
             HTMLElement* element = toHTMLElement(node);
-            RefPtr<StylePropertySet> inlineStyle = element->ensureInlineStyleDecl()->copy();
+            RefPtr<StylePropertySet> inlineStyle = element->ensureInlineStyle()->copy();
             inlineStyle->merge(style->style());
             setNodeAttribute(element, styleAttr, inlineStyle->asText());
             next = node->traverseNextSibling();
@@ -888,14 +888,12 @@ bool ApplyStyleCommand::removeCSSStyle(EditingStyle* style, HTMLElement* element
     if (!style->conflictsWithInlineStyleOfElement(element, extractedStyle, properties))
         return false;
 
-    StylePropertySet* inlineStyle = element->inlineStyleDecl();
-    ASSERT(inlineStyle);
     // FIXME: We should use a mass-removal function here but we don't have an undoable one yet.
     for (size_t i = 0; i < properties.size(); i++)
         removeCSSProperty(element, properties[i]);
 
     // No need to serialize <foo style=""> if we just removed the last css property
-    if (inlineStyle->isEmpty())
+    if (element->inlineStyle()->isEmpty())
         removeNodeAttribute(element, styleAttr);
 
     if (isSpanWithoutAttributesOrUnstyledStyleSpan(element))
@@ -932,7 +930,7 @@ void ApplyStyleCommand::applyInlineStyleToPushDown(Node* node, EditingStyle* sty
         return;
 
     RefPtr<EditingStyle> newInlineStyle = style;
-    if (node->isHTMLElement() && toHTMLElement(node)->inlineStyleDecl()) {
+    if (node->isHTMLElement() && toHTMLElement(node)->inlineStyle()) {
         newInlineStyle = style->copy();
         newInlineStyle->mergeInlineStyleOfElement(toHTMLElement(node), EditingStyle::OverrideValues);
     }
@@ -1308,7 +1306,7 @@ void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, HTMLElemen
         return;
         
     String cssText = styleChange.cssStyle();
-    if (StylePropertySet* decl = block->inlineStyleDecl())
+    if (const StylePropertySet* decl = block->inlineStyle())
         cssText += decl->asText();
     setNodeAttribute(block, styleAttr, cssText);
 }
@@ -1373,7 +1371,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtr<N
 
     if (styleChange.cssStyle().length()) {
         if (styleContainer) {
-            if (StylePropertySet* existingStyle = styleContainer->inlineStyleDecl())
+            if (const StylePropertySet* existingStyle = styleContainer->inlineStyle())
                 setNodeAttribute(styleContainer, styleAttr, existingStyle->asText() + styleChange.cssStyle());
             else
                 setNodeAttribute(styleContainer, styleAttr, styleChange.cssStyle());
index 15aa564..3a360d8 100644 (file)
@@ -125,7 +125,7 @@ public:
     virtual ~HTMLElementEquivalent() { }
     virtual bool matches(const Element* element) const { return !m_tagName || element->hasTagName(*m_tagName); }
     virtual bool hasAttribute() const { return false; }
-    virtual bool propertyExistsInStyle(StylePropertySet* style) const { return style && style->getPropertyCSSValue(m_propertyID); }
+    virtual bool propertyExistsInStyle(const StylePropertySet* style) const { return style && style->getPropertyCSSValue(m_propertyID); }
     virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const;
     virtual void addToStyle(Element*, EditingStyle*) const;
 
@@ -175,7 +175,7 @@ public:
     {
         return adoptPtr(new HTMLTextDecorationEquivalent(primitiveValue, tagName));
     }
-    virtual bool propertyExistsInStyle(StylePropertySet*) const;
+    virtual bool propertyExistsInStyle(const StylePropertySet*) const;
     virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const;
 
 private:
@@ -188,7 +188,7 @@ HTMLTextDecorationEquivalent::HTMLTextDecorationEquivalent(int primitiveValue, c
 {
 }
 
-bool HTMLTextDecorationEquivalent::propertyExistsInStyle(StylePropertySet* style) const
+bool HTMLTextDecorationEquivalent::propertyExistsInStyle(const StylePropertySet* style) const
 {
     return style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect) || style->getPropertyCSSValue(CSSPropertyTextDecoration);
 }
@@ -664,7 +664,7 @@ bool EditingStyle::conflictsWithInlineStyleOfElement(StyledElement* element, Edi
     ASSERT(element);
     ASSERT(!conflictingProperties || conflictingProperties->isEmpty());
 
-    StylePropertySet* inlineStyle = element->inlineStyleDecl();
+    const StylePropertySet* inlineStyle = element->inlineStyle();
     if (!m_mutableStyle || !inlineStyle)
         return false;
 
@@ -850,7 +850,7 @@ bool EditingStyle::elementIsStyledSpanOrHTMLEquivalent(const HTMLElement* elemen
         matchedAttributes++;
 
     if (element->hasAttribute(HTMLNames::styleAttr)) {
-        if (StylePropertySet* style = element->inlineStyleDecl()) {
+        if (const StylePropertySet* style = element->inlineStyle()) {
             unsigned propertyCount = style->propertyCount();
             for (unsigned i = 0; i < propertyCount; ++i) {
                 if (!isEditingProperty(style->propertyAt(i).id()))
@@ -912,18 +912,18 @@ void EditingStyle::mergeTypingStyle(Document* document)
 void EditingStyle::mergeInlineStyleOfElement(StyledElement* element, CSSPropertyOverrideMode mode, PropertiesToInclude propertiesToInclude)
 {
     ASSERT(element);
-    if (!element->inlineStyleDecl())
+    if (!element->inlineStyle())
         return;
 
     switch (propertiesToInclude) {
     case AllProperties:
-        mergeStyle(element->inlineStyleDecl(), mode);
+        mergeStyle(element->inlineStyle(), mode);
         return;
     case OnlyEditingInheritableProperties:
-        mergeStyle(copyEditingProperties(element->inlineStyleDecl(), OnlyInheritableEditingProperties).get(), mode);
+        mergeStyle(copyEditingProperties(element->inlineStyle(), OnlyInheritableEditingProperties).get(), mode);
         return;
     case EditingPropertiesInEffect:
-        mergeStyle(copyEditingProperties(element->inlineStyleDecl(), AllEditingProperties).get(), mode);
+        mergeStyle(copyEditingProperties(element->inlineStyle(), AllEditingProperties).get(), mode);
         return;
     }
 }
@@ -931,7 +931,7 @@ void EditingStyle::mergeInlineStyleOfElement(StyledElement* element, CSSProperty
 static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(const HTMLElementEquivalent* equivalent, const StyledElement* element,
     EditingStyle::CSSPropertyOverrideMode mode, StylePropertySet* style)
 {
-    return equivalent->matches(element) && !equivalent->propertyExistsInStyle(element->inlineStyleDecl())
+    return equivalent->matches(element) && !equivalent->propertyExistsInStyle(element->inlineStyle())
         && (mode == EditingStyle::OverrideValues || !equivalent->propertyExistsInStyle(style));
 }
 
@@ -997,7 +997,7 @@ static void mergeTextDecorationValues(CSSValueList* mergedValue, const CSSValueL
         mergedValue->append(lineThrough.get());
 }
 
-void EditingStyle::mergeStyle(StylePropertySet* style, CSSPropertyOverrideMode mode)
+void EditingStyle::mergeStyle(const StylePropertySet* style, CSSPropertyOverrideMode mode)
 {
     if (!style)
         return;
index 71dc652..c213036 100644 (file)
@@ -161,7 +161,7 @@ private:
     TriState triStateOfStyle(CSSStyleDeclaration* styleToCompare, ShouldIgnoreTextOnlyProperties) const;
     bool conflictsWithInlineStyleOfElement(StyledElement*, EditingStyle* extractedStyle, Vector<CSSPropertyID>* conflictingProperties) const;
     void mergeInlineAndImplicitStyleOfElement(StyledElement*, CSSPropertyOverrideMode, PropertiesToInclude);
-    void mergeStyle(StylePropertySet*, CSSPropertyOverrideMode);
+    void mergeStyle(const StylePropertySet*, CSSPropertyOverrideMode);
 
     RefPtr<StylePropertySet> m_mutableStyle;
     bool m_shouldUseFixedDefaultFontSize;
index ca5baba..58ca6db 100644 (file)
@@ -43,7 +43,7 @@ RemoveCSSPropertyCommand::RemoveCSSPropertyCommand(Document* document, PassRefPt
 
 void RemoveCSSPropertyCommand::doApply()
 {
-    StylePropertySet* style = m_element->inlineStyleDecl();
+    const StylePropertySet* style = m_element->inlineStyle();
     m_oldValue = style->getPropertyValue(m_property);
     m_important = style->propertyIsImportant(m_property);
 
index 95fdaf0..af5a8be 100644 (file)
@@ -484,7 +484,7 @@ void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert
 
         StyledElement* element = static_cast<StyledElement*>(node.get());
 
-        StylePropertySet* inlineStyle = element->inlineStyleDecl();
+        const StylePropertySet* inlineStyle = element->inlineStyle();
         RefPtr<EditingStyle> newInlineStyle = EditingStyle::create(inlineStyle);
         if (inlineStyle) {
             ContainerNode* context = element->parentNode();
@@ -703,7 +703,7 @@ void ReplaceSelectionCommand::handleStyleSpans(InsertedNodes& insertedNodes)
     if (!wrappingStyleSpan)
         return;
 
-    RefPtr<EditingStyle> style = EditingStyle::create(wrappingStyleSpan->ensureInlineStyleDecl());
+    RefPtr<EditingStyle> style = EditingStyle::create(wrappingStyleSpan->ensureInlineStyle());
     ContainerNode* context = wrappingStyleSpan->parentNode();
 
     // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region,
index 624c363..05cde4a 100644 (file)
@@ -310,8 +310,8 @@ void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element* element
         } else
             newInlineStyle = EditingStyle::create();
 
-        if (element->isStyledElement() && static_cast<StyledElement*>(element)->inlineStyleDecl())
-            newInlineStyle->overrideWithStyle(static_cast<StyledElement*>(element)->inlineStyleDecl());
+        if (element->isStyledElement() && static_cast<StyledElement*>(element)->inlineStyle())
+            newInlineStyle->overrideWithStyle(static_cast<StyledElement*>(element)->inlineStyle());
 
         if (shouldAnnotateOrForceInline) {
             if (shouldAnnotate())
@@ -495,7 +495,7 @@ static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* n
     // FIXME: Having to const_cast here is ugly, but it is quite a bit of work to untangle
     // the non-const-ness of styleFromMatchedRulesForElement.
     HTMLElement* element = const_cast<HTMLElement*>(static_cast<const HTMLElement*>(node));
-    RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyleDecl());
+    RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle());
     style->mergeStyleFromRules(element);
     return style.release();
 }
index e0978a2..51a3a74 100644 (file)
@@ -1106,12 +1106,12 @@ void StyledElement::copyNonAttributeProperties(const Element* sourceElement)
     ASSERT(sourceElement->isStyledElement());
 
     const StyledElement* source = static_cast<const StyledElement*>(sourceElement);
-    if (!source->inlineStyleDecl())
+    if (!source->inlineStyle())
         return;
 
-    StylePropertySet* inlineStyle = ensureInlineStyleDecl();
-    inlineStyle->copyPropertiesFrom(*source->inlineStyleDecl());
-    inlineStyle->setStrictParsing(source->inlineStyleDecl()->useStrictParsing());
+    StylePropertySet* inlineStyle = ensureAttributeData()->ensureMutableInlineStyle(this);
+    inlineStyle->copyPropertiesFrom(*source->inlineStyle());
+    inlineStyle->setStrictParsing(source->inlineStyle()->useStrictParsing());
 
     setIsStyleAttributeValid(source->isStyleAttributeValid());
 
index 3ed1fee..26e310e 100644 (file)
@@ -69,7 +69,7 @@ RGBA32 currentColor(HTMLCanvasElement* canvas)
     if (!canvas || !canvas->inDocument())
         return Color::black;
     RGBA32 rgba = Color::black;
-    CSSParser::parseColor(rgba, canvas->ensureInlineStyleDecl()->getPropertyValue(CSSPropertyColor));
+    CSSParser::parseColor(rgba, canvas->ensureInlineStyle()->getPropertyValue(CSSPropertyColor));
     return rgba;
 }
 
index 0c72736..9d50211 100644 (file)
@@ -228,7 +228,7 @@ void PageSerializer::serializeFrame(Frame* frame)
         Element* element = toElement(node);
         // We have to process in-line style as it might contain some resources (typically background images).
         if (element->isStyledElement())
-            retrieveResourcesForProperties(static_cast<StyledElement*>(element)->inlineStyleDecl(), document);
+            retrieveResourcesForProperties(static_cast<StyledElement*>(element)->inlineStyle(), document);
 
         if (element->hasTagName(HTMLNames::imgTag)) {
             HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(element);
@@ -308,7 +308,7 @@ void PageSerializer::retrieveResourcesForRule(StyleRule* rule, Document* documen
     retrieveResourcesForProperties(rule->properties(), document);
 }
 
-void PageSerializer::retrieveResourcesForProperties(StylePropertySet* styleDeclaration, Document* document)
+void PageSerializer::retrieveResourcesForProperties(const StylePropertySet* styleDeclaration, Document* document)
 {
     if (!styleDeclaration)
         return;
index b203913..4e81579 100644 (file)
@@ -78,7 +78,7 @@ private:
     void serializeCSSStyleSheet(CSSStyleSheet*, const KURL&);
 
     void addImageToResources(CachedImage*, RenderObject*, const KURL&);
-    void retrieveResourcesForProperties(StylePropertySet*, Document*);
+    void retrieveResourcesForProperties(const StylePropertySet*, Document*);
     void retrieveResourcesForRule(StyleRule*, Document*);
 
     Vector<Resource>* m_resources;
index 40efd59..79751ba 100644 (file)
@@ -183,7 +183,7 @@ static bool isEmptyOrUnstyledAppleStyleSpan(const Node* node)
     if (!node->hasChildNodes())
         return true;
 
-    StylePropertySet* inlineStyleDecl = elem->inlineStyleDecl();
+    const StylePropertySet* inlineStyleDecl = elem->inlineStyle();
     return (!inlineStyleDecl || inlineStyleDecl->isEmpty());
 }