1 /* 2 * Copyright (C) 1999-2003 Lars Knoll (knoll (at) kde.org) 3 * 1999 Waldo Bastian (bastian (at) 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: 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 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 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 191 PseudoType pseudoType() const 192 { 193 if (m_pseudoType == PseudoNotParsed) 194 extractPseudoType(); 195 return static_cast<PseudoType>(m_pseudoType); 196 } 197 198 CSSSelector* tagHistory() const { return m_hasRareData ? m_data.m_rareData->m_tagHistory.get() : m_data.m_tagHistory; } 199 void setTagHistory(CSSSelector* tagHistory); 200 201 bool hasTag() const { return m_tag != anyQName(); } 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; 205 const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; } 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 215 Relation relation() const { return static_cast<Relation>(m_relation); } 216 217 bool isLastInSelectorList() const { return m_isLastInSelectorList; } 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 { 235 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 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 { 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