Don't use CSSRuleList for child rule ownership
https://bugs.webkit.org/show_bug.cgi?id=82127

Reviewed by Andreas Kling.

CSSMediaRule, WebKitCSSKeyframesRule and WebKitRegionRule use CSSRuleList for storing children. 
They should use a simple rule vector instead. CSSRuleList is a CSSOM type that should be 
instantiated on-demand for API purposes only.
        
- Use Vector<RefPtr<CSSRule>> for storing the rule children of CSSMediaRule, WebKitCSSKeyframesRule 
  and WebKitRegionRule.
- Add direct accessors, use internally instead of CSSRuleList.
- Make CSSRuleList an abstract base. Add concrete subclasses for dealing with the underlying storage.
- Instantiate CSSRuleLists on-demand.
- Make CSSStyleSheet.cssRules always return the same object instance. This matches Firefox and the rest
  of our CSSOM implementation. Tested by fast/dom/gc-9.html.
          
The patch decouples internals from the external API. It simplifies the child rule ownership and reduces 
indirection. Memory use of css rules with children is reduced (by a ptr, refcount and heap allocation overhead).

* css/CSSGrammar.y:
* css/CSSMediaRule.cpp:
(WebCore::CSSMediaRule::CSSMediaRule):
(WebCore::CSSMediaRule::~CSSMediaRule):
(WebCore::CSSMediaRule::append):
(WebCore::CSSMediaRule::insertRule):
(WebCore::CSSMediaRule::deleteRule):
(WebCore::CSSMediaRule::cssText):
(WebCore::CSSMediaRule::cssRules):
* css/CSSMediaRule.h:
(WebCore::CSSMediaRule::create):
(CSSMediaRule):
(WebCore::CSSMediaRule::ruleCount):
(WebCore::CSSMediaRule::ruleAt):
* css/CSSParser.cpp:
(WebCore::CSSParser::createMediaRule):
(WebCore::CSSParser::createRuleList):
(WebCore::CSSParser::createRegionRule):
* css/CSSParser.h:
(WebCore):
* css/CSSRuleList.cpp:
(WebCore):
(WebCore::StaticCSSRuleList::StaticCSSRuleList):
(WebCore::StaticCSSRuleList::~StaticCSSRuleList):
(WebCore::StaticCSSRuleList::deref):
(WebCore::StaticCSSRuleList::item):        
* css/CSSRuleList.h:
(CSSRuleList):

    Turn CSSRuleList into abstract interface.
                    
(StaticCSSRuleList):
(WebCore::StaticCSSRuleList::create):
(WebCore::StaticCSSRuleList::ref):
(WebCore::StaticCSSRuleList::rules):
(WebCore::StaticCSSRuleList::styleSheet):
(WebCore::StaticCSSRuleList::length):
        
    Concrete implementation for fixed list of rules.
    
(WebCore):
(LiveCSSRuleList):
(WebCore::LiveCSSRuleList::LiveCSSRuleList):
(WebCore::LiveCSSRuleList::ref):
(WebCore::LiveCSSRuleList::deref):
(WebCore::LiveCSSRuleList::length):
(WebCore::LiveCSSRuleList::item):
(WebCore::LiveCSSRuleList::styleSheet):
        
    Concrete implemenation for live list backed by the underlying container rule.
    LiveCSSRuleList is owned by the underlying rule. Refcount is forwarded. 
        
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::sortAndTransferMatchedRules):
(WebCore::CSSStyleSelector::collectMatchingRulesForList):
* css/CSSStyleSelector.h:
(CSSStyleSelector):
* css/CSSStyleSheet.cpp:
        
    The same scheme for CSSStyleSheet.cssRule as with container rules.
        
