Split each RuleSet and feature out from StyleResolver into its own class.
authorhayato@chromium.org <hayato@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Feb 2013 04:32:05 +0000 (04:32 +0000)
committerhayato@chromium.org <hayato@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Feb 2013 04:32:05 +0000 (04:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=107777

Reviewed by Dimitri Glazkov.

Re-landing r141964, which was reverted in r141973, since r141964 seem to be innocent.

No tests. No change in behavior.

* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSAllInOne.cpp:
* css/DocumentRuleSets.cpp: Added.
(WebCore):
(WebCore::DocumentRuleSets::DocumentRuleSets):
(WebCore::DocumentRuleSets::~DocumentRuleSets):
(WebCore::DocumentRuleSets::initUserStyle): New helper to initialize each RuleSets.
(WebCore::DocumentRuleSets::collectRulesFromUserStyleSheets): Factored out from StyleResolver.
(WebCore::makeRuleSet): Ditto.
(WebCore::DocumentRuleSets::resetAuthorStyle): Ditto.
(WebCore::DocumentRuleSets::appendAuthorStyleSheets): Ditto.
(WebCore::DocumentRuleSets::collectFeatures): Ditto.
(WebCore::DocumentRuleSets::reportMemoryUsage): New methods to report memory usage. Factored out from StyleResolver.
* css/DocumentRuleSets.h: Added.
(WebCore):
(DocumentRuleSets):
(WebCore::DocumentRuleSets::authorStyle): Moved from StyleResolver.
(WebCore::DocumentRuleSets::userStyle): Ditto.
(WebCore::DocumentRuleSets::features): Ditto.
(WebCore::DocumentRuleSets::sibling): Ditto.
(WebCore::DocumentRuleSets::uncommonAttribute): Ditto.
* css/StyleResolver.cpp:
(WebCore::StyleResolver::StyleResolver):
(WebCore::StyleResolver::appendAuthorStyleSheets): Now calls DocumentRuleSets::appendAuthorStyleSheets.
(WebCore::StyleResolver::matchAuthorRules): Use m_ruleSets.
(WebCore::StyleResolver::matchUserRules): Ditto.
(WebCore::StyleResolver::classNamesAffectedByRules): Ditto.
(WebCore::StyleResolver::locateCousinList): Ditto.
(WebCore::StyleResolver::canShareStyleWithElement): Ditto.
(WebCore::StyleResolver::locateSharedStyle): Ditto.
(WebCore::StyleResolver::styleForPage): Ditto.
(WebCore::StyleResolver::checkRegionStyle): Ditto.
(WebCore::StyleResolver::applyProperty): Ditto.
(WebCore::StyleResolver::reportMemoryUsage): Now calls DocumentRuleSets::reportMemoryUsage.
* css/StyleResolver.h:
(WebCore::StyleResolver::scopeResolver):
(StyleResolver):
(WebCore::StyleResolver::ruleSets): accessor r to DocumentRuleSets.
(WebCore::StyleResolver::usesSiblingRules): Use m_ruleSets.
(WebCore::StyleResolver::usesFirstLineRules): Ditto.
(WebCore::StyleResolver::usesBeforeAfterRules): Ditto.
(WebCore::StyleResolver::hasSelectorForAttribute): Ditto.
(WebCore::StyleResolver::hasSelectorForClass): Ditto.
(WebCore::StyleResolver::hasSelectorForId): Ditto.
* dom/DocumentStyleSheetCollection.cpp:
(WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@142573 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/css/CSSAllInOne.cpp
Source/WebCore/css/DocumentRuleSets.cpp [new file with mode: 0644]
Source/WebCore/css/DocumentRuleSets.h [new file with mode: 0644]
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/dom/DocumentStyleSheetCollection.cpp

index d331aeb..040f228 100644 (file)
@@ -1063,6 +1063,7 @@ set(WebCore_SOURCES
     css/CSSValue.cpp
     css/CSSValueList.cpp
     css/CSSValuePool.cpp
+    css/DocumentRuleSets.cpp
     css/FontFeatureValue.cpp
     css/FontValue.cpp
     css/InspectorCSSOMWrappers.cpp
index 1ef9987..313b23f 100644 (file)
@@ -1,3 +1,65 @@
+2013-02-11  Hayato Ito  <hayato@chromium.org>
+
+        Split each RuleSet and feature out from StyleResolver into its own class.
+        https://bugs.webkit.org/show_bug.cgi?id=107777
+
+        Reviewed by Dimitri Glazkov.
+
+        Re-landing r141964, which was reverted in r141973, since r141964 seem to be innocent.
+
+        No tests. No change in behavior.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.gypi:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSAllInOne.cpp:
+        * css/DocumentRuleSets.cpp: Added.
+        (WebCore):
+        (WebCore::DocumentRuleSets::DocumentRuleSets):
+        (WebCore::DocumentRuleSets::~DocumentRuleSets):
+        (WebCore::DocumentRuleSets::initUserStyle): New helper to initialize each RuleSets.
+        (WebCore::DocumentRuleSets::collectRulesFromUserStyleSheets): Factored out from StyleResolver.
+        (WebCore::makeRuleSet): Ditto.
+        (WebCore::DocumentRuleSets::resetAuthorStyle): Ditto.
+        (WebCore::DocumentRuleSets::appendAuthorStyleSheets): Ditto.
+        (WebCore::DocumentRuleSets::collectFeatures): Ditto.
+        (WebCore::DocumentRuleSets::reportMemoryUsage): New methods to report memory usage. Factored out from StyleResolver.
+        * css/DocumentRuleSets.h: Added.
+        (WebCore):
+        (DocumentRuleSets):
+        (WebCore::DocumentRuleSets::authorStyle): Moved from StyleResolver.
+        (WebCore::DocumentRuleSets::userStyle): Ditto.
+        (WebCore::DocumentRuleSets::features): Ditto.
+        (WebCore::DocumentRuleSets::sibling): Ditto.
+        (WebCore::DocumentRuleSets::uncommonAttribute): Ditto.
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::StyleResolver):
+        (WebCore::StyleResolver::appendAuthorStyleSheets): Now calls DocumentRuleSets::appendAuthorStyleSheets.
+        (WebCore::StyleResolver::matchAuthorRules): Use m_ruleSets.
+        (WebCore::StyleResolver::matchUserRules): Ditto.
+        (WebCore::StyleResolver::classNamesAffectedByRules): Ditto.
+        (WebCore::StyleResolver::locateCousinList): Ditto.
+        (WebCore::StyleResolver::canShareStyleWithElement): Ditto.
+        (WebCore::StyleResolver::locateSharedStyle): Ditto.
+        (WebCore::StyleResolver::styleForPage): Ditto.
+        (WebCore::StyleResolver::checkRegionStyle): Ditto.
+        (WebCore::StyleResolver::applyProperty): Ditto.
+        (WebCore::StyleResolver::reportMemoryUsage): Now calls DocumentRuleSets::reportMemoryUsage.
+        * css/StyleResolver.h:
+        (WebCore::StyleResolver::scopeResolver):
+        (StyleResolver):
+        (WebCore::StyleResolver::ruleSets): accessor r to DocumentRuleSets.
+        (WebCore::StyleResolver::usesSiblingRules): Use m_ruleSets.
+        (WebCore::StyleResolver::usesFirstLineRules): Ditto.
+        (WebCore::StyleResolver::usesBeforeAfterRules): Ditto.
+        (WebCore::StyleResolver::hasSelectorForAttribute): Ditto.
+        (WebCore::StyleResolver::hasSelectorForClass): Ditto.
+        (WebCore::StyleResolver::hasSelectorForId): Ditto.
+        * dom/DocumentStyleSheetCollection.cpp:
+        (WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets):
+
 2013-02-11  Keishi Hattori  <keishi@webkit.org>
 
         REGRESSION (r140778):Calendar Picker buttons are wrong when rtl
index 2b9b1be..fbe11e6 100644 (file)
@@ -2637,6 +2637,8 @@ webcore_sources += \
        Source/WebCore/css/CSSValuePool.h \
        Source/WebCore/css/CSSVariableValue.h \
        Source/WebCore/css/DashboardRegion.h \
+       Source/WebCore/css/DocumentRuleSets.cpp \
+       Source/WebCore/css/DocumentRuleSets.h \
        Source/WebCore/css/FontFeatureValue.cpp \
        Source/WebCore/css/FontFeatureValue.h \
        Source/WebCore/css/FontValue.cpp \
index 9aae16c..1d1a531 100644 (file)
@@ -305,6 +305,7 @@ SOURCES += \
     css/CSSValue.cpp \
     css/CSSValueList.cpp \
     css/CSSValuePool.cpp \
+    css/DocumentRuleSets.cpp \
     css/FontFeatureValue.cpp \
     css/FontValue.cpp \
     css/InspectorCSSOMWrappers.cpp \
index 7aa3c0e..175ed66 100644 (file)
             'css/CSSVariableValue.h',
             'css/Counter.h',
             'css/DashboardRegion.h',
+            'css/DocumentRuleSets.cpp',
+            'css/DocumentRuleSets.h',
             'css/FontFeatureValue.cpp',
             'css/FontFeatureValue.h',
             'css/FontValue.cpp',
index 5ac57bb..2aae977 100644 (file)
                4A1E71A614E106AC00626F9D /* JSShadowRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A1E71A414E106AC00626F9D /* JSShadowRoot.h */; };
                4A38BF5014FE1C0900612512 /* WebSocketDeflateFramer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A38BF4E14FE1C0900612512 /* WebSocketDeflateFramer.cpp */; };
                4A38BF5114FE1C0900612512 /* WebSocketDeflateFramer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A38BF4F14FE1C0900612512 /* WebSocketDeflateFramer.h */; };
