1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
4 * Copyright (C) 2012 Google Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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 INC. 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 INC. 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 ON
22 * 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 THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #ifndef ScopedStyleTree_h
28 #define ScopedStyleTree_h
29
30 #include "core/css/resolver/ScopedStyleResolver.h"
31 #include "wtf/HashMap.h"
32 #include "wtf/OwnPtr.h"
33 #include "wtf/Vector.h"
34
35 namespace WebCore {
36
37 class ScopedStyleTree {
38 WTF_MAKE_NONCOPYABLE(ScopedStyleTree); WTF_MAKE_FAST_ALLOCATED;
39 public:
ScopedStyleTree()40 ScopedStyleTree() : m_scopedResolverForDocument(0), m_buildInDocumentOrder(true) { }
41
42 ScopedStyleResolver* ensureScopedStyleResolver(ContainerNode& scopingNode);
lookupScopedStyleResolverFor(const ContainerNode * scopingNode)43 ScopedStyleResolver* lookupScopedStyleResolverFor(const ContainerNode* scopingNode)
44 {
45 HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator it = m_authorStyles.find(scopingNode);
46 return it != m_authorStyles.end() ? it->value.get() : 0;
47 }
48
49 ScopedStyleResolver* scopedStyleResolverFor(const ContainerNode& scopingNode);
50 ScopedStyleResolver* addScopedStyleResolver(ContainerNode& scopingNode, bool& isNewEntry);
51 void clear();
52
53 // for fast-path.
hasOnlyScopedResolverForDocument()54 bool hasOnlyScopedResolverForDocument() const { return m_scopedResolverForDocument && m_authorStyles.size() == 1; }
scopedStyleResolverForDocument()55 ScopedStyleResolver* scopedStyleResolverForDocument() const { return m_scopedResolverForDocument; }
56
57 void resolveScopedStyles(const Element*, Vector<ScopedStyleResolver*, 8>&);
58 void collectScopedResolversForHostedShadowTrees(const Element*, Vector<ScopedStyleResolver*, 8>&);
59 void resolveScopedKeyframesRules(const Element*, Vector<ScopedStyleResolver*, 8>&);
60 ScopedStyleResolver* scopedResolverFor(const Element*);
61
62 void remove(const ContainerNode* scopingNode);
63
64 void pushStyleCache(const ContainerNode& scopingNode, const ContainerNode* parent);
65 void popStyleCache(const ContainerNode& scopingNode);
66
67 void collectFeaturesTo(RuleFeatureSet& features);
setBuildInDocumentOrder(bool enabled)68 void setBuildInDocumentOrder(bool enabled) { m_buildInDocumentOrder = enabled; }
buildInDocumentOrder()69 bool buildInDocumentOrder() const { return m_buildInDocumentOrder; }
70
71 private:
72 void setupScopedStylesTree(ScopedStyleResolver* target);
73
cacheIsValid(const ContainerNode * parent)74 bool cacheIsValid(const ContainerNode* parent) const { return parent && parent == m_cache.nodeForScopedStyles; }
75 void resolveStyleCache(const ContainerNode* scopingNode);
76 ScopedStyleResolver* enclosingScopedStyleResolverFor(const ContainerNode* scopingNode);
77
78 void reparentNodes(const ScopedStyleResolver* oldParent, ScopedStyleResolver* newParent);
79
80 private:
81 HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> > m_authorStyles;
82 ScopedStyleResolver* m_scopedResolverForDocument;
83 bool m_buildInDocumentOrder;
84
85 struct ScopedStyleCache {
86 ScopedStyleResolver* scopedResolver;
87 const ContainerNode* nodeForScopedStyles;
88
clearScopedStyleCache89 void clear()
90 {
91 scopedResolver = 0;
92 nodeForScopedStyles = 0;
93 }
94 };
95 ScopedStyleCache m_cache;
96 };
97
scopedResolverFor(const Element * element)98 inline ScopedStyleResolver* ScopedStyleTree::scopedResolverFor(const Element* element)
99 {
100 if (!cacheIsValid(element))
101 resolveStyleCache(element);
102
103 return m_cache.scopedResolver;
104 }
105
106 } // namespace WebCore
107
108 #endif // ScopedStyleTree_h
109