diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2017-12-17 17:56:15 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-01-09 14:26:02 +0100 |
commit | b26f3280d2f470e25c63d2acb10a80c97d08b3ab (patch) | |
tree | 6c0c1e9b051fa4f499d0f3169debd25f103f9a1c /components | |
parent | 040379208e5cc648cf7ebde30b2a42e70c15e602 (diff) | |
download | servo-b26f3280d2f470e25c63d2acb10a80c97d08b3ab.tar.gz servo-b26f3280d2f470e25c63d2acb10a80c97d08b3ab.zip |
style: Add invalidation support for ::slotted().
Bug: 1424607
Reviewed-by: heycam
MozReview-Commit-ID: 8pIVUx27o7x
Diffstat (limited to 'components')
-rw-r--r-- | components/layout_thread/dom_wrapper.rs | 4 | ||||
-rw-r--r-- | components/style/dom.rs | 14 | ||||
-rw-r--r-- | components/style/dom_apis.rs | 7 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 39 | ||||
-rw-r--r-- | components/style/invalidation/element/collector.rs | 70 | ||||
-rw-r--r-- | components/style/invalidation/element/invalidation_map.rs | 54 | ||||
-rw-r--r-- | components/style/invalidation/element/invalidator.rs | 192 |
7 files changed, 282 insertions, 98 deletions
diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs index e595ac06f45..8a8a2b57131 100644 --- a/components/layout_thread/dom_wrapper.rs +++ b/components/layout_thread/dom_wrapper.rs @@ -363,6 +363,10 @@ impl<'le> TElement for ServoLayoutElement<'le> { LayoutIterator(self.as_node().dom_children()) } + fn is_html_element(&self) -> bool { + unsafe { self.element.is_html_element() } + } + fn style_attribute(&self) -> Option<ArcBorrow<StyleLocked<PropertyDeclarationBlock>>> { unsafe { (*self.element.style_attribute()).as_ref().map(|x| x.borrow_arc()) diff --git a/components/style/dom.rs b/components/style/dom.rs index ea438b66dd9..85f4f49c4b7 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -416,6 +416,20 @@ pub trait TElement F: FnMut(Self), {} + /// 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] { + &[] + } + /// For a given NAC element, return the closest non-NAC ancestor, which is /// guaranteed to exist. fn closest_non_native_anonymous_ancestor(&self) -> Option<Self> { diff --git a/components/style/dom_apis.rs b/components/style/dom_apis.rs index 8f6ea273aa0..c1c5c989193 100644 --- a/components/style/dom_apis.rs +++ b/components/style/dom_apis.rs @@ -8,7 +8,8 @@ use Atom; use context::QuirksMode; use dom::{TDocument, TElement, TNode}; -use invalidation::element::invalidator::{Invalidation, InvalidationProcessor, InvalidationVector}; +use invalidation::element::invalidator::{DescendantInvalidationLists, Invalidation}; +use invalidation::element::invalidator::{InvalidationProcessor, InvalidationVector}; use selectors::{Element, NthIndexCache, SelectorList}; use selectors::attr::CaseSensitivity; use selectors::matching::{self, MatchingContext, MatchingMode}; @@ -143,7 +144,7 @@ where &mut self, element: E, self_invalidations: &mut InvalidationVector<'a>, - descendant_invalidations: &mut InvalidationVector<'a>, + descendant_invalidations: &mut DescendantInvalidationLists<'a>, _sibling_invalidations: &mut InvalidationVector<'a>, ) -> bool { // TODO(emilio): If the element is not a root element, and @@ -163,7 +164,7 @@ where let target_vector = if self.matching_context.scope_element.is_some() { - descendant_invalidations + &mut descendant_invalidations.dom_descendants } else { self_invalidations }; diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index ff0f9634afb..401479b950b 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -610,10 +610,7 @@ impl<'le> GeckoElement<'le> { self.as_node().node_info().mInner.mNamespaceID } - fn is_html_element(&self) -> bool { - self.namespace_id() == (structs::root::kNameSpaceID_XHTML as i32) - } - + #[inline] fn is_xul_element(&self) -> bool { self.namespace_id() == (structs::root::kNameSpaceID_XUL as i32) } @@ -974,6 +971,40 @@ impl<'le> TElement for GeckoElement<'le> { self.as_node().owner_doc().as_node() } + + #[inline] + fn is_html_element(&self) -> bool { + self.namespace_id() == (structs::root::kNameSpaceID_XHTML as i32) + } + + /// Return the list of slotted nodes of this node. + #[inline] + fn slotted_nodes(&self) -> &[Self::ConcreteNode] { + if !self.is_html_slot_element() || !self.is_in_shadow_tree() { + return &[]; + } + + let slot: &structs::HTMLSlotElement = unsafe { + mem::transmute(self.0) + }; + + if cfg!(debug_assertions) { + let base: &RawGeckoElement = &slot._base._base._base._base; + assert_eq!(base as *const _, self.0 as *const _, "Bad cast"); + } + + let assigned_nodes: &[structs::RefPtr<structs::nsINode>] = + &*slot.mAssignedNodes; + + debug_assert_eq!( + mem::size_of::<structs::RefPtr<structs::nsINode>>(), + mem::size_of::<Self::ConcreteNode>(), + "Bad cast!" + ); + + unsafe { mem::transmute(assigned_nodes) } + } + /// Execute `f` for each anonymous content child element (apart from /// ::before and ::after) whose originating element is `self`. fn each_anonymous_content_child<F>(&self, mut f: F) diff --git a/components/style/invalidation/element/collector.rs b/components/style/invalidation/element/collector.rs index 4f0460502c4..008d6e428ea 100644 --- a/components/style/invalidation/element/collector.rs +++ b/components/style/invalidation/element/collector.rs @@ -13,7 +13,8 @@ use dom::TElement; use element_state::ElementState; use invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper}; use invalidation::element::invalidation_map::*; -use invalidation::element::invalidator::{InvalidationVector, Invalidation, InvalidationProcessor}; +use invalidation::element::invalidator::{DescendantInvalidationLists, InvalidationVector}; +use invalidation::element::invalidator::{Invalidation, InvalidationProcessor}; use invalidation::element::restyle_hints::RestyleHint; use selector_map::SelectorMap; use selector_parser::Snapshot; @@ -47,7 +48,7 @@ where classes_removed: &'a SmallVec<[Atom; 8]>, classes_added: &'a SmallVec<[Atom; 8]>, state_changes: ElementState, - descendant_invalidations: &'a mut InvalidationVector<'selectors>, + descendant_invalidations: &'a mut DescendantInvalidationLists<'selectors>, sibling_invalidations: &'a mut InvalidationVector<'selectors>, invalidates_self: bool, } @@ -109,7 +110,7 @@ where &mut self, element: E, _self_invalidations: &mut InvalidationVector<'a>, - descendant_invalidations: &mut InvalidationVector<'a>, + descendant_invalidations: &mut DescendantInvalidationLists<'a>, sibling_invalidations: &mut InvalidationVector<'a>, ) -> bool { debug_assert!(element.has_snapshot(), "Why bothering?"); @@ -236,7 +237,10 @@ where // // This number is completely made-up, but the page that made us add this // code generated 1960+ invalidations (bug 1420741). - if descendant_invalidations.len() > 150 { + // + // We don't look at slotted_descendants because those don't propagate + // down more than one level anyway. + if descendant_invalidations.dom_descendants.len() > 150 { self.data.hint.insert(RestyleHint::RESTYLE_DESCENDANTS); } @@ -509,36 +513,52 @@ where } fn note_dependency(&mut self, dependency: &'selectors Dependency) { - if dependency.affects_self() { + debug_assert!(self.dependency_may_be_relevant(dependency)); + + let invalidation_kind = dependency.invalidation_kind(); + if matches!(invalidation_kind, DependencyInvalidationKind::Element) { self.invalidates_self = true; + return; } - if dependency.affects_descendants() { - debug_assert_ne!(dependency.selector_offset, 0); - debug_assert_ne!(dependency.selector_offset, dependency.selector.len()); - debug_assert!(!dependency.affects_later_siblings()); - self.descendant_invalidations.push(Invalidation::new( - &dependency.selector, - dependency.selector.len() - dependency.selector_offset + 1, - )); - } else if dependency.affects_later_siblings() { - debug_assert_ne!(dependency.selector_offset, 0); - debug_assert_ne!(dependency.selector_offset, dependency.selector.len()); - self.sibling_invalidations.push(Invalidation::new( - &dependency.selector, - dependency.selector.len() - dependency.selector_offset + 1, - )); + debug_assert_ne!(dependency.selector_offset, 0); + debug_assert_ne!( + dependency.selector_offset, + dependency.selector.len() + ); + + let invalidation = Invalidation::new( + &dependency.selector, + dependency.selector.len() - dependency.selector_offset + 1, + ); + + match invalidation_kind { + DependencyInvalidationKind::Element => unreachable!(), + DependencyInvalidationKind::ElementAndDescendants => { + self.invalidates_self = true; + self.descendant_invalidations.dom_descendants.push(invalidation); + } + DependencyInvalidationKind::Descendants => { + self.descendant_invalidations.dom_descendants.push(invalidation); + } + DependencyInvalidationKind::Siblings => { + self.sibling_invalidations.push(invalidation); + } + DependencyInvalidationKind::SlottedElements => { + self.descendant_invalidations.slotted_descendants.push(invalidation); + } } } /// Returns whether `dependency` may cause us to invalidate the style of /// more elements than what we've already invalidated. fn dependency_may_be_relevant(&self, dependency: &Dependency) -> bool { - if dependency.affects_descendants() || dependency.affects_later_siblings() { - return true; + match dependency.invalidation_kind() { + DependencyInvalidationKind::Element => !self.invalidates_self, + DependencyInvalidationKind::SlottedElements => self.element.is_html_slot_element(), + DependencyInvalidationKind::ElementAndDescendants | + DependencyInvalidationKind::Siblings | + DependencyInvalidationKind::Descendants => true, } - - debug_assert!(dependency.affects_self()); - !self.invalidates_self } } diff --git a/components/style/invalidation/element/invalidation_map.rs b/components/style/invalidation/element/invalidation_map.rs index 0ae08aa0bfa..809d3eb4a78 100644 --- a/components/style/invalidation/element/invalidation_map.rs +++ b/components/style/invalidation/element/invalidation_map.rs @@ -63,6 +63,25 @@ pub struct Dependency { pub selector_offset: usize, } +/// The kind of elements down the tree this dependency may affect. +#[derive(Debug, Eq, PartialEq)] +pub enum DependencyInvalidationKind { + /// This dependency may affect the element that changed itself. + Element, + /// This dependency affects the style of the element itself, and also the + /// style of its descendants. + /// + /// TODO(emilio): Each time this feels more of a hack for eager pseudos... + ElementAndDescendants, + /// This dependency may affect descendants down the tree. + Descendants, + /// This dependency may affect siblings to the right of the element that + /// changed. + Siblings, + /// This dependency may affect slotted elements of the element that changed. + SlottedElements, +} + impl Dependency { /// Returns the combinator to the right of the partial selector this /// dependency represents. @@ -76,28 +95,19 @@ impl Dependency { Some(self.selector.combinator_at_match_order(self.selector_offset - 1)) } - /// Whether this dependency affects the style of the element. - /// - /// NOTE(emilio): pseudo-elements need to be here to account for eager - /// pseudos, since they just grab the style from the originating element. - /// - /// TODO(emilio): We could look at the selector itself to see if it's an - /// eager pseudo, and return false here if not. - pub fn affects_self(&self) -> bool { - matches!(self.combinator(), None | Some(Combinator::PseudoElement)) - } - - /// Whether this dependency may affect style of any of our descendants. - pub fn affects_descendants(&self) -> bool { - matches!(self.combinator(), Some(Combinator::PseudoElement) | - Some(Combinator::Child) | - Some(Combinator::Descendant)) - } - - /// Whether this dependency may affect style of any of our later siblings. - pub fn affects_later_siblings(&self) -> bool { - matches!(self.combinator(), Some(Combinator::NextSibling) | - Some(Combinator::LaterSibling)) + /// The kind of invalidation that this would generate. + pub fn invalidation_kind(&self) -> DependencyInvalidationKind { + match self.combinator() { + None => DependencyInvalidationKind::Element, + Some(Combinator::Child) | + Some(Combinator::Descendant) => DependencyInvalidationKind::Descendants, + Some(Combinator::LaterSibling) | + Some(Combinator::NextSibling) => DependencyInvalidationKind::Siblings, + // TODO(emilio): We could look at the selector itself to see if it's + // an eager pseudo, and return only Descendants here if not. + Some(Combinator::PseudoElement) => DependencyInvalidationKind::ElementAndDescendants, + Some(Combinator::SlotAssignment) => DependencyInvalidationKind::SlottedElements, + } } } diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs index 62bac3fd8be..14aa084a1b0 100644 --- a/components/style/invalidation/element/invalidator.rs +++ b/components/style/invalidation/element/invalidator.rs @@ -39,7 +39,7 @@ where &mut self, element: E, self_invalidations: &mut InvalidationVector<'a>, - descendant_invalidations: &mut InvalidationVector<'a>, + descendant_invalidations: &mut DescendantInvalidationLists<'a>, sibling_invalidations: &mut InvalidationVector<'a>, ) -> bool; @@ -58,6 +58,25 @@ where fn invalidated_descendants(&mut self, element: E, child: E); } +/// Different invalidation lists for descendants. +#[derive(Debug, Default)] +pub struct DescendantInvalidationLists<'a> { + /// Invalidations for normal DOM children and pseudo-elements. + /// + /// TODO(emilio): Having a list of invalidations just for pseudo-elements + /// may save some work here and there. + pub dom_descendants: InvalidationVector<'a>, + /// Invalidations for slotted children of an element. + pub slotted_descendants: InvalidationVector<'a>, +} + +impl<'a> DescendantInvalidationLists<'a> { + fn is_empty(&self) -> bool { + self.dom_descendants.is_empty() && + self.slotted_descendants.is_empty() + } +} + /// The struct that takes care of encapsulating all the logic on where and how /// element styles need to be invalidated. pub struct TreeStyleInvalidator<'a, 'b, E, P: 'a> @@ -75,13 +94,22 @@ where /// A vector of invalidations, optimized for small invalidation sets. pub type InvalidationVector<'a> = SmallVec<[Invalidation<'a>; 10]>; +/// The kind of descendant invalidation we're processing. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +enum DescendantInvalidationKind { + /// A DOM descendant invalidation. + Dom, + /// A ::slotted() descendant invalidation. + Slotted, +} + /// The kind of invalidation we're processing. /// /// We can use this to avoid pushing invalidations of the same kind to our /// descendants or siblings. #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum InvalidationKind { - Descendant, + Descendant(DescendantInvalidationKind), Sibling, } @@ -126,21 +154,27 @@ impl<'a> Invalidation<'a> { // // We should be able to do better here! match self.selector.combinator_at_parse_order(self.offset - 1) { + Combinator::Descendant | + Combinator::LaterSibling | + Combinator::PseudoElement => true, + Combinator::SlotAssignment | Combinator::NextSibling | Combinator::Child => false, - _ => true, } } fn kind(&self) -> InvalidationKind { if self.offset == 0 { - return InvalidationKind::Descendant; + return InvalidationKind::Descendant(DescendantInvalidationKind::Dom); } - if self.selector.combinator_at_parse_order(self.offset - 1).is_ancestor() { - InvalidationKind::Descendant - } else { - InvalidationKind::Sibling + match self.selector.combinator_at_parse_order(self.offset - 1) { + Combinator::Child | + Combinator::Descendant | + Combinator::PseudoElement => InvalidationKind::Descendant(DescendantInvalidationKind::Dom), + Combinator::SlotAssignment => InvalidationKind::Descendant(DescendantInvalidationKind::Slotted), + Combinator::NextSibling | + Combinator::LaterSibling => InvalidationKind::Sibling, } } } @@ -230,7 +264,7 @@ where debug!("StyleTreeInvalidator::invalidate({:?})", self.element); let mut self_invalidations = InvalidationVector::new(); - let mut descendant_invalidations = InvalidationVector::new(); + let mut descendant_invalidations = DescendantInvalidationLists::default(); let mut sibling_invalidations = InvalidationVector::new(); let mut invalidated_self = self.processor.collect_invalidations( @@ -242,7 +276,7 @@ where debug!("Collected invalidations (self: {}): ", invalidated_self); debug!(" > self: {}, {:?}", self_invalidations.len(), self_invalidations); - debug!(" > descendants: {}, {:?}", descendant_invalidations.len(), descendant_invalidations); + debug!(" > descendants: {:?}", descendant_invalidations); debug!(" > siblings: {}, {:?}", sibling_invalidations.len(), sibling_invalidations); let invalidated_self_from_collection = invalidated_self; @@ -251,6 +285,7 @@ where &self_invalidations, &mut descendant_invalidations, &mut sibling_invalidations, + DescendantInvalidationKind::Dom, ); if invalidated_self && !invalidated_self_from_collection { @@ -260,7 +295,11 @@ where let invalidated_descendants = self.invalidate_descendants(&descendant_invalidations); let invalidated_siblings = self.invalidate_siblings(&mut sibling_invalidations); - InvalidationResult { invalidated_self, invalidated_descendants, invalidated_siblings } + InvalidationResult { + invalidated_self, + invalidated_descendants, + invalidated_siblings, + } } /// Go through later DOM siblings, invalidating style as needed using the @@ -286,7 +325,8 @@ where self.processor, ); - let mut invalidations_for_descendants = InvalidationVector::new(); + let mut invalidations_for_descendants = + DescendantInvalidationLists::default(); let invalidated_sibling = sibling_invalidator.process_sibling_invalidations( &mut invalidations_for_descendants, @@ -301,7 +341,7 @@ where any_invalidated |= sibling_invalidator.invalidate_descendants( - &invalidations_for_descendants + &invalidations_for_descendants, ); if sibling_invalidations.is_empty() { @@ -324,7 +364,8 @@ where let result = self.invalidate_child( child, invalidations, - &mut sibling_invalidations + &mut sibling_invalidations, + DescendantInvalidationKind::Dom, ); // Roots of NAC subtrees can indeed generate sibling invalidations, but @@ -344,8 +385,10 @@ where child: E, invalidations: &[Invalidation<'b>], sibling_invalidations: &mut InvalidationVector<'b>, + descendant_invalidation_kind: DescendantInvalidationKind, ) -> bool { - let mut invalidations_for_descendants = InvalidationVector::new(); + let mut invalidations_for_descendants = + DescendantInvalidationLists::default(); let mut invalidated_child = false; let invalidated_descendants = { @@ -366,13 +409,16 @@ where invalidations, &mut invalidations_for_descendants, sibling_invalidations, + descendant_invalidation_kind, ); if invalidated_child { child_invalidator.processor.invalidated_self(child); } - child_invalidator.invalidate_descendants(&invalidations_for_descendants) + child_invalidator.invalidate_descendants( + &invalidations_for_descendants, + ) }; // The child may not be a flattened tree child of the current element, @@ -418,10 +464,6 @@ where // // This probably needs a shadow root check on `child` here, and // recursing if that's the case. - // - // Also, what's the deal with HTML <content>? We don't need to - // support that for now, though we probably need to recurse into the - // distributed children too. let child = match child.as_element() { Some(e) => e, None => continue, @@ -431,15 +473,14 @@ where child, invalidations, &mut sibling_invalidations, + DescendantInvalidationKind::Dom, ); } any_descendant } - /// Given a descendant invalidation list, go through the current element's - /// descendants, and invalidate style on them. - fn invalidate_descendants( + fn invalidate_slotted_elements( &mut self, invalidations: &[Invalidation<'b>], ) -> bool { @@ -447,22 +488,40 @@ where return false; } - debug!("StyleTreeInvalidator::invalidate_descendants({:?})", - self.element); - debug!(" > {:?}", invalidations); + let mut any = false; - let should_process = - self.processor.should_process_descendants(self.element); + let mut sibling_invalidations = InvalidationVector::new(); + let element = self.element; + for node in element.slotted_nodes() { + let element = match node.as_element() { + Some(e) => e, + None => continue, + }; - if !should_process { - return false; + any |= self.invalidate_child( + element, + invalidations, + &mut sibling_invalidations, + DescendantInvalidationKind::Slotted, + ); + + debug_assert!( + sibling_invalidations.is_empty(), + "::slotted() shouldn't have sibling combinators to the right, \ + this makes no sense! {:?}", + sibling_invalidations + ); } - if let Some(checker) = self.stack_limit_checker { - if checker.limit_exceeded() { - self.processor.recursion_limit_exceeded(self.element); - return true; - } + any + } + + fn invalidate_non_slotted_descendants( + &mut self, + invalidations: &[Invalidation<'b>], + ) -> bool { + if invalidations.is_empty() { + return false; } if self.processor.light_tree_only() { @@ -477,8 +536,6 @@ where self.invalidate_dom_descendants_of(anon_content, invalidations); } - // TODO(emilio): Having a list of invalidations just for pseudo-elements - // may save some work here and there. if let Some(before) = self.element.before_pseudo_element() { any_descendant |= self.invalidate_pseudo_element_or_nac(before, invalidations); @@ -498,6 +555,44 @@ where any_descendant } + /// Given the descendant invalidation lists, go through the current + /// element's descendants, and invalidate style on them. + fn invalidate_descendants( + &mut self, + invalidations: &DescendantInvalidationLists<'b>, + ) -> bool { + if invalidations.is_empty() { + return false; + } + + debug!("StyleTreeInvalidator::invalidate_descendants({:?})", + self.element); + debug!(" > {:?}", invalidations); + + let should_process = + self.processor.should_process_descendants(self.element); + + if !should_process { + return false; + } + + if let Some(checker) = self.stack_limit_checker { + if checker.limit_exceeded() { + self.processor.recursion_limit_exceeded(self.element); + return true; + } + } + + let mut any_descendant = false; + + any_descendant |= + self.invalidate_non_slotted_descendants(&invalidations.dom_descendants); + any_descendant |= + self.invalidate_slotted_elements(&invalidations.slotted_descendants); + + any_descendant + } + /// Process the given sibling invalidations coming from our previous /// sibling. /// @@ -511,7 +606,7 @@ where /// Returns whether invalidated the current element's style. fn process_sibling_invalidations( &mut self, - descendant_invalidations: &mut InvalidationVector<'b>, + descendant_invalidations: &mut DescendantInvalidationLists<'b>, sibling_invalidations: &mut InvalidationVector<'b>, ) -> bool { let mut i = 0; @@ -547,8 +642,9 @@ where fn process_descendant_invalidations( &mut self, invalidations: &[Invalidation<'b>], - descendant_invalidations: &mut InvalidationVector<'b>, + descendant_invalidations: &mut DescendantInvalidationLists<'b>, sibling_invalidations: &mut InvalidationVector<'b>, + descendant_invalidation_kind: DescendantInvalidationKind, ) -> bool { let mut invalidated = false; @@ -557,14 +653,19 @@ where invalidation, descendant_invalidations, sibling_invalidations, - InvalidationKind::Descendant, + InvalidationKind::Descendant(descendant_invalidation_kind), ); invalidated |= result.invalidated_self; if invalidation.effective_for_next() { let mut invalidation = invalidation.clone(); invalidation.matched_by_any_previous |= result.matched; - descendant_invalidations.push(invalidation.clone()); + debug_assert_eq!( + descendant_invalidation_kind, + DescendantInvalidationKind::Dom, + "Slotted invalidations don't propagate." + ); + descendant_invalidations.dom_descendants.push(invalidation); } } @@ -580,7 +681,7 @@ where fn process_invalidation( &mut self, invalidation: &Invalidation<'b>, - descendant_invalidations: &mut InvalidationVector<'b>, + descendant_invalidations: &mut DescendantInvalidationLists<'b>, sibling_invalidations: &mut InvalidationVector<'b>, invalidation_kind: InvalidationKind, ) -> SingleInvalidationResult { @@ -732,8 +833,11 @@ where already been matched before"); } else { match next_invalidation_kind { - InvalidationKind::Descendant => { - descendant_invalidations.push(next_invalidation); + InvalidationKind::Descendant(DescendantInvalidationKind::Dom) => { + descendant_invalidations.dom_descendants.push(next_invalidation); + } + InvalidationKind::Descendant(DescendantInvalidationKind::Slotted) => { + descendant_invalidations.slotted_descendants.push(next_invalidation); } InvalidationKind::Sibling => { sibling_invalidations.push(next_invalidation); |