+               4A4F48A916B0DFC000EDBB29 /* DocumentRuleSets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A4F48A716B0DFC000EDBB29 /* DocumentRuleSets.cpp */; };
+               4A4F48AA16B0DFC000EDBB29 /* DocumentRuleSets.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A4F48A816B0DFC000EDBB29 /* DocumentRuleSets.h */; };
                4A5A2ADB161E7E00005889DD /* WebSocketExtensionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A5A2AD9161E7E00005889DD /* WebSocketExtensionParser.cpp */; };
                4A5A2ADC161E7E00005889DD /* WebSocketExtensionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A5A2ADA161E7E00005889DD /* WebSocketExtensionParser.h */; };
                4A6A0C5B15232F2400B09C6E /* ComposedShadowTreeWalker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6A0C5915232F2400B09C6E /* ComposedShadowTreeWalker.cpp */; };
                4A1E71A414E106AC00626F9D /* JSShadowRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSShadowRoot.h; sourceTree = "<group>"; };
                4A38BF4E14FE1C0900612512 /* WebSocketDeflateFramer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebSocketDeflateFramer.cpp; path = Modules/websockets/WebSocketDeflateFramer.cpp; sourceTree = "<group>"; };
                4A38BF4F14FE1C0900612512 /* WebSocketDeflateFramer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebSocketDeflateFramer.h; path = Modules/websockets/WebSocketDeflateFramer.h; sourceTree = "<group>"; };
+               4A4F48A716B0DFC000EDBB29 /* DocumentRuleSets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentRuleSets.cpp; sourceTree = "<group>"; };
+               4A4F48A816B0DFC000EDBB29 /* DocumentRuleSets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentRuleSets.h; sourceTree = "<group>"; };
                4A5A2AD9161E7E00005889DD /* WebSocketExtensionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebSocketExtensionParser.cpp; path = Modules/websockets/WebSocketExtensionParser.cpp; sourceTree = "<group>"; };
                4A5A2ADA161E7E00005889DD /* WebSocketExtensionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebSocketExtensionParser.h; path = Modules/websockets/WebSocketExtensionParser.h; sourceTree = "<group>"; };
                4A6A0C5915232F2400B09C6E /* ComposedShadowTreeWalker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComposedShadowTreeWalker.cpp; sourceTree = "<group>"; };
                                E49BD9F9131FD2ED003C56F0 /* CSSValuePool.h */,
                                CAE9F90E146441F000C245B1 /* CSSVariableValue.h */,
                                A80E6CE10A1989CA007FB8C5 /* DashboardRegion.h */,
