Skip to content

Commit

Permalink
selectors: Never match ::slotted on <slot>s.
Browse files Browse the repository at this point in the history
This fixes the test from web-platform-tests/wpt#9212 in
Gecko.
  • Loading branch information
emilio committed Jan 27, 2018
1 parent bc7dd64 commit 61e60a8
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 7 deletions.
11 changes: 11 additions & 0 deletions components/layout_thread/dom_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion components/script/dom/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,8 +916,12 @@ impl LayoutElementHelpers for LayoutDom<Element> {
}

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::<Node>().is_in_html_doc()
self.is_html_element() && self.upcast::<Node>().is_in_html_doc()
}

pub fn local_name(&self) -> &LocalName {
Expand Down Expand Up @@ -2713,6 +2717,10 @@ impl<'a> SelectorsElement for DomRoot<Element> {
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")
}
}


Expand Down
3 changes: 3 additions & 0 deletions components/selectors/matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down Expand Up @@ -631,6 +632,8 @@ where
Component::Combinator(_) => unreachable!(),
Component::Slotted(ref selector) => {
context.shared.nest(|context| {
// <slots> are never flattened tree slottables.
!element.is_html_slot_element() &&
element.assigned_slot().is_some() &&
matches_complex_selector(
selector.iter(),
Expand Down
3 changes: 3 additions & 0 deletions components/selectors/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <slot> element.
fn is_html_slot_element(&self) -> bool;

/// Returns the assigned <slot> element this element is assigned to.
///
/// Necessary for the `::slotted` pseudo-class.
Expand Down
6 changes: 0 additions & 6 deletions components/style/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <html:slot> 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] {
&[]
Expand Down
6 changes: 6 additions & 0 deletions components/style/gecko/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
4 changes: 4 additions & 0 deletions components/style/invalidation/element/element_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) -> &<Self::Impl as ::selectors::SelectorImpl>::BorrowedLocalName {
self.element.get_local_name()
}
Expand Down

0 comments on commit 61e60a8

Please sign in to comment.