Changeset 116235 in webkit


Ignore:
Timestamp:
May 6, 2012, 3:29:14 AM (13 years ago)
Author:
Antti Koivisto
Message:

Share stylesheet data structures between documents
https://bugs.webkit.org/show_bug.cgi?id=85598

Source/WebCore:

Reviewed by Darin Adler.

We currently make a copy of the data structures when restoring a cached stylesheet. This patch lets us share
the data until someone uses CSSOM to modify the sheet.

The patch implements copy-on-write for the internal style sheet data structures. If any mutation CSSOM API is
invoked, we check if the stylesheet can be safely mutated (we are the only client, it is not cached). If not
then the internal structures are copied and any existing CSSOM objects are re-attached to the new tree.

Sharing can save significant amount of memory on sites with large stylesheets. For example if you have
multiple articles open on wsj.com this saves ~2.6MB per tab.

Test: http/tests/css/shared-stylesheet-mutation.html

http/tests/css/shared-stylesheet-mutation-preconstruct.html

  • css/CSSFontFaceRule.cpp:

(WebCore::CSSFontFaceRule::reattach):
(WebCore):

  • css/CSSFontFaceRule.h:

(CSSFontFaceRule):

  • css/CSSMediaRule.cpp:

(WebCore::CSSMediaRule::insertRule):
(WebCore::CSSMediaRule::deleteRule):
(WebCore::CSSMediaRule::reattach):
(WebCore):

  • css/CSSMediaRule.h:

(CSSMediaRule):

  • css/CSSPageRule.cpp:

(WebCore::CSSPageRule::setSelectorText):
(WebCore::CSSPageRule::reattach):
(WebCore):

  • css/CSSPageRule.h:

(CSSPageRule):

  • css/CSSRule.cpp:

(WebCore::CSSRule::reattach):

After the internal stylerule tree has been copied, the existing wrappers are re-attached using recursive reattach() function.

  • css/CSSRule.h:

(WebCore):
(CSSRule):

  • css/CSSStyleRule.cpp:

(WebCore::CSSStyleRule::setSelectorText):
(WebCore::CSSStyleRule::reattach):
(WebCore):

  • css/CSSStyleRule.h:

(CSSStyleRule):

  • css/CSSStyleSheet.cpp:

(WebCore::StyleSheetInternal::StyleSheetInternal):
(WebCore::StyleSheetInternal::isCacheable):
(WebCore::StyleSheetInternal::ruleAt):

Add ruleAt(), use it for both wrapper creation and reattaching. Remove createChildRuleCSSOMWrapper .

(WebCore):
(WebCore::StyleSheetInternal::wrapperInsertRule):
(WebCore::StyleSheetInternal::wrapperDeleteRule):

Invalidation moves to the calling wrapper.

(WebCore::StyleSheetInternal::addedToMemoryCache):
(WebCore::StyleSheetInternal::removedFromMemoryCache):
(WebCore::CSSStyleSheet::willMutateRules):

This is called whenever StyleSheetInternal is going to be mutated. It will do copy-on-write if needed.


Usually invoked by CSSStyleSheet::RuleMutation RAII type.

(WebCore::CSSStyleSheet::didMutateRules):

This is called after the mutation is complete and will trigger the style recalc in the document.

(WebCore::CSSStyleSheet::didMutate):

This is called directly after mutations that don't change StyleSheetInternal so don't require copy-on-write.

(WebCore::CSSStyleSheet::reattachChildRuleCSSOMWrappers):
(WebCore::CSSStyleSheet::setDisabled):
(WebCore::CSSStyleSheet::insertRule):
(WebCore::CSSStyleSheet::deleteRule):

  • css/CSSStyleSheet.h:

(StyleSheetInternal):
(WebCore::StyleSheetInternal::hasOneClient):
(WebCore::StyleSheetInternal::isMutable):
(WebCore::StyleSheetInternal::setMutable):

Track mutability. Mutation is allowed only after willMutate call.

(WebCore::StyleSheetInternal::isInMemoryCache):

Track if the object is in memory cache.

(WebCore::CSSStyleSheet::clearOwnerRule):
(CSSStyleSheet):

  • css/MediaList.cpp:

(WebCore::MediaList::setMediaText):
(WebCore::MediaList::deleteMedium):
(WebCore::MediaList::appendMedium):
(WebCore::MediaList::didMutate):
(WebCore):
(WebCore::MediaList::reattach):

  • css/MediaList.h:

(MediaList):

  • css/PropertySetCSSStyleDeclaration.cpp:

(WebCore::PropertySetCSSStyleDeclaration::setCssText):
(WebCore::PropertySetCSSStyleDeclaration::setProperty):
(WebCore::PropertySetCSSStyleDeclaration::removeProperty):
(WebCore::PropertySetCSSStyleDeclaration::setPropertyInternal):
(WebCore):
(WebCore::StyleRuleCSSStyleDeclaration::willMutate):
(WebCore::StyleRuleCSSStyleDeclaration::didMutate):
(WebCore::StyleRuleCSSStyleDeclaration::reattach):
(WebCore::InlineCSSStyleDeclaration::didMutate):

  • css/PropertySetCSSStyleDeclaration.h:

(WebCore::PropertySetCSSStyleDeclaration::willMutate):
(WebCore::PropertySetCSSStyleDeclaration::didMutate):
(StyleRuleCSSStyleDeclaration):

  • css/WebKitCSSKeyframesRule.cpp:

(WebCore::WebKitCSSKeyframesRule::setName):
(WebCore::WebKitCSSKeyframesRule::insertRule):
(WebCore::WebKitCSSKeyframesRule::deleteRule):
(WebCore::WebKitCSSKeyframesRule::reattach):
(WebCore):

  • css/WebKitCSSKeyframesRule.h:

(WebKitCSSKeyframesRule):

  • css/WebKitCSSRegionRule.cpp:

(WebCore::WebKitCSSRegionRule::reattach):

  • css/WebKitCSSRegionRule.h:

(WebKitCSSRegionRule):

  • inspector/InspectorStyleSheet.cpp:

(WebCore::InspectorStyleSheet::reparseStyleSheet):

  • loader/cache/CachedCSSStyleSheet.cpp:

(WebCore::CachedCSSStyleSheet::~CachedCSSStyleSheet):
(WebCore::CachedCSSStyleSheet::destroyDecodedData):
(WebCore::CachedCSSStyleSheet::restoreParsedStyleSheet):

Don't copy when restoring. It is no longer necessary.
Set the cache bit on the stylesheet.

(WebCore::CachedCSSStyleSheet::saveParsedStyleSheet):

