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