From 3390b77281bd7c65054b623ff4e4007918b1890a Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Tue, 7 Mar 2023 23:57:55 +0000 Subject: [PATCH] style: Create timeline objects when mutating scroll-timeline property And so we can lookup the timeline from TimelineCollection. Differential Revision: https://phabricator.services.mozilla.com/D169273 --- components/style/context.rs | 4 ++++ components/style/matching.rs | 15 ++++++++++++ components/style/properties/gecko.mako.rs | 23 +++++++++++++++++++ .../style/properties/properties.mako.rs | 12 ++++++++++ 4 files changed, 54 insertions(+) diff --git a/components/style/context.rs b/components/style/context.rs index d6b4d2cc102..f38963539b9 100644 --- a/components/style/context.rs +++ b/components/style/context.rs @@ -419,6 +419,10 @@ bitflags! { /// the second animation restyles for the script animations in the case where /// the display property was changed from 'none' to others. const DISPLAY_CHANGED_FROM_NONE = structs::UpdateAnimationsTasks_DisplayChangedFromNone; + /// Update CSS named scroll progress timelines. + const SCROLL_TIMELINES = structs::UpdateAnimationsTasks_ScrollTimelines; + /// Update CSS named view progress timelines. + const VIEW_TIMELINES = structs::UpdateAnimationsTasks_ViewTimelines; } } diff --git a/components/style/matching.rs b/components/style/matching.rs index fa757693e5b..e9980ef29a6 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -418,6 +418,21 @@ trait PrivateMatchMethods: TElement { // in addition to the unvisited styles. let mut tasks = UpdateAnimationsTasks::empty(); + + if old_values.as_deref().map_or_else( + || new_values.get_ui().specifies_scroll_timelines(), + |old| !old.get_ui().scroll_timelines_equals(new_values.get_ui()), + ) { + tasks.insert(UpdateAnimationsTasks::SCROLL_TIMELINES); + } + + if old_values.as_deref().map_or_else( + || new_values.get_ui().specifies_view_timelines(), + |old| !old.get_ui().view_timelines_equals(new_values.get_ui()), + ) { + tasks.insert(UpdateAnimationsTasks::VIEW_TIMELINES); + } + if self.needs_animations_update( context, old_values.as_deref(), diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 116ed004b7b..ebd58d3bc91 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1907,9 +1907,32 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask- ${impl_coordinated_property('scroll_timeline', 'name', 'Name')} ${impl_coordinated_property('scroll_timeline', 'axis', 'Axis')} + pub fn scroll_timelines_equals(&self, other: &Self) -> bool { + self.gecko.mScrollTimelineNameCount == other.gecko.mScrollTimelineNameCount + && self.gecko.mScrollTimelineAxisCount == other.gecko.mScrollTimelineAxisCount + && unsafe { + bindings::Gecko_StyleScrollTimelinesEquals( + &self.gecko.mScrollTimelines, + &other.gecko.mScrollTimelines, + ) + } + } + ${impl_coordinated_property('view_timeline', 'name', 'Name')} ${impl_coordinated_property('view_timeline', 'axis', 'Axis')} ${impl_coordinated_property('view_timeline', 'inset', 'Inset')} + + pub fn view_timelines_equals(&self, other: &Self) -> bool { + self.gecko.mViewTimelineNameCount == other.gecko.mViewTimelineNameCount + && self.gecko.mViewTimelineAxisCount == other.gecko.mViewTimelineAxisCount + && self.gecko.mViewTimelineInsetCount == other.gecko.mViewTimelineInsetCount + && unsafe { + bindings::Gecko_StyleViewTimelinesEquals( + &self.gecko.mViewTimelines, + &other.gecko.mViewTimelines, + ) + } + } <%self:impl_trait style_struct_name="XUL"> diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index b1b12e24395..d0a62fc76e3 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2972,6 +2972,18 @@ pub mod style_structs { }) } + /// Returns whether there is any named progress timeline specified with + /// scroll-timeline-name other than `none`. + pub fn specifies_scroll_timelines(&self) -> bool { + self.scroll_timeline_name_iter().any(|name| !name.is_none()) + } + + /// Returns whether there is any named progress timeline specified with + /// view-timeline-name other than `none`. + pub fn specifies_view_timelines(&self) -> bool { + self.view_timeline_name_iter().any(|name| !name.is_none()) + } + /// Returns true if animation properties are equal between styles, but without /// considering keyframe data and animation-timeline. #[cfg(feature = "servo")]