diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs index 0110704edad..a909ce72e8f 100644 --- a/components/layout_thread/dom_wrapper.rs +++ b/components/layout_thread/dom_wrapper.rs @@ -784,6 +784,13 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { } } + fn is_html_slot_element(&self) -> bool { + unsafe { + self.element.is_html_element() && + self.get_local_name() == &local_name!("slot") + } + } + fn is_html_element_in_html_document(&self) -> bool { unsafe { if !self.element.is_html_element() { @@ -1176,6 +1183,10 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { None } + fn is_html_slot_element(&self) -> bool { + self.element.is_html_slot_element() + } + fn is_html_element_in_html_document(&self) -> bool { debug!("ServoThreadSafeLayoutElement::is_html_element_in_html_document called"); true diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 16a84737c47..ad050be3dda 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -916,8 +916,12 @@ impl LayoutElementHelpers for LayoutDom { } impl Element { + pub fn is_html_element(&self) -> bool { + self.namespace == ns!(html) + } + pub fn html_element_in_html_document(&self) -> bool { - self.namespace == ns!(html) && self.upcast::().is_in_html_doc() + self.is_html_element() && self.upcast::().is_in_html_doc() } pub fn local_name(&self) -> &LocalName { @@ -2713,6 +2717,10 @@ impl<'a> SelectorsElement for DomRoot { fn is_html_element_in_html_document(&self) -> bool { self.html_element_in_html_document() } + + fn is_html_slot_element(&self) -> bool { + self.is_html_element() && self.local_name() == &local_name!("slot") + } } diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index eda52011ac7..a8bf3f689f9 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -416,6 +416,7 @@ where element.parent_element() } Combinator::SlotAssignment => { + debug_assert!(element.assigned_slot().map_or(true, |s| s.is_html_slot_element())); element.assigned_slot() } Combinator::PseudoElement => { @@ -631,6 +632,8 @@ where Component::Combinator(_) => unreachable!(), Component::Slotted(ref selector) => { context.shared.nest(|context| { + // are never flattened tree slottables. + !element.is_html_slot_element() && element.assigned_slot().is_some() && matches_complex_selector( selector.iter(), diff --git a/components/selectors/tree.rs b/components/selectors/tree.rs index ea36aac6f89..0b0f65de073 100644 --- a/components/selectors/tree.rs +++ b/components/selectors/tree.rs @@ -82,6 +82,9 @@ pub trait Element: Sized + Clone + Debug { /// Whether this element is a `link`. fn is_link(&self) -> bool; + /// Returns whether the element is an HTML element. + fn is_html_slot_element(&self) -> bool; + /// Returns the assigned element this element is assigned to. /// /// Necessary for the `::slotted` pseudo-class. diff --git a/components/style/dom.rs b/components/style/dom.rs index 88cd7a82829..0a5733303db 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -419,12 +419,6 @@ pub trait TElement /// Return whether this element is an element in the HTML namespace. fn is_html_element(&self) -> bool; - /// Returns whether this element is a element. - fn is_html_slot_element(&self) -> bool { - self.get_local_name() == &*local_name!("slot") && - self.is_html_element() - } - /// Return the list of slotted nodes of this node. fn slotted_nodes(&self) -> &[Self::ConcreteNode] { &[] diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 92aedc3b5d7..6eab24153a8 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -2205,6 +2205,12 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { self.as_node().owner_doc().is_html_document() } + #[inline] + fn is_html_slot_element(&self) -> bool { + self.is_html_element() && + self.get_local_name().as_ptr() == local_name!("slot").as_ptr() + } + #[inline] fn ignores_nth_child_selectors(&self) -> bool { self.is_root_of_anonymous_subtree() diff --git a/components/style/invalidation/element/element_wrapper.rs b/components/style/invalidation/element/element_wrapper.rs index 22ca94a6e14..2fb0a4f8412 100644 --- a/components/style/invalidation/element/element_wrapper.rs +++ b/components/style/invalidation/element/element_wrapper.rs @@ -295,6 +295,10 @@ impl<'a, E> Element for ElementWrapper<'a, E> self.element.is_html_element_in_html_document() } + fn is_html_slot_element(&self) -> bool { + self.element.is_html_slot_element() + } + fn get_local_name(&self) -> &::BorrowedLocalName { self.element.get_local_name() }