summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp76
1 files changed, 64 insertions, 12 deletions
diff --git a/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp b/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp
index 30a5604c412..4d3b123d3bc 100644
--- a/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp
@@ -29,20 +29,68 @@
#include "config.h"
#include "core/css/TreeBoundaryCrossingRules.h"
+#include "core/css/ElementRuleCollector.h"
#include "core/css/RuleFeature.h"
#include "core/dom/StyleEngine.h"
+#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
-void TreeBoundaryCrossingRules::addRule(StyleRule* rule, size_t selectorIndex, ContainerNode* scopingNode, AddRuleFlags addRuleFlags)
+static void addRules(RuleSet* ruleSet, const WillBeHeapVector<MinimalRuleData>& rules)
{
- if (m_treeBoundaryCrossingRuleSetMap.contains(scopingNode)) {
- m_treeBoundaryCrossingRuleSetMap.get(scopingNode)->addRule(rule, selectorIndex, addRuleFlags);
- } else {
- OwnPtr<RuleSet> ruleSetForScope = RuleSet::create();
- ruleSetForScope->addRule(rule, selectorIndex, addRuleFlags);
- m_treeBoundaryCrossingRuleSetMap.add(scopingNode, ruleSetForScope.release());
- m_scopingNodes.add(scopingNode);
+ for (unsigned i = 0; i < rules.size(); ++i) {
+ const MinimalRuleData& info = rules[i];
+ ruleSet->addRule(info.m_rule, info.m_selectorIndex, info.m_flags);
+ }
+}
+
+void TreeBoundaryCrossingRules::addTreeBoundaryCrossingRules(const RuleSet& authorRules, ContainerNode& scopingNode, CSSStyleSheet* parentStyleSheet)
+{
+ if (authorRules.treeBoundaryCrossingRules().isEmpty() && (scopingNode.isDocumentNode() || authorRules.shadowDistributedRules().isEmpty()))
+ return;
+ OwnPtrWillBeRawPtr<RuleSet> ruleSetForScope = RuleSet::create();
+ addRules(ruleSetForScope.get(), authorRules.treeBoundaryCrossingRules());
+ if (!scopingNode.isDocumentNode())
+ addRules(ruleSetForScope.get(), authorRules.shadowDistributedRules());
+
+ if (!m_treeBoundaryCrossingRuleSetMap.contains(&scopingNode)) {
+ m_treeBoundaryCrossingRuleSetMap.add(&scopingNode, adoptPtrWillBeNoop(new CSSStyleSheetRuleSubSet()));
+ m_scopingNodes.add(&scopingNode);
+ }
+ CSSStyleSheetRuleSubSet* ruleSubSet = m_treeBoundaryCrossingRuleSetMap.get(&scopingNode);
+ ruleSubSet->append(std::make_pair(parentStyleSheet, ruleSetForScope.release()));
+}
+
+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, we should use ScopeIsShadowRoot.
+ if (scopingNode && scopingNode->isShadowRoot())
+ boundaryBehavior |= SelectorChecker::ScopeIsShadowRoot;
+
+ 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;
}
}
@@ -52,12 +100,16 @@ void TreeBoundaryCrossingRules::reset(const ContainerNode* scopingNode)
m_scopingNodes.remove(scopingNode);
}
+void TreeBoundaryCrossingRules::collectFeaturesFromRuleSubSet(CSSStyleSheetRuleSubSet* ruleSubSet, RuleFeatureSet& features)
+{
+ for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != ruleSubSet->end(); ++it)
+ features.add(it->second->features());
+}
+
void TreeBoundaryCrossingRules::collectFeaturesTo(RuleFeatureSet& features)
{
- for (TreeBoundaryCrossingRuleSetMap::iterator::Values it = m_treeBoundaryCrossingRuleSetMap.values().begin(); it != m_treeBoundaryCrossingRuleSetMap.values().end(); ++it) {
- RuleSet* ruleSet = it->get();
- features.add(ruleSet->features());
- }
+ for (TreeBoundaryCrossingRuleSetMap::iterator::Values it = m_treeBoundaryCrossingRuleSetMap.values().begin(); it != m_treeBoundaryCrossingRuleSetMap.values().end(); ++it)
+ collectFeaturesFromRuleSubSet(it->get(), features);
}
} // namespace WebCore