diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index c80e81f98c4..1628e53b890 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -634,70 +634,13 @@ where debug_assert!(context.shared.is_nested() || !context.shared.in_negation()); match *selector { - Component::Combinator(_) => unreachable!(), - Component::Part(ref parts) => { - let mut hosts = SmallVec::<[E; 4]>::new(); - - let mut host = match element.containing_shadow_host() { - Some(h) => h, - None => return false, - }; - - let current_host = context.shared.current_host; - if current_host != Some(host.opaque()) { - loop { - let outer_host = host.containing_shadow_host(); - if outer_host.as_ref().map(|h| h.opaque()) == current_host { - break; - } - let outer_host = match outer_host { - Some(h) => h, - None => return false, - }; - // TODO(emilio): if worth it, we could early return if - // host doesn't have the exportparts attribute. - hosts.push(host); - host = outer_host; - } - } - - // Translate the part into the right scope. - parts.iter().all(|part| { - let mut part = part.clone(); - for host in hosts.iter().rev() { - part = match host.imported_part(&part) { - Some(p) => p, - None => return false, - }; - } - element.is_part(&part) - }) - }, - Component::Slotted(ref selector) => { - // are never flattened tree slottables. - !element.is_html_slot_element() && - context.shared.nest(|context| { - matches_complex_selector(selector.iter(), element, context) - }) - }, - Component::PseudoElement(ref pseudo) => { - element.match_pseudo_element(pseudo, context.shared) - }, - Component::LocalName(ref local_name) => matches_local_name(element, local_name), - Component::ExplicitUniversalType | Component::ExplicitAnyNamespace => true, - Component::Namespace(_, ref url) | Component::DefaultNamespace(ref url) => { - element.has_namespace(&url.borrow()) - }, - Component::ExplicitNoNamespace => { - let ns = crate::parser::namespace_empty_string::(); - element.has_namespace(&ns.borrow()) - }, Component::ID(ref id) => { element.has_id(id, context.shared.classes_and_ids_case_sensitivity()) }, Component::Class(ref class) => { element.has_class(class, context.shared.classes_and_ids_case_sensitivity()) }, + Component::LocalName(ref local_name) => matches_local_name(element, local_name), Component::AttributeInNoNamespaceExists { ref local_name, ref local_name_lower, @@ -760,6 +703,62 @@ where }, ) }, + Component::Part(ref parts) => { + let mut hosts = SmallVec::<[E; 4]>::new(); + + let mut host = match element.containing_shadow_host() { + Some(h) => h, + None => return false, + }; + + let current_host = context.shared.current_host; + if current_host != Some(host.opaque()) { + loop { + let outer_host = host.containing_shadow_host(); + if outer_host.as_ref().map(|h| h.opaque()) == current_host { + break; + } + let outer_host = match outer_host { + Some(h) => h, + None => return false, + }; + // TODO(emilio): if worth it, we could early return if + // host doesn't have the exportparts attribute. + hosts.push(host); + host = outer_host; + } + } + + // Translate the part into the right scope. + parts.iter().all(|part| { + let mut part = part.clone(); + for host in hosts.iter().rev() { + part = match host.imported_part(&part) { + Some(p) => p, + None => return false, + }; + } + element.is_part(&part) + }) + }, + Component::Slotted(ref selector) => { + // are never flattened tree slottables. + !element.is_html_slot_element() && + context.shared.nest(|context| { + matches_complex_selector(selector.iter(), element, context) + }) + }, + Component::PseudoElement(ref pseudo) => { + element.match_pseudo_element(pseudo, context.shared) + }, + Component::ExplicitUniversalType | Component::ExplicitAnyNamespace => true, + Component::Namespace(_, ref url) | Component::DefaultNamespace(ref url) => { + element.has_namespace(&url.borrow()) + }, + Component::ExplicitNoNamespace => { + let ns = crate::parser::namespace_empty_string::(); + element.has_namespace(&ns.borrow()) + }, Component::NonTSPseudoClass(ref pc) => { if let Some((ref rightmost, ref iter)) = context.quirks_data { if pc.is_active_or_hover() && !element.is_link() && hover_and_active_quirk_applies(iter, context.shared, *rightmost) { @@ -833,6 +832,7 @@ where } true }), + Component::Combinator(_) => unreachable!(), } } diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 295136dea3f..2720d723568 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -1030,17 +1030,6 @@ impl Combinator { #[cfg_attr(feature = "shmem", derive(ToShmem))] #[cfg_attr(feature = "shmem", shmem(no_bounds))] pub enum Component { - Combinator(Combinator), - - ExplicitAnyNamespace, - ExplicitNoNamespace, - DefaultNamespace(#[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::NamespaceUrl), - Namespace( - #[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::NamespacePrefix, - #[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::NamespaceUrl, - ), - - ExplicitUniversalType, LocalName(LocalName), ID(#[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::Identifier), @@ -1063,6 +1052,16 @@ pub enum Component { // Use a Box in the less common cases with more data to keep size_of::() small. AttributeOther(Box>), + ExplicitUniversalType, + ExplicitAnyNamespace, + + ExplicitNoNamespace, + DefaultNamespace(#[shmem(field_bound)] Impl::NamespaceUrl), + Namespace( + #[shmem(field_bound)] Impl::NamespacePrefix, + #[shmem(field_bound)] Impl::NamespaceUrl, + ), + /// Pseudo-classes Negation(Box<[Selector]>), FirstChild, @@ -1119,6 +1118,8 @@ pub enum Component { Is(Box<[Selector]>), /// An implementation-dependent pseudo-element selector. PseudoElement(#[cfg_attr(feature = "shmem", shmem(field_bound))] Impl::PseudoElement), + + Combinator(Combinator), } impl Component {