(StyleSheetCSSRuleList):
(WebCore::StyleSheetCSSRuleList::StyleSheetCSSRuleList):
(WebCore::StyleSheetCSSRuleList::ref):
(WebCore::StyleSheetCSSRuleList::deref):
(WebCore::StyleSheetCSSRuleList::length):
(WebCore::StyleSheetCSSRuleList::item):
(WebCore::StyleSheetCSSRuleList::styleSheet):
(WebCore):
(WebCore::CSSStyleSheet::rules):
(WebCore::CSSStyleSheet::cssRules):
* css/CSSStyleSheet.h:
(CSSStyleSheet):
* css/WebKitCSSKeyframesRule.cpp:
(WebCore::WebKitCSSKeyframesRule::WebKitCSSKeyframesRule):
(WebCore::WebKitCSSKeyframesRule::~WebKitCSSKeyframesRule):
(WebCore):
(WebCore::WebKitCSSKeyframesRule::append):
(WebCore::WebKitCSSKeyframesRule::deleteRule):
(WebCore::WebKitCSSKeyframesRule::findRule):
(WebCore::WebKitCSSKeyframesRule::findRuleIndex):
(WebCore::WebKitCSSKeyframesRule::cssText):
(WebCore::WebKitCSSKeyframesRule::cssRules):
* css/WebKitCSSKeyframesRule.h:
(WebKitCSSKeyframesRule):
(WebCore::WebKitCSSKeyframesRule::ruleCount):
(WebCore::WebKitCSSKeyframesRule::ruleAt):
(WebCore::WebKitCSSKeyframesRule::length):
(WebCore::WebKitCSSKeyframesRule::item):
* css/WebKitCSSRegionRule.cpp:
(WebCore::WebKitCSSRegionRule::WebKitCSSRegionRule):
(WebCore::WebKitCSSRegionRule::~WebKitCSSRegionRule):
(WebCore::WebKitCSSRegionRule::cssText):
(WebCore::WebKitCSSRegionRule::cssRules):
* css/WebKitCSSRegionRule.h:
* inspector/InspectorStyleSheet.cpp:
(WebCore::asCSSRuleList):
(WebCore::InspectorStyleSheet::addRule):
(WebCore::InspectorStyleSheet::buildObjectForStyleSheet):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@112037 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index a75854c..3fd5935 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,125 @@
+2012-03-25  Antti Koivisto  <antti@apple.com>
+
+        Don't use CSSRuleList for child rule ownership
+        https://bugs.webkit.org/show_bug.cgi?id=82127
+
+        Reviewed by Andreas Kling.
+
+        CSSMediaRule, WebKitCSSKeyframesRule and WebKitRegionRule use CSSRuleList for storing children. 
+        They should use a simple rule vector instead. CSSRuleList is a CSSOM type that should be 
+        instantiated on-demand for API purposes only.
+        
+        - Use Vector<RefPtr<CSSRule>> for storing the rule children of CSSMediaRule, WebKitCSSKeyframesRule 
+          and WebKitRegionRule.
+        - Add direct accessors, use internally instead of CSSRuleList.
+        - Make CSSRuleList an abstract base. Add concrete subclasses for dealing with the underlying storage.
+        - Instantiate CSSRuleLists on-demand.
+        - Make CSSStyleSheet.cssRules always return the same object instance. This matches Firefox and the rest
+          of our CSSOM implementation. Tested by fast/dom/gc-9.html.
+          
+        The patch decouples internals from the external API. It simplifies the child rule ownership and reduces 
+        indirection. Memory use of css rules with children is reduced (by a ptr, refcount and heap allocation overhead).
+
+        * css/CSSGrammar.y:
+        * css/CSSMediaRule.cpp:
+        (WebCore::CSSMediaRule::CSSMediaRule):
+        (WebCore::CSSMediaRule::~CSSMediaRule):
+        (WebCore::CSSMediaRule::append):
+        (WebCore::CSSMediaRule::insertRule):
+        (WebCore::CSSMediaRule::deleteRule):
+        (WebCore::CSSMediaRule::cssText):
+        (WebCore::CSSMediaRule::cssRules):
+        * css/CSSMediaRule.h:
+        (WebCore::CSSMediaRule::create):
+        (CSSMediaRule):
+        (WebCore::CSSMediaRule::ruleCount):
+        (WebCore::CSSMediaRule::ruleAt):
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::createMediaRule):
+        (WebCore::CSSParser::createRuleList):
+        (WebCore::CSSParser::createRegionRule):
+        * css/CSSParser.h:
+        (WebCore):
+        * css/CSSRuleList.cpp:
+        (WebCore):
+        (WebCore::StaticCSSRuleList::StaticCSSRuleList):
+        (WebCore::StaticCSSRuleList::~StaticCSSRuleList):
+        (WebCore::StaticCSSRuleList::deref):
+        (WebCore::StaticCSSRuleList::item):        
+        * css/CSSRuleList.h:
+        (CSSRuleList):
+
+            Turn CSSRuleList into abstract interface.
+                    
+        (StaticCSSRuleList):
+        (WebCore::StaticCSSRuleList::create):
+        (WebCore::StaticCSSRuleList::ref):
+        (WebCore::StaticCSSRuleList::rules):
+        (WebCore::StaticCSSRuleList::styleSheet):
+        (WebCore::StaticCSSRuleList::length):
+        
+            Concrete implementation for fixed list of rules.
+    
+        (WebCore):
+        (LiveCSSRuleList):
+        (WebCore::LiveCSSRuleList::LiveCSSRuleList):
+        (WebCore::LiveCSSRuleList::ref):
+        (WebCore::LiveCSSRuleList::deref):
+        (WebCore::LiveCSSRuleList::length):
+        (WebCore::LiveCSSRuleList::item):
+        (WebCore::LiveCSSRuleList::styleSheet):
+        
+            Concrete implemenation for live list backed by the underlying container rule.
+            LiveCSSRuleList is owned by the underlying rule. Refcount is forwarded. 
+        
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::sortAndTransferMatchedRules):
+        (WebCore::CSSStyleSelector::collectMatchingRulesForList):
+        * css/CSSStyleSelector.h:
+        (CSSStyleSelector):
+        * css/CSSStyleSheet.cpp:
+        
+            The same scheme for CSSStyleSheet.cssRule as with container rules.
+        
+        (StyleSheetCSSRuleList):
+        (WebCore::StyleSheetCSSRuleList::StyleSheetCSSRuleList):
+        (WebCore::StyleSheetCSSRuleList::ref):
+        (WebCore::StyleSheetCSSRuleList::deref):
+        (WebCore::StyleSheetCSSRuleList::length):
+        (WebCore::StyleSheetCSSRuleList::item):
+        (WebCore::StyleSheetCSSRuleList::styleSheet):
+        (WebCore):
+        (WebCore::CSSStyleSheet::rules):
+        (WebCore::CSSStyleSheet::cssRules):
+        * css/CSSStyleSheet.h:
+        (CSSStyleSheet):
+        * css/WebKitCSSKeyframesRule.cpp:
+        (WebCore::WebKitCSSKeyframesRule::WebKitCSSKeyframesRule):
+        (WebCore::WebKitCSSKeyframesRule::~WebKitCSSKeyframesRule):
+        (WebCore):
+        (WebCore::WebKitCSSKeyframesRule::append):
+        (WebCore::WebKitCSSKeyframesRule::deleteRule):
+        (WebCore::WebKitCSSKeyframesRule::findRule):
+        (WebCore::WebKitCSSKeyframesRule::findRuleIndex):
+        (WebCore::WebKitCSSKeyframesRule::cssText):
+        (WebCore::WebKitCSSKeyframesRule::cssRules):
+        * css/WebKitCSSKeyframesRule.h:
+        (WebKitCSSKeyframesRule):
+        (WebCore::WebKitCSSKeyframesRule::ruleCount):
+        (WebCore::WebKitCSSKeyframesRule::ruleAt):
+        (WebCore::WebKitCSSKeyframesRule::length):
+        (WebCore::WebKitCSSKeyframesRule::item):
+        * css/WebKitCSSRegionRule.cpp:
+        (WebCore::WebKitCSSRegionRule::WebKitCSSRegionRule):
+        (WebCore::WebKitCSSRegionRule::~WebKitCSSRegionRule):
+        (WebCore::WebKitCSSRegionRule::cssText):
+        (WebCore::WebKitCSSRegionRule::cssRules):
+        * css/WebKitCSSRegionRule.h:
+        * inspector/InspectorStyleSheet.cpp:
+        (WebCore::asCSSRuleList):
+        (WebCore::InspectorStyleSheet::addRule):
+        (WebCore::InspectorStyleSheet::buildObjectForStyleSheet):
+
 2012-03-25  Kentaro Hara  <haraken@chromium.org>
 
         Remove duplicated GenerateConditionalString() from code generators
diff --git a/Source/WebCore/css/CSSGrammar.y b/Source/WebCore/css/CSSGrammar.y
index ece6d93..f032987 100644
--- a/Source/WebCore/css/CSSGrammar.y
+++ b/Source/WebCore/css/CSSGrammar.y
@@ -28,7 +28,6 @@
 #include "CSSParser.h"
 #include "CSSPrimitiveValue.h"
 #include "CSSPropertyNames.h"
-#include "CSSRuleList.h"
 #include "CSSSelector.h"
 #include "CSSSelectorList.h"
 #include "CSSStyleSheet.h"
@@ -69,7 +68,7 @@
     CSSParserString string;
 
     CSSRule* rule;
-    CSSRuleList* ruleList;
+    Vector<RefPtr<CSSRule> >* ruleList;
     CSSParserSelector* selector;
     Vector<OwnPtr<CSSParserSelector> >* selectorList;
     CSSSelector::MarginBoxType marginBox;
