void TreeBoundaryCrossingRules::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules) { if (m_treeBoundaryCrossingRuleSetMap.isEmpty()) return; RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); // When comparing rules declared in outer treescopes, outer's rules win. CascadeOrder outerCascadeOrder = size() + size(); // When comparing rules declared in inner treescopes, inner's rules win. CascadeOrder innerCascadeOrder = size(); for (DocumentOrderedList::iterator it = m_scopingNodes.begin(); it != m_scopingNodes.end(); ++it) { const ContainerNode* scopingNode = toContainerNode(*it); CSSStyleSheetRuleSubSet* ruleSubSet = m_treeBoundaryCrossingRuleSetMap.get(scopingNode); bool isInnerTreeScope = element->treeScope().isInclusiveAncestorOf(scopingNode->treeScope()); CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outerCascadeOrder; for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != ruleSubSet->end(); ++it) { CSSStyleSheet* parentStyleSheet = it->first; RuleSet* ruleSet = it->second.get(); collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode, parentStyleSheet), ruleRange, SelectorChecker::ScopeContainsLastMatchedElement, ignoreCascadeScope, cascadeOrder); } ++innerCascadeOrder; --outerCascadeOrder; } }
void TreeBoundaryCrossingRules::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules) { if (m_treeBoundaryCrossingRuleSetMap.isEmpty()) return; RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); // When comparing rules declared in outer treescopes, outer's rules win. CascadeOrder outerCascadeOrder = size() + size(); // When comparing rules declared in inner treescopes, inner's rules win. CascadeOrder innerCascadeOrder = size(); for (DocumentOrderedList::iterator it = m_scopingNodes.begin(); it != m_scopingNodes.end(); ++it) { const ContainerNode* scopingNode = toContainerNode(*it); CSSStyleSheetRuleSubSet* ruleSubSet = m_treeBoundaryCrossingRuleSetMap.get(scopingNode); unsigned boundaryBehavior = SelectorChecker::ScopeContainsLastMatchedElement; bool isInnerTreeScope = element->treeScope().isInclusiveAncestorOf(scopingNode->treeScope()); // 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())) boundaryBehavior |= SelectorChecker::ScopeIsShadowHost; scopingNode = toShadowRoot(scopingNode)->host(); } CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outerCascadeOrder; for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != ruleSubSet->end(); ++it) { CSSStyleSheet* parentStyleSheet = it->first; RuleSet* ruleSet = it->second.get(); collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode, parentStyleSheet), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder); } ++innerCascadeOrder; --outerCascadeOrder; } }