Title: [112281] trunk/Source/WebCore
Revision
112281
Author
[email protected]
Date
2012-03-27 10:46:59 -0700 (Tue, 27 Mar 2012)

Log Message

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):

Modified Paths

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();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to