+                               4A4F48A716B0DFC000EDBB29 /* DocumentRuleSets.cpp */,
+                               4A4F48A816B0DFC000EDBB29 /* DocumentRuleSets.h */,
                                4A6E9FC113C17D1D0046A7F8 /* FontFeatureValue.cpp */,
                                4A6E9FC213C17D1D0046A7F8 /* FontFeatureValue.h */,
                                A80E6CC70A1989CA007FB8C5 /* FontValue.cpp */,
                                CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */,
                                14947FFE12F80CD200A0F631 /* DocumentOrderedMap.h in Headers */,
                                BCCFBAE80B5152ED0001F1D7 /* DocumentParser.h in Headers */,
+                               4A4F48AA16B0DFC000EDBB29 /* DocumentRuleSets.h in Headers */,
                                AD6E71AD1668899D00320C13 /* DocumentSharedObjectPool.h in Headers */,
                                E47E276516036ED200EE2AFB /* DocumentStyleSheetCollection.h in Headers */,
                                0B90561A0F2578BF0095FF6A /* DocumentThreadableLoader.h in Headers */,
                                CE057FA51220731100A476D5 /* DocumentMarkerController.cpp in Sources */,
                                14947FFD12F80CD200A0F631 /* DocumentOrderedMap.cpp in Sources */,
                                A8C2280E11D4A59700D5A7D3 /* DocumentParser.cpp in Sources */,
+                               4A4F48A916B0DFC000EDBB29 /* DocumentRuleSets.cpp in Sources */,
                                AD6E71AC1668899D00320C13 /* DocumentSharedObjectPool.cpp in Sources */,
                                E47E276816036EDC00EE2AFB /* DocumentStyleSheetCollection.cpp in Sources */,
                                0B9056190F2578BE0095FF6A /* DocumentThreadableLoader.cpp in Sources */,
index c81c3b2..e73e358 100644 (file)
@@ -69,6 +69,7 @@
 #include "CSSValue.cpp"
 #include "CSSValueList.cpp"
 #include "CSSValuePool.cpp"
+#include "DocumentRuleSets.cpp"
 #include "InspectorCSSOMWrappers.cpp"
 #include "RuleFeature.cpp"
 #include "RuleSet.cpp"
