| 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 |