Index: Source/core/css/resolver/StyleResolver.cpp |
diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp |
index eeaac0a9ae34a938d36d89f7e57ee922f0f1d550..18b8d7a14eba73fb96a4bfee06b8569cadca0dea 100644 |
--- a/Source/core/css/resolver/StyleResolver.cpp |
+++ b/Source/core/css/resolver/StyleResolver.cpp |
@@ -403,15 +403,13 @@ StyleResolver::~StyleResolver() |
m_viewportStyleResolver->clearDocument(); |
} |
-inline void StyleResolver::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules) |
+inline void StyleResolver::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, CascadeOrder cascadeOrder) |
{ |
if (m_treeBoundaryCrossingRules.isEmpty()) |
return; |
RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); |
- CascadeOrder cascadeOrder = 0; |
- |
DocumentOrderedList::iterator it = m_treeBoundaryCrossingRules.end(); |
while (it != m_treeBoundaryCrossingRules.begin()) { |
--it; |
@@ -419,14 +417,22 @@ inline void StyleResolver::collectTreeBoundaryCrossingRules(Element* element, El |
RuleSet* ruleSet = m_treeBoundaryCrossingRules.ruleSetScopedBy(scopingNode); |
unsigned boundaryBehavior = SelectorChecker::ScopeContainsLastMatchedElement; |
- // If a given scoping node is a shadow root and a given element is in a descendant tree of tree hosted by |
- // the scoping node's shadow host, we should use ScopeIsShadowHost. |
+ CascadeOrder orderForRule; |
+ |
+ // If a given scoping node is a shadow root and a given element is in a descendant tree of tree |
+ // hosted by the scoping node's shadow host, we should use ScopeIsShadowHost. |
if (scopingNode && scopingNode->isShadowRoot()) { |
- if (element->isInDescendantTreeOf(toShadowRoot(scopingNode)->host())) |
+ if (element->isInDescendantTreeOf(toShadowRoot(scopingNode)->host())) { |
boundaryBehavior |= SelectorChecker::ScopeIsShadowHost; |
+ orderForRule = cascadeOrder; |
+ } else { |
+ orderForRule = 0; |
+ } |
scopingNode = toShadowRoot(scopingNode)->host(); |
+ } else { |
+ orderForRule = scopingNode->containsIncludingShadowDOM(element) ? cascadeOrder : 0; |
} |
- collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder++); |
+ collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope, orderForRule); |
} |
} |
@@ -435,28 +441,6 @@ static inline bool applyAuthorStylesOf(const Element* element) |
return element->treeScope().applyAuthorStyles() || (element->shadow() && element->shadow()->applyAuthorStyles()); |
} |
-void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, Vector<ScopedStyleResolver*, 8>& resolvers, Vector<ScopedStyleResolver*, 8>& resolversInShadowTree) |
-{ |
- collector.clearMatchedRules(); |
- collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1; |
- |
- CascadeScope cascadeScope = 0; |
- CascadeOrder cascadeOrder = 0; |
- bool applyAuthorStyles = applyAuthorStylesOf(element); |
- |
- for (int j = resolversInShadowTree.size() - 1; j >= 0; --j) |
- resolversInShadowTree.at(j)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope, cascadeOrder++); |
- |
- if (resolvers.isEmpty() || resolvers.first()->treeScope() != element->treeScope()) |
- ++cascadeScope; |
- cascadeOrder += resolvers.size(); |
- for (unsigned i = 0; i < resolvers.size(); ++i) |
- resolvers.at(i)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, --cascadeOrder); |
- |
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules); |
- collector.sortAndTransferMatchedRules(); |
-} |
- |
void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules) |
{ |
collector.clearMatchedRules(); |
@@ -465,33 +449,29 @@ void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col |
bool applyAuthorStyles = applyAuthorStylesOf(element); |
if (m_styleTree.hasOnlyScopedResolverForDocument()) { |
m_styleTree.scopedStyleResolverForDocument()->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, ignoreCascadeScope); |
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules); |
+ // Use 2 for CascadeOrder, because there is only one scopedStyleResolver, i.e. |
+ // resolvers.size() == 1 and resolvers.size() + 1 == 2. |
+ collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules, 2); |
collector.sortAndTransferMatchedRules(); |
return; |
} |
Vector<ScopedStyleResolver*, 8> resolvers; |
m_styleTree.resolveScopedStyles(element, resolvers); |
- |
- Vector<ScopedStyleResolver*, 8> resolversInShadowTree; |
- m_styleTree.collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree); |
- if (!resolversInShadowTree.isEmpty()) { |
- matchAuthorRulesForShadowHost(element, collector, includeEmptyRules, resolvers, resolversInShadowTree); |
- return; |
- } |
- |
if (resolvers.isEmpty()) |
return; |
- |
CascadeScope cascadeScope = 0; |
CascadeOrder cascadeOrder = resolvers.size(); |
for (unsigned i = 0; i < resolvers.size(); ++i, --cascadeOrder) { |
ScopedStyleResolver* resolver = resolvers.at(i); |
+ CascadeOrder resolverOrder = resolver->treeScope() == element->treeScope() && resolver->scopingNode().isShadowRoot() ? 0 : cascadeOrder; |
// FIXME: Need to clarify how to treat style scoped. |
- resolver->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, resolver->treeScope() == element->treeScope() && resolver->scopingNode().isShadowRoot() ? 0 : cascadeOrder); |
+ resolver->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope, resolverOrder); |
+ if (resolver->crossingScopeBoundary(element)) |
+ ++cascadeScope; |
} |
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules); |
+ collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules, resolvers.size() + 1); |
collector.sortAndTransferMatchedRules(); |
} |