Move RuleData to a file of its own
https://bugs.webkit.org/show_bug.cgi?id=204351
Reviewed by Anders Carlsson.
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* style/RuleData.cpp: Added.
(WebCore::Style::computeMatchBasedOnRuleHash):
(WebCore::Style::selectorCanMatchPseudoElement):
(WebCore::Style::isCommonAttributeSelectorAttribute):
(WebCore::Style::computeContainsUncommonAttributeSelector):
(WebCore::Style::determinePropertyWhitelistType):
(WebCore::Style::RuleData::RuleData):
* style/RuleData.h: Added.
(WebCore::Style::RuleData::position const):
(WebCore::Style::RuleData::rule const):
(WebCore::Style::RuleData::selector const):
(WebCore::Style::RuleData::selectorIndex const):
(WebCore::Style::RuleData::selectorListIndex const):
(WebCore::Style::RuleData::canMatchPseudoElement const):
(WebCore::Style::RuleData::matchBasedOnRuleHash const):
(WebCore::Style::RuleData::containsUncommonAttributeSelector const):
(WebCore::Style::RuleData::linkMatchType const):
(WebCore::Style::RuleData::propertyWhitelistType const):
(WebCore::Style::RuleData::descendantSelectorIdentifierHashes const):
(WebCore::Style::RuleData::disableSelectorFiltering):
* style/RuleSet.cpp:
(WebCore::Style::computeMatchBasedOnRuleHash): Deleted.
(WebCore::Style::selectorCanMatchPseudoElement): Deleted.
(WebCore::Style::isCommonAttributeSelectorAttribute): Deleted.
(WebCore::Style::computeContainsUncommonAttributeSelector): Deleted.
(WebCore::Style::determinePropertyWhitelistType): Deleted.
(WebCore::Style::RuleData::RuleData): Deleted.
* style/RuleSet.h:
(WebCore::Style::RuleData::position const): Deleted.
(WebCore::Style::RuleData::rule const): Deleted.
(WebCore::Style::RuleData::selector const): Deleted.
(WebCore::Style::RuleData::selectorIndex const): Deleted.
(WebCore::Style::RuleData::selectorListIndex const): Deleted.
(WebCore::Style::RuleData::canMatchPseudoElement const): Deleted.
(WebCore::Style::RuleData::matchBasedOnRuleHash const): Deleted.
(WebCore::Style::RuleData::containsUncommonAttributeSelector const): Deleted.
(WebCore::Style::RuleData::linkMatchType const): Deleted.
(WebCore::Style::RuleData::propertyWhitelistType const): Deleted.
(WebCore::Style::RuleData::descendantSelectorIdentifierHashes const): Deleted.
(WebCore::Style::RuleData::disableSelectorFiltering): Deleted.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@252629 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index b50a0e4..2854bf6 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,5 +1,55 @@
2019-11-19 Antti Koivisto <antti@apple.com>
+ Move RuleData to a file of its own
+ https://bugs.webkit.org/show_bug.cgi?id=204351
+
+ Reviewed by Anders Carlsson.
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * style/RuleData.cpp: Added.
+ (WebCore::Style::computeMatchBasedOnRuleHash):
+ (WebCore::Style::selectorCanMatchPseudoElement):
+ (WebCore::Style::isCommonAttributeSelectorAttribute):
+ (WebCore::Style::computeContainsUncommonAttributeSelector):
+ (WebCore::Style::determinePropertyWhitelistType):
+ (WebCore::Style::RuleData::RuleData):
+ * style/RuleData.h: Added.
+ (WebCore::Style::RuleData::position const):
+ (WebCore::Style::RuleData::rule const):
+ (WebCore::Style::RuleData::selector const):
+ (WebCore::Style::RuleData::selectorIndex const):
+ (WebCore::Style::RuleData::selectorListIndex const):
+ (WebCore::Style::RuleData::canMatchPseudoElement const):
+ (WebCore::Style::RuleData::matchBasedOnRuleHash const):
+ (WebCore::Style::RuleData::containsUncommonAttributeSelector const):
+ (WebCore::Style::RuleData::linkMatchType const):
+ (WebCore::Style::RuleData::propertyWhitelistType const):
+ (WebCore::Style::RuleData::descendantSelectorIdentifierHashes const):
+ (WebCore::Style::RuleData::disableSelectorFiltering):
+ * style/RuleSet.cpp:
+ (WebCore::Style::computeMatchBasedOnRuleHash): Deleted.
+ (WebCore::Style::selectorCanMatchPseudoElement): Deleted.
+ (WebCore::Style::isCommonAttributeSelectorAttribute): Deleted.
+ (WebCore::Style::computeContainsUncommonAttributeSelector): Deleted.
+ (WebCore::Style::determinePropertyWhitelistType): Deleted.
+ (WebCore::Style::RuleData::RuleData): Deleted.
+ * style/RuleSet.h:
+ (WebCore::Style::RuleData::position const): Deleted.
+ (WebCore::Style::RuleData::rule const): Deleted.
+ (WebCore::Style::RuleData::selector const): Deleted.
+ (WebCore::Style::RuleData::selectorIndex const): Deleted.
+ (WebCore::Style::RuleData::selectorListIndex const): Deleted.
+ (WebCore::Style::RuleData::canMatchPseudoElement const): Deleted.
+ (WebCore::Style::RuleData::matchBasedOnRuleHash const): Deleted.
+ (WebCore::Style::RuleData::containsUncommonAttributeSelector const): Deleted.
+ (WebCore::Style::RuleData::linkMatchType const): Deleted.
+ (WebCore::Style::RuleData::propertyWhitelistType const): Deleted.
+ (WebCore::Style::RuleData::descendantSelectorIdentifierHashes const): Deleted.
+ (WebCore::Style::RuleData::disableSelectorFiltering): Deleted.
+
+2019-11-19 Antti Koivisto <antti@apple.com>
+
Move ElementRuleCollector to Style namespace
https://bugs.webkit.org/show_bug.cgi?id=204329
diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt
index ee97339..0c9fdb9 100644
--- a/Source/WebCore/Sources.txt
+++ b/Source/WebCore/Sources.txt
@@ -2344,6 +2344,7 @@
style/MatchedDeclarationsCache.cpp
style/PageRuleCollector.cpp
style/PropertyCascade.cpp
+style/RuleData.cpp
style/RuleFeature.cpp
style/RuleSet.cpp
style/StyleAdjuster.cpp
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 02856dbb..cd13e9f 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -4841,6 +4841,7 @@
E47E276516036ED200EE2AFB /* ExtensionStyleSheets.h in Headers */ = {isa = PBXBuildFile; fileRef = E47E276416036ED200EE2AFB /* ExtensionStyleSheets.h */; settings = {ATTRIBUTES = (Private, ); }; };
E48137B91DB3B526005C59BF /* StyleValidity.h in Headers */ = {isa = PBXBuildFile; fileRef = E48137B81DB3B526005C59BF /* StyleValidity.h */; settings = {ATTRIBUTES = (Private, ); }; };
E484A33E23055325009ADE6A /* LineLayoutTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E484A33B23055303009ADE6A /* LineLayoutTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E4863CFE23842E9E00972158 /* RuleData.h in Headers */ = {isa = PBXBuildFile; fileRef = E4863CFD23842E9E00972158 /* RuleData.h */; };
E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E48944A1180B57D800F165D8 /* SimpleLineLayout.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4916FF7195DF6A0005AB349 /* LayerFlushThrottleState.h in Headers */ = {isa = PBXBuildFile; fileRef = E4916FF6195DF6A0005AB349 /* LayerFlushThrottleState.h */; settings = {ATTRIBUTES = (Private, ); }; };
E4946EAF156E64DD00D3297F /* StyleRuleImport.h in Headers */ = {isa = PBXBuildFile; fileRef = E4946EAD156E64DD00D3297F /* StyleRuleImport.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -15187,6 +15188,8 @@
E48137B81DB3B526005C59BF /* StyleValidity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleValidity.h; sourceTree = "<group>"; };
E484A33B23055303009ADE6A /* LineLayoutTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineLayoutTraversal.h; sourceTree = "<group>"; };
E484A33D23055303009ADE6A /* LineLayoutTraversal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LineLayoutTraversal.cpp; sourceTree = "<group>"; };
+ E4863CFA23842E8700972158 /* RuleData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RuleData.cpp; sourceTree = "<group>"; };
+ E4863CFD23842E9E00972158 /* RuleData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuleData.h; sourceTree = "<group>"; };
E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayout.cpp; sourceTree = "<group>"; };
E48944A1180B57D800F165D8 /* SimpleLineLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayout.h; sourceTree = "<group>"; };
E4916FF6195DF6A0005AB349 /* LayerFlushThrottleState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayerFlushThrottleState.h; sourceTree = "<group>"; };
@@ -27031,6 +27034,8 @@
FBDB61A016D6037E00BB3394 /* PageRuleCollector.h */,
E4ABABE52361A34200FA4345 /* PropertyCascade.cpp */,
E4ABABE22361A32900FA4345 /* PropertyCascade.h */,
+ E4863CFA23842E8700972158 /* RuleData.cpp */,
+ E4863CFD23842E9E00972158 /* RuleData.h */,
A79BAD9D161E7F3F00C2E652 /* RuleFeature.cpp */,
A79BAD9E161E7F3F00C2E652 /* RuleFeature.h */,
A79BAD9F161E7F3F00C2E652 /* RuleSet.cpp */,
@@ -31218,6 +31223,7 @@
E45BA6AA2374926C004DFC07 /* MatchedDeclarationsCache.h in Headers */,
FABE72F51059C1EB00D888CC /* MathMLAnnotationElement.h in Headers */,
FABE72F51059C1EB00D999DD /* MathMLElement.h in Headers */,
+ E4863CFE23842E9E00972158 /* RuleData.h in Headers */,
44A28AAC12DFB8AC00AE923B /* MathMLElementFactory.h in Headers */,
0BCF83F71059C1EB00D999DD /* MathMLFractionElement.h in Headers */,
FABE72F91059C1EB00D999DD /* MathMLMathElement.h in Headers */,
diff --git a/Source/WebCore/style/RuleData.cpp b/Source/WebCore/style/RuleData.cpp
new file mode 100644
index 0000000..f344db9
--- /dev/null
+++ b/Source/WebCore/style/RuleData.cpp
@@ -0,0 +1,179 @@
+/*
+ * 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-2019 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) 2012 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 "RuleData.h"
+
+#include "CSSFontSelector.h"
+#include "CSSKeyframesRule.h"
+#include "CSSSelector.h"
+#include "CSSSelectorList.h"
+#include "HTMLNames.h"
+#include "MediaQueryEvaluator.h"
+#include "SecurityOrigin.h"
+#include "SelectorChecker.h"
+#include "SelectorFilter.h"
+#include "StyleResolver.h"
+#include "StyleRule.h"
+#include "StyleRuleImport.h"
+#include "StyleSheetContents.h"
+#include "ViewportStyleResolver.h"
+
+#if ENABLE(VIDEO_TRACK)
+#include "TextTrackCue.h"
+#endif
+
+namespace WebCore {
+namespace Style {
+
+using namespace HTMLNames;
+
+struct SameSizeAsRuleData {
+ void* a;
+ unsigned b;
+ unsigned c;
+ unsigned d[4];
+};
+
+COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small);
+
+static inline MatchBasedOnRuleHash computeMatchBasedOnRuleHash(const CSSSelector& selector)
+{
+ if (selector.tagHistory())
+ return MatchBasedOnRuleHash::None;
+
+ if (selector.match() == CSSSelector::Tag) {
+ const QualifiedName& tagQualifiedName = selector.tagQName();
+ const AtomString& selectorNamespace = tagQualifiedName.namespaceURI();
+ if (selectorNamespace == starAtom() || selectorNamespace == xhtmlNamespaceURI) {
+ if (tagQualifiedName == anyQName())
+ return MatchBasedOnRuleHash::Universal;
+ return MatchBasedOnRuleHash::ClassC;
+ }
+ return MatchBasedOnRuleHash::None;
+ }
+ if (SelectorChecker::isCommonPseudoClassSelector(&selector))
+ return MatchBasedOnRuleHash::ClassB;
+ if (selector.match() == CSSSelector::Id)
+ return MatchBasedOnRuleHash::ClassA;
+ if (selector.match() == CSSSelector::Class)
+ return MatchBasedOnRuleHash::ClassB;
+ return MatchBasedOnRuleHash::None;
+}
+
+static bool selectorCanMatchPseudoElement(const CSSSelector& rootSelector)
+{
+ const CSSSelector* selector = &rootSelector;
+ do {
+ if (selector->matchesPseudoElement())
+ return true;
+
+ if (const CSSSelectorList* selectorList = selector->selectorList()) {
+ for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
+ if (selectorCanMatchPseudoElement(*subSelector))
+ return true;
+ }
+ }
+
+ selector = selector->tagHistory();
+ } while (selector);
+ return false;
+}
+
+static inline bool isCommonAttributeSelectorAttribute(const QualifiedName& attribute)
+{
+ // These are explicitly tested for equality in canShareStyleWithElement.
+ return attribute == typeAttr || attribute == readonlyAttr;
+}
+
+static bool computeContainsUncommonAttributeSelector(const CSSSelector& rootSelector, bool matchesRightmostElement = true)
+{
+ const CSSSelector* selector = &rootSelector;
+ do {
+ if (selector->isAttributeSelector()) {
+ // FIXME: considering non-rightmost simple selectors is necessary because of the style sharing of cousins.
+ // It is a primitive solution which disable a lot of style sharing on pages that rely on attributes for styling.
+ // We should investigate better ways of doing this.
+ if (!isCommonAttributeSelectorAttribute(selector->attribute()) || !matchesRightmostElement)
+ return true;
+ }
+
+ if (const CSSSelectorList* selectorList = selector->selectorList()) {
+ for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
+ if (computeContainsUncommonAttributeSelector(*subSelector, matchesRightmostElement))
+ return true;
+ }
+ }
+
+ if (selector->relation() != CSSSelector::Subselector)
+ matchesRightmostElement = false;
+
+ selector = selector->tagHistory();
+ } while (selector);
+ return false;
+}
+
+static inline PropertyWhitelistType determinePropertyWhitelistType(const CSSSelector* selector)
+{
+ for (const CSSSelector* component = selector; component; component = component->tagHistory()) {
+#if ENABLE(VIDEO_TRACK)
+ if (component->match() == CSSSelector::PseudoElement && (component->pseudoElementType() == CSSSelector::PseudoElementCue || component->value() == TextTrackCue::cueShadowPseudoId()))
+ return PropertyWhitelistCue;
+#endif
+ if (component->match() == CSSSelector::PseudoElement && component->pseudoElementType() == CSSSelector::PseudoElementMarker)
+ return PropertyWhitelistMarker;
+
+ if (const auto* selectorList = selector->selectorList()) {
+ for (const auto* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
+ auto whitelistType = determinePropertyWhitelistType(subSelector);
+ if (whitelistType != PropertyWhitelistNone)
+ return whitelistType;
+ }
+ }
+ }
+ return PropertyWhitelistNone;
+}
+
+RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned position)
+ : m_rule(rule)
+ , m_selectorIndex(selectorIndex)
+ , m_selectorListIndex(selectorListIndex)
+ , m_position(position)
+ , m_matchBasedOnRuleHash(static_cast<unsigned>(computeMatchBasedOnRuleHash(*selector())))
+ , m_canMatchPseudoElement(selectorCanMatchPseudoElement(*selector()))
+ , m_containsUncommonAttributeSelector(computeContainsUncommonAttributeSelector(*selector()))
+ , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector()))
+ , m_propertyWhitelistType(determinePropertyWhitelistType(selector()))
+ , m_descendantSelectorIdentifierHashes(SelectorFilter::collectHashes(*selector()))
+{
+ ASSERT(m_position == position);
+ ASSERT(m_selectorIndex == selectorIndex);
+}
+
+} // namespace Style
+} // namespace WebCore
diff --git a/Source/WebCore/style/RuleData.h b/Source/WebCore/style/RuleData.h
new file mode 100644
index 0000000..0125fae
--- /dev/null
+++ b/Source/WebCore/style/RuleData.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003-2019 Apple 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.
+ *
+ */
+
+#pragma once
+
+#include "SelectorFilter.h"
+#include "StyleRule.h"
+#include <wtf/text/AtomString.h>
+#include <wtf/text/AtomStringHash.h>
+
+namespace WebCore {
+namespace Style {
+
+enum PropertyWhitelistType {
+ PropertyWhitelistNone = 0,
+ PropertyWhitelistMarker,
+#if ENABLE(VIDEO_TRACK)
+ PropertyWhitelistCue
+#endif
+};
+
+enum class MatchBasedOnRuleHash : unsigned {
+ None,
+ Universal,
+ ClassA,
+ ClassB,
+ ClassC
+};
+
+class RuleData {
+public:
+ static const unsigned maximumSelectorComponentCount = 8192;
+
+ RuleData(StyleRule*, unsigned selectorIndex, unsigned selectorListIndex, unsigned position);
+
+ unsigned position() const { return m_position; }
+ StyleRule* rule() const { return m_rule.get(); }
+ const CSSSelector* selector() const { return m_rule->selectorList().selectorAt(m_selectorIndex); }
+ unsigned selectorIndex() const { return m_selectorIndex; }
+ unsigned selectorListIndex() const { return m_selectorListIndex; }
+
+ bool canMatchPseudoElement() const { return m_canMatchPseudoElement; }
+ MatchBasedOnRuleHash matchBasedOnRuleHash() const { return static_cast<MatchBasedOnRuleHash>(m_matchBasedOnRuleHash); }
+ bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; }
+ unsigned linkMatchType() const { return m_linkMatchType; }
+ PropertyWhitelistType propertyWhitelistType() const { return static_cast<PropertyWhitelistType>(m_propertyWhitelistType); }
+ const SelectorFilter::Hashes& descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
+
+ void disableSelectorFiltering() { m_descendantSelectorIdentifierHashes[0] = 0; }
+
+private:
+ RefPtr<StyleRule> m_rule;
+ unsigned m_selectorIndex : 16;
+ unsigned m_selectorListIndex : 16;
+ // This number was picked fairly arbitrarily. We can probably lower it if we need to.
+ // Some simple testing showed <100,000 RuleData's on large sites.
+ unsigned m_position : 18;
+ unsigned m_matchBasedOnRuleHash : 3;
+ unsigned m_canMatchPseudoElement : 1;
+ unsigned m_containsUncommonAttributeSelector : 1;
+ unsigned m_linkMatchType : 2; // SelectorChecker::LinkMatchMask
+ unsigned m_propertyWhitelistType : 2;
+ SelectorFilter::Hashes m_descendantSelectorIdentifierHashes;
+};
+
+} // namespace Style
+} // namespace WebCore
+
+namespace WTF {
+
+// RuleData is simple enough that initializing to 0 and moving with memcpy will totally work.
+template<> struct VectorTraits<WebCore::Style::RuleData> : SimpleClassVectorTraits { };
+
+} // namespace WTF
+
diff --git a/Source/WebCore/style/RuleSet.cpp b/Source/WebCore/style/RuleSet.cpp
index 1980f95..d401b67 100644
--- a/Source/WebCore/style/RuleSet.cpp
+++ b/Source/WebCore/style/RuleSet.cpp
@@ -2,7 +2,7 @@
* 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-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2005-2019 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/)
@@ -53,121 +53,6 @@
using namespace HTMLNames;
-// -----------------------------------------------------------------
-
-static inline MatchBasedOnRuleHash computeMatchBasedOnRuleHash(const CSSSelector& selector)
-{
- if (selector.tagHistory())
- return MatchBasedOnRuleHash::None;
-
- if (selector.match() == CSSSelector::Tag) {
- const QualifiedName& tagQualifiedName = selector.tagQName();
- const AtomString& selectorNamespace = tagQualifiedName.namespaceURI();
- if (selectorNamespace == starAtom() || selectorNamespace == xhtmlNamespaceURI) {
- if (tagQualifiedName == anyQName())
- return MatchBasedOnRuleHash::Universal;
- return MatchBasedOnRuleHash::ClassC;
- }
- return MatchBasedOnRuleHash::None;
- }
- if (SelectorChecker::isCommonPseudoClassSelector(&selector))
- return MatchBasedOnRuleHash::ClassB;
- if (selector.match() == CSSSelector::Id)
- return MatchBasedOnRuleHash::ClassA;
- if (selector.match() == CSSSelector::Class)
- return MatchBasedOnRuleHash::ClassB;
- return MatchBasedOnRuleHash::None;
-}
-
-static bool selectorCanMatchPseudoElement(const CSSSelector& rootSelector)
-{
- const CSSSelector* selector = &rootSelector;
- do {
- if (selector->matchesPseudoElement())
- return true;
-
- if (const CSSSelectorList* selectorList = selector->selectorList()) {
- for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
- if (selectorCanMatchPseudoElement(*subSelector))
- return true;
- }
- }
-
- selector = selector->tagHistory();
- } while (selector);
- return false;
-}
-
-static inline bool isCommonAttributeSelectorAttribute(const QualifiedName& attribute)
-{
- // These are explicitly tested for equality in canShareStyleWithElement.
- return attribute == typeAttr || attribute == readonlyAttr;
-}
-
-static bool computeContainsUncommonAttributeSelector(const CSSSelector& rootSelector, bool matchesRightmostElement = true)
-{
- const CSSSelector* selector = &rootSelector;
- do {
- if (selector->isAttributeSelector()) {
- // FIXME: considering non-rightmost simple selectors is necessary because of the style sharing of cousins.
- // It is a primitive solution which disable a lot of style sharing on pages that rely on attributes for styling.
- // We should investigate better ways of doing this.
- if (!isCommonAttributeSelectorAttribute(selector->attribute()) || !matchesRightmostElement)
- return true;
- }
-
- if (const CSSSelectorList* selectorList = selector->selectorList()) {
- for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
- if (computeContainsUncommonAttributeSelector(*subSelector, matchesRightmostElement))
- return true;
- }
- }
-
- if (selector->relation() != CSSSelector::Subselector)
- matchesRightmostElement = false;
-
- selector = selector->tagHistory();
- } while (selector);
- return false;
-}
-
-static inline PropertyWhitelistType determinePropertyWhitelistType(const CSSSelector* selector)
-{
- for (const CSSSelector* component = selector; component; component = component->tagHistory()) {
-#if ENABLE(VIDEO_TRACK)
- if (component->match() == CSSSelector::PseudoElement && (component->pseudoElementType() == CSSSelector::PseudoElementCue || component->value() == TextTrackCue::cueShadowPseudoId()))
- return PropertyWhitelistCue;
-#endif
- if (component->match() == CSSSelector::PseudoElement && component->pseudoElementType() == CSSSelector::PseudoElementMarker)
- return PropertyWhitelistMarker;
-
- if (const auto* selectorList = selector->selectorList()) {
- for (const auto* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
- auto whitelistType = determinePropertyWhitelistType(subSelector);
- if (whitelistType != PropertyWhitelistNone)
- return whitelistType;
- }
- }
- }
- return PropertyWhitelistNone;
-}
-
-RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned position)
- : m_rule(rule)
- , m_selectorIndex(selectorIndex)
- , m_selectorListIndex(selectorListIndex)
- , m_position(position)
- , m_matchBasedOnRuleHash(static_cast<unsigned>(computeMatchBasedOnRuleHash(*selector())))
- , m_canMatchPseudoElement(selectorCanMatchPseudoElement(*selector()))
- , m_containsUncommonAttributeSelector(computeContainsUncommonAttributeSelector(*selector()))
- , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector()))
- , m_propertyWhitelistType(determinePropertyWhitelistType(selector()))
- , m_descendantSelectorIdentifierHashes(SelectorFilter::collectHashes(*selector()))
-{
- ASSERT(m_position == position);
- ASSERT(m_selectorIndex == selectorIndex);
-}
-
RuleSet::RuleSet() = default;
RuleSet::~RuleSet() = default;
diff --git a/Source/WebCore/style/RuleSet.h b/Source/WebCore/style/RuleSet.h
index 7fadfa6..3b96581 100644
--- a/Source/WebCore/style/RuleSet.h
+++ b/Source/WebCore/style/RuleSet.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2003-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2019 Apple 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
@@ -21,6 +21,7 @@
#pragma once
+#include "RuleData.h"
#include "RuleFeature.h"
#include "SelectorCompiler.h"
#include "SelectorFilter.h"
@@ -33,76 +34,13 @@
namespace WebCore {
class CSSSelector;
-class ContainerNode;
class MediaQueryEvaluator;
-class Node;
class StyleSheetContents;
namespace Style {
class Resolver;
-enum PropertyWhitelistType {
- PropertyWhitelistNone = 0,
- PropertyWhitelistMarker,
-#if ENABLE(VIDEO_TRACK)
- PropertyWhitelistCue
-#endif
-};
-
-enum class MatchBasedOnRuleHash : unsigned {
- None,
- Universal,
- ClassA,
- ClassB,
- ClassC
-};
-
-class RuleData {
-public:
- static const unsigned maximumSelectorComponentCount = 8192;
-
- RuleData(StyleRule*, unsigned selectorIndex, unsigned selectorListIndex, unsigned position);
-
- unsigned position() const { return m_position; }
- StyleRule* rule() const { return m_rule.get(); }
- const CSSSelector* selector() const { return m_rule->selectorList().selectorAt(m_selectorIndex); }
- unsigned selectorIndex() const { return m_selectorIndex; }
- unsigned selectorListIndex() const { return m_selectorListIndex; }
-
- bool canMatchPseudoElement() const { return m_canMatchPseudoElement; }
- MatchBasedOnRuleHash matchBasedOnRuleHash() const { return static_cast<MatchBasedOnRuleHash>(m_matchBasedOnRuleHash); }
- bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; }
- unsigned linkMatchType() const { return m_linkMatchType; }
- PropertyWhitelistType propertyWhitelistType() const { return static_cast<PropertyWhitelistType>(m_propertyWhitelistType); }
- const SelectorFilter::Hashes& descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
-
- void disableSelectorFiltering() { m_descendantSelectorIdentifierHashes[0] = 0; }
-
-private:
- RefPtr<StyleRule> m_rule;
- unsigned m_selectorIndex : 16;
- unsigned m_selectorListIndex : 16;
- // This number was picked fairly arbitrarily. We can probably lower it if we need to.
- // Some simple testing showed <100,000 RuleData's on large sites.
- unsigned m_position : 18;
- unsigned m_matchBasedOnRuleHash : 3;
- unsigned m_canMatchPseudoElement : 1;
- unsigned m_containsUncommonAttributeSelector : 1;
- unsigned m_linkMatchType : 2; // SelectorChecker::LinkMatchMask
- unsigned m_propertyWhitelistType : 2;
- SelectorFilter::Hashes m_descendantSelectorIdentifierHashes;
-};
-
-struct SameSizeAsRuleData {
- void* a;
- unsigned b;
- unsigned c;
- unsigned d[4];
-};
-
-COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small);
-
class RuleSet {
WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -192,10 +130,3 @@
} // namespace Style
} // namespace WebCore
-
-namespace WTF {
-
-// RuleData is simple enough that initializing to 0 and moving with memcpy will totally work.
-template<> struct VectorTraits<WebCore::Style::RuleData> : SimpleClassVectorTraits { };
-
-} // namespace WTF