diff --git a/Source/WebCore/css/CSSMediaRule.cpp b/Source/WebCore/css/CSSMediaRule.cpp
index baf19b6..423c308 100644
--- a/Source/WebCore/css/CSSMediaRule.cpp
+++ b/Source/WebCore/css/CSSMediaRule.cpp
@@ -24,19 +24,22 @@
 #include "CSSMediaRule.h"
 
 #include "CSSParser.h"
+#include "CSSRuleList.h"
 #include "ExceptionCode.h"
+#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
-CSSMediaRule::CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList> media, PassRefPtr<CSSRuleList> rules)
+CSSMediaRule::CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList> media, Vector<RefPtr<CSSRule> >& adoptRules)
     : CSSRule(parent, CSSRule::MEDIA_RULE)
     , m_lstMedia(media)
-    , m_lstCSSRules(rules)
 {
+    m_childRules.swap(adoptRules);
+
     m_lstMedia->setParentStyleSheet(parent);
-    int length = m_lstCSSRules->length();
-    for (int i = 0; i < length; i++)
-        m_lstCSSRules->item(i)->setParentRule(this);
+    unsigned size = m_childRules.size();
+    for (unsigned i = 0; i < size; i++)
+        m_childRules[i]->setParentRule(this);
 }
 
 CSSMediaRule::~CSSMediaRule()
@@ -44,9 +47,9 @@
     if (m_lstMedia)
         m_lstMedia->setParentStyleSheet(0);
 
-    int length = m_lstCSSRules->length();
-    for (int i = 0; i < length; i++)
-        m_lstCSSRules->item(i)->setParentRule(0);
+    unsigned size = m_childRules.size();
+    for (unsigned i = 0; i < size; i++)
+        m_childRules[i]->setParentRule(0);
 }
 
 unsigned CSSMediaRule::append(CSSRule* rule)
@@ -55,12 +58,13 @@
         return 0;
 
     rule->setParentRule(this);
-    return m_lstCSSRules->insertRule(rule, m_lstCSSRules->length());
+    m_childRules.append(rule);
+    return m_childRules.size() - 1;
 }
 
 unsigned CSSMediaRule::insertRule(const String& rule, unsigned index, ExceptionCode& ec)
 {
-    if (index > m_lstCSSRules->length()) {
+    if (index > m_childRules.size()) {
         // INDEX_SIZE_ERR: Raised if the specified index is not a valid insertion point.
         ec = INDEX_SIZE_ERR;
         return 0;
@@ -87,25 +91,25 @@
     }
 
     newRule->setParentRule(this);
-    unsigned returnedIndex = m_lstCSSRules->insertRule(newRule.get(), index);
+    m_childRules.insert(index, newRule.get());
 
     if (CSSStyleSheet* styleSheet = parentStyleSheet())
         styleSheet->styleSheetChanged();
 
-    return returnedIndex;
+    return index;
 }
 
 void CSSMediaRule::deleteRule(unsigned index, ExceptionCode& ec)
 {
-    if (index >= m_lstCSSRules->length()) {
+    if (index >= m_childRules.size()) {
         // INDEX_SIZE_ERR: Raised if the specified index does not correspond to a
         // rule in the media rule list.
         ec = INDEX_SIZE_ERR;
         return;
     }
 
-    m_lstCSSRules->item(index)->setParentRule(0);
-    m_lstCSSRules->deleteRule(index);
+    m_childRules[index]->setParentRule(0);
+    m_childRules.remove(index);
 
     if (CSSStyleSheet* styleSheet = parentStyleSheet())
         styleSheet->styleSheetChanged();
@@ -113,18 +117,29 @@
 
 String CSSMediaRule::cssText() const
 {
-    String result = "@media ";
+    StringBuilder result;
+    result.append("@media ");
     if (m_lstMedia) {
-        result += m_lstMedia->mediaText();
-        result += " ";
+        result.append(m_lstMedia->mediaText());
+        result.append(" ");
     }
-    result += "{ \n";
+    result.append("{ \n");
+    
+    for (unsigned i = 0; i < m_childRules.size(); ++i) {
+        result.append("  ");
+        result.append(m_childRules[i]->cssText());
+        result.append("\n");
+    }
 
-    if (m_lstCSSRules)
-        result += m_lstCSSRules->rulesText();
+    result.append("}");
+    return result.toString();
+}
 
-    result += "}";
-    return result;
+CSSRuleList* CSSMediaRule::cssRules()
+{
+    if (!m_ruleListCSSOMWrapper)
+        m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSMediaRule>(this));
+    return m_ruleListCSSOMWrapper.get();
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/CSSMediaRule.h b/Source/WebCore/css/CSSMediaRule.h
index a591192..7410302 100644
--- a/Source/WebCore/css/CSSMediaRule.h
+++ b/Source/WebCore/css/CSSMediaRule.h
@@ -24,7 +24,6 @@
 #define CSSMediaRule_h
 
 #include "CSSRule.h"
-#include "CSSRuleList.h"
 #include "MediaList.h"
 #include "PlatformString.h" // needed so bindings will compile
 
@@ -34,14 +33,14 @@
 
 class CSSMediaRule : public CSSRule {
 public:
-    static PassRefPtr<CSSMediaRule> create(CSSStyleSheet* parent, PassRefPtr<MediaList> media, PassRefPtr<CSSRuleList> rules)
+    static PassRefPtr<CSSMediaRule> create(CSSStyleSheet* parent, PassRefPtr<MediaList> media, Vector<RefPtr<CSSRule> >& adoptRules)
     {
-        return adoptRef(new CSSMediaRule(parent, media, rules));
+        return adoptRef(new CSSMediaRule(parent, media, adoptRules));
     }
     ~CSSMediaRule();
 
     MediaList* media() const { return m_lstMedia.get(); }
-    CSSRuleList* cssRules() { return m_lstCSSRules.get(); }
+    CSSRuleList* cssRules();
 
     unsigned insertRule(const String& rule, unsigned index, ExceptionCode&);
     void deleteRule(unsigned index, ExceptionCode&);
@@ -50,12 +49,17 @@
 
     // Not part of the CSSOM
     unsigned append(CSSRule*);
+    
+    unsigned ruleCount() const { return m_childRules.size(); }
+    CSSRule* ruleAt(unsigned index) const { return m_childRules[index].get(); }
 
 private:
-    CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList>, PassRefPtr<CSSRuleList>);
+    CSSMediaRule(CSSStyleSheet* parent, PassRefPtr<MediaList>, Vector<RefPtr<CSSRule> >& adoptRules);
 
     RefPtr<MediaList> m_lstMedia;
-    RefPtr<CSSRuleList> m_lstCSSRules;
+    Vector<RefPtr<CSSRule> > m_childRules;
+    
+    OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index dc758dc..339135f 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -52,7 +52,6 @@
 #include "CSSPropertyNames.h"
 #include "CSSPropertySourceData.h"
 #include "CSSReflectValue.h"
-#include "CSSRuleList.h"
 #include "CSSSelector.h"
 #include "CSSStyleRule.h"
 #include "CSSStyleSheet.h"
@@ -9011,21 +9010,21 @@
     return result;
 }
 
-CSSRule* CSSParser::createMediaRule(MediaList* media, CSSRuleList* rules)
+CSSRule* CSSParser::createMediaRule(MediaList* media, RuleList* rules)
 {
     if (!media || !rules || !m_styleSheet)
         return 0;
     m_allowImportRules = m_allowNamespaceDeclarations = false;
-    RefPtr<CSSMediaRule> rule = CSSMediaRule::create(m_styleSheet, media, rules);
+    RefPtr<CSSMediaRule> rule = CSSMediaRule::create(m_styleSheet, media, *rules);
     CSSMediaRule* result = rule.get();
     m_parsedRules.append(rule.release());
     return result;
 }
 
-CSSRuleList* CSSParser::createRuleList()
+CSSParser::RuleList* CSSParser::createRuleList()
 {
-    RefPtr<CSSRuleList> list = CSSRuleList::create();
-    CSSRuleList* listPtr = list.get();
+    OwnPtr<RuleList> list = adoptPtr(new RuleList);
+    RuleList* listPtr = list.get();
 
     m_parsedRuleLists.append(list.release());
     return listPtr;
@@ -9173,14 +9172,14 @@
         m_reusableRegionSelectorVector.swap(*selectors);
 }
 
-CSSRule* CSSParser::createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, CSSRuleList* rules)
+CSSRule* CSSParser::createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, RuleList* rules)
 {
     if (!cssRegionsEnabled() || !regionSelector || !rules)
         return 0;
 
     m_allowImportRules = m_allowNamespaceDeclarations = false;
 
-    RefPtr<WebKitCSSRegionRule> regionRule = WebKitCSSRegionRule::create(m_styleSheet, regionSelector, rules);
+    RefPtr<WebKitCSSRegionRule> regionRule = WebKitCSSRegionRule::create(m_styleSheet, regionSelector, *rules);
 
     WebKitCSSRegionRule* result = regionRule.get();
     m_parsedRules.append(regionRule.release());
diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h
index bf48e97..7b715de 100644
--- a/Source/WebCore/css/CSSParser.h
+++ b/Source/WebCore/css/CSSParser.h
@@ -49,7 +49,6 @@
 class CSSValuePool;
 class CSSProperty;
 class CSSRule;
-class CSSRuleList;
 class CSSSelectorList;
 class CSSStyleSheet;
 class CSSValue;
@@ -248,12 +247,14 @@
     CSSRule* createImportRule(const CSSParserString&, MediaList*);
     WebKitCSSKeyframeRule* createKeyframeRule(CSSParserValueList*);
     WebKitCSSKeyframesRule* createKeyframesRule();
-    CSSRule* createMediaRule(MediaList*, CSSRuleList*);
-    CSSRuleList* createRuleList();
+
+    typedef Vector<RefPtr<CSSRule> > RuleList;
+    CSSRule* createMediaRule(MediaList*, RuleList*);
+    RuleList* createRuleList();
     CSSRule* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors);
     CSSRule* createFontFaceRule();
     CSSRule* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