LayoutTests:

Reviewed by Darin Adler.

Test that mutations of a shared stylesheet work as expected.

This is an http test due to cross-document security restrictions with file urls
(they can be overriden in DRT but I'd like this to work in browser too).

  • http/tests/css/resources/shared.css: Added.
  • http/tests/css/resources/shared-stylesheet-mutation.js: Added.
  • http/tests/css/shared-stylesheet-mutation-expected.txt: Added.
  • http/tests/css/shared-stylesheet-mutation-preconstruct-expected.txt: Added.
  • http/tests/css/shared-stylesheet-mutation-preconstruct.html: Added.
  • http/tests/css/shared-stylesheet-mutation.html: Added.
Location:
trunk
Files:
6 added
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r116232 r116235  
     12012-05-05  Antti Koivisto  <antti@apple.com>
     2
     3        Share stylesheet data structures between documents
     4        https://bugs.webkit.org/show_bug.cgi?id=85598
     5
     6        Reviewed by Darin Adler.
     7       
     8        Test that mutations of a shared stylesheet work as expected.
     9       
     10        This is an http test due to cross-document security restrictions with file urls
     11        (they can be overriden in DRT but I'd like this to work in browser too).
     12
     13        * http/tests/css/resources/shared.css: Added.
     14        * http/tests/css/resources/shared-stylesheet-mutation.js: Added.
     15        * http/tests/css/shared-stylesheet-mutation-expected.txt: Added.
     16        * http/tests/css/shared-stylesheet-mutation-preconstruct-expected.txt: Added.
     17        * http/tests/css/shared-stylesheet-mutation-preconstruct.html: Added.
     18        * http/tests/css/shared-stylesheet-mutation.html: Added.
     19
    1202012-05-05  Sheriff Bot  <webkit.review.bot@gmail.com>
    221
  • trunk/Source/WebCore/ChangeLog

    r116232 r116235  
     12012-05-04  Antti Koivisto  <antti@apple.com>
     2
     3        Share stylesheet data structures between documents
     4        https://bugs.webkit.org/show_bug.cgi?id=85598
     5
     6        Reviewed by Darin Adler.
     7
     8        We currently make a copy of the data structures when restoring a cached stylesheet. This patch lets us share
     9        the data until someone uses CSSOM to modify the sheet.
     10       
     11        The patch implements copy-on-write for the internal style sheet data structures. If any mutation CSSOM API is
     12        invoked, we check if the stylesheet can be safely mutated (we are the only client, it is not cached). If not
     13        then the internal structures are copied and any existing CSSOM objects are re-attached to the new tree.
     14       
     15        Sharing can save significant amount of memory on sites with large stylesheets. For example if you have
     16        multiple articles open on wsj.com this saves ~2.6MB per tab.
     17       
     18        Test: http/tests/css/shared-stylesheet-mutation.html
     19              http/tests/css/shared-stylesheet-mutation-preconstruct.html
     20
     21        * css/CSSFontFaceRule.cpp:
     22        (WebCore::CSSFontFaceRule::reattach):
     23        (WebCore):
     24        * css/CSSFontFaceRule.h:
     25        (CSSFontFaceRule):
     26        * css/CSSMediaRule.cpp:
     27        (WebCore::CSSMediaRule::insertRule):
     28        (WebCore::CSSMediaRule::deleteRule):
     29        (WebCore::CSSMediaRule::reattach):
     30        (WebCore):
     31        * css/CSSMediaRule.h:
     32        (CSSMediaRule):
     33        * css/CSSPageRule.cpp:
     34        (WebCore::CSSPageRule::setSelectorText):
     35        (WebCore::CSSPageRule::reattach):
     36        (WebCore):
     37        * css/CSSPageRule.h:
     38        (CSSPageRule):
     39        * css/CSSRule.cpp:
     40        (WebCore::CSSRule::reattach):
     41       
     42            After the internal stylerule tree has been copied, the existing wrappers are re-attached using recursive reattach() function.
     43
     44        * css/CSSRule.h:
     45        (WebCore):
     46        (CSSRule):
     47        * css/CSSStyleRule.cpp:
     48        (WebCore::CSSStyleRule::setSelectorText):
     49        (WebCore::CSSStyleRule::reattach):
     50        (WebCore):
     51        * css/CSSStyleRule.h:
     52        (CSSStyleRule):
     53        * css/CSSStyleSheet.cpp:
     54        (WebCore::StyleSheetInternal::StyleSheetInternal):
     55        (WebCore::StyleSheetInternal::isCacheable):
     56        (WebCore::StyleSheetInternal::ruleAt):
     57       
     58            Add ruleAt(), use it for both wrapper creation and reattaching.  Remove createChildRuleCSSOMWrapper .
     59
     60        (WebCore):
     61        (WebCore::StyleSheetInternal::wrapperInsertRule):
     62        (WebCore::StyleSheetInternal::wrapperDeleteRule):
     63       
     64            Invalidation moves to the calling wrapper.
     65
     66        (WebCore::StyleSheetInternal::addedToMemoryCache):
     67        (WebCore::StyleSheetInternal::removedFromMemoryCache):
     68        (WebCore::CSSStyleSheet::willMutateRules):
     69       
     70            This is called whenever StyleSheetInternal is going to be mutated. It will do copy-on-write if needed.
     71           
     72            Usually invoked by CSSStyleSheet::RuleMutation RAII type.
     73
     74        (WebCore::CSSStyleSheet::didMutateRules):
     75       
     76            This is called after the mutation is complete and will trigger the style recalc in the document.
     77
     78        (WebCore::CSSStyleSheet::didMutate):
     79       
     80            This is called directly after mutations that don't change StyleSheetInternal so don't require copy-on-write.
     81
     82        (WebCore::CSSStyleSheet::reattachChildRuleCSSOMWrappers):
     83        (WebCore::CSSStyleSheet::setDisabled):
     84        (WebCore::CSSStyleSheet::insertRule):
     85        (WebCore::CSSStyleSheet::deleteRule):
     86        * css/CSSStyleSheet.h:
     87        (StyleSheetInternal):
     88        (WebCore::StyleSheetInternal::hasOneClient):
     89        (WebCore::StyleSheetInternal::isMutable):
     90        (WebCore::StyleSheetInternal::setMutable):
     91       
     92            Track mutability. Mutation is allowed only after willMutate call.
     93
     94        (WebCore::StyleSheetInternal::isInMemoryCache):
     95       
     96            Track if the object is in memory cache.
     97
     98        (WebCore::CSSStyleSheet::clearOwnerRule):
     99        (CSSStyleSheet):
     100        * css/MediaList.cpp:
     101        (WebCore::MediaList::setMediaText):
     102        (WebCore::MediaList::deleteMedium):
     103        (WebCore::MediaList::appendMedium):
     104        (WebCore::MediaList::didMutate):
     105        (WebCore):
     106        (WebCore::MediaList::reattach):
     107        * css/MediaList.h:
     108        (MediaList):
     109        * css/PropertySetCSSStyleDeclaration.cpp:
     110        (WebCore::PropertySetCSSStyleDeclaration::setCssText):
     111        (WebCore::PropertySetCSSStyleDeclaration::setProperty):
     112        (WebCore::PropertySetCSSStyleDeclaration::removeProperty):
     113        (WebCore::PropertySetCSSStyleDeclaration::setPropertyInternal):
     114        (WebCore):
     115        (WebCore::StyleRuleCSSStyleDeclaration::willMutate):
     116        (WebCore::StyleRuleCSSStyleDeclaration::didMutate):
     117        (WebCore::StyleRuleCSSStyleDeclaration::reattach):
     118        (WebCore::InlineCSSStyleDeclaration::didMutate):
     119        * css/PropertySetCSSStyleDeclaration.h:
     120        (WebCore::PropertySetCSSStyleDeclaration::willMutate):
     121        (WebCore::PropertySetCSSStyleDeclaration::didMutate):
     122        (StyleRuleCSSStyleDeclaration):
     123        * css/WebKitCSSKeyframesRule.cpp:
     124        (WebCore::WebKitCSSKeyframesRule::setName):
     125        (WebCore::WebKitCSSKeyframesRule::insertRule):
     126        (WebCore::WebKitCSSKeyframesRule::deleteRule):
     127        (WebCore::WebKitCSSKeyframesRule::reattach):
     128        (WebCore):
     129        * css/WebKitCSSKeyframesRule.h:
     130        (WebKitCSSKeyframesRule):
     131        * css/WebKitCSSRegionRule.cpp:
     132        (WebCore::WebKitCSSRegionRule::reattach):
     133        * css/WebKitCSSRegionRule.h:
     134        (WebKitCSSRegionRule):
     135        * inspector/InspectorStyleSheet.cpp:
     136        (WebCore::InspectorStyleSheet::reparseStyleSheet):
     137        * loader/cache/CachedCSSStyleSheet.cpp:
     138        (WebCore::CachedCSSStyleSheet::~CachedCSSStyleSheet):
     139        (WebCore::CachedCSSStyleSheet::destroyDecodedData):
     140        (WebCore::CachedCSSStyleSheet::restoreParsedStyleSheet):
     141       
     142            Don't copy when restoring. It is no longer necessary.
     143            Set the cache bit on the stylesheet.
     144
     145        (WebCore::CachedCSSStyleSheet::saveParsedStyleSheet):
     146
    11472012-05-05  Sheriff Bot  <webkit.review.bot@gmail.com>
    2148
  • trunk/Source/WebCore/bindings/objc/DOMCSS.mm

    r105514 r116235  
    2929
    3030#import "CSSRule.h"
     31#import "CSSStyleSheet.h"
    3132#import "CSSValue.h"
    3233#import "DOMCSSCharsetRule.h"
  • trunk/Source/WebCore/css/CSSFontFaceRule.cpp

    r112923 r116235  
    5656}
    5757
     58void CSSFontFaceRule::reattach(StyleRuleFontFace* rule)
     59{
     60    ASSERT(rule);
     61    m_fontFaceRule = rule;
     62    if (m_propertiesCSSOMWrapper)
     63        m_propertiesCSSOMWrapper->reattach(m_fontFaceRule->properties());
     64}
     65
    5866} // namespace WebCore
  • trunk/Source/WebCore/css/CSSFontFaceRule.h

    r112923 r116235  
    4444    String cssText() const;
    4545
     46    void reattach(StyleRuleFontFace*);
     47
    4648private:
    4749    CSSFontFaceRule(StyleRuleFontFace*, CSSStyleSheet* parent);
  • trunk/Source/WebCore/css/CSSImportRule.cpp

    r115805 r116235  
    2323#include "CSSImportRule.h"
    2424
     25#include "CSSStyleSheet.h"
    2526#include "CachedCSSStyleSheet.h"
    2627#include "CachedResourceLoader.h"
  • trunk/Source/WebCore/css/CSSMediaRule.cpp

    r115060 r116235  
    2626#include "CSSParser.h"
    2727#include "CSSRuleList.h"
     28#include "CSSStyleSheet.h"
    2829#include "ExceptionCode.h"
    2930#include "StyleRule.h"
     
    8182        return 0;
    8283    }
     84    CSSStyleSheet::RuleMutationScope mutationScope(this);
     85
    8386    m_mediaRule->wrapperInsertRule(index, newRule);
    8487
    8588    m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
    86 
    87     if (CSSStyleSheet* styleSheet = parentStyleSheet())
    88         styleSheet->styleSheetChanged();
    89 
    9089    return index;
    9190}
     
    101100        return;
    102101    }
     102
     103    CSSStyleSheet::RuleMutationScope mutationScope(this);
     104
    103105    m_mediaRule->wrapperRemoveRule(index);
    104106
     
    106108        m_childRuleCSSOMWrappers[index]->setParentRule(0);
    107109    m_childRuleCSSOMWrappers.remove(index);
    108 
    109     if (CSSStyleSheet* styleSheet = parentStyleSheet())
    110         styleSheet->styleSheetChanged();
    111110}
    112111
     
    164163}
    165164
     165void CSSMediaRule::reattach(StyleRuleMedia* rule)
     166{
     167    ASSERT(rule);
     168    m_mediaRule = rule;
     169    if (m_mediaCSSOMWrapper)
     170        m_mediaCSSOMWrapper->reattach(m_mediaRule->mediaQueries());
     171    for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
     172        if (m_childRuleCSSOMWrappers[i])
     173            m_childRuleCSSOMWrappers[i]->reattach(m_mediaRule->childRules()[i].get());
     174    }
     175}
     176
    166177} // namespace WebCore
  • trunk/Source/WebCore/css/CSSMediaRule.h

    r115060 r116235  
    5151    CSSRule* item(unsigned index) const;
    5252
     53    void reattach(StyleRuleMedia*);
     54
    5355private:
    5456    CSSMediaRule(StyleRuleMedia*, CSSStyleSheet*);
  • trunk/Source/WebCore/css/CSSPageRule.cpp

    r115250 r116235  
    2525#include "CSSParser.h"
    2626#include "CSSSelector.h"
     27#include "CSSStyleSheet.h"
    2728#include "Document.h"
    2829#include "PropertySetCSSStyleDeclaration.h"
     
    6667void CSSPageRule::setSelectorText(const String& selectorText)
    6768{
    68     Document* doc = 0;
    69     if (CSSStyleSheet* styleSheet = parentStyleSheet())
    70         doc = styleSheet->ownerDocument();
    71     if (!doc)
    72         return;
    73    
    7469    CSSParser parser(parserContext());
    7570    CSSSelectorList selectorList;
     
    7772    if (!selectorList.first())
    7873        return;
    79    
     74
     75    CSSStyleSheet::RuleMutationScope mutationScope(this);
     76
    8077    String oldSelectorText = this->selectorText();
    8178    m_pageRule->wrapperAdoptSelectorList(selectorList);
    82    
    83     if (this->selectorText() == oldSelectorText)
    84         return;
    85     doc->styleResolverChanged(DeferRecalcStyle);
    8679}
    8780
     
    9588}
    9689
     90void CSSPageRule::reattach(StyleRulePage* rule)
     91{
     92    ASSERT(rule);
     93    m_pageRule = rule;
     94    if (m_propertiesCSSOMWrapper)
     95        m_propertiesCSSOMWrapper->reattach(m_pageRule->properties());
     96}
     97
    9798} // namespace WebCore
  • trunk/Source/WebCore/css/CSSPageRule.h

    r112923 r116235  
    4646
    4747    String cssText() const;
    48    
     48
     49    void reattach(StyleRulePage*);
     50
    4951private:
    5052    CSSPageRule(StyleRulePage*, CSSStyleSheet*);
  • trunk/Source/WebCore/css/CSSRule.cpp

    r107526 r116235  
    2929#include "CSSPageRule.h"
    3030#include "CSSStyleRule.h"
     31#include "CSSStyleSheet.h"
    3132#include "CSSUnknownRule.h"
    3233#include "WebKitCSSKeyframeRule.h"
     
    3435#include "WebKitCSSRegionRule.h"
    3536#include "NotImplemented.h"
     37#include "StyleRule.h"
    3638
    3739namespace WebCore {
     
    114116}
    115117
     118void CSSRule::reattach(StyleRuleBase* rule)
     119{
     120    switch (type()) {
     121    case UNKNOWN_RULE:
     122        return;
     123    case STYLE_RULE:
     124        static_cast<CSSStyleRule*>(this)->reattach(static_cast<StyleRule*>(rule));
     125        return;
     126    case PAGE_RULE:
     127        static_cast<CSSPageRule*>(this)->reattach(static_cast<StyleRulePage*>(rule));
     128        return;
     129    case CHARSET_RULE:
     130        ASSERT(!rule);
     131        return;
     132    case IMPORT_RULE:
     133        // FIXME: Implement when enabling caching for stylesheets with import rules.
     134        ASSERT_NOT_REACHED();
     135        return;
     136    case MEDIA_RULE:
     137        static_cast<CSSMediaRule*>(this)->reattach(static_cast<StyleRuleMedia*>(rule));
     138        return;
     139    case FONT_FACE_RULE:
     140        static_cast<CSSFontFaceRule*>(this)->reattach(static_cast<StyleRuleFontFace*>(rule));
     141        return;
     142    case WEBKIT_KEYFRAMES_RULE:
     143        static_cast<WebKitCSSKeyframesRule*>(this)->reattach(static_cast<StyleRuleKeyframes*>(rule));
     144        return;
     145    case WEBKIT_KEYFRAME_RULE:
     146        // No need to reattach, the underlying data is shareable on mutation.
     147        ASSERT_NOT_REACHED();
     148        return;
     149    case WEBKIT_REGION_RULE:
     150        static_cast<WebKitCSSRegionRule*>(this)->reattach(static_cast<StyleRuleRegion*>(rule));
     151        return;
     152    }
     153    ASSERT_NOT_REACHED();
     154}
     155
     156const CSSParserContext& CSSRule::parserContext() const
     157{
     158    CSSStyleSheet* styleSheet = parentStyleSheet();
     159    return styleSheet ? styleSheet->internal()->parserContext() : strictCSSParserContext();
     160}
     161
    116162} // namespace WebCore
  • trunk/Source/WebCore/css/CSSRule.h

    r114217 r116235  
    2424#define CSSRule_h
    2525
    26 #include "CSSStyleSheet.h"
    2726#include "KURLHash.h"
    2827#include <wtf/ListHashSet.h>
     28#include <wtf/RefCounted.h>
    2929
    3030namespace WebCore {
    3131
     32class CSSStyleSheet;
     33class StyleRuleBase;
     34struct CSSParserContext;
    3235typedef int ExceptionCode;
    3336
     
    9497    void setCssText(const String&, ExceptionCode&);
    9598
     99    void reattach(StyleRuleBase*);
     100
    96101protected:
    97102    CSSRule(CSSStyleSheet* parent, Type type)
     
    111116    void setHasCachedSelectorText(bool hasCachedSelectorText) const { m_hasCachedSelectorText = hasCachedSelectorText; }
    112117
    113     const CSSParserContext& parserContext() const
    114     {
    115         CSSStyleSheet* styleSheet = parentStyleSheet();
    116         return styleSheet ? styleSheet->internal()->parserContext() : strictCSSParserContext();
    117     }
     118    const CSSParserContext& parserContext() const;
    118119
    119120private:
  • trunk/Source/WebCore/css/CSSStyleRule.cpp

    r115250 r116235  
    9292void CSSStyleRule::setSelectorText(const String& selectorText)
    9393{
    94     Document* doc = 0;
    95     if (CSSStyleSheet* styleSheet = parentStyleSheet())
    96         doc = styleSheet->ownerDocument();
    97     if (!doc)
    98         return;
    99 
    10094    CSSParser p(parserContext());
    10195    CSSSelectorList selectorList;
     
    10397    if (!selectorList.first())
    10498        return;
     99
     100    CSSStyleSheet::RuleMutationScope mutationScope(this);
    105101
    106102    String oldSelectorText = this->selectorText();
     
    111107        selectorTextCache().set(this, generateSelectorText());
    112108    }
    113 
    114     doc->styleResolverChanged(DeferRecalcStyle);
    115109}
    116110
     
    126120}
    127121
     122void CSSStyleRule::reattach(StyleRule* rule)
     123{
     124    m_styleRule = rule;
     125    if (m_propertiesCSSOMWrapper)
     126        m_propertiesCSSOMWrapper->reattach(m_styleRule->properties());
     127}
     128
    128129} // namespace WebCore
  • trunk/Source/WebCore/css/CSSStyleRule.h

    r112923 r116235  
    4949    StyleRule* styleRule() const { return m_styleRule.get(); }
    5050
     51    void reattach(StyleRule*);
     52
    5153private:
    5254    CSSStyleRule(StyleRule*, CSSStyleSheet*);
  • trunk/Source/WebCore/css/CSSStyleSheet.cpp

    r115860 r116235  
    100100    , m_didLoadErrorOccur(false)
    101101    , m_usesRemUnits(false)
    102     , m_hasMutated(false)
     102    , m_isMutable(false)
     103    , m_isInMemoryCache(false)
    103104    , m_parserContext(context)
    104105{
     
    119120    , m_didLoadErrorOccur(false)
    120121    , m_usesRemUnits(o.m_usesRemUnits)
    121     , m_hasMutated(false)
     122    , m_isMutable(false)
     123    , m_isInMemoryCache(false)
    122124    , m_parserContext(o.m_parserContext)
    123125{
     
    140142    // FIXME: Support copying import rules.
    141143    if (!m_importRules.isEmpty())
     144        return false;
     145    // FIXME: Support cached stylesheets in import rules.
     146    if (m_ownerRule)
    142147        return false;
    143148    // This would require dealing with multiple clients for load callbacks.
     
    147152        return false;
    148153    // It is not the original sheet anymore.
    149     if (m_hasMutated)
     154    if (m_isMutable)
    150155        return false;
    151156    // If the header is valid we are not going to need to check the SecurityOrigin.
     
    170175}
    171176
    172 PassRefPtr<CSSRule> StyleSheetInternal::createChildRuleCSSOMWrapper(unsigned index, CSSStyleSheet* parentWrapper)
     177StyleRuleBase* StyleSheetInternal::ruleAt(unsigned index) const
    173178{
    174179    ASSERT(index < ruleCount());
     
    177182    if (hasCharsetRule()) {
    178183        if (index == 0)
    179             return CSSCharsetRule::create(parentWrapper, m_encodingFromCharsetRule);
     184            return 0;
    180185        --childVectorIndex;
    181186    }
    182187    if (childVectorIndex < m_importRules.size())
    183         return m_importRules[childVectorIndex]->createCSSOMWrapper(parentWrapper);
    184    
     188        return m_importRules[childVectorIndex].get();
     189
    185190    childVectorIndex -= m_importRules.size();
    186     return m_childRules[childVectorIndex]->createCSSOMWrapper(parentWrapper);
     191    return m_childRules[childVectorIndex].get();
    187192}
    188193
     
    221226bool StyleSheetInternal::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsigned index)
    222227{
     228    ASSERT(m_isMutable);
    223229    ASSERT(index <= ruleCount());
    224230    // Parser::parseRule doesn't currently allow @charset so we don't need to deal with it.
     
    243249        m_importRules[childVectorIndex]->requestStyleSheet();
    244250        // FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded.
    245         styleSheetChanged();
    246251        return true;
    247252    }
     
    252257 
    253258    m_childRules.insert(childVectorIndex, rule);
    254    
    255     styleSheetChanged();
    256259    return true;
    257260}
     
    259262void StyleSheetInternal::wrapperDeleteRule(unsigned index)
    260263{
     264    ASSERT(m_isMutable);
    261265    ASSERT(index < ruleCount());
    262266
     
    265269        if (childVectorIndex == 0) {
    266270            clearCharsetRule();
    267             styleSheetChanged();
    268271            return;
    269272        }
     
    273276        m_importRules[childVectorIndex]->clearParentStyleSheet();
    274277        m_importRules.remove(childVectorIndex);
    275         styleSheetChanged();
    276278        return;
    277279    }
     
    279281
    280282    m_childRules.remove(childVectorIndex);
    281     styleSheetChanged();
    282283}
    283284
     
    414415    Node* ownerNode = singleOwnerNode();
    415416    return ownerNode ? ownerNode->document() : 0;
    416 }
    417 
    418 void StyleSheetInternal::styleSheetChanged()
    419 {
    420     m_hasMutated = true;
    421 
    422     Document* ownerDocument = singleOwnerDocument();
    423     if (!ownerDocument)
    424         return;
    425     ownerDocument->styleResolverChanged(DeferRecalcStyle);
    426417}
    427418
     
    474465}
    475466
     467void StyleSheetInternal::addedToMemoryCache()
     468{
     469    ASSERT(!m_isInMemoryCache);
     470    ASSERT(isCacheable());
     471    m_isInMemoryCache = true;
     472}
     473
     474void StyleSheetInternal::removedFromMemoryCache()
     475{
     476    ASSERT(m_isInMemoryCache);
     477    ASSERT(isCacheable());
     478    m_isInMemoryCache = false;
     479}
     480
    476481PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const String& encoding)
    477482{
     
    515520}
    516521
     522void CSSStyleSheet::willMutateRules()
     523{
     524    // If we are the only client it is safe to mutate.
     525    if (m_internal->hasOneClient() && !m_internal->isInMemoryCache()) {
     526        m_internal->setMutable();
     527        return;
     528    }
     529    // Only cacheable stylesheets should have multiple clients.
     530    ASSERT(m_internal->isCacheable());
     531
     532    // Copy-on-write.
     533    m_internal->unregisterClient(this);
     534    m_internal = m_internal->copy();
     535    m_internal->registerClient(this);
     536
     537    m_internal->setMutable();
     538
     539    // Any existing CSSOM wrappers need to be connected to the copied child rules.
     540    reattachChildRuleCSSOMWrappers();
     541}
     542
     543void CSSStyleSheet::didMutateRules()
     544{
     545    ASSERT(m_internal->isMutable());
     546    ASSERT(m_internal->hasOneClient());
     547
     548    didMutate();
     549}
     550
     551void CSSStyleSheet::didMutate()
     552{
     553    Document* owner = ownerDocument();
     554    if (!owner)
     555        return;
     556    owner->styleResolverChanged(DeferRecalcStyle);
     557}
     558
     559void CSSStyleSheet::reattachChildRuleCSSOMWrappers()
     560{
     561    for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
     562        if (!m_childRuleCSSOMWrappers[i])
     563            continue;
     564        m_childRuleCSSOMWrappers[i]->reattach(m_internal->ruleAt(i));
     565    }
     566}
     567
    517568void CSSStyleSheet::setDisabled(bool disabled)
    518569{
     
    520571        return;
    521572    m_isDisabled = disabled;
    522     Document* owner = ownerDocument();
    523     if (owner)
    524         owner->styleResolverChanged(DeferRecalcStyle);
     573
     574    didMutate();
    525575}
    526576
     
    546596   
    547597    RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index];
    548     if (!cssRule)
    549         cssRule = m_internal->createChildRuleCSSOMWrapper(index, this);
     598    if (!cssRule) {
     599        if (index == 0 && m_internal->hasCharsetRule()) {
     600            ASSERT(!m_internal->ruleAt(0));
     601            cssRule = CSSCharsetRule::create(this, m_internal->encodingFromCharsetRule());
     602        } else
     603            cssRule = m_internal->ruleAt(index)->createCSSOMWrapper(this);
     604    }
    550605    return cssRule.get();
    551606}
     
    585640        return 0;
    586641    }
     642    RuleMutationScope mutationScope(this);
     643
    587644    bool success = m_internal->wrapperInsertRule(rule, index);
    588645    if (!success) {
     
    592649    if (!m_childRuleCSSOMWrappers.isEmpty())
    593650        m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
     651
    594652    return index;
    595653}
     
    604662        return;
    605663    }
     664    RuleMutationScope mutationScope(this);
     665
    606666    m_internal->wrapperDeleteRule(index);
    607667
  • trunk/Source/WebCore/css/CSSStyleSheet.h

    r115860 r116235  
    2323
    2424#include "CSSParserMode.h"
     25#include "CSSRule.h"
    2526#include "StyleSheet.h"
    2627#include <wtf/HashMap.h>
     28#include <wtf/Noncopyable.h>
    2729#include <wtf/text/AtomicStringHash.h>
    2830
     
    6668    const AtomicString& determineNamespace(const AtomicString& prefix);
    6769
    68     void styleSheetChanged();
    69 
    7070    void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*);
    7171    bool parseString(const String&);
     
    102102    void clearRules();
    103103
     104    bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); }
     105    String encodingFromCharsetRule() const { return m_encodingFromCharsetRule; }
    104106    // Rules other than @charset and @import.
    105107    const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
     
    121123
    122124    unsigned ruleCount() const;
    123    
     125    StyleRuleBase* ruleAt(unsigned index) const;
     126
    124127    bool usesRemUnits() const { return m_usesRemUnits; }
    125128
     
    129132    void wrapperDeleteRule(unsigned index);
    130133
    131     PassRefPtr<CSSRule> createChildRuleCSSOMWrapper(unsigned index, CSSStyleSheet* parentWrapper);
    132 
    133134    PassRefPtr<StyleSheetInternal> copy() const { return adoptRef(new StyleSheetInternal(*this)); }
    134135
    135136    void registerClient(CSSStyleSheet*);
    136137    void unregisterClient(CSSStyleSheet*);
     138    bool hasOneClient() { return m_clients.size() == 1; }
     139
     140    bool isMutable() const { return m_isMutable; }
     141    void setMutable() { m_isMutable = true; }
     142
     143    bool isInMemoryCache() const { return m_isInMemoryCache; }
     144    void addedToMemoryCache();
     145    void removedFromMemoryCache();
    137146
    138147private:
     
    141150
    142151    void clearCharsetRule();
    143     bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); }
    144152
    145153    StyleRuleImport* m_ownerRule;
     
    159167    bool m_didLoadErrorOccur : 1;
    160168    bool m_usesRemUnits : 1;
    161     bool m_hasMutated : 1;
     169    bool m_isMutable : 1;
     170    bool m_isInMemoryCache : 1;
    162171   
    163172    CSSParserContext m_parserContext;
     
    208217   
    209218    void clearOwnerRule() { m_ownerRule = 0; }
    210     void styleSheetChanged() { m_internal->styleSheetChanged(); }
    211219    Document* ownerDocument() const;
    212220    MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
    213221    void setMediaQueries(PassRefPtr<MediaQuerySet>);
    214222    void setTitle(const String& title) { m_title = title; }
     223
     224    class RuleMutationScope {
     225        WTF_MAKE_NONCOPYABLE(RuleMutationScope);
     226    public:
     227        RuleMutationScope(CSSStyleSheet*);
     228        RuleMutationScope(CSSRule*);
     229        ~RuleMutationScope();
     230
     231    private:
     232        CSSStyleSheet* m_styleSheet;
     233    };
     234
     235    void willMutateRules();
     236    void didMutateRules();
     237    void didMutate();
    215238   
    216239    void clearChildRuleCSSOMWrappers();
     240    void reattachChildRuleCSSOMWrappers();
    217241
    218242    StyleSheetInternal* internal() const { return m_internal.get(); }
     
    238262};
    239263
     264inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSStyleSheet* sheet)
     265    : m_styleSheet(sheet)
     266{
     267    if (m_styleSheet)
     268        m_styleSheet->willMutateRules();
     269}
     270
     271inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSRule* rule)
     272    : m_styleSheet(rule ? rule->parentStyleSheet() : 0)
     273{
     274    if (m_styleSheet)
     275        m_styleSheet->willMutateRules();
     276}
     277
     278inline CSSStyleSheet::RuleMutationScope::~RuleMutationScope()
     279{
     280    if (m_styleSheet)
     281        m_styleSheet->didMutateRules();
     282}
     283
    240284} // namespace
    241285
  • trunk/Source/WebCore/css/MediaList.cpp

    r115120 r116235  
    231231void MediaList::setMediaText(const String& value, ExceptionCode& ec)
    232232{
     233    CSSStyleSheet::RuleMutationScope mutationScope(m_parentRule);
     234
    233235    bool success = m_mediaQueries->parse(value);
    234236    if (!success) {
     
    236238        return;
    237239    }
    238     notifyChanged();
     240    if (m_parentStyleSheet)
     241        m_parentStyleSheet->didMutate();
    239242}
    240243
     
    249252void MediaList::deleteMedium(const String& medium, ExceptionCode& ec)
    250253{
     254    CSSStyleSheet::RuleMutationScope mutationScope(m_parentRule);
     255
    251256    bool success = m_mediaQueries->remove(medium);
    252257    if (!success) {
     
    254259        return;
    255260    }
    256     notifyChanged();
     261    if (m_parentStyleSheet)
     262        m_parentStyleSheet->didMutate();
    257263}
    258264
    259265void MediaList::appendMedium(const String& medium, ExceptionCode& ec)
    260266{
     267    CSSStyleSheet::RuleMutationScope mutationScope(m_parentRule);
     268
    261269    bool success = m_mediaQueries->add(medium);
    262270    if (!success) {
     
    265273        return;
    266274    }
    267     notifyChanged();
    268 }
    269 
    270 void MediaList::notifyChanged()
    271 {
    272     CSSStyleSheet* parentStyleSheet = m_parentRule ? m_parentRule->parentStyleSheet() : m_parentStyleSheet;
    273     if (!parentStyleSheet)
    274         return;
    275     parentStyleSheet->styleSheetChanged();
    276 }
    277 
    278 }
     275    if (m_parentStyleSheet)
     276        m_parentStyleSheet->didMutate();
     277}
     278
     279void MediaList::reattach(MediaQuerySet* mediaQueries)
     280{
     281    ASSERT(mediaQueries);
     282    m_mediaQueries = mediaQueries;
     283}
     284
     285}
  • trunk/Source/WebCore/css/MediaList.h

    r115115 r116235  
    105105    const MediaQuerySet* queries() const { return m_mediaQueries.get(); }
    106106
     107    void reattach(MediaQuerySet*);
     108
    107109private:
    108110    MediaList();
    109111    MediaList(MediaQuerySet*, CSSStyleSheet* parentSheet);
    110112    MediaList(MediaQuerySet*, CSSRule* parentRule);
    111 
    112     void notifyChanged();
    113113
    114114    RefPtr<MediaQuerySet> m_mediaQueries;
  • trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp

    r115250 r116235  
    152152    StyleAttributeMutationScope mutationScope(this);
    153153#endif
     154    willMutate();
     155
    154156    ec = 0;
    155157    // FIXME: Detect syntax errors and set ec.
    156158    m_propertySet->parseDeclaration(text, contextStyleSheet());
    157159
    158     didMutate();
     160    didMutate(PropertyChanged);
     161
    159162#if ENABLE(MUTATION_OBSERVERS)
    160163    mutationScope.enqueueMutationRecord();   
     
    213216    if (!propertyID)
    214217        return;
     218
    215219    bool important = priority.find("important", 0, false) != notFound;
     220
     221    willMutate();
     222
    216223    ec = 0;
    217224    bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet());
     225
     226    didMutate(changed ? PropertyChanged : NoChanges);
     227
    218228    if (changed) {
    219229        // CSS DOM requires raising SYNTAX_ERR of parsing failed, but this is too dangerous for compatibility,
    220230        // see <http://bugs.webkit.org/show_bug.cgi?id=7296>.
    221         didMutate();
    222231#if ENABLE(MUTATION_OBSERVERS)
    223232        mutationScope.enqueueMutationRecord();
     
    234243    if (!propertyID)
    235244        return String();
     245
     246    willMutate();
     247
    236248    ec = 0;
    237249    String result;
    238     bool changes = m_propertySet->removeProperty(propertyID, &result);
    239     if (changes) {
    240         didMutate();
     250    bool changed = m_propertySet->removeProperty(propertyID, &result);
     251
     252    didMutate(changed ? PropertyChanged : NoChanges);
     253
     254    if (changed) {
    241255#if ENABLE(MUTATION_OBSERVERS)
    242256        mutationScope.enqueueMutationRecord();
     
    261275    StyleAttributeMutationScope mutationScope(this);
    262276#endif
     277    willMutate();
     278
    263279    ec = 0;
    264280    bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet());
     281
     282    didMutate(changed ? PropertyChanged : NoChanges);
     283
    265284    if (changed) {
    266         didMutate();
    267285#if ENABLE(MUTATION_OBSERVERS)
    268286        mutationScope.enqueueMutationRecord();
    269287#endif
    270288    }
    271 }
    272 
    273 void PropertySetCSSStyleDeclaration::didMutate()
    274 {
    275     m_cssomCSSValueClones.clear();
    276     setNeedsStyleRecalc();
    277289}
    278290
     
    339351}
    340352
    341 void StyleRuleCSSStyleDeclaration::setNeedsStyleRecalc()
    342 {
    343     if (CSSStyleSheet* styleSheet = parentStyleSheet()) {
    344         if (Document* document = styleSheet->ownerDocument())
    345             document->styleResolverChanged(DeferRecalcStyle);
    346     }
     353void StyleRuleCSSStyleDeclaration::willMutate()
     354{
     355    if (m_parentRule && m_parentRule->parentStyleSheet())
     356        m_parentRule->parentStyleSheet()->willMutateRules();
     357}
     358
     359void StyleRuleCSSStyleDeclaration::didMutate(MutationType type)
     360{
     361    if (type == PropertyChanged)
     362        m_cssomCSSValueClones.clear();
     363
     364    // Style sheet mutation needs to be signaled even if the change failed. willMutateRules/didMutateRules must pair.
     365    if (m_parentRule && m_parentRule->parentStyleSheet())
     366        m_parentRule->parentStyleSheet()->didMutateRules();
    347367}
    348368
     
    352372}
    353373
    354 void InlineCSSStyleDeclaration::setNeedsStyleRecalc()
    355 {
     374void StyleRuleCSSStyleDeclaration::reattach(StylePropertySet* propertySet)
     375{
     376    ASSERT(propertySet);
     377    m_propertySet->deref();
     378    m_propertySet = propertySet;
     379    m_propertySet->ref();
     380}
     381
     382void InlineCSSStyleDeclaration::didMutate(MutationType type)
     383{
     384    if (type == NoChanges)
     385        return;
     386
     387    m_cssomCSSValueClones.clear();
     388
    356389    if (!m_parentElement)
    357390        return;
     
    359392    m_parentElement->invalidateStyleAttribute();
    360393    StyleAttributeMutationScope(this).didInvalidateStyleAttr();
    361     return;
    362394}
    363395
  • trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.h

    r113922 r116235  
    6969    virtual PassRefPtr<StylePropertySet> copy() const OVERRIDE;
    7070    virtual PassRefPtr<StylePropertySet> makeMutable() OVERRIDE;
    71     virtual void setNeedsStyleRecalc() { }
    72    
    73     void didMutate();
     71
    7472    CSSValue* cloneAndCacheForCSSOM(CSSValue*);
    7573   
    7674protected:
     75    enum MutationType { NoChanges, PropertyChanged };
     76    virtual void willMutate() { }
     77    virtual void didMutate(MutationType) { }
     78
    7779    StylePropertySet* m_propertySet;
    7880    OwnPtr<HashMap<CSSValue*, RefPtr<CSSValue> > > m_cssomCSSValueClones;
     
    9294    virtual void deref() OVERRIDE;
    9395
     96    void reattach(StylePropertySet*);
     97
    9498private:
    9599    StyleRuleCSSStyleDeclaration(StylePropertySet*, CSSRule*);
     
    99103
    100104    virtual CSSRule* parentRule() const OVERRIDE { return m_parentRule;  }
    101     virtual void setNeedsStyleRecalc() OVERRIDE;
    102    
     105
     106    virtual void willMutate() OVERRIDE;
     107    virtual void didMutate(MutationType) OVERRIDE;
     108
    103109    unsigned m_refCount;
    104110    CSSRule* m_parentRule;
     
    118124    virtual StyledElement* parentElement() const OVERRIDE { return m_parentElement; }
    119125    virtual void clearParentElement() OVERRIDE { m_parentElement = 0; }
    120     virtual void setNeedsStyleRecalc() OVERRIDE;
     126
     127    virtual void didMutate(MutationType) OVERRIDE;
    121128   
    122129    StyledElement* m_parentElement;
  • trunk/Source/WebCore/css/StylePropertySet.cpp

    r115379 r116235  
    2424
    2525#include "CSSParser.h"
     26#include "CSSStyleSheet.h"
    2627#include "CSSValueKeywords.h"
    2728#include "CSSValueList.h"
  • trunk/Source/WebCore/css/WebKitCSSKeyframesRule.cpp

    r115115 r116235  
    2929#include "CSSParser.h"
    3030#include "CSSRuleList.h"
     31#include "CSSStyleSheet.h"
    3132#include "StylePropertySet.h"
    3233#include "StyleSheet.h"
     
    105106void WebKitCSSKeyframesRule::setName(const String& name)
    106107{
     108    CSSStyleSheet::RuleMutationScope mutationScope(this);
     109
    107110    m_keyframesRule->setName(name);
    108 
    109     // Since the name is used in the keyframe map list in StyleResolver, we need
    110     // to recompute the style sheet to get the updated name.
    111     if (CSSStyleSheet* styleSheet = parentStyleSheet())
    112         styleSheet->styleSheetChanged();
    113111}
    114112
     
    123121        return;
    124122
     123    CSSStyleSheet::RuleMutationScope mutationScope(this);
     124
    125125    m_keyframesRule->wrapperAppendKeyframe(keyframe);
    126126
     
    135135    if (i < 0)
    136136        return;
     137
     138    CSSStyleSheet::RuleMutationScope mutationScope(this);
    137139
    138140    m_keyframesRule->wrapperRemoveKeyframe(i);
     
    191193}
    192194
     195void WebKitCSSKeyframesRule::reattach(StyleRuleKeyframes* rule)
     196{
     197    ASSERT(rule);
     198    m_keyframesRule = rule;
     199}
     200
    193201} // namespace WebCore
  • trunk/Source/WebCore/css/WebKitCSSKeyframesRule.h

    r115115 r116235  
    8888    WebKitCSSKeyframeRule* item(unsigned index) const;
    8989
     90    void reattach(StyleRuleKeyframes*);
     91
    9092private:
    9193    WebKitCSSKeyframesRule(StyleRuleKeyframes*, CSSStyleSheet* parent);
  • trunk/Source/WebCore/css/WebKitCSSRegionRule.cpp

    r112923 r116235  
    9797}
    9898
     99void WebKitCSSRegionRule::reattach(StyleRuleRegion* rule)
     100{
     101    ASSERT(rule);
     102    m_regionRule = rule;
     103    for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
     104        if (m_childRuleCSSOMWrappers[i])
     105            m_childRuleCSSOMWrappers[i]->reattach(m_regionRule->childRules()[i].get());
     106    }
     107}
    99108
    100109} // namespace WebCore
  • trunk/Source/WebCore/css/WebKitCSSRegionRule.h

    r112923 r116235  
    5454    CSSRule* item(unsigned index) const;
    5555
     56    void reattach(StyleRuleRegion*);
     57
    5658private:
    5759    WebKitCSSRegionRule(StyleRuleRegion*, CSSStyleSheet* parent);
  • trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp

    r115250 r116235  
    719719void InspectorStyleSheet::reparseStyleSheet(const String& text)
    720720{
     721    CSSStyleSheet::RuleMutationScope mutationScope(m_pageStyleSheet.get());
    721722    m_pageStyleSheet->internal()->clearRules();
    722723    m_pageStyleSheet->internal()->parseString(text);
    723724    m_pageStyleSheet->clearChildRuleCSSOMWrappers();
    724     m_pageStyleSheet->styleSheetChanged();
    725725    m_inspectorStyles.clear();
    726726    fireStyleSheetChanged();
  • trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp

    r115379 r116235  
    5151CachedCSSStyleSheet::~CachedCSSStyleSheet()
    5252{
     53    if (m_parsedStyleSheetCache)
     54        m_parsedStyleSheetCache->removedFromMemoryCache();
    5355}
    5456
     
    154156void CachedCSSStyleSheet::destroyDecodedData()
    155157{
     158    if (!m_parsedStyleSheetCache)
     159        return;
     160
     161    m_parsedStyleSheetCache->removedFromMemoryCache();
    156162    m_parsedStyleSheetCache.clear();
     163
    157164    setDecodedSize(0);
    158165}
     
    162169    if (!m_parsedStyleSheetCache)
    163170        return 0;
    164     // Cached parsed stylesheet has mutated, kick it out.
    165     if (!m_parsedStyleSheetCache->isCacheable()) {
    166         m_parsedStyleSheetCache.clear();
    167         setDecodedSize(0);
    168         return 0;
    169     }
     171    ASSERT(m_parsedStyleSheetCache->isCacheable());
     172    ASSERT(m_parsedStyleSheetCache->isInMemoryCache());
     173
    170174    // Contexts must be identical so we know we would get the same exact result if we parsed again.
    171175    if (m_parsedStyleSheetCache->parserContext() != context)
     
    173177
    174178    didAccessDecodedData(currentTime());
    175     // FIXME: Implement copy-on-write to avoid copying when not necessary.
    176     return m_parsedStyleSheetCache->copy();
     179
     180    return m_parsedStyleSheetCache;
    177181}
    178182
     
    180184{
    181185    ASSERT(sheet && sheet->isCacheable());
     186
     187    if (m_parsedStyleSheetCache)
     188        m_parsedStyleSheetCache->removedFromMemoryCache();
    182189    m_parsedStyleSheetCache = sheet;
     190    m_parsedStyleSheetCache->addedToMemoryCache();
    183191
    184192    setDecodedSize(m_parsedStyleSheetCache->estimatedSizeInBytes());
Note: See TracChangeset for help on using the changeset viewer.