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 23 matching lines...) Expand all Loading... |
34 #include "core/css/RuleSet.h" | 34 #include "core/css/RuleSet.h" |
35 #include "core/css/StyleRule.h" | 35 #include "core/css/StyleRule.h" |
36 #include "core/css/resolver/StyleResolver.h" // For MatchRequest. | 36 #include "core/css/resolver/StyleResolver.h" // For MatchRequest. |
37 #include "core/dom/Document.h" | 37 #include "core/dom/Document.h" |
38 #include "core/dom/shadow/ElementShadow.h" | 38 #include "core/dom/shadow/ElementShadow.h" |
39 #include "core/dom/shadow/ShadowRoot.h" | 39 #include "core/dom/shadow/ShadowRoot.h" |
40 #include "core/html/HTMLStyleElement.h" | 40 #include "core/html/HTMLStyleElement.h" |
41 | 41 |
42 namespace WebCore { | 42 namespace WebCore { |
43 | 43 |
44 ScopedStyleResolver* ScopedStyleTree::ensureScopedStyleResolver(const ContainerN
ode* scopingNode) | 44 ScopedStyleResolver* ScopedStyleTree::ensureScopedStyleResolver(const ContainerN
ode& scopingNode) |
45 { | 45 { |
46 ASSERT(scopingNode); | |
47 bool isNewEntry; | 46 bool isNewEntry; |
48 ScopedStyleResolver* scopedStyleResolver = addScopedStyleResolver(scopingNod
e, isNewEntry); | 47 ScopedStyleResolver* scopedStyleResolver = addScopedStyleResolver(scopingNod
e, isNewEntry); |
49 if (isNewEntry) | 48 if (isNewEntry) |
50 setupScopedStylesTree(scopedStyleResolver); | 49 setupScopedStylesTree(scopedStyleResolver); |
51 return scopedStyleResolver; | 50 return scopedStyleResolver; |
52 } | 51 } |
53 | 52 |
54 ScopedStyleResolver* ScopedStyleTree::scopedStyleResolverFor(const ContainerNode
* scopingNode) | 53 ScopedStyleResolver* ScopedStyleTree::scopedStyleResolverFor(const ContainerNode
& scopingNode) |
55 { | 54 { |
56 if (!scopingNode->hasScopedHTMLStyleChild() | 55 if (!scopingNode.hasScopedHTMLStyleChild() |
57 && !(scopingNode->isElementNode() && toElement(scopingNode)->shadow()) | 56 && !(scopingNode.isElementNode() && toElement(scopingNode).shadow()) |
58 && !scopingNode->isDocumentNode() | 57 && !scopingNode.isDocumentNode() |
59 && !scopingNode->isShadowRoot()) | 58 && !scopingNode.isShadowRoot()) |
60 return 0; | 59 return 0; |
61 HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator it = m
_authorStyles.find(scopingNode); | 60 HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator it = m
_authorStyles.find(&scopingNode); |
62 return it != m_authorStyles.end() ? it->value.get() : 0; | 61 return it != m_authorStyles.end() ? it->value.get() : 0; |
63 } | 62 } |
64 | 63 |
65 ScopedStyleResolver* ScopedStyleTree::addScopedStyleResolver(const ContainerNode
* scopingNode, bool& isNewEntry) | 64 ScopedStyleResolver* ScopedStyleTree::addScopedStyleResolver(const ContainerNode
& scopingNode, bool& isNewEntry) |
66 { | 65 { |
67 HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::AddResult addRe
sult = m_authorStyles.add(scopingNode, nullptr); | 66 HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::AddResult addRe
sult = m_authorStyles.add(&scopingNode, nullptr); |
68 | 67 |
69 if (addResult.isNewEntry) { | 68 if (addResult.isNewEntry) { |
70 addResult.iterator->value = ScopedStyleResolver::create(scopingNode); | 69 addResult.iterator->value = ScopedStyleResolver::create(scopingNode); |
71 if (!scopingNode || scopingNode->isDocumentNode()) | 70 if (scopingNode.isDocumentNode()) |
72 m_scopedResolverForDocument = addResult.iterator->value.get(); | 71 m_scopedResolverForDocument = addResult.iterator->value.get(); |
73 } | 72 } |
74 isNewEntry = addResult.isNewEntry; | 73 isNewEntry = addResult.isNewEntry; |
75 return addResult.iterator->value.get(); | 74 return addResult.iterator->value.get(); |
76 } | 75 } |
77 | 76 |
78 void ScopedStyleTree::setupScopedStylesTree(ScopedStyleResolver* target) | 77 void ScopedStyleTree::setupScopedStylesTree(ScopedStyleResolver* target) |
79 { | 78 { |
80 ASSERT(target); | 79 ASSERT(target); |
81 ASSERT(target->scopingNode()); | |
82 | 80 |
83 const ContainerNode* scopingNode = target->scopingNode(); | 81 const ContainerNode& scopingNode = target->scopingNode(); |
84 | 82 |
85 // Since StyleResolver creates RuleSets according to styles' document | 83 // Since StyleResolver creates RuleSets according to styles' document |
86 // order, a parent of the given ScopedRuleData has been already | 84 // order, a parent of the given ScopedRuleData has been already |
87 // prepared. | 85 // prepared. |
88 for (const ContainerNode* node = scopingNode->parentOrShadowHostNode(); node
; node = node->parentOrShadowHostNode()) { | 86 for (const ContainerNode* node = scopingNode.parentOrShadowHostNode(); node;
node = node->parentOrShadowHostNode()) { |
89 if (ScopedStyleResolver* scopedResolver = scopedStyleResolverFor(node))
{ | 87 if (ScopedStyleResolver* scopedResolver = scopedStyleResolverFor(*node))
{ |
90 target->setParent(scopedResolver); | 88 target->setParent(scopedResolver); |
91 break; | 89 break; |
92 } | 90 } |
93 if (node->isDocumentNode()) { | 91 if (node->isDocumentNode()) { |
94 bool dummy; | 92 bool dummy; |
95 ScopedStyleResolver* scopedResolver = addScopedStyleResolver(node, d
ummy); | 93 ScopedStyleResolver* scopedResolver = addScopedStyleResolver(*node,
dummy); |
96 target->setParent(scopedResolver); | 94 target->setParent(scopedResolver); |
97 setupScopedStylesTree(scopedResolver); | 95 setupScopedStylesTree(scopedResolver); |
98 break; | 96 break; |
99 } | 97 } |
100 } | 98 } |
101 | 99 |
102 if (m_buildInDocumentOrder) | 100 if (m_buildInDocumentOrder) |
103 return; | 101 return; |
104 | 102 |
105 // Reparent all nodes whose scoping node is contained by target's one. | 103 // Reparent all nodes whose scoping node is contained by target's one. |
106 for (HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator i
t = m_authorStyles.begin(); it != m_authorStyles.end(); ++it) { | 104 for (HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator i
t = m_authorStyles.begin(); it != m_authorStyles.end(); ++it) { |
107 if (it->value == target) | 105 if (it->value == target) |
108 continue; | 106 continue; |
109 if (it->value->parent() == target->parent() && scopingNode->containsIncl
udingShadowDOM(it->key)) | 107 if (it->value->parent() == target->parent() && scopingNode.containsInclu
dingShadowDOM(it->key)) |
110 it->value->setParent(target); | 108 it->value->setParent(target); |
111 } | 109 } |
112 } | 110 } |
113 | 111 |
114 void ScopedStyleTree::clear() | 112 void ScopedStyleTree::clear() |
115 { | 113 { |
116 m_authorStyles.clear(); | 114 m_authorStyles.clear(); |
117 m_scopedResolverForDocument = 0; | 115 m_scopedResolverForDocument = 0; |
118 m_cache.clear(); | 116 m_cache.clear(); |
119 } | 117 } |
120 | 118 |
121 void ScopedStyleTree::resolveScopedStyles(const Element* element, Vector<ScopedS
tyleResolver*, 8>& resolvers) | 119 void ScopedStyleTree::resolveScopedStyles(const Element* element, Vector<ScopedS
tyleResolver*, 8>& resolvers) |
122 { | 120 { |
123 for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scope
dResolver; scopedResolver = scopedResolver->parent()) | 121 for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scope
dResolver; scopedResolver = scopedResolver->parent()) |
124 resolvers.append(scopedResolver); | 122 resolvers.append(scopedResolver); |
125 } | 123 } |
126 | 124 |
127 void ScopedStyleTree::collectScopedResolversForHostedShadowTrees(const Element*
element, Vector<ScopedStyleResolver*, 8>& resolvers) | 125 void ScopedStyleTree::collectScopedResolversForHostedShadowTrees(const Element*
element, Vector<ScopedStyleResolver*, 8>& resolvers) |
128 { | 126 { |
129 ElementShadow* shadow = element->shadow(); | 127 ElementShadow* shadow = element->shadow(); |
130 if (!shadow) | 128 if (!shadow) |
131 return; | 129 return; |
132 | 130 |
133 // Adding scoped resolver for active shadow roots for shadow host styling. | 131 // Adding scoped resolver for active shadow roots for shadow host styling. |
134 for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shad
owRoot = shadowRoot->olderShadowRoot()) { | 132 for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shad
owRoot = shadowRoot->olderShadowRoot()) { |
135 if (shadowRoot->hasScopedHTMLStyleChild()) { | 133 if (shadowRoot->hasScopedHTMLStyleChild()) { |
136 if (ScopedStyleResolver* resolver = scopedStyleResolverFor(shadowRoo
t)) | 134 if (ScopedStyleResolver* resolver = scopedStyleResolverFor(*shadowRo
ot)) |
137 resolvers.append(resolver); | 135 resolvers.append(resolver); |
138 } | 136 } |
139 if (!shadowRoot->containsShadowElements()) | 137 if (!shadowRoot->containsShadowElements()) |
140 break; | 138 break; |
141 } | 139 } |
142 } | 140 } |
143 | 141 |
144 void ScopedStyleTree::resolveScopedKeyframesRules(const Element* element, Vector
<ScopedStyleResolver*, 8>& resolvers) | 142 void ScopedStyleTree::resolveScopedKeyframesRules(const Element* element, Vector
<ScopedStyleResolver*, 8>& resolvers) |
145 { | 143 { |
146 Document& document = element->document(); | 144 Document& document = element->document(); |
147 TreeScope* treeScope = element->treeScope(); | 145 TreeScope* treeScope = element->treeScope(); |
148 bool applyAuthorStyles = treeScope->applyAuthorStyles(); | 146 bool applyAuthorStyles = treeScope->applyAuthorStyles(); |
149 | 147 |
150 for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scope
dResolver; scopedResolver = scopedResolver->parent()) { | 148 for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scope
dResolver; scopedResolver = scopedResolver->parent()) { |
151 if (scopedResolver->treeScope() == treeScope || (applyAuthorStyles && sc
opedResolver->treeScope() == &document)) | 149 if (scopedResolver->treeScope() == treeScope || (applyAuthorStyles && sc
opedResolver->treeScope() == &document)) |
152 resolvers.append(scopedResolver); | 150 resolvers.append(scopedResolver); |
153 } | 151 } |
154 } | 152 } |
155 | 153 |
156 inline ScopedStyleResolver* ScopedStyleTree::enclosingScopedStyleResolverFor(con
st ContainerNode* scopingNode) | 154 inline ScopedStyleResolver* ScopedStyleTree::enclosingScopedStyleResolverFor(con
st ContainerNode* scopingNode) |
157 { | 155 { |
158 for (; scopingNode; scopingNode = scopingNode->parentOrShadowHostNode()) { | 156 for (; scopingNode; scopingNode = scopingNode->parentOrShadowHostNode()) { |
159 if (ScopedStyleResolver* scopedStyleResolver = scopedStyleResolverFor(sc
opingNode)) | 157 if (ScopedStyleResolver* scopedStyleResolver = scopedStyleResolverFor(*s
copingNode)) |
160 return scopedStyleResolver; | 158 return scopedStyleResolver; |
161 } | 159 } |
162 return 0; | 160 return 0; |
163 } | 161 } |
164 | 162 |
165 void ScopedStyleTree::resolveStyleCache(const ContainerNode* scopingNode) | 163 void ScopedStyleTree::resolveStyleCache(const ContainerNode* scopingNode) |
166 { | 164 { |
167 m_cache.scopedResolver = enclosingScopedStyleResolverFor(scopingNode); | 165 m_cache.scopedResolver = enclosingScopedStyleResolverFor(scopingNode); |
168 m_cache.nodeForScopedStyles = scopingNode; | 166 m_cache.nodeForScopedStyles = scopingNode; |
169 } | 167 } |
170 | 168 |
171 void ScopedStyleTree::pushStyleCache(const ContainerNode* scopingNode, const Con
tainerNode* parent) | 169 void ScopedStyleTree::pushStyleCache(const ContainerNode& scopingNode, const Con
tainerNode* parent) |
172 { | 170 { |
173 if (m_authorStyles.isEmpty()) | 171 if (m_authorStyles.isEmpty()) |
174 return; | 172 return; |
175 | 173 |
176 if (!cacheIsValid(parent)) { | 174 if (!cacheIsValid(parent)) { |
177 resolveStyleCache(scopingNode); | 175 resolveStyleCache(&scopingNode); |
178 return; | 176 return; |
179 } | 177 } |
180 | 178 |
181 ScopedStyleResolver* scopedResolver = scopedStyleResolverFor(scopingNode); | 179 ScopedStyleResolver* scopedResolver = scopedStyleResolverFor(scopingNode); |
182 if (scopedResolver) | 180 if (scopedResolver) |
183 m_cache.scopedResolver = scopedResolver; | 181 m_cache.scopedResolver = scopedResolver; |
184 m_cache.nodeForScopedStyles = scopingNode; | 182 m_cache.nodeForScopedStyles = &scopingNode; |
185 } | 183 } |
186 | 184 |
187 void ScopedStyleTree::popStyleCache(const ContainerNode* scopingNode) | 185 void ScopedStyleTree::popStyleCache(const ContainerNode& scopingNode) |
188 { | 186 { |
189 if (!cacheIsValid(scopingNode)) | 187 if (!cacheIsValid(&scopingNode)) |
190 return; | 188 return; |
191 | 189 |
192 if (m_cache.scopedResolver && m_cache.scopedResolver->scopingNode() == scopi
ngNode) | 190 if (m_cache.scopedResolver && &m_cache.scopedResolver->scopingNode() == &sco
pingNode) |
193 m_cache.scopedResolver = m_cache.scopedResolver->parent(); | 191 m_cache.scopedResolver = m_cache.scopedResolver->parent(); |
194 m_cache.nodeForScopedStyles = scopingNode->parentOrShadowHostNode(); | 192 m_cache.nodeForScopedStyles = scopingNode.parentOrShadowHostNode(); |
195 } | 193 } |
196 | 194 |
197 void ScopedStyleTree::collectFeaturesTo(RuleFeatureSet& features) | 195 void ScopedStyleTree::collectFeaturesTo(RuleFeatureSet& features) |
198 { | 196 { |
199 for (HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator i
t = m_authorStyles.begin(); it != m_authorStyles.end(); ++it) | 197 for (HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator i
t = m_authorStyles.begin(); it != m_authorStyles.end(); ++it) |
200 it->value->collectFeaturesTo(features); | 198 it->value->collectFeaturesTo(features); |
201 } | 199 } |
202 | 200 |
203 inline void ScopedStyleTree::reparentNodes(const ScopedStyleResolver* oldParent,
ScopedStyleResolver* newParent) | 201 inline void ScopedStyleTree::reparentNodes(const ScopedStyleResolver* oldParent,
ScopedStyleResolver* newParent) |
204 { | 202 { |
205 // FIXME: this takes O(N) (N = number of all scoping nodes). | 203 // FIXME: this takes O(N) (N = number of all scoping nodes). |
206 for (HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator i
t = m_authorStyles.begin(); it != m_authorStyles.end(); ++it) { | 204 for (HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator i
t = m_authorStyles.begin(); it != m_authorStyles.end(); ++it) { |
207 if (it->value->parent() == oldParent) | 205 if (it->value->parent() == oldParent) |
208 it->value->setParent(newParent); | 206 it->value->setParent(newParent); |
209 } | 207 } |
210 } | 208 } |
211 | 209 |
212 void ScopedStyleTree::remove(const ContainerNode* scopingNode) | 210 void ScopedStyleTree::remove(const ContainerNode* scopingNode) |
213 { | 211 { |
214 if (!scopingNode || scopingNode->isDocumentNode()) | 212 if (!scopingNode || scopingNode->isDocumentNode()) |
215 return; | 213 return; |
216 | 214 |
217 ScopedStyleResolver* resolverRemoved = scopedStyleResolverFor(scopingNode); | 215 ScopedStyleResolver* resolverRemoved = scopedStyleResolverFor(*scopingNode); |
218 if (!resolverRemoved) | 216 if (!resolverRemoved) |
219 return; | 217 return; |
220 | 218 |
221 reparentNodes(resolverRemoved, resolverRemoved->parent()); | 219 reparentNodes(resolverRemoved, resolverRemoved->parent()); |
222 if (m_cache.scopedResolver == resolverRemoved) | 220 if (m_cache.scopedResolver == resolverRemoved) |
223 m_cache.clear(); | 221 m_cache.clear(); |
224 | 222 |
225 m_authorStyles.remove(scopingNode); | 223 m_authorStyles.remove(scopingNode); |
226 } | 224 } |
227 | 225 |
(...skipping 16 matching lines...) Expand all Loading... |
244 if (!parent) | 242 if (!parent) |
245 return 0; | 243 return 0; |
246 | 244 |
247 return (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0; | 245 return (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0; |
248 } | 246 } |
249 | 247 |
250 void ScopedStyleResolver::addRulesFromSheet(StyleSheetContents* sheet, const Med
iaQueryEvaluator& medium, StyleResolver* resolver) | 248 void ScopedStyleResolver::addRulesFromSheet(StyleSheetContents* sheet, const Med
iaQueryEvaluator& medium, StyleResolver* resolver) |
251 { | 249 { |
252 if (!m_authorStyle) | 250 if (!m_authorStyle) |
253 m_authorStyle = RuleSet::create(); | 251 m_authorStyle = RuleSet::create(); |
254 m_authorStyle->addRulesFromSheet(sheet, medium, resolver, m_scopingNode); | 252 m_authorStyle->addRulesFromSheet(sheet, medium, resolver, &m_scopingNode); |
255 } | 253 } |
256 | 254 |
257 inline RuleSet* ScopedStyleResolver::ensureAtHostRuleSetFor(const ShadowRoot* sh
adowRoot) | 255 inline RuleSet* ScopedStyleResolver::ensureAtHostRuleSetFor(const ShadowRoot* sh
adowRoot) |
258 { | 256 { |
259 HashMap<const ShadowRoot*, OwnPtr<RuleSet> >::AddResult addResult = m_atHost
Rules.add(shadowRoot, nullptr); | 257 HashMap<const ShadowRoot*, OwnPtr<RuleSet> >::AddResult addResult = m_atHost
Rules.add(shadowRoot, nullptr); |
260 if (addResult.isNewEntry) | 258 if (addResult.isNewEntry) |
261 addResult.iterator->value = RuleSet::create(); | 259 addResult.iterator->value = RuleSet::create(); |
262 return addResult.iterator->value.get(); | 260 return addResult.iterator->value.get(); |
263 } | 261 } |
264 | 262 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 { | 348 { |
351 HashMap<const ShadowRoot*, OwnPtr<RuleSet> >::const_iterator it = m_atHostRu
les.find(shadowRoot); | 349 HashMap<const ShadowRoot*, OwnPtr<RuleSet> >::const_iterator it = m_atHostRu
les.find(shadowRoot); |
352 return it != m_atHostRules.end() ? it->value.get() : 0; | 350 return it != m_atHostRules.end() ? it->value.get() : 0; |
353 } | 351 } |
354 | 352 |
355 void ScopedStyleResolver::matchHostRules(ElementRuleCollector& collector, bool i
ncludeEmptyRules) | 353 void ScopedStyleResolver::matchHostRules(ElementRuleCollector& collector, bool i
ncludeEmptyRules) |
356 { | 354 { |
357 // FIXME: Determine tree position. | 355 // FIXME: Determine tree position. |
358 CascadeScope cascadeScope = ignoreCascadeScope; | 356 CascadeScope cascadeScope = ignoreCascadeScope; |
359 | 357 |
360 if (m_atHostRules.isEmpty() || !m_scopingNode->isElementNode()) | 358 if (m_atHostRules.isEmpty() || !m_scopingNode.isElementNode()) |
361 return; | 359 return; |
362 | 360 |
363 ElementShadow* shadow = toElement(m_scopingNode)->shadow(); | 361 ElementShadow* shadow = toElement(m_scopingNode).shadow(); |
364 if (!shadow) | 362 if (!shadow) |
365 return; | 363 return; |
366 | 364 |
367 collector.clearMatchedRules(); | 365 collector.clearMatchedRules(); |
368 collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().
matchedProperties.size() - 1; | 366 collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().
matchedProperties.size() - 1; |
369 | 367 |
370 // FIXME(99827): https://bugs.webkit.org/show_bug.cgi?id=99827 | 368 // FIXME(99827): https://bugs.webkit.org/show_bug.cgi?id=99827 |
371 // add a new flag to ElementShadow and cache whether any @host @-rules are | 369 // add a new flag to ElementShadow and cache whether any @host @-rules are |
372 // applied to the element or not. So we can quickly exit this method | 370 // applied to the element or not. So we can quickly exit this method |
373 // by using the flag. | 371 // by using the flag. |
374 ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); | 372 ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); |
375 for (; shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) | 373 for (; shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) |
376 if (!shadowRoot->containsShadowElements()) | 374 if (!shadowRoot->containsShadowElements()) |
377 break; | 375 break; |
378 // All shadow roots have <shadow>. | 376 // All shadow roots have <shadow>. |
379 if (!shadowRoot) | 377 if (!shadowRoot) |
380 shadowRoot = shadow->oldestShadowRoot(); | 378 shadowRoot = shadow->oldestShadowRoot(); |
381 | 379 |
382 RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); | 380 RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); |
383 collector.setBehaviorAtBoundary(static_cast<SelectorChecker::BehaviorAtBound
ary>(SelectorChecker::DoesNotCrossBoundary | SelectorChecker::ScopeContainsLastM
atchedElement)); | 381 collector.setBehaviorAtBoundary(static_cast<SelectorChecker::BehaviorAtBound
ary>(SelectorChecker::DoesNotCrossBoundary | SelectorChecker::ScopeContainsLastM
atchedElement)); |
384 for (; shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) { | 382 for (; shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) { |
385 if (RuleSet* ruleSet = atHostRuleSetFor(shadowRoot)) | 383 if (RuleSet* ruleSet = atHostRuleSetFor(shadowRoot)) |
386 collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRul
es, m_scopingNode), ruleRange, cascadeScope); | 384 collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRul
es, &m_scopingNode), ruleRange, cascadeScope); |
387 } | 385 } |
388 | 386 |
389 collector.sortAndTransferMatchedRules(); | 387 collector.sortAndTransferMatchedRules(); |
390 } | 388 } |
391 | 389 |
392 void ScopedStyleResolver::matchAuthorRules(ElementRuleCollector& collector, bool
includeEmptyRules, bool applyAuthorStyles) | 390 void ScopedStyleResolver::matchAuthorRules(ElementRuleCollector& collector, bool
includeEmptyRules, bool applyAuthorStyles) |
393 { | 391 { |
394 collector.clearMatchedRules(); | 392 collector.clearMatchedRules(); |
395 collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().
matchedProperties.size() - 1; | 393 collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().
matchedProperties.size() - 1; |
396 collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles,
ignoreCascadeScope); | 394 collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles,
ignoreCascadeScope); |
397 collector.sortAndTransferMatchedRules(); | 395 collector.sortAndTransferMatchedRules(); |
398 } | 396 } |
399 | 397 |
400 void ScopedStyleResolver::collectMatchingAuthorRules(ElementRuleCollector& colle
ctor, bool includeEmptyRules, bool applyAuthorStyles, CascadeScope cascadeScope,
CascadeOrder cascadeOrder) | 398 void ScopedStyleResolver::collectMatchingAuthorRules(ElementRuleCollector& colle
ctor, bool includeEmptyRules, bool applyAuthorStyles, CascadeScope cascadeScope,
CascadeOrder cascadeOrder) |
401 { | 399 { |
402 if (!m_authorStyle) | 400 if (!m_authorStyle) |
403 return; | 401 return; |
404 | 402 |
405 const ContainerNode* scopingNode = m_scopingNode; | 403 const ContainerNode* scopingNode = &m_scopingNode; |
406 unsigned behaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary; | 404 unsigned behaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary; |
407 | 405 |
408 if (!applyAuthorStyles) | 406 if (!applyAuthorStyles) |
409 behaviorAtBoundary |= SelectorChecker::ScopeContainsLastMatchedElement; | 407 behaviorAtBoundary |= SelectorChecker::ScopeContainsLastMatchedElement; |
410 | 408 |
411 if (m_scopingNode->isShadowRoot()) { | 409 if (m_scopingNode.isShadowRoot()) { |
412 scopingNode = toShadowRoot(m_scopingNode)->host(); | 410 scopingNode = toShadowRoot(m_scopingNode).host(); |
413 behaviorAtBoundary |= SelectorChecker::ScopeIsShadowHost; | 411 behaviorAtBoundary |= SelectorChecker::ScopeIsShadowHost; |
414 } | 412 } |
415 | 413 |
416 MatchRequest matchRequest(m_authorStyle.get(), includeEmptyRules, scopingNod
e, applyAuthorStyles); | 414 MatchRequest matchRequest(m_authorStyle.get(), includeEmptyRules, scopingNod
e, applyAuthorStyles); |
417 RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); | 415 RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); |
418 collector.setBehaviorAtBoundary(static_cast<SelectorChecker::BehaviorAtBound
ary>(behaviorAtBoundary)); | 416 collector.setBehaviorAtBoundary(static_cast<SelectorChecker::BehaviorAtBound
ary>(behaviorAtBoundary)); |
419 collector.collectMatchingRules(matchRequest, ruleRange, cascadeScope, cascad
eOrder); | 417 collector.collectMatchingRules(matchRequest, ruleRange, cascadeScope, cascad
eOrder); |
420 collector.collectMatchingRulesForRegion(matchRequest, ruleRange, cascadeScop
e, cascadeOrder); | 418 collector.collectMatchingRulesForRegion(matchRequest, ruleRange, cascadeScop
e, cascadeOrder); |
421 } | 419 } |
422 | 420 |
423 void ScopedStyleResolver::matchPageRules(PageRuleCollector& collector) | 421 void ScopedStyleResolver::matchPageRules(PageRuleCollector& collector) |
424 { | 422 { |
425 // Only consider the global author RuleSet for @page rules, as per the HTML5
spec. | 423 // Only consider the global author RuleSet for @page rules, as per the HTML5
spec. |
426 ASSERT(m_scopingNode->isDocumentNode()); | 424 ASSERT(m_scopingNode.isDocumentNode()); |
427 collector.matchPageRules(m_authorStyle.get()); | 425 collector.matchPageRules(m_authorStyle.get()); |
428 } | 426 } |
429 | 427 |
430 void ScopedStyleResolver::collectViewportRulesTo(StyleResolver* resolver) const | 428 void ScopedStyleResolver::collectViewportRulesTo(StyleResolver* resolver) const |
431 { | 429 { |
432 if (m_authorStyle) | 430 if (m_authorStyle) |
433 resolver->collectViewportRules(m_authorStyle.get()); | 431 resolver->collectViewportRules(m_authorStyle.get()); |
434 } | 432 } |
435 | 433 |
436 } // namespace WebCore | 434 } // namespace WebCore |
OLD | NEW |