Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Unified Diff: Source/core/css/TreeBoundaryCrossingRules.cpp

Issue 206043009: Setup parent stylesheet for tree boundary crossing rules. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: address @apavlov comment Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/css/TreeBoundaryCrossingRules.cpp
diff --git a/Source/core/css/TreeBoundaryCrossingRules.cpp b/Source/core/css/TreeBoundaryCrossingRules.cpp
index 4184d9f568108a3d9e6f7122bb872fae445ee1f9..e055848df5c4f5162c23f5c4cf9cdc126ccb33e0 100644
--- a/Source/core/css/TreeBoundaryCrossingRules.cpp
+++ b/Source/core/css/TreeBoundaryCrossingRules.cpp
@@ -29,35 +29,101 @@
#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/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
-void TreeBoundaryCrossingRules::addRule(StyleRule* rule, size_t selectorIndex, ContainerNode* scopingNode, AddRuleFlags addRuleFlags)
+void TreeBoundaryCrossingRules::addRule(StyleRule* rule, size_t selectorIndex, ContainerNode* scopingNode, CSSStyleSheet* parentStyleSheet, AddRuleFlags addRuleFlags)
{
- if (m_treeBoundaryCrossingRuleSetMap.contains(scopingNode)) {
- m_treeBoundaryCrossingRuleSetMap.get(scopingNode)->addRule(rule, selectorIndex, addRuleFlags);
+ if (!m_treeBoundaryCrossingRuleSetMap.contains(scopingNode)) {
+ OwnPtrWillBeRawPtr<CSSStyleSheetRuleSubSet> styleSheetRuleSubSetForScope = adoptPtr(new CSSStyleSheetRuleSubSet());
+ m_treeBoundaryCrossingRuleSetMap.add(scopingNode, styleSheetRuleSubSetForScope.release());
+ OwnPtrWillBeRawPtr<CSSStyleSheetOrder> styleSheetOrderMap = adoptPtr(new CSSStyleSheetOrder());
+ m_styleSheetsOrder.add(scopingNode, styleSheetOrderMap.release());
+ m_scopingNodes.add(scopingNode);
+ }
+ CSSStyleSheetRuleSubSet* ruleSubSet = m_treeBoundaryCrossingRuleSetMap.get(scopingNode);
+
+ if (ruleSubSet->contains(parentStyleSheet)) {
+ ruleSubSet->get(parentStyleSheet)->addRule(rule, selectorIndex, addRuleFlags);
} else {
OwnPtrWillBeRawPtr<RuleSet> ruleSetForScope = RuleSet::create();
ruleSetForScope->addRule(rule, selectorIndex, addRuleFlags);
- m_treeBoundaryCrossingRuleSetMap.add(scopingNode, ruleSetForScope.release());
- m_scopingNodes.add(scopingNode);
+ ruleSubSet->add(parentStyleSheet, ruleSetForScope.release());
+ m_styleSheetsOrder.get(scopingNode)->add(parentStyleSheet);
}
}
void TreeBoundaryCrossingRules::reset(const ContainerNode* scopingNode)
{
m_treeBoundaryCrossingRuleSetMap.remove(scopingNode);
+ m_styleSheetsOrder.remove(scopingNode);
m_scopingNodes.remove(scopingNode);
}
-void TreeBoundaryCrossingRules::collectFeaturesTo(RuleFeatureSet& features)
+void TreeBoundaryCrossingRules::collectFeaturesFromStyleSheetSubSet(TreeBoundaryCrossingRules::CSSStyleSheetRuleSubSet* styleSheetSubSet, RuleFeatureSet& features)
{
- for (TreeBoundaryCrossingRuleSetMap::iterator::Values it = m_treeBoundaryCrossingRuleSetMap.values().begin(); it != m_treeBoundaryCrossingRuleSetMap.values().end(); ++it) {
+ for (TreeBoundaryCrossingRules::CSSStyleSheetRuleSubSet::iterator::Values it = styleSheetSubSet->values().begin(); it != styleSheetSubSet->values().end(); ++it) {
RuleSet* ruleSet = it->get();
features.add(ruleSet->features());
}
}
+void TreeBoundaryCrossingRules::collectFeaturesTo(RuleFeatureSet& features)
+{
+ for (TreeBoundaryCrossingRuleSetMap::iterator::Values it = m_treeBoundaryCrossingRuleSetMap.values().begin(); it != m_treeBoundaryCrossingRuleSetMap.values().end(); ++it) {
+ CSSStyleSheetRuleSubSet* styleSheetSubSet = it->get();
+ collectFeaturesFromStyleSheetSubSet(styleSheetSubSet, features);
+ }
+}
+
+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);
+
+ if (ShadowRoot* shadowRoot = scopingNode->containingShadowRoot()) {
+ if (!shadowRoot->isActiveForStyling())
+ continue;
+ }
+
+ TreeBoundaryCrossingRules::CSSStyleSheetRuleSubSet* styleSheetsRuleSubSets = m_treeBoundaryCrossingRuleSetMap.get(scopingNode);
+ CSSStyleSheetOrder* styleSheetsOrder = m_styleSheetsOrder.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 (CSSStyleSheetOrder::iterator it = styleSheetsOrder->begin(); it != styleSheetsOrder->end(); ++it) {
+ CSSStyleSheet* parentStyleSheet = *it;
+ RuleSet* ruleSet = styleSheetsRuleSubSets->get(parentStyleSheet);
+ collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode, parentStyleSheet), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder);
+ }
+ ++innerCascadeOrder;
+ --outerCascadeOrder;
+ }
+}
+
+
} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698