diff --git a/Source/WebCore/css/DocumentRuleSets.cpp b/Source/WebCore/css/DocumentRuleSets.cpp
new file mode 100644 (file)
index 0000000..40597cb
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
+ * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "DocumentRuleSets.h"
+
+#include "CSSDefaultStyleSheets.h"
+#include "CSSStyleSheet.h"
+#include "DocumentStyleSheetCollection.h"
+#include "MediaQueryEvaluator.h"
+#include "StyleResolver.h"
+#include "StyleSheetContents.h"
+
+namespace WebCore {
+
+DocumentRuleSets::DocumentRuleSets()
+{
+}
+
+DocumentRuleSets::~DocumentRuleSets()
+{
+}
+
+void DocumentRuleSets::initUserStyle(DocumentStyleSheetCollection* styleSheetCollection, const MediaQueryEvaluator& medium, StyleResolver& resolver)
+{
+    OwnPtr<RuleSet> tempUserStyle = RuleSet::create();
+    if (CSSStyleSheet* pageUserSheet = styleSheetCollection->pageUserSheet())
+        tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), medium, &resolver);
+    collectRulesFromUserStyleSheets(styleSheetCollection->injectedUserStyleSheets(), *tempUserStyle, medium, resolver);
+    collectRulesFromUserStyleSheets(styleSheetCollection->documentUserStyleSheets(), *tempUserStyle, medium, resolver);
+    if (tempUserStyle->m_ruleCount > 0 || tempUserStyle->m_pageRules.size() > 0)
+        m_userStyle = tempUserStyle.release();
+}
+
+void DocumentRuleSets::collectRulesFromUserStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& userSheets, RuleSet& userStyle, const MediaQueryEvaluator& medium, StyleResolver& resolver)
+{
+    for (unsigned i = 0; i < userSheets.size(); ++i) {
+        ASSERT(userSheets[i]->contents()->isUserStyleSheet());
+        userStyle.addRulesFromSheet(userSheets[i]->contents(), medium, &resolver);
+    }
+}
+
+static PassOwnPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
+{
+    size_t size = rules.size();
+    if (!size)
+        return nullptr;
+    OwnPtr<RuleSet> ruleSet = RuleSet::create();
+    for (size_t i = 0; i < size; ++i)
+        ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
+    ruleSet->shrinkToFit();
+    return ruleSet.release();
+}
+
+void DocumentRuleSets::resetAuthorStyle()
+{
+    m_authorStyle = RuleSet::create();
+    m_authorStyle->disableAutoShrinkToFit();
+}
+
+void DocumentRuleSets::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets, MediaQueryEvaluator* medium, InspectorCSSOMWrappers& inspectorCSSOMWrappers, bool isViewSource, StyleResolver* resolver)
+{
+    // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
+    // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated.
+    unsigned size = styleSheets.size();
+    for (unsigned i = firstNew; i < size; ++i) {
+        CSSStyleSheet* cssSheet = styleSheets[i].get();
+        ASSERT(!cssSheet->disabled());
+        if (cssSheet->mediaQueries() && !medium->eval(cssSheet->mediaQueries(), resolver))
+            continue;
+        StyleSheetContents* sheet = cssSheet->contents();
+#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
+        if (const ContainerNode* scope = StyleScopeResolver::scopeFor(cssSheet)) {
+            // FIXME: Remove a dependency to calling a StyleResolver's member function.
+            // If we can avoid calling resolver->ensureScopeResolver() here, we don't have to include "StyleResolver.h".
+            // https://bugs.webkit.org/show_bug.cgi?id=108890
+            resolver->ensureScopeResolver()->ensureRuleSetFor(scope)->addRulesFromSheet(sheet, *medium, resolver, scope);
+            continue;
+        }
+#endif
+        m_authorStyle->addRulesFromSheet(sheet, *medium, resolver);
+        inspectorCSSOMWrappers.collectFromStyleSheetIfNeeded(cssSheet);
+    }
+    m_authorStyle->shrinkToFit();
+    collectFeatures(isViewSource, resolver->scopeResolver());
+}
+
+void DocumentRuleSets::collectFeatures(bool isViewSource, StyleScopeResolver* scopeResolver)
+{
+    m_features.clear();
+    // Collect all ids and rules using sibling selectors (:first-child and similar)
+    // in the current set of stylesheets. Style sharing code uses this information to reject
+    // sharing candidates.
+    if (CSSDefaultStyleSheets::defaultStyle)
+        m_features.add(CSSDefaultStyleSheets::defaultStyle->features());
+    if (m_authorStyle)
+        m_features.add(m_authorStyle->features());
+    if (isViewSource)
+        m_features.add(CSSDefaultStyleSheets::viewSourceStyle()->features());
+
+    if (scopeResolver)
+        scopeResolver->collectFeaturesTo(m_features);
+    if (m_userStyle)
+        m_features.add(m_userStyle->features());
+
+    m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
+    m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
+}
+
+void DocumentRuleSets::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+    MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
+    info.addMember(m_authorStyle);
+    info.addMember(m_userStyle);
+    info.addMember(m_features);
+    info.addMember(m_siblingRuleSet);
+    info.addMember(m_uncommonAttributeRuleSet);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/css/DocumentRuleSets.h b/Source/WebCore/css/DocumentRuleSets.h
new file mode 100644 (file)
index 0000000..46a50fc
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DocumentRuleSets_h
+#define DocumentRuleSets_h
+
+#include "RuleFeature.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class CSSStyleRule;
+class CSSStyleSheet;
+class DocumentStyleSheetCollection;
+class InspectorCSSOMWrappers;
+class MediaQueryEvaluator;
+class RuleSet;
+class StyleResolver;
+class StyleScopeResolver;
+
+class DocumentRuleSets {
+public:
+    DocumentRuleSets();
+    ~DocumentRuleSets();
+    RuleSet* authorStyle() const { return m_authorStyle.get(); }
+    RuleSet* userStyle() const { return m_userStyle.get(); }
+    RuleFeatureSet& features() { return m_features; }
+    const RuleFeatureSet& features() const { return m_features; }
+    RuleSet* sibling() const { return m_siblingRuleSet.get(); }
+    RuleSet* uncommonAttribute() const { return m_uncommonAttributeRuleSet.get(); }
+
+    void initUserStyle(DocumentStyleSheetCollection*, const MediaQueryEvaluator&, StyleResolver&);
+    void resetAuthorStyle();
+    void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >&, MediaQueryEvaluator*, InspectorCSSOMWrappers&, bool isViewSource, StyleResolver*);
+
+    void collectFeatures(bool isViewSource, StyleScopeResolver*);
+    void reportMemoryUsage(MemoryObjectInfo*) const;
+
+private:
+    void collectRulesFromUserStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&, RuleSet& userStyle, const MediaQueryEvaluator&, StyleResolver&);
+    OwnPtr<RuleSet> m_authorStyle;
+    OwnPtr<RuleSet> m_userStyle;
+    RuleFeatureSet m_features;
+    OwnPtr<RuleSet> m_siblingRuleSet;
+    OwnPtr<RuleSet> m_uncommonAttributeRuleSet;
+};
+
+} // namespace WebCore
+
+#endif // DocumentRuleSets_h
index 18290f3..970500c 100644 (file)
@@ -259,16 +259,10 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles)
     if (m_rootDefaultStyle && view)
         m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle.get()));
 
