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());