initial import
[vuplus_webkit] / Source / WebCore / css / SelectorChecker.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6  * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7  * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9  * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB.  If not, write to
24  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  */
27
28 #ifndef SelectorChecker_h
29 #define SelectorChecker_h
30
31 #include "Element.h"
32 #include "LinkHash.h"
33 #include "RenderStyleConstants.h"
34 #include <wtf/BloomFilter.h>
35 #include <wtf/HashSet.h>
36 #include <wtf/Vector.h>
37
38 namespace WebCore {
39
40 class CSSSelector;
41 class Document;
42 class RenderStyle;
43
44 class SelectorChecker {
45     WTF_MAKE_NONCOPYABLE(SelectorChecker);
46 public:
47     SelectorChecker(Document*, bool strictParsing);
48
49     enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely };
50
51     bool checkSelector(CSSSelector*, Element*, bool isFastCheckableSelector = false) const;
52     SelectorMatch checkSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
53     static bool isFastCheckableSelector(const CSSSelector*);
54     static bool fastCheckSelector(const CSSSelector*, const Element*);
55
56     template <unsigned maximumIdentifierCount>
57     inline bool fastRejectSelector(const unsigned* identifierHashes) const;
58     static void collectIdentifierHashes(const CSSSelector*, unsigned* identifierHashes, unsigned maximumIdentifierCount);
59
60     void pushParent(Element* parent);
61     void popParent(Element* parent);
62     bool parentStackIsConsistent(ContainerNode* parentNode) const { return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode; }
63
64     EInsideLink determineLinkState(Element*) const;
65     void allVisitedStateChanged();
66     void visitedStateChanged(LinkHash visitedHash);
67     
68     Document* document() const { return m_document; }
69     bool strictParsing() const { return m_strictParsing; }
70     
71     bool isCollectingRulesOnly() const { return m_isCollectingRulesOnly; }
72     void setCollectingRulesOnly(bool b) { m_isCollectingRulesOnly = b; }
73     
74     bool isMatchingVisitedPseudoClass() const { return m_isMatchingVisitedPseudoClass; }
75     void setMatchingVisitedPseudoClass(bool b) { m_isMatchingVisitedPseudoClass = b; }
76     
77     PseudoId pseudoStyle() const { return m_pseudoStyle; }
78     void setPseudoStyle(PseudoId pseudoId) { m_pseudoStyle = pseudoId; }
79
80     bool hasUnknownPseudoElements() const { return m_hasUnknownPseudoElements; }
81     void clearHasUnknownPseudoElements() { m_hasUnknownPseudoElements = false; }
82
83 private:
84     bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle*, RenderStyle* elementParentStyle) const;
85     bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
86
87     EInsideLink determineLinkStateSlowCase(Element*) const;
88
89     void pushParentStackFrame(Element* parent);
90     void popParentStackFrame();
91
92     Document* m_document;
93     bool m_strictParsing;
94     bool m_documentIsHTML;
95     bool m_isCollectingRulesOnly;
96     PseudoId m_pseudoStyle;
97     mutable bool m_hasUnknownPseudoElements;
98     mutable bool m_isMatchingVisitedPseudoClass;
99     mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
100
101     struct ParentStackFrame {
102         ParentStackFrame() { }
103         ParentStackFrame(Element* element) : element(element) { }
104         Element* element;
105         Vector<unsigned, 4> identifierHashes;
106     };
107     Vector<ParentStackFrame> m_parentStack;
108
109     // With 100 unique strings in the filter, 2^12 slot table has false positive rate of ~0.2%.
110     static const unsigned bloomFilterKeyBits = 12;
111     OwnPtr<BloomFilter<bloomFilterKeyBits> > m_ancestorIdentifierFilter;
112 };
113
114 inline EInsideLink SelectorChecker::determineLinkState(Element* element) const
115 {
116     if (!element || !element->isLink())
117         return NotInsideLink;
118     return determineLinkStateSlowCase(element);
119 }
120     
121 template <unsigned maximumIdentifierCount>
122 inline bool SelectorChecker::fastRejectSelector(const unsigned* identifierHashes) const
123 {
124     ASSERT(m_ancestorIdentifierFilter);
125     for (unsigned n = 0; n < maximumIdentifierCount && identifierHashes[n]; ++n) {
126         if (!m_ancestorIdentifierFilter->mayContain(identifierHashes[n]))
127             return true;
128     }
129     return false;
130 }
131
132 }
133
134 #endif