Chromium Code Reviews| Index: Source/core/css/SelectorChecker.cpp |
| diff --git a/Source/core/css/SelectorChecker.cpp b/Source/core/css/SelectorChecker.cpp |
| index 36d9f5f8c2ddee0301070505f5bd4d84b48fe9e4..5dbb69ca71d004e0cef91b5c7463b6a0f5748594 100644 |
| --- a/Source/core/css/SelectorChecker.cpp |
| +++ b/Source/core/css/SelectorChecker.cpp |
| @@ -154,6 +154,9 @@ SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext& con |
| } else if (context.selector->isContentPseudoElement()) { |
| if (!context.element->isInShadowTree() || !context.element->isInsertionPoint()) |
| return SelectorFailsLocally; |
| + } else if (context.selector->isShadowPseudoElement()) { |
| + if (!context.element->isInShadowTree()) |
| + return SelectorFailsLocally; |
|
rune
2014/03/25 20:58:21
You're just checking for isInShadowTree(). Won't t
tasak
2014/03/26 11:01:46
If we have "::shadow ::shadow ::shadow span", CSSP
|
| } else { |
| if ((!context.elementStyle && m_mode == ResolvingStyle) || m_mode == QueryingRules) |
| return SelectorFailsLocally; |
| @@ -211,6 +214,11 @@ static inline SelectorChecker::SelectorCheckingContext prepareNextContextForRela |
| return nextContext; |
| } |
| +static inline bool isAuthorShadowRoot(const Node* node) |
| +{ |
| + return node && node->isShadowRoot() && toShadowRoot(node)->type() == ShadowRoot::AuthorShadowRoot; |
| +} |
| + |
| template<typename SiblingTraversalStrategy> |
| SelectorChecker::Match SelectorChecker::matchForSubSelector(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const |
| { |
| @@ -231,6 +239,11 @@ SelectorChecker::Match SelectorChecker::matchForSubSelector(const SelectorChecki |
| return match(nextContext, siblingTraversalStrategy, result); |
| } |
| +static bool selectorMatchesShadowRoot(const CSSSelector* selector) |
| +{ |
| + return selector && selector->isShadowPseudoElement(); |
| +} |
| + |
| template<typename SiblingTraversalStrategy> |
| SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const |
| { |
| @@ -255,6 +268,14 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC |
| } |
| nextContext.isSubSelector = false; |
| nextContext.elementStyle = 0; |
| + |
| + if (selectorMatchesShadowRoot(nextContext.selector)) { |
| + if (!isAuthorShadowRoot(context.element->containingShadowRoot())) |
| + return SelectorFailsCompletely; |
| + nextContext.element = context.element; |
| + return this->match(nextContext, siblingTraversalStrategy, result); |
| + } |
| + |
| for (nextContext.element = parentElement(context); nextContext.element; nextContext.element = parentElement(nextContext)) { |
| Match match = this->match(nextContext, siblingTraversalStrategy, result); |
| if (match == SelectorMatches || match == SelectorFailsCompletely) |
| @@ -268,12 +289,18 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC |
| if (context.selector->relationIsAffectedByPseudoContent()) |
| return matchForShadowDistributed(context.element, siblingTraversalStrategy, nextContext, result); |
| - nextContext.element = parentElement(context); |
| - if (!nextContext.element) |
| - return SelectorFailsCompletely; |
| - |
| nextContext.isSubSelector = false; |
| nextContext.elementStyle = 0; |
| + nextContext.element = parentElement(context); |
| + if (!nextContext.element) { |
| + if (!selectorMatchesShadowRoot(nextContext.selector)) |
|
dglazkov
2014/03/25 17:10:53
This is effectively copy-paste code from CSSSelect
tasak
2014/03/26 11:01:46
I see. I created a new method for this.
|
| + return SelectorFailsCompletely; |
| + if (isAuthorShadowRoot(context.element->parentNode())) { |
| + nextContext.element = context.element; |
| + return match(nextContext, siblingTraversalStrategy, result); |
| + } |
| + return SelectorFailsCompletely; |
| + } |
| return match(nextContext, siblingTraversalStrategy, result); |
| } |
| case CSSSelector::DirectAdjacent: |
| @@ -304,7 +331,6 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC |
| return SelectorFailsAllSiblings; |
| case CSSSelector::ShadowPseudo: |
| - case CSSSelector::Shadow: |
| { |
| // 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->treeScope() == context.element->treeScope() && (context.behaviorAtBoundary & BoundaryBehaviorMask) != StaysWithinTreeScope) |