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); |