• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the CSS implementation for KDE.
3  *
4  * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
5  *               1999 Waldo Bastian (bastian@kde.org)
6  * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #ifndef CSSSelector_h
25 #define CSSSelector_h
26 
27 #include "QualifiedName.h"
28 #include <wtf/Noncopyable.h>
29 #include <wtf/OwnPtr.h>
30 
31 namespace WebCore {
32 
33     // this class represents a selector for a StyleRule
34     class CSSSelector : public Noncopyable {
35     public:
CSSSelector()36         CSSSelector()
37             : m_tag(anyQName())
38             , m_relation(Descendant)
39             , m_match(None)
40             , m_pseudoType(PseudoNotParsed)
41             , m_parsedNth(false)
42             , m_isLastInSelectorList(false)
43             , m_hasRareData(false)
44         {
45         }
46 
CSSSelector(const QualifiedName & qName)47         CSSSelector(const QualifiedName& qName)
48             : m_tag(qName)
49             , m_relation(Descendant)
50             , m_match(None)
51             , m_pseudoType(PseudoNotParsed)
52             , m_parsedNth(false)
53             , m_isLastInSelectorList(false)
54             , m_hasRareData(false)
55         {
56         }
57 
~CSSSelector()58         ~CSSSelector()
59         {
60             if (m_hasRareData)
61                 delete m_data.m_rareData;
62             else
63                 delete m_data.m_tagHistory;
64         }
65 
66         /**
67          * Re-create selector text from selector's data
68          */
69         String selectorText() const;
70 
71         // checks if the 2 selectors (including sub selectors) agree.
72         bool operator==(const CSSSelector&);
73 
74         // tag == -1 means apply to all elements (Selector = *)
75 
76         unsigned specificity();
77 
78         /* how the attribute value has to match.... Default is Exact */
79         enum Match {
80             None = 0,
81             Id,
82             Class,
83             Exact,
84             Set,
85             List,
86             Hyphen,
87             PseudoClass,
88             PseudoElement,
89             Contain,   // css3: E[foo*="bar"]
90             Begin,     // css3: E[foo^="bar"]
91             End        // css3: E[foo$="bar"]
92         };
93 
94         enum Relation {
95             Descendant = 0,
96             Child,
97             DirectAdjacent,
98             IndirectAdjacent,
99             SubSelector
100         };
101 
102         enum PseudoType {
103             PseudoNotParsed = 0,
104             PseudoUnknown,
105             PseudoEmpty,
106             PseudoFirstChild,
107             PseudoFirstOfType,
108             PseudoLastChild,
109             PseudoLastOfType,
110             PseudoOnlyChild,
111             PseudoOnlyOfType,
112             PseudoFirstLine,
113             PseudoFirstLetter,
114             PseudoNthChild,
115             PseudoNthOfType,
116             PseudoNthLastChild,
117             PseudoNthLastOfType,
118             PseudoLink,
119             PseudoVisited,
120             PseudoAnyLink,
121             PseudoAutofill,
122             PseudoHover,
123             PseudoDrag,
124             PseudoFocus,
125             PseudoActive,
126             PseudoChecked,
127             PseudoEnabled,
128             PseudoFullPageMedia,
129             PseudoDisabled,
130             PseudoInputPlaceholder,
131             PseudoOptional,
132             PseudoRequired,
133             PseudoReadOnly,
134             PseudoReadWrite,
135             PseudoIndeterminate,
136             PseudoTarget,
137             PseudoBefore,
138             PseudoAfter,
139             PseudoLang,
140             PseudoNot,
141             PseudoResizer,
142             PseudoRoot,
143             PseudoScrollbar,
144             PseudoScrollbarBack,
145             PseudoScrollbarButton,
146             PseudoScrollbarCorner,
147             PseudoScrollbarForward,
148             PseudoScrollbarThumb,
149             PseudoScrollbarTrack,
150             PseudoScrollbarTrackPiece,
151             PseudoWindowInactive,
152             PseudoCornerPresent,
153             PseudoDecrement,
154             PseudoIncrement,
155             PseudoHorizontal,
156             PseudoVertical,
157             PseudoStart,
158             PseudoEnd,
159             PseudoDoubleButton,
160             PseudoSingleButton,
161             PseudoNoButton,
162             PseudoSelection,
163             PseudoFileUploadButton,
164             PseudoSliderThumb,
165             PseudoSearchCancelButton,
166             PseudoSearchDecoration,
167             PseudoSearchResultsDecoration,
168             PseudoSearchResultsButton,
169             PseudoMediaControlsPanel,
170             PseudoMediaControlsMuteButton,
171             PseudoMediaControlsPlayButton,
172             PseudoMediaControlsTimelineContainer,
173             PseudoMediaControlsCurrentTimeDisplay,
174             PseudoMediaControlsTimeRemainingDisplay,
175             PseudoMediaControlsTimeline,
176             PseudoMediaControlsSeekBackButton,
177             PseudoMediaControlsSeekForwardButton,
178             PseudoMediaControlsRewindButton,
179             PseudoMediaControlsReturnToRealtimeButton,
180             PseudoMediaControlsStatusDisplay,
181             PseudoMediaControlsFullscreenButton
182         };
183 
pseudoType()184         PseudoType pseudoType() const
185         {
186             if (m_pseudoType == PseudoNotParsed)
187                 extractPseudoType();
188             return static_cast<PseudoType>(m_pseudoType);
189         }
190 
tagHistory()191         CSSSelector* tagHistory() const { return m_hasRareData ? m_data.m_rareData->m_tagHistory.get() : m_data.m_tagHistory; }
192         void setTagHistory(CSSSelector* tagHistory);
193 
hasTag()194         bool hasTag() const { return m_tag != anyQName(); }
hasAttribute()195         bool hasAttribute() const { return m_match == Id || m_match == Class || (m_hasRareData && m_data.m_rareData->m_attribute != anyQName()); }
196 
197         const QualifiedName& attribute() const;
argument()198         const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; }
simpleSelector()199         CSSSelector* simpleSelector() const { return m_hasRareData ? m_data.m_rareData->m_simpleSelector.get() : 0; }
200 
201         void setAttribute(const QualifiedName& value);
202         void setArgument(const AtomicString& value);
203         void setSimpleSelector(CSSSelector* value);
204 
205         bool parseNth();
206         bool matchNth(int count);
207 
relation()208         Relation relation() const { return static_cast<Relation>(m_relation); }
209 
isLastInSelectorList()210         bool isLastInSelectorList() const { return m_isLastInSelectorList; }
setLastInSelectorList()211         void setLastInSelectorList() { m_isLastInSelectorList = true; }
212 
213         mutable AtomicString m_value;
214         QualifiedName m_tag;
215 
216         unsigned m_relation           : 3; // enum Relation
217         mutable unsigned m_match      : 4; // enum Match
218         mutable unsigned m_pseudoType : 8; // PseudoType
219 
220     private:
221         bool m_parsedNth              : 1; // Used for :nth-*
222         bool m_isLastInSelectorList   : 1;
223         bool m_hasRareData            : 1;
224 
225         void extractPseudoType() const;
226 
227         struct RareData {
RareDataRareData228             RareData(CSSSelector* tagHistory)
229                 : m_tagHistory(tagHistory)
230                 , m_simpleSelector(0)
231                 , m_attribute(anyQName())
232                 , m_argument(nullAtom)
233                 , m_a(0)
234                 , m_b(0)
235             {
236             }
237 
238             bool parseNth();
239             bool matchNth(int count);
240 
241             OwnPtr<CSSSelector> m_tagHistory;
242             OwnPtr<CSSSelector> m_simpleSelector; // Used for :not.
243             QualifiedName m_attribute; // used for attribute selector
244             AtomicString m_argument; // Used for :contains, :lang and :nth-*
245             int m_a; // Used for :nth-*
246             int m_b; // Used for :nth-*
247         };
248 
createRareData()249         void createRareData()
250         {
251             if (m_hasRareData)
252                 return;
253             m_data.m_rareData = new RareData(m_data.m_tagHistory);
254             m_hasRareData = true;
255         }
256 
257         union DataUnion {
DataUnion()258             DataUnion() : m_tagHistory(0) { }
259             CSSSelector* m_tagHistory;
260             RareData* m_rareData;
261         } m_data;
262     };
263 
264 } // namespace WebCore
265 
266 #endif // CSSSelector_h
267