OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 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. | 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. | 4 * Copyright (C) 2012 Google Inc. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "core/dom/shadow/ShadowRoot.h" | 33 #include "core/dom/shadow/ShadowRoot.h" |
34 | 34 |
35 namespace blink { | 35 namespace blink { |
36 | 36 |
37 class StyleSheetContents; | 37 class StyleSheetContents; |
38 | 38 |
39 ScopedStyleTree::ScopedStyleTree() | 39 ScopedStyleTree::ScopedStyleTree() |
40 { | 40 { |
41 } | 41 } |
42 | 42 |
43 ScopedStyleTree::~ScopedStyleTree() | |
44 { | |
45 #if !ENABLE(OILPAN) | |
46 for (HashMap<RawPtr<const ContainerNode>, RawPtr<ScopedStyleResolver> >::ite
rator it = m_authorStyles.begin(); it != m_authorStyles.end(); ++it) | |
47 it->key->treeScope().clearScopedStyleResolver(); | |
48 #endif | |
49 } | |
50 | |
51 ScopedStyleResolver* ScopedStyleTree::ensureScopedStyleResolver(ContainerNode& s
copingNode) | |
52 { | |
53 ASSERT(scopingNode.isShadowRoot() || scopingNode.isDocumentNode()); | |
54 | |
55 m_authorStyles.add(&scopingNode, &scopingNode.treeScope().ensureScopedStyleR
esolver()); | |
56 return scopingNode.treeScope().scopedStyleResolver(); | |
57 } | |
58 | |
59 ScopedStyleResolver* ScopedStyleTree::scopedStyleResolverFor(const ContainerNode
& scopingNode) | |
60 { | |
61 if (!isShadowHost(&scopingNode) | |
62 && !scopingNode.isDocumentNode() | |
63 && !scopingNode.isShadowRoot()) | |
64 return 0; | |
65 return scopingNode.treeScope().scopedStyleResolver(); | |
66 } | |
67 | |
68 void ScopedStyleTree::resolveScopedStyles(const Element* element, WillBeHeapVect
or<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers) | 43 void ScopedStyleTree::resolveScopedStyles(const Element* element, WillBeHeapVect
or<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers) |
69 { | 44 { |
70 for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scope
dResolver; scopedResolver = scopedResolver->parent()) | 45 for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scope
dResolver; scopedResolver = scopedResolver->parent()) |
71 resolvers.append(scopedResolver); | 46 resolvers.append(scopedResolver); |
72 } | 47 } |
73 | 48 |
74 void ScopedStyleTree::collectScopedResolversForHostedShadowTrees(const Element*
element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers
) | 49 void ScopedStyleTree::collectScopedResolversForHostedShadowTrees(const Element*
element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers
) |
75 { | 50 { |
76 ElementShadow* shadow = element->shadow(); | 51 ElementShadow* shadow = element->shadow(); |
77 if (!shadow) | 52 if (!shadow) |
78 return; | 53 return; |
79 | 54 |
80 // Adding scoped resolver for active shadow roots for shadow host styling. | 55 // Adding scoped resolver for active shadow roots for shadow host styling. |
81 for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shad
owRoot = shadowRoot->olderShadowRoot()) { | 56 for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shad
owRoot = shadowRoot->olderShadowRoot()) { |
82 if (shadowRoot->numberOfStyles() > 0) { | 57 if (shadowRoot->numberOfStyles() > 0) { |
83 if (ScopedStyleResolver* resolver = scopedStyleResolverFor(*shadowRo
ot)) | 58 if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver(
)) |
84 resolvers.append(resolver); | 59 resolvers.append(resolver); |
85 } | 60 } |
86 } | 61 } |
87 } | 62 } |
88 | 63 |
89 void ScopedStyleTree::resolveScopedKeyframesRules(const Element* element, WillBe
HeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers) | 64 void ScopedStyleTree::resolveScopedKeyframesRules(const Element* element, WillBe
HeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers) |
90 { | 65 { |
91 Document& document = element->document(); | 66 Document& document = element->document(); |
92 TreeScope& treeScope = element->treeScope(); | 67 TreeScope& treeScope = element->treeScope(); |
93 bool applyAuthorStyles = treeScope.applyAuthorStyles(); | 68 bool applyAuthorStyles = treeScope.applyAuthorStyles(); |
94 | 69 |
95 // Add resolvers for shadow roots hosted by the given element. | 70 // Add resolvers for shadow roots hosted by the given element. |
96 collectScopedResolversForHostedShadowTrees(element, resolvers); | 71 collectScopedResolversForHostedShadowTrees(element, resolvers); |
97 | 72 |
98 // Add resolvers while walking up DOM tree from the given element. | 73 // Add resolvers while walking up DOM tree from the given element. |
99 for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scope
dResolver; scopedResolver = scopedResolver->parent()) { | 74 for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scope
dResolver; scopedResolver = scopedResolver->parent()) { |
100 if (scopedResolver->treeScope() == treeScope || (applyAuthorStyles && sc
opedResolver->treeScope() == document)) | 75 if (scopedResolver->treeScope() == treeScope || (applyAuthorStyles && sc
opedResolver->treeScope() == document)) |
101 resolvers.append(scopedResolver); | 76 resolvers.append(scopedResolver); |
102 } | 77 } |
103 } | 78 } |
104 | 79 |
105 inline ScopedStyleResolver* ScopedStyleTree::enclosingScopedStyleResolverFor(con
st ContainerNode* scopingNode) | 80 inline ScopedStyleResolver* ScopedStyleTree::scopedResolverFor(const Element* el
ement) |
106 { | 81 { |
107 for (; scopingNode; scopingNode = scopingNode->parentOrShadowHostNode()) { | 82 for (TreeScope* treeScope = &element->treeScope(); treeScope; treeScope = tr
eeScope->parentTreeScope()) { |
108 if (ScopedStyleResolver* scopedStyleResolver = scopedStyleResolverFor(*s
copingNode)) | 83 if (ScopedStyleResolver* scopedStyleResolver = treeScope->scopedStyleRes
olver()) |
109 return scopedStyleResolver; | 84 return scopedStyleResolver; |
110 } | 85 } |
111 return 0; | 86 return 0; |
112 } | 87 } |
113 | 88 |
114 void ScopedStyleTree::resolveStyleCache(const ContainerNode* scopingNode) | |
115 { | |
116 m_cache.scopedResolver = enclosingScopedStyleResolverFor(scopingNode); | |
117 m_cache.nodeForScopedStyles = scopingNode; | |
118 } | |
119 | |
120 void ScopedStyleTree::pushStyleCache(const ContainerNode& scopingNode, const Con
tainerNode* parent) | |
121 { | |
122 if (m_authorStyles.isEmpty()) | |
123 return; | |
124 | |
125 if (!cacheIsValid(parent)) { | |
126 resolveStyleCache(&scopingNode); | |
127 return; | |
128 } | |
129 | |
130 ScopedStyleResolver* scopedResolver = scopedStyleResolverFor(scopingNode); | |
131 if (scopedResolver) | |
132 m_cache.scopedResolver = scopedResolver; | |
133 m_cache.nodeForScopedStyles = &scopingNode; | |
134 } | |
135 | |
136 void ScopedStyleTree::popStyleCache(const ContainerNode& scopingNode) | |
137 { | |
138 if (!cacheIsValid(&scopingNode)) | |
139 return; | |
140 | |
141 if (m_cache.scopedResolver && m_cache.scopedResolver->scopingNode() == scopi
ngNode) | |
142 m_cache.scopedResolver = m_cache.scopedResolver->parent(); | |
143 m_cache.nodeForScopedStyles = scopingNode.parentOrShadowHostNode(); | |
144 } | |
145 | |
146 void ScopedStyleTree::collectFeaturesTo(RuleFeatureSet& features) | |
147 { | |
148 HashSet<const StyleSheetContents*> visitedSharedStyleSheetContents; | |
149 for (WillBeHeapHashMap<RawPtrWillBeMember<const ContainerNode>, RawPtrWillBe
Member<ScopedStyleResolver> >::iterator it = m_authorStyles.begin(); it != m_aut
horStyles.end(); ++it) | |
150 it->value->collectFeaturesTo(features, visitedSharedStyleSheetContents); | |
151 } | |
152 | |
153 void ScopedStyleTree::remove(const ContainerNode* scopingNode) | |
154 { | |
155 if (!scopingNode || scopingNode->isDocumentNode()) | |
156 return; | |
157 | |
158 ScopedStyleResolver* resolver = scopingNode->treeScope().scopedStyleResolver
(); | |
159 if (!resolver) | |
160 return; | |
161 | |
162 if (m_cache.scopedResolver == resolver) | |
163 m_cache.clear(); | |
164 | |
165 // resolver is going to be freed below. | |
166 resolver = 0; | |
167 m_authorStyles.remove(scopingNode); | |
168 scopingNode->treeScope().clearScopedStyleResolver(); | |
169 } | |
170 | |
171 void ScopedStyleTree::trace(Visitor* visitor) | 89 void ScopedStyleTree::trace(Visitor* visitor) |
172 { | 90 { |
173 #if ENABLE(OILPAN) | |
174 visitor->trace(m_authorStyles); | |
175 visitor->trace(m_cache); | |
176 #endif | |
177 } | 91 } |
178 | 92 |
179 } // namespace blink | 93 } // namespace blink |
OLD | NEW |