From 744b21e72a00f9fdb27e6bb52a4a010155aa7067 Mon Sep 17 00:00:00 2001 From: Zach Hoffman Date: Tue, 14 Mar 2023 21:23:05 +0000 Subject: [PATCH] style: Apply selector flags to the shadow root Because restyle events cannot be posted for non-element nodes like the shadow root, a child's siblings are restyled directly if its parent has NODE_HAS_SLOW_SELECTOR or NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS but that parent is the shadow root. Drive-by, but braces were also added to some single-line "if" statements in RestyleManager. Differential Revision: https://phabricator.services.mozilla.com/D172352 --- components/selectors/tree.rs | 27 +++--------------- components/style/gecko/wrapper.rs | 28 +++++++++++++++---- .../invalidation/element/element_wrapper.rs | 2 +- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/components/selectors/tree.rs b/components/selectors/tree.rs index 7d6c1bed967..fa150def0d6 100644 --- a/components/selectors/tree.rs +++ b/components/selectors/tree.rs @@ -92,29 +92,10 @@ pub trait Element: Sized + Clone + Debug { context: &mut MatchingContext, ) -> bool; - /// Sets selector flags, which indicate what kinds of selectors may have - /// matched on this element and therefore what kind of work may need to - /// be performed when DOM state changes. - /// - /// You probably don't want to use this directly and want to use - /// apply_selector_flags, since that sets flags on the parent as needed. - fn set_selector_flags(&self, flags: ElementSelectorFlags); - - fn apply_selector_flags(&self, flags: ElementSelectorFlags) { - // Handle flags that apply to the element. - let self_flags = flags.for_self(); - if !self_flags.is_empty() { - self.set_selector_flags(self_flags); - } - - // Handle flags that apply to the parent. - let parent_flags = flags.for_parent(); - if !parent_flags.is_empty() { - if let Some(p) = self.parent_element() { - p.set_selector_flags(parent_flags); - } - } - } + /// Sets selector flags on the elemnt itself or the parent, depending on the + /// flags, which indicate what kind of work may need to be performed when + /// DOM state changes. + fn apply_selector_flags(&self, flags: ElementSelectorFlags); /// Whether this element is a `link`. fn is_link(&self) -> bool; diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 0e914bc1ff5..8d4fb224639 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -268,6 +268,11 @@ impl<'ln> GeckoNode<'ln> { GeckoNode(&content._base) } + #[inline] + fn set_flags(&self, flags: u32) { + self.flags_atomic().fetch_or(flags, Ordering::Relaxed); + } + #[inline] fn flags_atomic(&self) -> &AtomicU32 { use std::cell::Cell; @@ -672,9 +677,7 @@ impl<'le> GeckoElement<'le> { #[inline] fn set_flags(&self, flags: u32) { - self.as_node() - .flags_atomic() - .fetch_or(flags, Ordering::Relaxed); + self.as_node().set_flags(flags); } #[inline] @@ -1866,9 +1869,22 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { None } - fn set_selector_flags(&self, flags: ElementSelectorFlags) { - debug_assert!(!flags.is_empty()); - self.set_flags(selector_flags_to_node_flags(flags)); + fn apply_selector_flags(&self, flags: ElementSelectorFlags) { + // Handle flags that apply to the element. + let self_flags = flags.for_self(); + if !self_flags.is_empty() { + self.set_flags(selector_flags_to_node_flags(flags)) + } + + // Handle flags that apply to the parent. + let parent_flags = flags.for_parent(); + if !parent_flags.is_empty() { + if let Some(p) = self.as_node().parent_node() { + if p.is_element() || p.is_shadow_root() { + p.set_flags(selector_flags_to_node_flags(parent_flags)); + } + } + } } fn attr_matches( diff --git a/components/style/invalidation/element/element_wrapper.rs b/components/style/invalidation/element/element_wrapper.rs index 4530c249c23..8c25153d1a8 100644 --- a/components/style/invalidation/element/element_wrapper.rs +++ b/components/style/invalidation/element/element_wrapper.rs @@ -238,7 +238,7 @@ where } } - fn set_selector_flags(&self, _flags: ElementSelectorFlags) { + fn apply_selector_flags(&self, _flags: ElementSelectorFlags) { debug_assert!(false, "Shouldn't need selector flags for invalidation"); }