-    resetAuthorStyle();
+    m_ruleSets.resetAuthorStyle();
 
     DocumentStyleSheetCollection* styleSheetCollection = document->styleSheetCollection();
-    OwnPtr<RuleSet> tempUserStyle = RuleSet::create();
-    if (CSSStyleSheet* pageUserSheet = styleSheetCollection->pageUserSheet())
-        tempUserStyle->addRulesFromSheet(pageUserSheet->contents(), *m_medium, this);
-    collectRulesFromUserStyleSheets(styleSheetCollection->injectedUserStyleSheets(), *tempUserStyle);
-    collectRulesFromUserStyleSheets(styleSheetCollection->documentUserStyleSheets(), *tempUserStyle);
-    if (tempUserStyle->m_ruleCount > 0 || tempUserStyle->m_pageRules.size() > 0)
-        m_userStyle = tempUserStyle.release();
+    m_ruleSets.initUserStyle(styleSheetCollection, *m_medium, *this);
 
 #if ENABLE(SVG_FONTS)
     if (document->svgExtensions()) {
@@ -282,56 +276,9 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles)
     appendAuthorStyleSheets(0, styleSheetCollection->activeAuthorStyleSheets());
 }
 
-void StyleResolver::collectRulesFromUserStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& userSheets, RuleSet& userStyle)
-{
-    for (unsigned i = 0; i < userSheets.size(); ++i) {
-        ASSERT(userSheets[i]->contents()->isUserStyleSheet());
-        userStyle.addRulesFromSheet(userSheets[i]->contents(), *m_medium, this);
-    }
-}
-
-static PassOwnPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
-{
-    size_t size = rules.size();
-    if (!size)
-        return nullptr;
-    OwnPtr<RuleSet> ruleSet = RuleSet::create();
-    for (size_t i = 0; i < size; ++i)
-        ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
-    ruleSet->shrinkToFit();
-    return ruleSet.release();
-}
-
-void StyleResolver::resetAuthorStyle()
-{
-    m_authorStyle = RuleSet::create();
-    m_authorStyle->disableAutoShrinkToFit();
-}
-
 void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
 {
-    // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
-    // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated.
-    unsigned size = styleSheets.size();
-    for (unsigned i = firstNew; i < size; ++i) {
-        CSSStyleSheet* cssSheet = styleSheets[i].get();
-        ASSERT(!cssSheet->disabled());
-        if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), this))
-            continue;
-        StyleSheetContents* sheet = cssSheet->contents();
-#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
-        if (const ContainerNode* scope = StyleScopeResolver::scopeFor(cssSheet)) {
-            ensureScopeResolver()->ensureRuleSetFor(scope)->addRulesFromSheet(sheet, *m_medium, this, scope);
-            continue;
-        }
-#endif
-
-        m_authorStyle->addRulesFromSheet(sheet, *m_medium, this);
-        m_inspectorCSSOMWrappers.collectFromStyleSheetIfNeeded(cssSheet);
-    }
-    m_authorStyle->shrinkToFit();
-    collectFeatures();
-    
+    m_ruleSets.appendAuthorStyleSheets(firstNew, styleSheets, m_medium.get(), m_inspectorCSSOMWrappers, document()->isViewSource(), this);
     if (document()->renderer() && document()->renderer()->style())
         document()->renderer()->style()->font().update(fontSelector());
 
