1/*
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 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#pragma once
22
23#include "CSSSelector.h"
24#include "CSSValueKeywords.h"
25#include <wtf/text/AtomicString.h>
26#include <wtf/text/AtomicStringHash.h>
27#include <wtf/text/WTFString.h>
28
29namespace WebCore {
30
31class CSSValue;
32class QualifiedName;
33
34enum class CSSParserSelectorCombinator {
35 Child,
36 DescendantSpace,
37 DirectAdjacent,
38 IndirectAdjacent
39};
40
41class CSSParserSelector {
42 WTF_MAKE_FAST_ALLOCATED;
43public:
44 static CSSParserSelector* parsePseudoClassSelectorFromStringView(StringView&);
45 static CSSParserSelector* parsePseudoElementSelectorFromStringView(StringView&);
46 static CSSParserSelector* parsePagePseudoSelector(const AtomicString&);
47
48 CSSParserSelector();
49 explicit CSSParserSelector(const QualifiedName&);
50 ~CSSParserSelector();
51
52 std::unique_ptr<CSSSelector> releaseSelector() { return WTFMove(m_selector); }
53
54 void setValue(const AtomicString& value, bool matchLowerCase = false) { m_selector->setValue(value, matchLowerCase); }
55
56 void setAttribute(const QualifiedName& value, bool convertToLowercase, CSSSelector::AttributeMatchType type) { m_selector->setAttribute(value, convertToLowercase, type); }
57
58 void setArgument(const AtomicString& value) { m_selector->setArgument(value); }
59 void setNth(int a, int b) { m_selector->setNth(a, b); }
60 void setMatch(CSSSelector::Match value) { m_selector->setMatch(value); }
61 void setRelation(CSSSelector::RelationType value) { m_selector->setRelation(value); }
62 void setForPage() { m_selector->setForPage(); }
63
64 CSSSelector::Match match() const { return m_selector->match(); }
65 CSSSelector::PseudoElementType pseudoElementType() const { return m_selector->pseudoElementType(); }
66 const CSSSelectorList* selectorList() const { return m_selector->selectorList(); }
67
68 void setPseudoElementType(CSSSelector::PseudoElementType type) { m_selector->setPseudoElementType(type); }
69
70 void adoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>&&);
71 void setLangArgumentList(std::unique_ptr<Vector<AtomicString>>);
72 void setSelectorList(std::unique_ptr<CSSSelectorList>);
73
74 CSSSelector::PseudoClassType pseudoClassType() const { return m_selector->pseudoClassType(); }
75 bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); }
76
77 bool isPseudoElementCueFunction() const
78 {
79#if ENABLE(VIDEO_TRACK)
80 return m_selector->match() == CSSSelector::PseudoElement && m_selector->pseudoElementType() == CSSSelector::PseudoElementCue;
81#else
82 return false;
83#endif
84 }
85
86 bool hasShadowDescendant() const;
87 bool matchesPseudoElement() const;
88
89 bool isHostPseudoSelector() const;
90
91 // FIXME-NEWPARSER: "slotted" was removed here for now, since it leads to a combinator
92 // connection of ShadowDescendant, and the current shadow DOM code doesn't expect this. When
93 // we do fix this issue, make sure to patch the namespace prependTag code to remove the slotted
94 // special case, since it will be covered by this function once again.
95 bool needsImplicitShadowCombinatorForMatching() const;
96
97 CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
98 void setTagHistory(std::unique_ptr<CSSParserSelector> selector) { m_tagHistory = WTFMove(selector); }
99 void clearTagHistory() { m_tagHistory.reset(); }
100 void insertTagHistory(CSSSelector::RelationType before, std::unique_ptr<CSSParserSelector>, CSSSelector::RelationType after);
101 void appendTagHistory(CSSSelector::RelationType, std::unique_ptr<CSSParserSelector>);
102 void appendTagHistory(CSSParserSelectorCombinator, std::unique_ptr<CSSParserSelector>);
103 void prependTagSelector(const QualifiedName&, bool tagIsForNamespaceRule = false);
104 std::unique_ptr<CSSParserSelector> releaseTagHistory();
105
106private:
107 std::unique_ptr<CSSSelector> m_selector;
108 std::unique_ptr<CSSParserSelector> m_tagHistory;
109};
110
111inline bool CSSParserSelector::hasShadowDescendant() const
112{
113 return m_selector->relation() == CSSSelector::ShadowDescendant;
114}
115
116inline bool CSSParserSelector::needsImplicitShadowCombinatorForMatching() const
117{
118 return match() == CSSSelector::PseudoElement
119 && (pseudoElementType() == CSSSelector::PseudoElementWebKitCustom
120#if ENABLE(VIDEO_TRACK)
121 || pseudoElementType() == CSSSelector::PseudoElementCue
122#endif
123 || pseudoElementType() == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed);
124}
125
126}
127