Chromium Code Reviews| Index: third_party/WebKit/Source/core/css/SelectorChecker.cpp |
| diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp |
| index 059d75bd91d9fbce37afaef90ba93f758c1e3973..de08250631e660f87318c7750ed1c9ad1872233f 100644 |
| --- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp |
| +++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp |
| @@ -47,6 +47,7 @@ |
| #include "core/html/HTMLInputElement.h" |
| #include "core/html/HTMLOptionElement.h" |
| #include "core/html/HTMLSelectElement.h" |
| +#include "core/html/HTMLSlotElement.h" |
| #include "core/html/parser/HTMLParserIdioms.h" |
| #include "core/html/track/vtt/VTTElement.h" |
| #include "core/inspector/InspectorInstrumentation.h" |
| @@ -113,6 +114,20 @@ static Element* parentElement(const SelectorChecker::SelectorCheckingContext& co |
| return context.element->parentElement(); |
| } |
| +static const HTMLSlotElement* findSlotElementInScope(const SelectorChecker::SelectorCheckingContext& context) |
| +{ |
| + if (!context.scope) |
| + return nullptr; |
| + |
| + const HTMLSlotElement* slot = context.element->assignedSlot(); |
| + while (slot) { |
| + if (slot->treeScope() == context.scope->treeScope()) |
| + return slot; |
| + slot = slot->assignedSlot(); |
| + } |
| + return nullptr; |
| +} |
| + |
| static bool scopeContainsLastMatchedElement(const SelectorChecker::SelectorCheckingContext& context) |
| { |
| // If this context isn't scoped, skip checking. |
| @@ -452,6 +467,16 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC |
| return SelectorFailsCompletely; |
| } |
| + case CSSSelector::ShadowSlot: |
|
rune
2016/01/11 10:07:23
It's possible to implement this without this combi
|
| + { |
| + const HTMLSlotElement* slot = findSlotElementInScope(context); |
| + if (!slot) |
| + return SelectorFailsCompletely; |
| + |
| + nextContext.element = const_cast<HTMLSlotElement*>(slot); |
| + return matchSelector(nextContext, result); |
| + } |
| + |
| case CSSSelector::SubSelector: |
| ASSERT_NOT_REACHED(); |
| } |
| @@ -1023,6 +1048,19 @@ bool SelectorChecker::checkPseudoElement(const SelectorCheckingContext& context, |
| return root->type() == ShadowRootType::UserAgent && element.shadowPseudoId() == selector.value(); |
| return false; |
| } |
| + case CSSSelector::PseudoSlotted: |
| + { |
| + SelectorCheckingContext subContext(context); |
| + subContext.isSubSelector = true; |
| + subContext.scope = nullptr; |
| + subContext.treatShadowHostAsNormalScope = false; |
| + |
| + // ::slotted() only allows one compound selector. |
| + ASSERT(selector.selectorList()->first()); |
| + ASSERT(!CSSSelectorList::next(*selector.selectorList()->first())); |
| + subContext.selector = selector.selectorList()->first(); |
| + return match(subContext); |
| + } |
| case CSSSelector::PseudoContent: |
| return element.isInShadowTree() && element.isInsertionPoint(); |
| case CSSSelector::PseudoShadow: |