@@ -639,7 +586,7 @@ void StyleResolver::matchAuthorRules(MatchResult& result, bool includeEmptyRules
         return;
 
     // Match global author rules.
-    MatchRequest matchRequest(m_authorStyle.get(), includeEmptyRules);
+    MatchRequest matchRequest(m_ruleSets.authorStyle(), includeEmptyRules);
     RuleRange ruleRange = result.ranges.authorRuleRange();
     collectMatchingRules(matchRequest, ruleRange);
     collectMatchingRulesForRegion(matchRequest, ruleRange);
@@ -650,13 +597,13 @@ void StyleResolver::matchAuthorRules(MatchResult& result, bool includeEmptyRules
 
 void StyleResolver::matchUserRules(MatchResult& result, bool includeEmptyRules)
 {
-    if (!m_userStyle)
+    if (!m_ruleSets.userStyle())
         return;
     
     m_state.matchedRules.clear();
 
     result.ranges.lastUserRule = result.matchedProperties.size() - 1;
-    MatchRequest matchRequest(m_userStyle.get(), includeEmptyRules);
+    MatchRequest matchRequest(m_ruleSets.userStyle(), includeEmptyRules);
     RuleRange ruleRange = result.ranges.userRuleRange();
     collectMatchingRules(matchRequest, ruleRange);
     collectMatchingRulesForRegion(matchRequest, ruleRange);
@@ -792,7 +739,7 @@ void StyleResolver::matchAllRules(MatchResult& result, bool includeSMILPropertie
 bool StyleResolver::classNamesAffectedByRules(const SpaceSplitString& classNames) const
 {
     for (unsigned i = 0; i < classNames.size(); ++i) {
-        if (m_features.classesInRules.contains(classNames[i].impl()))
+        if (m_ruleSets.features().classesInRules.contains(classNames[i].impl()))
             return true;
     }
     return false;
@@ -867,7 +814,7 @@ Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCoun
     if (p->isSVGElement() && static_cast<SVGElement*>(p)->animatedSMILStyleProperties())
         return 0;
 #endif
-    if (p->hasID() && m_features.idsInRules.contains(p->idForStyleResolution().impl()))
+    if (p->hasID() && m_ruleSets.features().idsInRules.contains(p->idForStyleResolution().impl()))
         return 0;
 
     RenderStyle* parentStyle = p->renderStyle();
@@ -1049,7 +996,7 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
     if (element->additionalPresentationAttributeStyle() != state.styledElement->additionalPresentationAttributeStyle())
         return false;
 
-    if (element->hasID() && m_features.idsInRules.contains(element->idForStyleResolution().impl()))
+    if (element->hasID() && m_ruleSets.features().idsInRules.contains(element->idForStyleResolution().impl()))
         return false;
     if (element->hasScopedHTMLStyleChild())
         return false;
@@ -1132,7 +1079,7 @@ RenderStyle* StyleResolver::locateSharedStyle()
         return 0;
 #endif
     // Ids stop style sharing if they show up in the stylesheets.
-    if (state.styledElement->hasID() && m_features.idsInRules.contains(state.styledElement->idForStyleResolution().impl()))
+    if (state.styledElement->hasID() && m_ruleSets.features().idsInRules.contains(state.styledElement->idForStyleResolution().impl()))
         return 0;
     if (parentElementPreventsSharing(state.element->parentElement()))
         return 0;
@@ -1164,10 +1111,10 @@ RenderStyle* StyleResolver::locateSharedStyle()
         return 0;
 
     // Can't share if sibling rules apply. This is checked at the end as it should rarely fail.
-    if (styleSharingCandidateMatchesRuleSet(m_siblingRuleSet.get()))
+    if (styleSharingCandidateMatchesRuleSet(m_ruleSets.sibling()))
         return 0;
     // Can't share if attribute rules apply.
-    if (styleSharingCandidateMatchesRuleSet(m_uncommonAttributeRuleSet.get()))
+    if (styleSharingCandidateMatchesRuleSet(m_ruleSets.uncommonAttribute()))
         return 0;
     // Can't share if @host @-rules apply.
     if (styleSharingCandidateMatchesHostRules())
@@ -1436,7 +1383,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
     bool needsCollection = false;
     CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(element, needsCollection);
     if (needsCollection)
-        collectFeatures();
+        m_ruleSets.collectFeatures(document()->isViewSource(), m_scopeResolver.get());
 
     MatchResult matchResult;
     if (matchingBehavior == MatchOnlyUserAgentRules)
@@ -1637,9 +1584,9 @@ PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
     
     MatchResult result;
     matchPageRules(result, CSSDefaultStyleSheets::defaultPrintStyle, isLeft, isFirst, page);
-    matchPageRules(result, m_userStyle.get(), isLeft, isFirst, page);
+    matchPageRules(result, m_ruleSets.userStyle(), isLeft, isFirst, page);
     // Only consider the global author RuleSet for @page rules, as per the HTML5 spec.
-    matchPageRules(result, m_authorStyle.get(), isLeft, isFirst, page);
+    matchPageRules(result, m_ruleSets.authorStyle(), isLeft, isFirst, page);
     m_state.lineHeightValue = 0;
     bool inheritedOnly = false;
 #if ENABLE(CSS_VARIABLES)
@@ -2009,18 +1956,18 @@ bool StyleResolver::checkRegionStyle(Element* regionElement)
     // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment,
     // so all region rules are global by default. Verify whether that can stand or needs changing.
 
-    unsigned rulesSize = m_authorStyle->m_regionSelectorsAndRuleSets.size();
+    unsigned rulesSize = m_ruleSets.authorStyle()->m_regionSelectorsAndRuleSets.size();
     for (unsigned i = 0; i < rulesSize; ++i) {
-        ASSERT(m_authorStyle->m_regionSelectorsAndRuleSets.at(i).ruleSet.get());
-        if (checkRegionSelector(m_authorStyle->m_regionSelectorsAndRuleSets.at(i).selector, regionElement))
+        ASSERT(m_ruleSets.authorStyle()->m_regionSelectorsAndRuleSets.at(i).ruleSet.get());
+        if (checkRegionSelector(m_ruleSets.authorStyle()->m_regionSelectorsAndRuleSets.at(i).selector, regionElement))
             return true;
     }
 
-    if (m_userStyle) {
-        rulesSize = m_userStyle->m_regionSelectorsAndRuleSets.size();
+    if (m_ruleSets.userStyle()) {
+        rulesSize = m_ruleSets.userStyle()->m_regionSelectorsAndRuleSets.size();
         for (unsigned i = 0; i < rulesSize; ++i) {
-            ASSERT(m_userStyle->m_regionSelectorsAndRuleSets.at(i).ruleSet.get());
-            if (checkRegionSelector(m_userStyle->m_regionSelectorsAndRuleSets.at(i).selector, regionElement))
+            ASSERT(m_ruleSets.userStyle()->m_regionSelectorsAndRuleSets.at(i).ruleSet.get());
+            if (checkRegionSelector(m_ruleSets.userStyle()->m_regionSelectorsAndRuleSets.at(i).selector, regionElement))
                 return true;
         }
     }
@@ -2884,7 +2831,7 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value)
                     state.style->setContent(value.isNull() ? emptyAtom : value.impl(), didSet);
                     didSet = true;
                     // register the fact that the attribute value affects the style
-                    m_features.attrsInRules.add(attr.localName().impl());
+                    m_ruleSets.features().attrsInRules.add(attr.localName().impl());
                 } else if (contentValue->isCounter()) {
                     Counter* counterValue = contentValue->getCounterValue();
                     EListStyleType listStyleType = NoneListStyle;
@@ -5166,28 +5113,6 @@ void StyleResolver::loadPendingResources()
 #endif
 }
 
-void StyleResolver::collectFeatures()
-{
-    m_features.clear();
-    // Collect all ids and rules using sibling selectors (:first-child and similar)
-    // in the current set of stylesheets. Style sharing code uses this information to reject
-    // sharing candidates.
-    if (CSSDefaultStyleSheets::defaultStyle)
-        m_features.add(CSSDefaultStyleSheets::defaultStyle->features());
-    if (m_authorStyle)
-        m_features.add(m_authorStyle->features());
-    if (document()->isViewSource())
-        m_features.add(CSSDefaultStyleSheets::viewSourceStyle()->features());
-
-    if (m_scopeResolver)
-        m_scopeResolver->collectFeaturesTo(m_features);
-    if (m_userStyle)
-        m_features.add(m_userStyle->features());
-
-    m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
-    m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
-}
-
 void StyleResolver::MatchedProperties::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
@@ -5212,11 +5137,7 @@ void MediaQueryResult::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) con
 void StyleResolver::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
-    info.addMember(m_authorStyle, "authorStyle");
-    info.addMember(m_userStyle, "userStyle");
-    info.addMember(m_features, "features");
-    info.addMember(m_siblingRuleSet, "siblingRuleSet");
-    info.addMember(m_uncommonAttributeRuleSet, "uncommonAttributeRuleSet");
+    info.addMember(m_ruleSets, "ruleSets");
     info.addMember(m_keyframesRuleMap, "keyframesRuleMap");
     info.addMember(m_matchedPropertiesCache, "matchedPropertiesCache");
     info.addMember(m_matchedPropertiesCacheSweepTimer, "matchedPropertiesCacheSweepTimer");
index 84c3cd1..e8ca3c0 100644 (file)
@@ -26,6 +26,7 @@
 #include "CSSRuleList.h"
 #include "CSSToStyleMap.h"
 #include "CSSValueList.h"
+#include "DocumentRuleSets.h"
 #include "InspectorCSSOMWrappers.h"
 #include "LinkHash.h"
 #include "MediaQueryExp.h"
@@ -169,6 +170,7 @@ public:
     RenderStyle* rootElementStyle() const { return m_state.rootElementStyle; }
     Element* element() const { return m_state.element; }
     Document* document() const { return m_document; }
+    StyleScopeResolver* scopeResolver() const { return m_scopeResolver.get(); }
     const FontDescription& fontDescription() { return style()->fontDescription(); }
     const FontDescription& parentFontDescription() { return parentStyle()->fontDescription(); }
     void setFontDescription(const FontDescription& fontDescription) { m_state.fontDirty |= style()->setFontDescription(fontDescription); }
@@ -179,10 +181,13 @@ public:
     void setTextOrientation(TextOrientation textOrientation) { m_state.fontDirty |= style()->setTextOrientation(textOrientation); }
     bool hasParentNode() const { return m_state.parentNode; }
 
-    void resetAuthorStyle();
+    // FIXME: It could be better to call m_ruleSets.appendAuthorStyleSheets() directly after we factor StyleRsolver further.
+    // https://bugs.webkit.org/show_bug.cgi?id=108890
     void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >&);
 
-private:
+    DocumentRuleSets& ruleSets() { return m_ruleSets; }
+    const DocumentRuleSets& ruleSets() const { return m_ruleSets; }
+
 #if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
     StyleScopeResolver* ensureScopeResolver()
     {
@@ -201,9 +206,9 @@ private:
     }
 #endif
 
+private:
     void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
     void initElement(Element*);
-    void collectFeatures();
     RenderStyle* locateSharedStyle();
     bool styleSharingCandidateMatchesRuleSet(RuleSet*);
     bool styleSharingCandidateMatchesHostRules();
@@ -271,9 +276,9 @@ public:
 
     bool checkRegionStyle(Element* regionElement);
 
-    bool usesSiblingRules() const { return !m_features.siblingRules.isEmpty(); }
-    bool usesFirstLineRules() const { return m_features.usesFirstLineRules; }
-    bool usesBeforeAfterRules() const { return m_features.usesBeforeAfterRules; }
+    bool usesSiblingRules() const { return !m_ruleSets.features().siblingRules.isEmpty(); }
+    bool usesFirstLineRules() const { return m_ruleSets.features().usesFirstLineRules; }
+    bool usesBeforeAfterRules() const { return m_ruleSets.features().usesBeforeAfterRules; }
 
     static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
     
@@ -412,12 +417,7 @@ private:
     bool isFirstPage(int pageIndex) const;
     String pageName(int pageIndex) const;
 
-    OwnPtr<RuleSet> m_authorStyle;
-    OwnPtr<RuleSet> m_userStyle;
-
-    RuleFeatureSet m_features;
-    OwnPtr<RuleSet> m_siblingRuleSet;
-    OwnPtr<RuleSet> m_uncommonAttributeRuleSet;
+    DocumentRuleSets m_ruleSets;
 
     typedef HashMap<AtomicStringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap;
     KeyframesRuleMap m_keyframesRuleMap;
@@ -524,8 +524,6 @@ public:
 private:
     static RenderStyle* s_styleNotYetAvailable;
 
-    void collectRulesFromUserStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&, RuleSet& userStyle);
-
     void cacheBorderAndBackground();
 
 private:
@@ -603,19 +601,19 @@ private:
 inline bool StyleResolver::hasSelectorForAttribute(const AtomicString &attributeName) const
 {
     ASSERT(!attributeName.isEmpty());
-    return m_features.attrsInRules.contains(attributeName.impl());
+    return m_ruleSets.features().attrsInRules.contains(attributeName.impl());
 }
 
 inline bool StyleResolver::hasSelectorForClass(const AtomicString& classValue) const
 {
     ASSERT(!classValue.isEmpty());
-    return m_features.classesInRules.contains(classValue.impl());
+    return m_ruleSets.features().classesInRules.contains(classValue.impl());
 }
 
 inline bool StyleResolver::hasSelectorForId(const AtomicString& idValue) const
 {
     ASSERT(!idValue.isEmpty());
-    return m_features.idsInRules.contains(idValue.impl());
+    return m_ruleSets.features().idsInRules.contains(idValue.impl());
 }
 
 } // namespace WebCore
index 632fa94..3ac1f5e 100644 (file)
@@ -478,7 +478,7 @@ bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag
     else {
         StyleResolver* styleResolver = m_document->styleResolver();
         if (styleResolverUpdateType == Reset) {
-            styleResolver->resetAuthorStyle();
+            styleResolver->ruleSets().resetAuthorStyle();
             styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
         } else {
             ASSERT(styleResolverUpdateType == Additive);