1 /* 2 * This file is part of the CSS implementation for KDE. 3 * 4 * Copyright 1999-2003 Lars Knoll (knoll@kde.org) 5 * Copyright 1999 Waldo Bastian (bastian@kde.org) 6 * Copyright 2002 Apple Computer, Inc. 7 * Copyright 2004 Allan Sandfeld Jensen (kde@carewolf.com) 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Library General Public 11 * License as published by the Free Software Foundation; either 12 * version 2 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Library General Public License for more details. 18 * 19 * You should have received a copy of the GNU Library General Public License 20 * along with this library; see the file COPYING.LIB. If not, write to 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301, USA. 23 * 24 */ 25 #ifndef _CSS_BASE_H 26 #define _CSS_BASE_H 27 28 #include "misc/AtomicString.h" 29 #include "dom/dom_misc.h" 30 #include "xml/dom_nodeimpl.h" 31 #include "misc/shared.h" 32 #include "misc/enum.h" 33 34 #include <QDate> 35 36 namespace DOM 37 { 38 39 class StyleSheetImpl; 40 class MediaList; 41 42 class CSSSelector; 43 class CSSProperty; 44 class CSSValueImpl; 45 46 // this class represents a selector for a StyleRule 47 class CSSSelector 48 { 49 public: CSSSelector()50 CSSSelector() 51 : tagHistory(nullptr), simpleSelector(nullptr), relation(Descendant), 52 match(None), pseudoId(0), _pseudoType(PseudoNotParsed) 53 { 54 tagLocalName = LocalName::fromId(anyLocalName); 55 tagNamespace = NamespaceName::fromId(anyNamespace); 56 attrLocalName = LocalName::fromId(0); 57 attrNamespace = NamespaceName::fromId(0); 58 } 59 ~CSSSelector()60 ~CSSSelector() 61 { 62 delete tagHistory; 63 delete simpleSelector; 64 } 65 66 /** 67 * Print debug output for this selector 68 */ 69 void print(); 70 71 /** 72 * Re-create selector text from selector's data 73 */ 74 DOMString selectorText() const; 75 76 // checks if the 2 selectors (including sub selectors) agree. 77 bool operator == (const CSSSelector &other) const; 78 79 // tag == -1 means apply to all elements (Selector = *) 80 81 unsigned int specificity() const; 82 83 /* how the attribute value has to match.... Default is Exact */ 84 enum Match { 85 None = 0, 86 Id, 87 Exact, 88 Set, 89 Class, 90 List, 91 Hyphen, 92 PseudoClass, 93 PseudoElement, 94 Contain, // css3: E[foo*="bar"] 95 Begin, // css3: E[foo^="bar"] 96 End // css3: E[foo$="bar"] 97 }; 98 99 enum Relation { 100 Descendant = 0, 101 Child, 102 DirectAdjacent, 103 IndirectAdjacent, 104 SubSelector 105 }; 106 107 enum PseudoType { 108 PseudoNotParsed = 0, 109 PseudoOther, 110 PseudoEmpty, 111 PseudoFirstChild, 112 PseudoLastChild, 113 PseudoNthChild, 114 PseudoNthLastChild, 115 PseudoOnlyChild, 116 PseudoFirstOfType, 117 PseudoLastOfType, 118 PseudoNthOfType, 119 PseudoNthLastOfType, 120 PseudoOnlyOfType, 121 PseudoLink, 122 PseudoVisited, 123 PseudoHover, 124 PseudoFocus, 125 PseudoActive, 126 PseudoTarget, 127 PseudoLang, 128 PseudoNot, 129 PseudoContains, 130 PseudoRoot, 131 PseudoEnabled, 132 PseudoDisabled, 133 PseudoDefault, 134 PseudoReadOnly, 135 PseudoReadWrite, 136 PseudoChecked, 137 PseudoIndeterminate, 138 // pseudo-elements: 139 // inherited: 140 PseudoFirstLine, 141 PseudoFirstLetter, 142 PseudoSelection, 143 // generated: 144 PseudoBefore, 145 PseudoAfter, 146 PseudoMarker, 147 PseudoReplaced 148 }; 149 pseudoType()150 PseudoType pseudoType() const 151 { 152 if (_pseudoType == PseudoNotParsed) { 153 extractPseudoType(); 154 } 155 return KDE_CAST_BF_ENUM(PseudoType, _pseudoType); 156 } 157 158 mutable khtml::AtomicString value; 159 CSSSelector *tagHistory; 160 CSSSelector *simpleSelector; // Used by :not 161 DOM::DOMString string_arg; // Used by :contains, :lang and :nth-* 162 LocalName attrLocalName; 163 NamespaceName attrNamespace; 164 LocalName tagLocalName; 165 NamespaceName tagNamespace; 166 167 KDE_BF_ENUM(Relation) relation : 3; 168 mutable KDE_BF_ENUM(Match) match : 4; 169 unsigned int pseudoId : 4; 170 mutable KDE_BF_ENUM(PseudoType) _pseudoType : 6; 171 172 private: 173 void extractPseudoType() const; 174 }; 175 176 // a style class which has a parent (almost all have) 177 class StyleBaseImpl : public khtml::TreeShared<StyleBaseImpl> 178 { 179 public: StyleBaseImpl()180 StyleBaseImpl() 181 { 182 m_parent = nullptr; 183 hasInlinedDecl = false; 184 strictParsing = true; 185 multiLength = false; 186 } StyleBaseImpl(StyleBaseImpl * p)187 StyleBaseImpl(StyleBaseImpl *p) 188 { 189 m_parent = p; hasInlinedDecl = false; 190 strictParsing = (m_parent ? m_parent->useStrictParsing() : true); 191 multiLength = false; 192 } 193 ~StyleBaseImpl()194 virtual ~StyleBaseImpl() {} 195 196 // returns the url of the style sheet this object belongs to 197 // not const 198 QUrl baseURL(); 199 isStyleSheet()200 virtual bool isStyleSheet() const 201 { 202 return false; 203 } isCSSStyleSheet()204 virtual bool isCSSStyleSheet() const 205 { 206 return false; 207 } isStyleSheetList()208 virtual bool isStyleSheetList() const 209 { 210 return false; 211 } isMediaList()212 virtual bool isMediaList() const 213 { 214 return false; 215 } isRuleList()216 virtual bool isRuleList() const 217 { 218 return false; 219 } isRule()220 virtual bool isRule() const 221 { 222 return false; 223 } isStyleRule()224 virtual bool isStyleRule() const 225 { 226 return false; 227 } isCharsetRule()228 virtual bool isCharsetRule() const 229 { 230 return false; 231 } isImportRule()232 virtual bool isImportRule() const 233 { 234 return false; 235 } isMediaRule()236 virtual bool isMediaRule() const 237 { 238 return false; 239 } isFontFaceRule()240 virtual bool isFontFaceRule() const 241 { 242 return false; 243 } isPageRule()244 virtual bool isPageRule() const 245 { 246 return false; 247 } isUnknownRule()248 virtual bool isUnknownRule() const 249 { 250 return false; 251 } isStyleDeclaration()252 virtual bool isStyleDeclaration() const 253 { 254 return false; 255 } isValue()256 virtual bool isValue() const 257 { 258 return false; 259 } isPrimitiveValue()260 virtual bool isPrimitiveValue() const 261 { 262 return false; 263 } isValueList()264 virtual bool isValueList() const 265 { 266 return false; 267 } isValueCustom()268 virtual bool isValueCustom() const 269 { 270 return false; 271 } 272 setParent(StyleBaseImpl * parent)273 void setParent(StyleBaseImpl *parent) 274 { 275 m_parent = parent; 276 } 277 278 static void setParsedValue(int propId, const CSSValueImpl *parsedValue, 279 bool important, QList<CSSProperty *> *propList); 280 281 virtual bool parseString(const DOMString &/*cssString*/, bool = false) 282 { 283 return false; 284 } 285 286 // verifies if the resource chain is fully loaded, 287 // and in the affirmative, notifies the owner document 288 virtual void checkLoaded() const; 289 // makes sure the resource chain is considered 'Pending' by the owner document 290 virtual void checkPending() const; 291 setStrictParsing(bool b)292 void setStrictParsing(bool b) 293 { 294 strictParsing = b; 295 } useStrictParsing()296 bool useStrictParsing() const 297 { 298 return strictParsing; 299 } 300 301 // not const 302 StyleSheetImpl *stylesheet(); 303 304 protected: 305 bool hasInlinedDecl : 1; 306 bool strictParsing : 1; 307 bool multiLength : 1; 308 }; 309 310 // a style class which has a list of children (StyleSheets for example) 311 class StyleListImpl : public StyleBaseImpl 312 { 313 public: StyleListImpl()314 StyleListImpl() : StyleBaseImpl() 315 { 316 m_lstChildren = nullptr; 317 } StyleListImpl(StyleBaseImpl * parent)318 StyleListImpl(StyleBaseImpl *parent) : StyleBaseImpl(parent) 319 { 320 m_lstChildren = nullptr; 321 } 322 virtual ~StyleListImpl(); 323 length()324 unsigned long length() const 325 { 326 return m_lstChildren->count(); 327 } item(unsigned long num)328 StyleBaseImpl *item(unsigned long num) const 329 { 330 return num < length() ? m_lstChildren->at(num) : nullptr; 331 } 332 append(StyleBaseImpl * item)333 void append(StyleBaseImpl *item) 334 { 335 m_lstChildren->append(item); 336 } 337 338 protected: 339 QList<StyleBaseImpl *> *m_lstChildren; 340 }; 341 342 KHTML_NO_EXPORT int getPropertyID(const char *tagStr, int len); 343 KHTML_NO_EXPORT int getValueID(const char *tagStr, int len); 344 345 struct SelectorHash { hashSelectorHash346 static unsigned hash(CSSSelector *selector) 347 { 348 unsigned result = 0; 349 while (selector) { 350 result ^= (quintptr)selector->value.impl(); 351 result ^= (selector->attrLocalName.id() << 3); 352 result ^= (selector->attrNamespace.id() << 7); 353 result ^= (selector->tagLocalName.id() << 10); 354 result ^= (selector->tagNamespace.id() << 13); 355 result ^= (selector->relation << 17); 356 result ^= (selector->match << 20); 357 result ^= result << 5; 358 selector = selector->tagHistory; 359 } 360 return result; 361 } equalSelectorHash362 static bool equal(CSSSelector *a, CSSSelector *b) 363 { 364 return a == b || *a == *b; 365 } 366 static const bool safeToCompareToEmptyOrDeleted = false; 367 }; 368 369 } 370 371 namespace WTF 372 { 373 template<typename T> struct DefaultHash; 374 template<> struct DefaultHash<DOM::CSSSelector *> { 375 typedef DOM::SelectorHash Hash; 376 }; 377 } 378 379 #endif 380