Permalink
Browse files

Auto merge of #19541 - emilio:parse-slotted, r=heycam

selectors: Add parsing support for ::slotted().

Without turning it on yet, of course.

The reason why I didn't use the general PseudoElement mechanism is because this
pseudo is a bit of its own thing, and I found easier to make ::selectors know
about it (because you need to jump to the assigned slot) than the other way
around.

Also, we need to support ::slotted(..)::before and such, and supporting multiple
pseudo-elements like that breaks some other invariants around the SelectorMap,
and fixing those would require special-casing slotted a lot more in other parts
of the code.

Let me know if you think otherwise.

I also don't like much the boolean tuple return value, but I plan to do some
cleanup in the area in a bit, so it should go away soon, I'd hope.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19541)
<!-- Reviewable:end -->
  • Loading branch information...
2 parents c258bfb + 7886e03 commit f5129ef7b5efa59a176cac98dc68d910cb3279c9 @bors-servo bors-servo committed Dec 14, 2017
Showing with 175 additions and 42 deletions.
  1. +14 −3 components/selectors/builder.rs
  2. +19 −0 components/selectors/matching.rs
  3. +135 −39 components/selectors/parser.rs
  4. +7 −0 components/selectors/tree.rs
@@ -264,12 +264,23 @@ fn complex_selector_specificity<Impl>(mut iter: slice::Iter<Component<Impl>>)
-> Specificity
where Impl: SelectorImpl
{
- fn simple_selector_specificity<Impl>(simple_selector: &Component<Impl>,
- specificity: &mut Specificity)
- where Impl: SelectorImpl
+ fn simple_selector_specificity<Impl>(
+ simple_selector: &Component<Impl>,
+ specificity: &mut Specificity,
+ )
+ where
+ Impl: SelectorImpl
{
match *simple_selector {
Component::Combinator(..) => unreachable!(),
+ // FIXME(emilio): Spec doesn't define any particular specificity for
+ // ::slotted(), so apply the general rule for pseudos per:
+ //
+ // https://github.com/w3c/csswg-drafts/issues/1915
+ //
+ // Though other engines compute it dynamically, so maybe we should
+ // do that instead, eventually.
+ Component::Slotted(..) |
Component::PseudoElement(..) |
Component::LocalName(..) => {
specificity.element_selectors += 1
@@ -393,6 +393,9 @@ where
element.parent_element()
}
+ Combinator::SlotAssignment => {
+ element.assigned_slot()
+ }
Combinator::PseudoElement => {
element.pseudo_element_originating_element()
}
@@ -453,6 +456,7 @@ where
}
Combinator::Child |
Combinator::Descendant |
+ Combinator::SlotAssignment |
Combinator::PseudoElement => {
SelectorMatchingResult::NotMatchedGlobally
}
@@ -541,6 +545,21 @@ where
{
match *selector {
Component::Combinator(_) => unreachable!(),
+ Component::Slotted(ref selectors) => {
+ context.shared.nesting_level += 1;
+ let result =
+ element.assigned_slot().is_some() &&
+ selectors.iter().any(|s| {
+ matches_complex_selector(
+ s.iter(),
+ element,
+ context.shared,
+ flags_setter,
+ )
+ });
+ context.shared.nesting_level -= 1;
+ result
+ }
Component::PseudoElement(ref pseudo) => {
element.match_pseudo_element(pseudo, context.shared)
}
Oops, something went wrong.

0 comments on commit f5129ef

Please sign in to comment.