Diff
Modified: trunk/Source/WebCore/ChangeLog (112280 => 112281)
--- trunk/Source/WebCore/ChangeLog 2012-03-27 17:44:28 UTC (rev 112280)
+++ trunk/Source/WebCore/ChangeLog 2012-03-27 17:46:59 UTC (rev 112281)
@@ -1,3 +1,45 @@
+2012-03-27 Antti Koivisto <[email protected]>
+
+ Construct CSSCharsetRule on CSSOM API access only
+ https://bugs.webkit.org/show_bug.cgi?id=82332
+
+ Reviewed by Andreas Kling.
+
+ Charset is just a string. There is usually no need to construct CSSCharsetRule at all.
+
+ - Make CSS parser to return encoding string instead of CSSCharsetRule object. This
+ string is used for constructing CSSCharsetRule if it is needed (and nothing else,
+ @charset has no effect after string decoding).
+ - Remove internal interface for adding and removing rules. It has no clients.
+
+ * css/CSSGrammar.y:
+ * css/CSSParser.cpp:
+ (WebCore):
+ * css/CSSParser.h:
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::collectMatchingRulesForList):
+ * css/CSSStyleSheet.cpp:
+ (WebCore::CSSStyleSheet::~CSSStyleSheet):
+ (WebCore::CSSStyleSheet::parserAppendRule):
+ (WebCore::CSSStyleSheet::ensureCharsetRule):
+ (WebCore):
+ (WebCore::CSSStyleSheet::length):
+ (WebCore::CSSStyleSheet::item):
+ (WebCore::CSSStyleSheet::clearCharsetRule):
+ (WebCore::CSSStyleSheet::clearRules):
+ (WebCore::CSSStyleSheet::parserSetEncodingFromCharsetRule):
+ (WebCore::CSSStyleSheet::rules):
+ (WebCore::CSSStyleSheet::insertRule):
+ (WebCore::CSSStyleSheet::addRule):
+ (WebCore::CSSStyleSheet::deleteRule):
+ * css/CSSStyleSheet.h:
+ (WebCore):
+ (CSSStyleSheet):
+ (WebCore::CSSStyleSheet::ruleVector):
+ (WebCore::CSSStyleSheet::hasCharsetRule):
+ * inspector/InspectorStyleSheet.cpp:
+ (WebCore::InspectorStyleSheet::reparseStyleSheet):
+
2012-03-27 Stephen White <[email protected]>
[chromium] Fix filter context creation to be more conservative.
Modified: trunk/Source/WebCore/css/CSSGrammar.y (112280 => 112281)
--- trunk/Source/WebCore/css/CSSGrammar.y 2012-03-27 17:44:28 UTC (rev 112280)
+++ trunk/Source/WebCore/css/CSSGrammar.y 2012-03-27 17:46:59 UTC (rev 112281)
@@ -375,9 +375,9 @@
charset:
CHARSET_SYM maybe_space STRING maybe_space ';' {
CSSParser* p = static_cast<CSSParser*>(parser);
- $$ = static_cast<CSSParser*>(parser)->createCharsetRule($3);
- if ($$ && p->m_styleSheet)
- p->m_styleSheet->append($$);
+ if (p->m_styleSheet)
+ p->m_styleSheet->parserSetEncodingFromCharsetRule($3);
+ $$ = 0;
}
| CHARSET_SYM error invalid_block {
}
@@ -397,7 +397,7 @@
| rule_list rule maybe_sgml {
CSSParser* p = static_cast<CSSParser*>(parser);
if ($2 && p->m_styleSheet)
- p->m_styleSheet->append($2);
+ p->m_styleSheet->parserAppendRule($2);
}
;
Modified: trunk/Source/WebCore/css/CSSParser.cpp (112280 => 112281)
--- trunk/Source/WebCore/css/CSSParser.cpp 2012-03-27 17:44:28 UTC (rev 112280)
+++ trunk/Source/WebCore/css/CSSParser.cpp 2012-03-27 17:46:59 UTC (rev 112281)
@@ -28,7 +28,6 @@
#include "CSSAspectRatioValue.h"
#include "CSSBorderImage.h"
#include "CSSCanvasValue.h"
-#include "CSSCharsetRule.h"
#include "CSSCrossfadeValue.h"
#include "CSSCursorImageValue.h"
#include "CSSFlexValue.h"
@@ -8984,16 +8983,6 @@
return result;
}
-CSSRule* CSSParser::createCharsetRule(const CSSParserString& charset)
-{
- if (!m_styleSheet)
- return 0;
- RefPtr<CSSCharsetRule> rule = CSSCharsetRule::create(m_styleSheet, charset);
- CSSCharsetRule* result = rule.get();
- m_parsedRules.append(rule.release());
- return result;
-}
-
CSSRule* CSSParser::createImportRule(const CSSParserString& url, MediaQuerySet* media)
{
if (!media || !m_styleSheet || !m_allowImportRules)
Modified: trunk/Source/WebCore/css/CSSParser.h (112280 => 112281)
--- trunk/Source/WebCore/css/CSSParser.h 2012-03-27 17:44:28 UTC (rev 112280)
+++ trunk/Source/WebCore/css/CSSParser.h 2012-03-27 17:46:59 UTC (rev 112281)
@@ -243,7 +243,6 @@
CSSParserValue& sinkFloatingValue(CSSParserValue&);
MediaQuerySet* createMediaQuerySet();
- CSSRule* createCharsetRule(const CSSParserString&);
CSSRule* createImportRule(const CSSParserString&, MediaQuerySet*);
WebKitCSSKeyframeRule* createKeyframeRule(CSSParserValueList*);
WebKitCSSKeyframesRule* createKeyframesRule();
Modified: trunk/Source/WebCore/css/CSSStyleSelector.cpp (112280 => 112281)
--- trunk/Source/WebCore/css/CSSStyleSelector.cpp 2012-03-27 17:44:28 UTC (rev 112280)
+++ trunk/Source/WebCore/css/CSSStyleSelector.cpp 2012-03-27 17:46:59 UTC (rev 112281)
@@ -2224,10 +2224,10 @@
bool CSSStyleSelector::determineStylesheetSelectorScopes(CSSStyleSheet* stylesheet, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes)
{
ASSERT(!stylesheet->isLoading());
-
- size_t size = stylesheet->length();
- for (size_t i = 0; i < size; i++) {
- CSSRule* rule = stylesheet->item(i);
+
+ const Vector<RefPtr<CSSRule> >& rules = stylesheet->ruleVector();
+ for (unsigned i = 0; i < rules.size(); i++) {
+ CSSRule* rule = rules[i].get();
if (rule->isStyleRule()) {
StyleRule* styleRule = static_cast<CSSStyleRule*>(rule)->styleRule();
if (!SelectorChecker::determineSelectorScopes(styleRule->selectorList(), idScopes, classScopes))
@@ -2454,10 +2454,9 @@
if (sheet->mediaQueries() && !medium.eval(sheet->mediaQueries(), styleSelector))
return; // the style sheet doesn't apply
- int len = sheet->length();
-
- for (int i = 0; i < len; i++) {
- CSSRule* rule = sheet->item(i);
+ const Vector<RefPtr<CSSRule> >& rules = sheet->ruleVector();
+ for (unsigned i = 0; i < rules.size(); ++i) {
+ CSSRule* rule = rules[i].get();
if (rule->isStyleRule())
addStyleRule(static_cast<CSSStyleRule*>(rule)->styleRule(), !scope);
else if (rule->isPageRule())
Modified: trunk/Source/WebCore/css/CSSStyleSheet.cpp (112280 => 112281)
--- trunk/Source/WebCore/css/CSSStyleSheet.cpp 2012-03-27 17:44:28 UTC (rev 112280)
+++ trunk/Source/WebCore/css/CSSStyleSheet.cpp 2012-03-27 17:46:59 UTC (rev 112281)
@@ -21,6 +21,7 @@
#include "config.h"
#include "CSSStyleSheet.h"
+#include "CSSCharsetRule.h"
#include "CSSFontFaceRule.h"
#include "CSSImportRule.h"
#include "CSSNamespace.h"
@@ -98,6 +99,56 @@
CSSStyleSheet::~CSSStyleSheet()
{
+ clearRules();
+}
+
+void CSSStyleSheet::parserAppendRule(PassRefPtr<CSSRule> child)
+{
+ ASSERT(!child->isCharsetRule());
+ CSSRule* c = child.get();
+ m_children.append(child);
+ if (c->isImportRule())
+ static_cast<CSSImportRule*>(c)->requestStyleSheet();
+}
+
+CSSCharsetRule* CSSStyleSheet::ensureCharsetRule()
+{
+ // Note that mutating charset has absolutely no effect.
+ if (!m_charsetRuleCSSOMWrapper)
+ m_charsetRuleCSSOMWrapper = CSSCharsetRule::create(this, m_encodingFromCharsetRule);
+ return m_charsetRuleCSSOMWrapper.get();
+}
+
+unsigned CSSStyleSheet::length() const
+{
+ unsigned result = 0;
+ result += hasCharsetRule() ? 1 : 0;
+ result += m_children.size();
+ return result;
+}
+
+CSSRule* CSSStyleSheet::item(unsigned index)
+{
+ unsigned childVectorIndex = index;
+ if (hasCharsetRule()) {
+ if (index == 0)
+ return ensureCharsetRule();
+ --childVectorIndex;
+ }
+ return childVectorIndex < m_children.size() ? m_children[childVectorIndex].get() : 0;
+}
+
+void CSSStyleSheet::clearCharsetRule()
+{
+ m_encodingFromCharsetRule = String();
+ if (m_charsetRuleCSSOMWrapper) {
+ m_charsetRuleCSSOMWrapper->setParentStyleSheet(0);
+ m_charsetRuleCSSOMWrapper.clear();
+ }
+}
+
+void CSSStyleSheet::clearRules()
+{
// For style rules outside the document, .parentStyleSheet can become null even if the style rule
// is still observable from _javascript_. This matches the behavior of .parentNode for nodes, but
// it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection.
@@ -105,21 +156,17 @@
ASSERT(m_children.at(i)->parentStyleSheet() == this);
m_children.at(i)->setParentStyleSheet(0);
}
+ m_children.clear();
+ clearCharsetRule();
}
-void CSSStyleSheet::append(PassRefPtr<CSSRule> child)
+void CSSStyleSheet::parserSetEncodingFromCharsetRule(const String& encoding)
{
- CSSRule* c = child.get();
- m_children.append(child);
- if (c->isImportRule())
- static_cast<CSSImportRule*>(c)->requestStyleSheet();
+ // Parser enforces that there is ever only one @charset.
+ ASSERT(m_encodingFromCharsetRule.isNull());
+ m_encodingFromCharsetRule = encoding;
}
-void CSSStyleSheet::remove(unsigned index)
-{
- m_children.remove(index);
-}
-
PassRefPtr<CSSRuleList> CSSStyleSheet::rules()
{
KURL url = ""
@@ -128,18 +175,14 @@
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]);
- }
+ nonCharsetRules->rules().append(m_children);
return nonCharsetRules.release();
}
unsigned CSSStyleSheet::insertRule(const String& rule, unsigned index, ExceptionCode& ec)
{
ec = 0;
- if (index > m_children.size()) {
+ if (index > length()) {
ec = INDEX_SIZE_ERR;
return 0;
}
@@ -150,27 +193,34 @@
ec = SYNTAX_ERR;
return 0;
}
-
- // Throw a HIERARCHY_REQUEST_ERR exception if the rule cannot be inserted at the specified index. The best
- // example of this is an @import rule inserted after regular rules.
- if (index > 0) {
- if (r->isImportRule()) {
- // Check all the rules that come before this one to make sure they are only @charset and @import rules.
- for (unsigned i = 0; i < index; ++i) {
- if (!m_children.at(i)->isCharsetRule() && !m_children.at(i)->isImportRule()) {
- ec = HIERARCHY_REQUEST_ERR;
- return 0;
- }
- }
- } else if (r->isCharsetRule()) {
- // The @charset rule has to come first and there can be only one.
+ // Parser::parseRule doesn't currently allow @charset so we don't need to deal with it.
+ ASSERT(!r->isCharsetRule());
+
+ unsigned childVectorIndex = index;
+ // m_children does not contain @charset which is always in index 0 if it exists.
+ if (hasCharsetRule()) {
+ if (index == 0) {
+ // Nothing can be inserted before @charset.
ec = HIERARCHY_REQUEST_ERR;
return 0;
}
+ --childVectorIndex;
}
+ // Throw a HIERARCHY_REQUEST_ERR exception if the rule cannot be inserted at the specified index. The best
+ // example of this is an @import rule inserted after regular rules.
+ if (r->isImportRule()) {
+ // Check all the rules that come before this one to make sure they are only @import rules.
+ for (unsigned i = 0; i < childVectorIndex; ++i) {
+ if (!m_children.at(i)->isImportRule()) {
+ ec = HIERARCHY_REQUEST_ERR;
+ return 0;
+ }
+ }
+ }
+
CSSRule* c = r.get();
- m_children.insert(index, r.release());
+ m_children.insert(childVectorIndex, r.release());
if (c->isImportRule())
static_cast<CSSImportRule*>(c)->requestStyleSheet();
@@ -189,7 +239,7 @@
int CSSStyleSheet::addRule(const String& selector, const String& style, ExceptionCode& ec)
{
- return addRule(selector, style, m_children.size(), ec);
+ return addRule(selector, style, length(), ec);
}
PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules()
@@ -205,14 +255,24 @@
void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec)
{
- if (index >= m_children.size()) {
+ if (index >= length()) {
ec = INDEX_SIZE_ERR;
return;
}
+
+ ec = 0;
+ unsigned childVectorIndex = index;
+ if (hasCharsetRule()) {
+ if (index == 0) {
+ clearCharsetRule();
+ styleSheetChanged();
+ return;
+ }
+ --childVectorIndex;
+ }
- ec = 0;
- m_children.at(index)->setParentStyleSheet(0);
- m_children.remove(index);
+ m_children.at(childVectorIndex)->setParentStyleSheet(0);
+ m_children.remove(childVectorIndex);
styleSheetChanged();
}
Modified: trunk/Source/WebCore/css/CSSStyleSheet.h (112280 => 112281)
--- trunk/Source/WebCore/css/CSSStyleSheet.h 2012-03-27 17:44:28 UTC (rev 112280)
+++ trunk/Source/WebCore/css/CSSStyleSheet.h 2012-03-27 17:46:59 UTC (rev 112281)
@@ -27,6 +27,7 @@
struct CSSNamespace;
class CSSParser;
+class CSSCharsetRule;
class CSSRule;
class CSSRuleList;
class CachedCSSStyleSheet;
@@ -110,12 +111,17 @@
void setHasSyntacticallyValidCSSHeader(bool b) { m_hasSyntacticallyValidCSSHeader = b; }
bool hasSyntacticallyValidCSSHeader() const { return m_hasSyntacticallyValidCSSHeader; }
- void append(PassRefPtr<CSSRule>);
- void remove(unsigned index);
+ void parserAppendRule(PassRefPtr<CSSRule>);
+ void parserSetEncodingFromCharsetRule(const String& encoding);
- unsigned length() const { return m_children.size(); }
- CSSRule* item(unsigned index) { return index < length() ? m_children.at(index).get() : 0; }
-
+ void clearRules();
+
+ unsigned length() const;
+ CSSRule* item(unsigned index);
+
+ // Does not contain @charset rule.
+ const Vector<RefPtr<CSSRule> >& ruleVector() const { return m_children; }
+
virtual MediaList* media() const OVERRIDE;
MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
@@ -129,7 +135,13 @@
virtual bool isCSSStyleSheet() const { return true; }
virtual String type() const { return "text/css"; }
+
+ void clearCharsetRule();
+ bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull() || m_charsetRuleCSSOMWrapper; }
+ CSSCharsetRule* ensureCharsetRule();
+ String m_encodingFromCharsetRule;
+ RefPtr<CSSCharsetRule> m_charsetRuleCSSOMWrapper;
Vector<RefPtr<CSSRule> > m_children;
OwnPtr<CSSNamespace> m_namespaces;
String m_charset;
Modified: trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp (112280 => 112281)
--- trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp 2012-03-27 17:44:28 UTC (rev 112280)
+++ trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp 2012-03-27 17:46:59 UTC (rev 112281)
@@ -718,8 +718,7 @@
void InspectorStyleSheet::reparseStyleSheet(const String& text)
{
- for (unsigned i = 0, size = m_pageStyleSheet->length(); i < size; ++i)
- m_pageStyleSheet->remove(0);
+ m_pageStyleSheet->clearRules();
m_pageStyleSheet->parseString(text, m_pageStyleSheet->useStrictParsing());
m_pageStyleSheet->styleSheetChanged();
m_inspectorStyles.clear();