-    CSSRule* createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, CSSRuleList* rules);
+    CSSRule* createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, RuleList* rules);
     CSSRule* createMarginAtRule(CSSSelector::MarginBoxType marginBox);
     void startDeclarationsForMarginBox();
     void endDeclarationsForMarginBox();
@@ -399,7 +400,7 @@
 
     Vector<RefPtr<CSSRule> > m_parsedRules;
     Vector<RefPtr<MediaList> > m_parsedMediaLists;
-    Vector<RefPtr<CSSRuleList> > m_parsedRuleLists;
+    Vector<OwnPtr<RuleList> > m_parsedRuleLists;
     HashSet<CSSParserSelector*> m_floatingSelectors;
     HashSet<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors;
     HashSet<CSSParserValueList*> m_floatingValueLists;
diff --git a/Source/WebCore/css/CSSRuleList.cpp b/Source/WebCore/css/CSSRuleList.cpp
index 6b080ef..a158d6f 100644
--- a/Source/WebCore/css/CSSRuleList.cpp
+++ b/Source/WebCore/css/CSSRuleList.cpp
@@ -1,7 +1,7 @@
 /**
  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
  * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2002, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2002, 2005, 2006, 2012 Apple Computer, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -24,7 +24,6 @@
 
 #include "CSSRule.h"
 #include "CSSStyleSheet.h"
-#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
@@ -32,80 +31,24 @@
 {
 }
 
-CSSRuleList::CSSRuleList(CSSStyleSheet* styleSheet, bool omitCharsetRules)
-    : m_styleSheet(styleSheet)
-{
-    if (styleSheet && omitCharsetRules) {
-        m_styleSheet = 0;
-        for (unsigned i = 0; i < styleSheet->length(); ++i) {
-            CSSRule* rule = styleSheet->item(i);
-            if (!rule->isCharsetRule())
-                append(static_cast<CSSRule*>(rule));
-        }
-    }
-}
-
 CSSRuleList::~CSSRuleList()
 {
 }
 
-unsigned CSSRuleList::length() const
-{
-    return m_styleSheet ? m_styleSheet->length() : m_lstCSSRules.size();
+StaticCSSRuleList::StaticCSSRuleList() 
+    : m_refCount(1)
+{ 
 }
 
-CSSRule* CSSRuleList::item(unsigned index) const
+StaticCSSRuleList::~StaticCSSRuleList()
 {
-    if (m_styleSheet)
-        return m_styleSheet->item(index);
-
-    if (index < m_lstCSSRules.size())
-        return m_lstCSSRules[index].get();
-    return 0;
 }
 
-void CSSRuleList::deleteRule(unsigned index)
-{
-    ASSERT(!m_styleSheet);
-
-    if (index >= m_lstCSSRules.size())
-        return;
-
-    m_lstCSSRules.remove(index);
-}
-
-void CSSRuleList::append(CSSRule* rule)
-{
-    ASSERT(!m_styleSheet);
-
-    if (!rule)
-        return;
-
-    m_lstCSSRules.append(rule);
-}
-
-unsigned CSSRuleList::insertRule(CSSRule* rule, unsigned index)
-{
-    ASSERT(!m_styleSheet);
-
-    if (!rule || index > m_lstCSSRules.size())
-        return 0;
-
-    m_lstCSSRules.insert(index, rule);
-    return index;
-}
-
-String CSSRuleList::rulesText() const
-{
-    StringBuilder result;
-
-    for (unsigned index = 0; index < length(); ++index) {
-        result.append("  ");
-        result.append(item(index)->cssText());
-        result.append("\n");
-    }
-
-    return result.toString();
+void StaticCSSRuleList::deref()
+{ 
+    ASSERT(m_refCount);
+    if (!--m_refCount)
+        delete this;
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/CSSRuleList.h b/Source/WebCore/css/CSSRuleList.h
index ea52c86..c71ceea 100644
--- a/Source/WebCore/css/CSSRuleList.h
+++ b/Source/WebCore/css/CSSRuleList.h
@@ -1,7 +1,7 @@
 /*
  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
  * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ * Copyright (C) 2002, 2006, 2012 Apple Computer, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -33,37 +33,60 @@
 class CSSRule;
 class CSSStyleSheet;
 
-class CSSRuleList : public RefCounted<CSSRuleList> {
+class CSSRuleList {
+    WTF_MAKE_NONCOPYABLE(CSSRuleList); WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassRefPtr<CSSRuleList> create(CSSStyleSheet* styleSheet, bool omitCharsetRules = false)
-    {
-        return adoptRef(new CSSRuleList(styleSheet, omitCharsetRules));
-    }
-    static PassRefPtr<CSSRuleList> create()
-    {
-        return adoptRef(new CSSRuleList);
-    }
-    ~CSSRuleList();
+    virtual ~CSSRuleList();
 
-    unsigned length() const;
-    CSSRule* item(unsigned index) const;
+    virtual void ref() = 0;
+    virtual void deref() = 0;
 
-    // FIXME: Not part of the CSSOM. Only used by @media and @-webkit-keyframes rules.
-    unsigned insertRule(CSSRule*, unsigned index);
-    void deleteRule(unsigned index);
-
-    void append(CSSRule*);
-
-    CSSStyleSheet* styleSheet() { return m_styleSheet.get(); }
-
-    String rulesText() const;
-
-private:
+    virtual unsigned length() const = 0;
+    virtual CSSRule* item(unsigned index) const = 0;
+    
+    virtual CSSStyleSheet* styleSheet() const = 0;
+    
+protected:
     CSSRuleList();
-    CSSRuleList(CSSStyleSheet*, bool omitCharsetRules);
+};
 
-    RefPtr<CSSStyleSheet> m_styleSheet;
-    Vector<RefPtr<CSSRule> > m_lstCSSRules; // FIXME: Want to eliminate, but used by IE rules() extension and still used by media rules.
+class StaticCSSRuleList : public CSSRuleList {
+public:
+    static PassRefPtr<StaticCSSRuleList> create() { return adoptRef(new StaticCSSRuleList()); }
+
+    virtual void ref() { ++m_refCount; }
+    virtual void deref();
+
+    Vector<RefPtr<CSSRule> >& rules() { return m_rules; }
+    
+    virtual CSSStyleSheet* styleSheet() const { return 0; }
+
+private:    
+    StaticCSSRuleList();
+    ~StaticCSSRuleList();
+
+    virtual unsigned length() const { return m_rules.size(); }
+    virtual CSSRule* item(unsigned index) const { return index < m_rules.size() ? m_rules[index].get() : 0; }
+
+    Vector<RefPtr<CSSRule> > m_rules;
+    unsigned m_refCount;
+};
+
+// The rule owns the live list.
+template <class Rule>
+class LiveCSSRuleList : public CSSRuleList {
+public:
+    LiveCSSRuleList(Rule* rule) : m_rule(rule) { }
+    
+    virtual void ref() { m_rule->ref(); }
+    virtual void deref() { m_rule->deref(); }
+    
+private:
+    virtual unsigned length() const { return m_rule->ruleCount(); }
+    virtual CSSRule* item(unsigned index) const  { return index < m_rule->ruleCount() ? m_rule->ruleAt(index) : 0; }
+    virtual CSSStyleSheet* styleSheet() const { return m_rule->parentStyleSheet(); }
+    
+    Rule* m_rule;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp
index c5fb2de..27bf7c6 100644
--- a/Source/WebCore/css/CSSStyleSelector.cpp
+++ b/Source/WebCore/css/CSSStyleSelector.cpp
@@ -858,9 +858,9 @@
 
     if (m_checker.isCollectingRulesOnly()) {
         if (!m_ruleList)
-            m_ruleList = CSSRuleList::create();
+            m_ruleList = StaticCSSRuleList::create();
         for (unsigned i = 0; i < m_matchedRules.size(); ++i)
-            m_ruleList->append(m_matchedRules[i]->rule()->ensureCSSStyleRule());
+            m_ruleList->rules().append(m_matchedRules[i]->rule()->ensureCSSStyleRule());
         return;
     }
 
@@ -1698,15 +1698,15 @@
     if (it == m_keyframesRuleMap.end())
         return;
 
-    const WebKitCSSKeyframesRule* rule = it->second.get();
+    const WebKitCSSKeyframesRule* keyframesRule = it->second.get();
 
     // Construct and populate the style for each keyframe
-    for (unsigned i = 0; i < rule->length(); ++i) {
+    for (unsigned i = 0; i < keyframesRule->ruleCount(); ++i) {
         // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
         initElement(e);
         initForStyleResolve(e);
 
-        const WebKitCSSKeyframeRule* keyframeRule = rule->item(i);
+        const WebKitCSSKeyframeRule* keyframeRule = keyframesRule->ruleAt(i);
 
         KeyframeValue keyframe(0, 0);
         keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule, keyframe));
@@ -2422,7 +2422,7 @@
     m_pageRules.append(rule);
 }
 
-void RuleSet::addRegionRule(WebKitCSSRegionRule* rule)
+void RuleSet::addRegionRule(WebKitCSSRegionRule* regionRule)
 {
     RuleSet* regionRuleSet = new RuleSet;
     // The region rule set should take into account the position inside the parent rule set.
@@ -2431,15 +2431,14 @@
     regionRuleSet->m_ruleCount = m_ruleCount;
 
     // Collect the region rules into a rule set
-    CSSRuleList* regionStylingRules = rule->cssRules();
-    unsigned rulesSize = regionStylingRules->length();
+    unsigned rulesSize = regionRule->ruleCount();
     for (unsigned i = 0; i < rulesSize; ++i) {
-        CSSRule* regionStylingRule = regionStylingRules->item(i);
+        CSSRule* regionStylingRule = regionRule->ruleAt(i);
         if (regionStylingRule->isStyleRule())
             regionRuleSet->addStyleRule(static_cast<CSSStyleRule*>(regionStylingRule)->styleRule(), true, true);
     }
 
-    m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(rule->selectorList().first(), regionRuleSet));
+    m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(regionRule->selectorList().first(), regionRuleSet));
 }
 
 void RuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluator& medium, CSSStyleSelector* styleSelector, const ContainerNode* scope)
@@ -2465,31 +2464,30 @@
                 addRulesFromSheet(import->styleSheet(), medium, styleSelector, scope);
         }
         else if (rule->isMediaRule()) {
-            CSSMediaRule* r = static_cast<CSSMediaRule*>(rule);
-            CSSRuleList* rules = r->cssRules();
+            CSSMediaRule* mediaRule = static_cast<CSSMediaRule*>(rule);
 
-            if ((!r->media() || medium.eval(r->media(), styleSelector)) && rules) {
+            if ((!mediaRule->media() || medium.eval(mediaRule->media(), styleSelector)) && mediaRule->ruleCount()) {
                 // Traverse child elements of the @media rule.
-                for (unsigned j = 0; j < rules->length(); j++) {
-                    CSSRule *childItem = rules->item(j);
-                    if (childItem->isStyleRule())
-                        addStyleRule(static_cast<CSSStyleRule*>(childItem)->styleRule(), !scope);
-                    else if (childItem->isPageRule())
-                        addPageRule(static_cast<CSSPageRule*>(childItem));
-                    else if (childItem->isFontFaceRule() && styleSelector) {
+                for (unsigned j = 0; j < mediaRule->ruleCount(); j++) {
+                    CSSRule* childRule = mediaRule->ruleAt(j);
+                    if (childRule->isStyleRule())
+                        addStyleRule(static_cast<CSSStyleRule*>(childRule)->styleRule(), !scope);
+                    else if (childRule->isPageRule())
+                        addPageRule(static_cast<CSSPageRule*>(childRule));
+                    else if (childRule->isFontFaceRule() && styleSelector) {
                         // Add this font face to our set.
                         // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
                         if (scope)
                             continue;
-                        const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childItem);
+                        const CSSFontFaceRule* fontFaceRule = static_cast<CSSFontFaceRule*>(childRule);
                         styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
                         styleSelector->invalidateMatchedPropertiesCache();
-                    } else if (childItem->isKeyframesRule() && styleSelector) {
+                    } else if (childRule->isKeyframesRule() && styleSelector) {
                         // Add this keyframe rule to our set.
                         // FIXME(BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment.
                         if (scope)
                             continue;
-                        styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childItem));
+                        styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childRule));
                     }
                 }   // for rules
             }   // if rules
diff --git a/Source/WebCore/css/CSSStyleSelector.h b/Source/WebCore/css/CSSStyleSelector.h
index 73ee184..1ba0118 100644
--- a/Source/WebCore/css/CSSStyleSelector.h
+++ b/Source/WebCore/css/CSSStyleSelector.h
@@ -42,12 +42,12 @@
 class CSSPageRule;
 class CSSPrimitiveValue;
 class CSSProperty;
+class CSSRuleList;
 class CSSFontFace;
 class CSSFontFaceRule;
 class CSSImageGeneratorValue;
 class CSSImageSetValue;
 class CSSImageValue;
-class CSSRuleList;
 class CSSSelector;
 class CSSStyleApplyProperty;
 class CSSStyleSheet;
@@ -68,6 +68,7 @@
 class RuleData;
 class RuleSet;
 class Settings;
+class StaticCSSRuleList;
 class StyleImage;
 class StylePendingImage;
 class StylePropertySet;
@@ -436,7 +437,7 @@
     // merge sorting.
     Vector<const RuleData*, 32> m_matchedRules;
 
-    RefPtr<CSSRuleList> m_ruleList;
+    RefPtr<StaticCSSRuleList> m_ruleList;
 
     HashSet<int> m_pendingImageProperties; // Hash of CSSPropertyIDs
 
diff --git a/Source/WebCore/css/CSSStyleSheet.cpp b/Source/WebCore/css/CSSStyleSheet.cpp
index 4cd82af..63d4de6 100644
--- a/Source/WebCore/css/CSSStyleSheet.cpp
+++ b/Source/WebCore/css/CSSStyleSheet.cpp
@@ -40,6 +40,22 @@
 
 namespace WebCore {
 
+class StyleSheetCSSRuleList : public CSSRuleList {
+public:
+    StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { }
+    
+private:
+    virtual void ref() { m_styleSheet->ref(); }
+    virtual void deref() { m_styleSheet->deref(); }
+    
+    virtual unsigned length() const { return m_styleSheet->length(); }
+    virtual CSSRule* item(unsigned index) const { return m_styleSheet->item(index); }
+    
+    virtual CSSStyleSheet* styleSheet() const { return m_styleSheet; }
+    
+    CSSStyleSheet* m_styleSheet;
+};
+
 #if !ASSERT_DISABLED
 static bool isAcceptableCSSStyleSheetParent(Node* parentNode)
 {
@@ -102,6 +118,22 @@
 {
     m_children.remove(index);
 }
+    
+PassRefPtr<CSSRuleList> CSSStyleSheet::rules()
+{
+    KURL url = finalURL();
+    Document* document = findDocument();
+    if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url))
+        return 0;
+    // IE behavior.
+    RefPtr<StaticCSSRuleList> nonCharsetRules = StaticCSSRuleList::create();
+    for (unsigned i = 0; i < m_children.size(); ++i) {
+        if (m_children[i]->isCharsetRule())
+            continue;
+        nonCharsetRules->rules().append(m_children[i]);
+    }
+    return nonCharsetRules.release();
+}
 
 unsigned CSSStyleSheet::insertRule(const String& rule, unsigned index, ExceptionCode& ec)
 {
@@ -159,13 +191,15 @@
     return addRule(selector, style, m_children.size(), ec);
 }
 
-PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules(bool omitCharsetRules)
+PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules()
 {
     KURL url = finalURL();
     Document* document = findDocument();
     if (!url.isEmpty() && document && !document->securityOrigin()->canRequest(url))
         return 0;
-    return CSSRuleList::create(this, omitCharsetRules);
+    if (!m_ruleListCSSOMWrapper)
+        m_ruleListCSSOMWrapper = adoptPtr(new StyleSheetCSSRuleList(this));
+    return m_ruleListCSSOMWrapper.get();
 }
 
 void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec)
diff --git a/Source/WebCore/css/CSSStyleSheet.h b/Source/WebCore/css/CSSStyleSheet.h
index e734919..0f139a9 100644
--- a/Source/WebCore/css/CSSStyleSheet.h
+++ b/Source/WebCore/css/CSSStyleSheet.h
@@ -21,7 +21,6 @@
 #ifndef CSSStyleSheet_h
 #define CSSStyleSheet_h
 
-#include "CSSRuleList.h"
 #include "StyleSheet.h"
 
 namespace WebCore {
@@ -29,6 +28,7 @@
 struct CSSNamespace;
 class CSSParser;
 class CSSRule;
+class CSSRuleList;
 class CachedCSSStyleSheet;
 class CachedResourceLoader;
 class Document;
@@ -67,12 +67,12 @@
         return static_cast<CSSStyleSheet*>(parentSheet);
     }
 
-    PassRefPtr<CSSRuleList> cssRules(bool omitCharsetRules = false);
+    PassRefPtr<CSSRuleList> cssRules();
     unsigned insertRule(const String& rule, unsigned index, ExceptionCode&);
     void deleteRule(unsigned index, ExceptionCode&);
 
     // IE Extensions
-    PassRefPtr<CSSRuleList> rules() { return cssRules(true); }
+    PassRefPtr<CSSRuleList> rules();
     int addRule(const String& selector, const String& style, int index, ExceptionCode&);
     int addRule(const String& selector, const String& style, ExceptionCode&);
     void removeRule(unsigned index, ExceptionCode& ec) { deleteRule(index, ec); }
@@ -132,6 +132,8 @@
     bool m_isUserStyleSheet : 1;
     bool m_hasSyntacticallyValidCSSHeader : 1;
     bool m_didLoadErrorOccur : 1;
+    
+    OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
 };
 
 } // namespace
diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
index 39492f5..e39986e 100644
--- a/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
+++ b/Source/WebCore/css/WebKitCSSKeyframesRule.cpp
@@ -31,21 +31,19 @@
 #include "StylePropertySet.h"
 #include "StyleSheet.h"
 #include "WebKitCSSKeyframeRule.h"
+#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
 WebKitCSSKeyframesRule::WebKitCSSKeyframesRule(CSSStyleSheet* parent)
     : CSSRule(parent, CSSRule::WEBKIT_KEYFRAMES_RULE)
-    , m_lstCSSRules(CSSRuleList::create())
 {
 }
 
 WebKitCSSKeyframesRule::~WebKitCSSKeyframesRule()
 {
-    for (unsigned i = 0; i < length(); ++i) {
-        WebKitCSSKeyframeRule* rule = item(i);
-        rule->setParentRule(0);
-    }
+    for (unsigned i = 0; i < m_childRules.size(); ++i)
+        m_childRules[i]->setParentRule(0);
 }
 
 void WebKitCSSKeyframesRule::setName(const String& name)
@@ -58,26 +56,12 @@
         styleSheet->styleSheetChanged();
 }
 
-WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index)
-{
-    CSSRule* rule = m_lstCSSRules->item(index);
-    ASSERT(rule->isKeyframeRule());
-    return static_cast<WebKitCSSKeyframeRule*>(rule);
-}
-
-const WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index) const
-{
-    const CSSRule* rule = m_lstCSSRules->item(index);
-    ASSERT(rule->isKeyframeRule());
-    return static_cast<const WebKitCSSKeyframeRule*>(rule);
-}
-
 void WebKitCSSKeyframesRule::append(WebKitCSSKeyframeRule* rule)
 {
     if (!rule)
         return;
 
-    m_lstCSSRules->append(rule);
+    m_childRules.append(rule);
     rule->setParentRule(this);
 }
 
@@ -97,13 +81,13 @@
 
     WebKitCSSKeyframeRule* rule = item(i);
     rule->setParentRule(0);
-    m_lstCSSRules->deleteRule(i);
+    m_childRules.remove(i);
 }
 
 WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::findRule(const String& s)
 {
     int i = findRuleIndex(s);
-    return (i >= 0) ? item(i) : 0;
+    return (i >= 0) ? m_childRules[i].get() : 0;
 }
 
 int WebKitCSSKeyframesRule::findRuleIndex(const String& key) const
@@ -116,8 +100,8 @@
     else
         percentageString = key;
 
-    for (unsigned i = 0; i < length(); ++i) {
-        if (item(i)->keyText() == percentageString)
+    for (unsigned i = 0; i < m_childRules.size(); ++i) {
+        if (m_childRules[i]->keyText() == percentageString)
             return i;
     }
 
@@ -126,15 +110,26 @@
 
 String WebKitCSSKeyframesRule::cssText() const
 {
-    String result = "@-webkit-keyframes ";
-    result += m_name;
-    result += " { \n";
+    StringBuilder result;
+    result.append("@-webkit-keyframes ");
+    result.append(m_name);
+    result.append(" { \n");
 
-    if (m_lstCSSRules)
-        result += m_lstCSSRules->rulesText();
+    for (unsigned i = 0; i < m_childRules.size(); ++i) {
+        result.append("  ");
+        result.append(m_childRules[i]->cssText());
+        result.append("\n");
+    }
 
-    result += "}";
-    return result;
+    result.append("}");
+    return result.toString();
+}
+    
+CSSRuleList* WebKitCSSKeyframesRule::cssRules()
+{
+    if (!m_ruleListCSSOMWrapper)
+        m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<WebKitCSSKeyframesRule>(this));
+    return m_ruleListCSSOMWrapper.get();
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.h b/Source/WebCore/css/WebKitCSSKeyframesRule.h
index b1a1b8f..f76eddc 100644
--- a/Source/WebCore/css/WebKitCSSKeyframesRule.h
+++ b/Source/WebCore/css/WebKitCSSKeyframesRule.h
@@ -62,7 +62,7 @@
         m_name = AtomicString(name);
     }
 
-    CSSRuleList* cssRules() { return m_lstCSSRules.get(); }
+    CSSRuleList* cssRules();
 
     void insertRule(const String& rule);
     void deleteRule(const String& key);
@@ -71,18 +71,24 @@
     String cssText() const;
 
     // Not part of the CSSOM.
-    unsigned length() const { return m_lstCSSRules->length(); }
-    WebKitCSSKeyframeRule* item(unsigned index);
-    const WebKitCSSKeyframeRule* item(unsigned index) const;
+    unsigned ruleCount() const { return m_childRules.size(); }
+    WebKitCSSKeyframeRule* ruleAt(unsigned index) const { return m_childRules[index].get(); }
+
     void append(WebKitCSSKeyframeRule*);
+    
+    // For IndexedGetter.
+    unsigned length() const { return ruleCount(); }
+    WebKitCSSKeyframeRule* item(unsigned index) const { return index < ruleCount() ? ruleAt(index) : 0; }
 
 private:
     WebKitCSSKeyframesRule(CSSStyleSheet* parent);
 
     int findRuleIndex(const String& key) const;
 
-    RefPtr<CSSRuleList> m_lstCSSRules;
+    Vector<RefPtr<WebKitCSSKeyframeRule> > m_childRules;
     AtomicString m_name;
+    
+    OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/WebKitCSSRegionRule.cpp b/Source/WebCore/css/WebKitCSSRegionRule.cpp
index cc377c4..7cfaec6 100644
--- a/Source/WebCore/css/WebKitCSSRegionRule.cpp
+++ b/Source/WebCore/css/WebKitCSSRegionRule.cpp
@@ -36,39 +36,50 @@
 #include "CSSRuleList.h"
 #include "Document.h"
 #include "ExceptionCode.h"
+#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
-WebKitCSSRegionRule::WebKitCSSRegionRule(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, PassRefPtr<CSSRuleList> rules)
+WebKitCSSRegionRule::WebKitCSSRegionRule(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, Vector<RefPtr<CSSRule> >& rules)
     : CSSRule(parent, CSSRule::WEBKIT_REGION_RULE)
-    , m_ruleList(rules)
 {
-    for (unsigned index = 0; index < m_ruleList->length(); ++index)
-        m_ruleList->item(index)->setParentRule(this);
-
     m_selectorList.adoptSelectorVector(*selectors);
+    m_childRules.swap(rules);
+    
+    for (unsigned i = 0; i < m_childRules.size(); ++i)
+        m_childRules[i]->setParentRule(this);
 }
 
 WebKitCSSRegionRule::~WebKitCSSRegionRule()
 {
-    for (unsigned index = 0; index < m_ruleList->length(); ++index)
-        m_ruleList->item(index)->setParentRule(0);
+    for (unsigned i = 0; i < m_childRules.size(); ++i)
+        m_childRules[i]->setParentRule(0);
 }
 
 String WebKitCSSRegionRule::cssText() const
 {
-    String result = "@-webkit-region ";
+    StringBuilder result;
+    result.append("@-webkit-region ");
 
     // First add the selectors.
-    result += m_selectorList.selectorsText();
+    result.append(m_selectorList.selectorsText());
 
     // Then add the rules.
-    result += " { \n";
+    result.append(" { \n");
 
-    if (m_ruleList)
-        result += m_ruleList->rulesText();
+    for (unsigned i = 0; i < m_childRules.size(); ++i) {
+        result.append("  ");
+        result.append(m_childRules[i]->cssText());
+        result.append("\n");
+    }
+    result.append("}");
+    return result.toString();
+}
 
-    result += "}";
-    return result;
+CSSRuleList* WebKitCSSRegionRule::cssRules()
+{
+    if (!m_ruleListCSSOMWrapper)
+        m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<WebKitCSSRegionRule>(this));
+    return m_ruleListCSSOMWrapper.get();
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/css/WebKitCSSRegionRule.h b/Source/WebCore/css/WebKitCSSRegionRule.h
index 624ed3f..103b71d 100644
--- a/Source/WebCore/css/WebKitCSSRegionRule.h
+++ b/Source/WebCore/css/WebKitCSSRegionRule.h
@@ -44,7 +44,7 @@
 
 class WebKitCSSRegionRule: public CSSRule {
 public:
-    static PassRefPtr<WebKitCSSRegionRule> create(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, PassRefPtr<CSSRuleList> rules)
+    static PassRefPtr<WebKitCSSRegionRule> create(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, Vector<RefPtr<CSSRule> >& rules)
     {
         return adoptRef(new WebKitCSSRegionRule(parent, selectors, rules));
     }
@@ -53,13 +53,19 @@
 
     String cssText() const;
     const CSSSelectorList& selectorList() const { return m_selectorList; }
-    CSSRuleList* cssRules() const { return m_ruleList.get(); }
+    CSSRuleList* cssRules();
+
+    // Not part of the CSSOM.
+    unsigned ruleCount() const { return m_childRules.size(); }
+    CSSRule* ruleAt(unsigned index) { return m_childRules[index].get(); }
 
 private:
-    WebKitCSSRegionRule(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, PassRefPtr<CSSRuleList> rules);
+    WebKitCSSRegionRule(CSSStyleSheet* parent, Vector<OwnPtr<CSSParserSelector> >* selectors, Vector<RefPtr<CSSRule> >&);
 
     CSSSelectorList m_selectorList;
-    RefPtr<CSSRuleList> m_ruleList;
+    Vector<RefPtr<CSSRule> > m_childRules;
+    
+    OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
 };
 
 }
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index 69eef34..5340cb4e 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -34,7 +34,6 @@
 #include "ChromeClient.h"
 #include "CSSParser.h"
 #include "CSSRule.h"
-#include "CSSRuleList.h"
 #include "CSSSelector.h"
 #include "CSSSelectorList.h"
 #include "CSSStyleRule.h"
diff --git a/Source/WebCore/editing/EditingStyle.cpp b/Source/WebCore/editing/EditingStyle.cpp
index 3a360d8..e67377d 100644
--- a/Source/WebCore/editing/EditingStyle.cpp
+++ b/Source/WebCore/editing/EditingStyle.cpp
@@ -30,6 +30,7 @@
 #include "ApplyStyleCommand.h"
 #include "CSSComputedStyleDeclaration.h"
 #include "CSSParser.h"
+#include "CSSRuleList.h"
 #include "CSSStyleRule.h"
 #include "CSSStyleSelector.h"
 #include "CSSValueKeywords.h"
diff --git a/Source/WebCore/inspector/InspectorStyleSheet.cpp b/Source/WebCore/inspector/InspectorStyleSheet.cpp
index b8f7eae..b05b498 100644
--- a/Source/WebCore/inspector/InspectorStyleSheet.cpp
+++ b/Source/WebCore/inspector/InspectorStyleSheet.cpp
@@ -153,7 +153,7 @@
     if (!styleSheet)
         return 0;
 
-    return CSSRuleList::create(styleSheet);
+    return styleSheet->cssRules();
 }
 
 static PassRefPtr<CSSRuleList> asCSSRuleList(CSSRule* rule)
@@ -769,9 +769,8 @@
     m_pageStyleSheet->addRule(selector, "", ec);
     if (ec)
         return 0;
-    RefPtr<CSSRuleList> rules = CSSRuleList::create(m_pageStyleSheet.get());
-    ASSERT(rules->length());
-    CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(rules->item(rules->length() - 1));
+    ASSERT(m_pageStyleSheet->length());
+    CSSStyleRule* rule = InspectorCSSAgent::asCSSStyleRule(m_pageStyleSheet->item(m_pageStyleSheet->length() - 1));
     ASSERT(rule);
 
     if (styleSheetText.length())
@@ -836,7 +835,7 @@
 
     RefPtr<InspectorObject> result = InspectorObject::create();
     result->setString("styleSheetId", id());
-    RefPtr<CSSRuleList> cssRuleList = CSSRuleList::create(styleSheet);
+    RefPtr<CSSRuleList> cssRuleList = styleSheet->cssRules();
     RefPtr<InspectorArray> cssRules = buildArrayForRuleList(cssRuleList.get());
     result->setArray("rules", cssRules.release());