File indexing completed on 2024-04-28 11:37:25

0001 /*
0002  * This file is part of the CSS implementation for KDE.
0003  *
0004  * Copyright 1999-2003 Lars Knoll (knoll@kde.org)
0005  * Copyright 1999 Waldo Bastian (bastian@kde.org)
0006  * Copyright 2002 Apple Computer, Inc.
0007  * Copyright 2004 Allan Sandfeld Jensen (kde@carewolf.com)
0008  *
0009  * This library is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU Library General Public
0011  * License as published by the Free Software Foundation; either
0012  * version 2 of the License, or (at your option) any later version.
0013  *
0014  * This library is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017  * Library General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU Library General Public License
0020  * along with this library; see the file COPYING.LIB.  If not, write to
0021  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022  * Boston, MA 02110-1301, USA.
0023  *
0024  */
0025 #ifndef _CSS_BASE_H
0026 #define _CSS_BASE_H
0027 
0028 #include "misc/AtomicString.h"
0029 #include "dom/dom_misc.h"
0030 #include "xml/dom_nodeimpl.h"
0031 #include "misc/shared.h"
0032 #include "misc/enum.h"
0033 
0034 #include <QDate>
0035 
0036 namespace DOM
0037 {
0038 
0039 class StyleSheetImpl;
0040 class MediaList;
0041 
0042 class CSSSelector;
0043 class CSSProperty;
0044 class CSSValueImpl;
0045 
0046 // this class represents a selector for a StyleRule
0047 class CSSSelector
0048 {
0049 public:
0050     CSSSelector()
0051         : tagHistory(nullptr), simpleSelector(nullptr), relation(Descendant),
0052           match(None), pseudoId(0), _pseudoType(PseudoNotParsed)
0053     {
0054         tagLocalName = LocalName::fromId(anyLocalName);
0055         tagNamespace = NamespaceName::fromId(anyNamespace);
0056         attrLocalName = LocalName::fromId(0);
0057         attrNamespace = NamespaceName::fromId(0);
0058     }
0059 
0060     ~CSSSelector()
0061     {
0062         delete tagHistory;
0063         delete simpleSelector;
0064     }
0065 
0066     /**
0067      * Print debug output for this selector
0068      */
0069     void print();
0070 
0071     /**
0072      * Re-create selector text from selector's data
0073      */
0074     DOMString selectorText() const;
0075 
0076     // checks if the 2 selectors (including sub selectors) agree.
0077     bool operator == (const CSSSelector &other) const;
0078 
0079     // tag == -1 means apply to all elements (Selector = *)
0080 
0081     unsigned int specificity() const;
0082 
0083     /* how the attribute value has to match.... Default is Exact */
0084     enum Match {
0085         None = 0,
0086         Id,
0087         Exact,
0088         Set,
0089         Class,
0090         List,
0091         Hyphen,
0092         PseudoClass,
0093         PseudoElement,
0094         Contain,   // css3: E[foo*="bar"]
0095         Begin,     // css3: E[foo^="bar"]
0096         End        // css3: E[foo$="bar"]
0097     };
0098 
0099     enum Relation {
0100         Descendant = 0,
0101         Child,
0102         DirectAdjacent,
0103         IndirectAdjacent,
0104         SubSelector
0105     };
0106 
0107     enum PseudoType {
0108         PseudoNotParsed = 0,
0109         PseudoOther,
0110         PseudoEmpty,
0111         PseudoFirstChild,
0112         PseudoLastChild,
0113         PseudoNthChild,
0114         PseudoNthLastChild,
0115         PseudoOnlyChild,
0116         PseudoFirstOfType,
0117         PseudoLastOfType,
0118         PseudoNthOfType,
0119         PseudoNthLastOfType,
0120         PseudoOnlyOfType,
0121         PseudoLink,
0122         PseudoVisited,
0123         PseudoHover,
0124         PseudoFocus,
0125         PseudoActive,
0126         PseudoTarget,
0127         PseudoLang,
0128         PseudoNot,
0129         PseudoContains,
0130         PseudoRoot,
0131         PseudoEnabled,
0132         PseudoDisabled,
0133         PseudoDefault,
0134         PseudoReadOnly,
0135         PseudoReadWrite,
0136         PseudoChecked,
0137         PseudoIndeterminate,
0138 // pseudo-elements:
0139         // inherited:
0140         PseudoFirstLine,
0141         PseudoFirstLetter,
0142         PseudoSelection,
0143         // generated:
0144         PseudoBefore,
0145         PseudoAfter,
0146         PseudoMarker,
0147         PseudoReplaced
0148     };
0149 
0150     PseudoType pseudoType() const
0151     {
0152         if (_pseudoType == PseudoNotParsed) {
0153             extractPseudoType();
0154         }
0155         return KDE_CAST_BF_ENUM(PseudoType, _pseudoType);
0156     }
0157 
0158     mutable khtml::AtomicString value;
0159     CSSSelector *tagHistory;
0160     CSSSelector *simpleSelector; // Used by :not
0161     DOM::DOMString string_arg; // Used by :contains, :lang and :nth-*
0162     LocalName attrLocalName;
0163     NamespaceName attrNamespace;
0164     LocalName tagLocalName;
0165     NamespaceName tagNamespace;
0166 
0167     KDE_BF_ENUM(Relation) relation     : 3;
0168     mutable KDE_BF_ENUM(Match)   match         : 4;
0169     unsigned int pseudoId : 4;
0170     mutable KDE_BF_ENUM(PseudoType) _pseudoType : 6;
0171 
0172 private:
0173     void extractPseudoType() const;
0174 };
0175 
0176 // a style class which has a parent (almost all have)
0177 class StyleBaseImpl : public khtml::TreeShared<StyleBaseImpl>
0178 {
0179 public:
0180     StyleBaseImpl()
0181     {
0182         m_parent = nullptr;
0183         hasInlinedDecl = false;
0184         strictParsing = true;
0185         multiLength = false;
0186     }
0187     StyleBaseImpl(StyleBaseImpl *p)
0188     {
0189         m_parent = p; hasInlinedDecl = false;
0190         strictParsing = (m_parent ? m_parent->useStrictParsing() : true);
0191         multiLength = false;
0192     }
0193 
0194     virtual ~StyleBaseImpl() {}
0195 
0196     // returns the url of the style sheet this object belongs to
0197     // not const
0198     QUrl baseURL();
0199 
0200     virtual bool isStyleSheet() const
0201     {
0202         return false;
0203     }
0204     virtual bool isCSSStyleSheet() const
0205     {
0206         return false;
0207     }
0208     virtual bool isStyleSheetList() const
0209     {
0210         return false;
0211     }
0212     virtual bool isMediaList() const
0213     {
0214         return false;
0215     }
0216     virtual bool isRuleList() const
0217     {
0218         return false;
0219     }
0220     virtual bool isRule() const
0221     {
0222         return false;
0223     }
0224     virtual bool isStyleRule() const
0225     {
0226         return false;
0227     }
0228     virtual bool isCharsetRule() const
0229     {
0230         return false;
0231     }
0232     virtual bool isImportRule() const
0233     {
0234         return false;
0235     }
0236     virtual bool isMediaRule() const
0237     {
0238         return false;
0239     }
0240     virtual bool isFontFaceRule() const
0241     {
0242         return false;
0243     }
0244     virtual bool isPageRule() const
0245     {
0246         return false;
0247     }
0248     virtual bool isUnknownRule() const
0249     {
0250         return false;
0251     }
0252     virtual bool isStyleDeclaration() const
0253     {
0254         return false;
0255     }
0256     virtual bool isValue() const
0257     {
0258         return false;
0259     }
0260     virtual bool isPrimitiveValue() const
0261     {
0262         return false;
0263     }
0264     virtual bool isValueList() const
0265     {
0266         return false;
0267     }
0268     virtual bool isValueCustom() const
0269     {
0270         return false;
0271     }
0272 
0273     void setParent(StyleBaseImpl *parent)
0274     {
0275         m_parent = parent;
0276     }
0277 
0278     static void setParsedValue(int propId, const CSSValueImpl *parsedValue,
0279                                bool important, QList<CSSProperty *> *propList);
0280 
0281     virtual bool parseString(const DOMString &/*cssString*/, bool = false)
0282     {
0283         return false;
0284     }
0285 
0286     // verifies if the resource chain is fully loaded,
0287     // and in the affirmative, notifies the owner document
0288     virtual void checkLoaded() const;
0289     // makes sure the resource chain is considered 'Pending' by the owner document
0290     virtual void checkPending() const;
0291 
0292     void setStrictParsing(bool b)
0293     {
0294         strictParsing = b;
0295     }
0296     bool useStrictParsing() const
0297     {
0298         return strictParsing;
0299     }
0300 
0301     // not const
0302     StyleSheetImpl *stylesheet();
0303 
0304 protected:
0305     bool hasInlinedDecl : 1;
0306     bool strictParsing : 1;
0307     bool multiLength : 1;
0308 };
0309 
0310 // a style class which has a list of children (StyleSheets for example)
0311 class StyleListImpl : public StyleBaseImpl
0312 {
0313 public:
0314     StyleListImpl() : StyleBaseImpl()
0315     {
0316         m_lstChildren = nullptr;
0317     }
0318     StyleListImpl(StyleBaseImpl *parent) : StyleBaseImpl(parent)
0319     {
0320         m_lstChildren = nullptr;
0321     }
0322     virtual ~StyleListImpl();
0323 
0324     unsigned long length() const
0325     {
0326         return m_lstChildren->count();
0327     }
0328     StyleBaseImpl *item(unsigned long num) const
0329     {
0330         return num < length() ? m_lstChildren->at(num) : nullptr;
0331     }
0332 
0333     void append(StyleBaseImpl *item)
0334     {
0335         m_lstChildren->append(item);
0336     }
0337 
0338 protected:
0339     QList<StyleBaseImpl *> *m_lstChildren;
0340 };
0341 
0342 KHTML_NO_EXPORT int getPropertyID(const char *tagStr, int len);
0343 KHTML_NO_EXPORT int getValueID(const char *tagStr, int len);
0344 
0345 struct SelectorHash {
0346     static unsigned hash(CSSSelector *selector)
0347     {
0348         unsigned result = 0;
0349         while (selector) {
0350             result ^= (quintptr)selector->value.impl();
0351             result ^= (selector->attrLocalName.id() << 3);
0352             result ^= (selector->attrNamespace.id() << 7);
0353             result ^= (selector->tagLocalName.id() << 10);
0354             result ^= (selector->tagNamespace.id() << 13);
0355             result ^= (selector->relation << 17);
0356             result ^= (selector->match << 20);
0357             result ^= result << 5;
0358             selector = selector->tagHistory;
0359         }
0360         return result;
0361     }
0362     static bool equal(CSSSelector *a, CSSSelector *b)
0363     {
0364         return a == b || *a == *b;
0365     }
0366     static const bool safeToCompareToEmptyOrDeleted = false;
0367 };
0368 
0369 }
0370 
0371 namespace WTF
0372 {
0373 template<typename T> struct DefaultHash;
0374 template<> struct DefaultHash<DOM::CSSSelector *> {
0375     typedef DOM::SelectorHash Hash;
0376 };
0377 }
0378 
0379 #endif