1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#pragma once
23
24#include "MediaQueryEvaluator.h"
25#include "SelectorChecker.h"
26#include "StyleResolver.h"
27#include <memory>
28#include <wtf/RefPtr.h>
29#include <wtf/Vector.h>
30
31namespace WebCore {
32
33class DocumentRuleSets;
34class MatchRequest;
35class RuleData;
36class RuleSet;
37class SelectorFilter;
38
39struct MatchedRule {
40 const RuleData* ruleData;
41 unsigned specificity;
42 Style::ScopeOrdinal styleScopeOrdinal;
43};
44
45class ElementRuleCollector {
46public:
47 ElementRuleCollector(const Element&, const DocumentRuleSets&, const SelectorFilter*);
48 ElementRuleCollector(const Element&, const RuleSet& authorStyle, const SelectorFilter*);
49
50 void matchAllRules(bool matchAuthorAndUserStyles, bool includeSMILProperties);
51 void matchUARules();
52 void matchAuthorRules(bool includeEmptyRules);
53 void matchUserRules(bool includeEmptyRules);
54
55 void setMode(SelectorChecker::Mode mode) { m_mode = mode; }
56 void setPseudoStyleRequest(const PseudoStyleRequest& request) { m_pseudoStyleRequest = request; }
57 void setMedium(const MediaQueryEvaluator* medium) { m_isPrintStyle = medium->mediaTypeMatchSpecific("print"); }
58
59 bool hasAnyMatchingRules(const RuleSet*);
60
61 StyleResolver::MatchResult& matchedResult();
62 const Vector<RefPtr<StyleRule>>& matchedRuleList() const;
63
64 bool hasMatchedRules() const { return !m_matchedRules.isEmpty(); }
65 void clearMatchedRules();
66
67 const PseudoIdSet& matchedPseudoElementIds() const { return m_matchedPseudoElementIds; }
68 const Style::Relations& styleRelations() const { return m_styleRelations; }
69 bool didMatchUncommonAttributeSelector() const { return m_didMatchUncommonAttributeSelector; }
70
71private:
72 void addElementStyleProperties(const StyleProperties*, bool isCacheable = true);
73
74 void matchUARules(const RuleSet&);
75 void matchAuthorShadowPseudoElementRules(bool includeEmptyRules, StyleResolver::RuleRange&);
76 void matchHostPseudoClassRules(bool includeEmptyRules, StyleResolver::RuleRange&);
77 void matchSlottedPseudoElementRules(bool includeEmptyRules, StyleResolver::RuleRange&);
78
79 void collectMatchingShadowPseudoElementRules(const MatchRequest&, StyleResolver::RuleRange&);
80 std::unique_ptr<RuleSet::RuleDataVector> collectSlottedPseudoElementRulesForSlot(bool includeEmptyRules);
81
82 void collectMatchingRules(const MatchRequest&, StyleResolver::RuleRange&);
83 void collectMatchingRulesForList(const RuleSet::RuleDataVector*, const MatchRequest&, StyleResolver::RuleRange&);
84 bool ruleMatches(const RuleData&, unsigned &specificity);
85
86 void sortMatchedRules();
87 void sortAndTransferMatchedRules();
88
89 void addMatchedRule(const RuleData&, unsigned specificity, Style::ScopeOrdinal, StyleResolver::RuleRange&);
90
91 const Element& m_element;
92 const RuleSet& m_authorStyle;
93 const RuleSet* m_userStyle { nullptr };
94 const RuleSet* m_userAgentMediaQueryStyle { nullptr };
95 const SelectorFilter* m_selectorFilter { nullptr };
96
97 bool m_isPrintStyle { false };
98 PseudoStyleRequest m_pseudoStyleRequest { PseudoId::None };
99 SelectorChecker::Mode m_mode { SelectorChecker::Mode::ResolvingStyle };
100 bool m_isMatchingSlottedPseudoElements { false };
101 bool m_isMatchingHostPseudoClass { false };
102 Vector<std::unique_ptr<RuleSet::RuleDataVector>> m_keepAliveSlottedPseudoElementRules;
103
104 Vector<MatchedRule, 64> m_matchedRules;
105
106 // Output.
107 Vector<RefPtr<StyleRule>> m_matchedRuleList;
108 bool m_didMatchUncommonAttributeSelector { false };
109 StyleResolver::MatchResult m_result;
110 Style::Relations m_styleRelations;
111 PseudoIdSet m_matchedPseudoElementIds;
112};
113
114} // namespace WebCore
115