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

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

Issue 334263020: Refactor SelectorChecker::BehaviorAtBoundary (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 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
« no previous file with comments | « Source/core/css/SelectorChecker.h ('k') | Source/core/css/TreeBoundaryCrossingRules.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/css/SelectorChecker.cpp
diff --git a/Source/core/css/SelectorChecker.cpp b/Source/core/css/SelectorChecker.cpp
index 5caa6fa46aa60fd9b450da1b057bbc901939e276..fe60f5d0d0cad6026f83dfb66a1ac24b9717c335 100644
--- a/Source/core/css/SelectorChecker.cpp
+++ b/Source/core/css/SelectorChecker.cpp
@@ -78,19 +78,12 @@ static bool matchesCustomPseudoElement(const Element* element, const CSSSelector
return true;
}
-Element* SelectorChecker::parentElement(const SelectorCheckingContext& context, bool allowToCrossBoundary) const
+static Element* parentElement(const SelectorChecker::SelectorCheckingContext& context)
{
- // CrossesBoundary means we don't care any context.scope. So we can walk up from a shadow root to its shadow host.
- if (allowToCrossBoundary)
- return context.element->parentOrShadowHostElement();
-
// If context.scope is a shadow root, we should walk up to its shadow host.
- if ((context.behaviorAtBoundary & SelectorChecker::ScopeIsShadowRoot) && context.scope == context.element->containingShadowRoot())
+ if (context.scope && context.scope == context.element->containingShadowRoot())
esprehn 2014/06/27 08:05:51 Why don't we need the ScopeIsShadowRoot stuff anym
kochi 2014/06/30 02:44:06 The flag used to mean that a context's scope was s
return context.element->parentOrShadowHostElement();
- if ((context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) != SelectorChecker::StaysWithinTreeScope)
esprehn 2014/06/27 08:05:51 Why is this not needed now?
kochi 2014/06/30 02:44:06 Now the condition will never be met. This conditi
- return context.element->parentElement();
-
// If context.scope is some element in some shadow tree and querySelector initialized the context,
// e.g. shadowRoot.querySelector(':host *'),
// (a) context.element has the same treescope as context.scope, need to walk up to its shadow host.
@@ -101,26 +94,22 @@ Element* SelectorChecker::parentElement(const SelectorCheckingContext& context,
return context.element->parentElement();
}
-bool SelectorChecker::scopeContainsLastMatchedElement(const SelectorCheckingContext& context) const
+static bool scopeContainsLastMatchedElement(const SelectorChecker::SelectorCheckingContext& context)
{
- if (!(context.behaviorAtBoundary & SelectorChecker::ScopeContainsLastMatchedElement))
+ if (!(context.contextFlags & SelectorChecker::ScopeContainsLastMatchedElement))
return true;
ASSERT(context.scope);
- // If behaviorAtBoundary is not ScopeIsShadowRoot, we can use "contains".
- if (!(context.behaviorAtBoundary & SelectorChecker::ScopeIsShadowRoot))
+ // If the scope is not a Shadow root, we can use "contains".
+ if (!context.scope->isShadowRoot())
return context.scope->contains(context.element);
// If a given element is scope, i.e. shadow host, matches.
if (context.element == context.scope->shadowHost() && (!context.previousElement || context.previousElement->isInDescendantTreeOf(context.element)))
return true;
- ShadowRoot* root = context.element->containingShadowRoot();
- if (!root)
- return false;
-
- // If a host of the containing shadow root is scope, matches.
- return root == context.scope;
+ // If the containing shadow root is scope, matches.
+ return context.element->containingShadowRoot() == context.scope;
}
static inline bool nextSelectorExceedsScope(const SelectorChecker::SelectorCheckingContext& context)
@@ -341,7 +330,7 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
case CSSSelector::ShadowPseudo:
{
// If we're in the same tree-scope as the scoping element, then following a shadow descendant combinator would escape that and thus the scope.
- if (context.scope && context.scope->shadowHost() && context.scope->shadowHost()->treeScope() == context.element->treeScope() && (context.behaviorAtBoundary & BoundaryBehaviorMask) != StaysWithinTreeScope)
+ if (context.scope && context.scope->shadowHost() && context.scope->shadowHost()->treeScope() == context.element->treeScope())
return SelectorFailsCompletely;
Element* shadowHost = context.element->shadowHost();
@@ -357,7 +346,7 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
{
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
- for (nextContext.element = parentElement(context, true); nextContext.element; nextContext.element = parentElement(nextContext, true)) {
+ for (nextContext.element = context.element->parentOrShadowHostElement(); nextContext.element; nextContext.element = nextContext.element->parentOrShadowHostElement()) {
Match match = this->match(nextContext, siblingTraversalStrategy, result);
if (match == SelectorMatches || match == SelectorFailsCompletely)
return match;
@@ -380,25 +369,11 @@ SelectorChecker::Match SelectorChecker::matchForShadowDistributed(const Element*
{
ASSERT(element);
WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
-
- const ContainerNode* scope = nextContext.scope;
- BehaviorAtBoundary behaviorAtBoundary = nextContext.behaviorAtBoundary;
-
collectDestinationInsertionPoints(*element, insertionPoints);
for (size_t i = 0; i < insertionPoints.size(); ++i) {
nextContext.element = insertionPoints[i];
-
- // If a given scope is a shadow host of an insertion point but behaviorAtBoundary doesn't have ScopeIsShadowRoot,
- // we need to update behaviorAtBoundary to make selectors like ":host > ::content" work correctly.
- if (m_mode == SharingRules) {
- nextContext.behaviorAtBoundary = static_cast<BehaviorAtBoundary>(behaviorAtBoundary | ScopeIsShadowRoot);
+ if (m_mode == SharingRules)
nextContext.scope = insertionPoints[i]->containingShadowRoot();
- } else if (scope == insertionPoints[i]->containingShadowRoot() && !(behaviorAtBoundary & ScopeIsShadowRoot)) {
- nextContext.behaviorAtBoundary = static_cast<BehaviorAtBoundary>(behaviorAtBoundary | ScopeIsShadowRoot);
- } else {
- nextContext.behaviorAtBoundary = behaviorAtBoundary;
- }
-
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
if (match(nextContext, siblingTraversalStrategy, result) == SelectorMatches)
@@ -534,11 +509,11 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
ASSERT(context.selector);
const CSSSelector& selector = *context.selector;
- bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.behaviorAtBoundary, context.scope);
+ bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.scope);
// Only :host and :ancestor should match the host: http://drafts.csswg.org/css-scoping/#host-element
if (elementIsHostInItsShadowTree && !selector.isHostPseudoClass()
- && !(context.behaviorAtBoundary & TreatShadowHostAsNormalScope))
+ && !(context.contextFlags & TreatShadowHostAsNormalScope))
return false;
if (selector.match() == CSSSelector::Tag)
@@ -947,7 +922,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
// If one of simple selectors matches an element, returns SelectorMatches. Just "OR".
for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
- subContext.behaviorAtBoundary = ScopeIsShadowHostInPseudoHostParameter;
+ subContext.contextFlags = TreatShadowHostAsNormalScope;
subContext.scope = context.scope;
// Use NodeRenderingTraversal to traverse a composed ancestor list of a given element.
Element* nextElement = &element;
@@ -961,7 +936,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
maxSpecificity = std::max(maxSpecificity, hostContext.selector->specificity() + subResult.specificity);
break;
}
- hostContext.behaviorAtBoundary = DoesNotCrossBoundary;
+ hostContext.contextFlags = DefaultBehavior;
hostContext.scope = 0;
if (selector.pseudoType() == CSSSelector::PseudoHost)
@@ -1001,7 +976,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
} else if (selector.match() == CSSSelector::PseudoElement && selector.pseudoType() == CSSSelector::PseudoCue) {
SelectorCheckingContext subContext(context);
subContext.isSubSelector = true;
- subContext.behaviorAtBoundary = StaysWithinTreeScope;
+ subContext.contextFlags = DefaultBehavior;
const CSSSelector* contextSelector = context.selector;
ASSERT(contextSelector);
« no previous file with comments | « Source/core/css/SelectorChecker.h ('k') | Source/core/css/TreeBoundaryCrossingRules.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698