1 /* 2 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. 3 * Copyright (C) 2014 Samsung Electronics. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef SelectorQuery_h 28 #define SelectorQuery_h 29 30 #include "core/css/CSSSelectorList.h" 31 #include "platform/heap/Handle.h" 32 #include "wtf/HashMap.h" 33 #include "wtf/Vector.h" 34 #include "wtf/text/AtomicStringHash.h" 35 36 namespace blink { 37 38 class CSSSelector; 39 class ContainerNode; 40 class Document; 41 class Element; 42 class ExceptionState; 43 template <typename NodeType> class StaticNodeTypeList; 44 typedef StaticNodeTypeList<Element> StaticElementList; 45 46 class SelectorDataList { 47 public: 48 void initialize(const CSSSelectorList&); 49 bool matches(Element&) const; 50 PassRefPtrWillBeRawPtr<StaticElementList> queryAll(ContainerNode& rootNode) const; 51 PassRefPtrWillBeRawPtr<Element> queryFirst(ContainerNode& rootNode) const; 52 53 private: 54 bool canUseFastQuery(const ContainerNode& rootNode) const; 55 bool selectorMatches(const CSSSelector&, Element&, const ContainerNode&) const; 56 57 template <typename SelectorQueryTrait> 58 void collectElementsByClassName(ContainerNode& rootNode, const AtomicString& className, typename SelectorQueryTrait::OutputType&) const; 59 template <typename SelectorQueryTrait> 60 void collectElementsByTagName(ContainerNode& rootNode, const QualifiedName& tagName, typename SelectorQueryTrait::OutputType&) const; 61 62 template <typename SelectorQueryTrait> 63 void findTraverseRootsAndExecute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const; 64 65 enum MatchTraverseRootState { DoesNotMatchTraverseRoots, MatchesTraverseRoots }; 66 template <typename SelectorQueryTrait> 67 void executeForTraverseRoot(const CSSSelector&, ContainerNode* traverseRoot, MatchTraverseRootState, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const; 68 template <typename SelectorQueryTrait, typename SimpleElementListType> 69 void executeForTraverseRoots(const CSSSelector&, SimpleElementListType& traverseRoots, MatchTraverseRootState, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const; 70 71 template <typename SelectorQueryTrait> 72 bool selectorListMatches(ContainerNode& rootNode, Element&, typename SelectorQueryTrait::OutputType&) const; 73 template <typename SelectorQueryTrait> 74 void executeSlow(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const; 75 template <typename SelectorQueryTrait> 76 void executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const; 77 template <typename SelectorQueryTrait> 78 void execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const; 79 const CSSSelector* selectorForIdLookup(const CSSSelector&) const; 80 81 Vector<const CSSSelector*> m_selectors; 82 bool m_crossesTreeBoundary; 83 }; 84 85 class SelectorQuery { 86 WTF_MAKE_NONCOPYABLE(SelectorQuery); 87 WTF_MAKE_FAST_ALLOCATED; 88 public: 89 static PassOwnPtr<SelectorQuery> adopt(CSSSelectorList&); 90 91 bool matches(Element&) const; 92 PassRefPtrWillBeRawPtr<StaticElementList> queryAll(ContainerNode& rootNode) const; 93 PassRefPtrWillBeRawPtr<Element> queryFirst(ContainerNode& rootNode) const; 94 private: 95 explicit SelectorQuery(CSSSelectorList&); 96 97 SelectorDataList m_selectors; 98 CSSSelectorList m_selectorList; 99 }; 100 101 class SelectorQueryCache { 102 WTF_MAKE_FAST_ALLOCATED; 103 public: 104 SelectorQuery* add(const AtomicString&, const Document&, ExceptionState&); 105 void invalidate(); 106 107 private: 108 HashMap<AtomicString, OwnPtr<SelectorQuery> > m_entries; 109 }; 110 111 } 112 113 #endif 114