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.
This commit is contained in:
Emilio Cobos Álvarez 2017-12-10 14:23:27 +01:00
parent 0fa605d243
commit 7886e033aa
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
4 changed files with 175 additions and 42 deletions

View file

@ -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)
}