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