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

Reviewed by Dimitri Glazkov.

Splitting each RuleSet and feature out from StyleResover into its onw class, DocumentRuleSets,
to manage them separately.

This is one of the attempts to try to resolve meta bug (bug 89879)
to lose StyleResolver's weight.  We need further action to factor
StyleResolver to separate it into some classes cleanly.
See also https://bugs.webkit.org/show_bug.cgi?id=108890. A following patch will address that.

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@141964 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 ec286bb..8931df3 100644 (file)
@@ -1070,6 +1070,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 8184d02..54c4dd7 100644 (file)
@@ -1,3 +1,71 @@
+2013-02-05  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.
+
+        Splitting each RuleSet and feature out from StyleResover into its onw class, DocumentRuleSets,
+        to manage them separately.
+
+        This is one of the attempts to try to resolve meta bug (bug 89879)
+        to lose StyleResolver's weight.  We need further action to factor
+        StyleResolver to separate it into some classes cleanly.
+        See also https://bugs.webkit.org/show_bug.cgi?id=108890. A following patch will address that.
+
+        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-05  Julien Chaffraix  <jchaffraix@webkit.org>
 
         [CSS Grid Layout] Grid item's logical height is not properly recomputed after -webkit-grid-column / -webkit-grid-row changes
index aae5c3b..571575a 100644 (file)
@@ -2620,6 +2620,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 5293cad..94e6e1b 100644 (file)
@@ -307,6 +307,7 @@ SOURCES += \
     css/CSSValue.cpp \
     css/CSSValueList.cpp \
     css/CSSValuePool.cpp \
+    css/DocumentRuleSets.cpp \
     css/FontFeatureValue.cpp \
     css/FontValue.cpp \
     css/InspectorCSSOMWrappers.cpp \
index fc1155c..c5adc01 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 c2afefd..2271a76 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);