diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index d9baaa1cd17d..958499c18576 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -636,6 +636,7 @@ cbindgen-types = [ { gecko = "StyleFontStretch", servo = "crate::values::computed::font::FontStretch" }, { gecko = "StyleFontPalette", servo = "crate::values::computed::font::FontPalette" }, { gecko = "StyleBoolInteger", servo = "crate::values::computed::BoolInteger" }, + { gecko = "StyleTime", servo = "crate::values::computed::Time" }, ] mapped-generic-types = [ diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 196d4156de03..39f2fff58bff 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -248,7 +248,8 @@ static already_AddRefed BuildAnimation( } TimingParams timing = TimingParamsFromCSSParams( - aStyle.GetAnimationDuration(animIdx), aStyle.GetAnimationDelay(animIdx), + aStyle.GetAnimationDuration(animIdx).ToMilliseconds(), + aStyle.GetAnimationDelay(animIdx).ToMilliseconds(), aStyle.GetAnimationIterationCount(animIdx), aStyle.GetAnimationDirection(animIdx), aStyle.GetAnimationFillMode(animIdx)); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 6b39e4ee9449..eb6f2205ef0c 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -2167,8 +2167,8 @@ StyleTransition::StyleTransition(const StyleTransition& aCopy) = default; void StyleTransition::SetInitialValues() { mTimingFunction = StyleComputedTimingFunction::Keyword(StyleTimingKeyword::Ease); - mDuration = 0.0; - mDelay = 0.0; + mDuration = {0.0}; + mDelay = {0.0}; mProperty = eCSSPropertyExtra_all_properties; } @@ -2185,8 +2185,8 @@ StyleAnimation::StyleAnimation(const StyleAnimation& aCopy) = default; void StyleAnimation::SetInitialValues() { mTimingFunction = StyleComputedTimingFunction::Keyword(StyleTimingKeyword::Ease); - mDuration = 0.0; - mDelay = 0.0; + mDuration = {0.0}; + mDelay = {0.0}; mName = nsGkAtoms::_empty; mDirection = dom::PlaybackDirection::Normal; mFillMode = dom::FillMode::None; diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 4a0979dea225..dbf113810645 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1196,8 +1196,7 @@ inline bool StyleTextUnderlinePosition::IsRight() const { } struct StyleTransition { - StyleTransition() { /* leaves uninitialized; see also SetInitialValues */ - } + StyleTransition() = default; explicit StyleTransition(const StyleTransition& aCopy); void SetInitialValues(); @@ -1207,8 +1206,8 @@ struct StyleTransition { const StyleComputedTimingFunction& GetTimingFunction() const { return mTimingFunction; } - float GetDelay() const { return mDelay; } - float GetDuration() const { return mDuration; } + const mozilla::StyleTime& GetDelay() const { return mDelay; } + const mozilla::StyleTime& GetDuration() const { return mDuration; } nsCSSPropertyID GetProperty() const { return mProperty; } nsAtom* GetUnknownProperty() const { return mUnknownProperty; } @@ -1219,8 +1218,8 @@ struct StyleTransition { private: StyleComputedTimingFunction mTimingFunction; - float mDuration; - float mDelay; + mozilla::StyleTime mDuration{0.0}; + mozilla::StyleTime mDelay{0.0}; nsCSSPropertyID mProperty; RefPtr mUnknownProperty; // used when mProperty is // eCSSProperty_UNKNOWN or @@ -1228,8 +1227,7 @@ struct StyleTransition { }; struct StyleAnimation { - StyleAnimation() { /* leaves uninitialized; see also SetInitialValues */ - } + StyleAnimation() = default; explicit StyleAnimation(const StyleAnimation& aCopy); void SetInitialValues(); @@ -1239,8 +1237,8 @@ struct StyleAnimation { const StyleComputedTimingFunction& GetTimingFunction() const { return mTimingFunction; } - float GetDelay() const { return mDelay; } - float GetDuration() const { return mDuration; } + const mozilla::StyleTime& GetDelay() const { return mDelay; } + const mozilla::StyleTime& GetDuration() const { return mDuration; } nsAtom* GetName() const { return mName; } dom::PlaybackDirection GetDirection() const { return mDirection; } dom::FillMode GetFillMode() const { return mFillMode; } @@ -1259,8 +1257,8 @@ struct StyleAnimation { private: StyleComputedTimingFunction mTimingFunction; - float mDuration; - float mDelay; + StyleTime mDuration{0.0f}; + StyleTime mDelay{0.0f}; RefPtr mName; // nsGkAtoms::_empty for 'none' dom::PlaybackDirection mDirection; dom::FillMode mFillMode; @@ -1799,10 +1797,10 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset { nsCSSPropertyID GetTransitionProperty(uint32_t aIndex) const { return mTransitions[aIndex % mTransitionPropertyCount].GetProperty(); } - float GetTransitionDelay(uint32_t aIndex) const { + const mozilla::StyleTime& GetTransitionDelay(uint32_t aIndex) const { return mTransitions[aIndex % mTransitionDelayCount].GetDelay(); } - float GetTransitionDuration(uint32_t aIndex) const { + const mozilla::StyleTime& GetTransitionDuration(uint32_t aIndex) const { return mTransitions[aIndex % mTransitionDurationCount].GetDuration(); } const mozilla::StyleComputedTimingFunction& GetTransitionTimingFunction( @@ -1810,21 +1808,19 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset { return mTransitions[aIndex % mTransitionTimingFunctionCount] .GetTimingFunction(); } - float GetTransitionCombinedDuration(uint32_t aIndex) const { + mozilla::StyleTime GetTransitionCombinedDuration(uint32_t aIndex) const { // https://drafts.csswg.org/css-transitions/#transition-combined-duration - return std::max( - mTransitions[aIndex % mTransitionDurationCount].GetDuration(), - 0.0f) + - mTransitions[aIndex % mTransitionDelayCount].GetDelay(); + return {std::max(GetTransitionDuration(aIndex).seconds, 0.0f) + + GetTransitionDelay(aIndex).seconds}; } nsAtom* GetAnimationName(uint32_t aIndex) const { return mAnimations[aIndex % mAnimationNameCount].GetName(); } - float GetAnimationDelay(uint32_t aIndex) const { + const mozilla::StyleTime& GetAnimationDelay(uint32_t aIndex) const { return mAnimations[aIndex % mAnimationDelayCount].GetDelay(); } - float GetAnimationDuration(uint32_t aIndex) const { + const mozilla::StyleTime& GetAnimationDuration(uint32_t aIndex) const { return mAnimations[aIndex % mAnimationDurationCount].GetDuration(); } mozilla::dom::PlaybackDirection GetAnimationDirection(uint32_t aIndex) const { diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 95f1a5056cbd..4cc7d73e198e 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -86,7 +86,7 @@ bool nsTransitionManager::DoUpdateTransitions( for (uint32_t i = aStyle.mTransitionPropertyCount; i--;) { // We're not going to look at any further transitions, so we can just avoid // looking at this if we know it will not start any transitions. - if (i == 0 && aStyle.GetTransitionCombinedDuration(i) <= 0.0f) { + if (i == 0 && aStyle.GetTransitionCombinedDuration(i).seconds <= 0.0f) { continue; } @@ -310,10 +310,10 @@ bool nsTransitionManager::ConsiderInitiatingTransition( return false; } - float delay = aStyle.GetTransitionDelay(transitionIdx); + float delay = aStyle.GetTransitionDelay(transitionIdx).ToMilliseconds(); // The spec says a negative duration is treated as zero. - float duration = std::max(aStyle.GetTransitionDuration(transitionIdx), 0.0f); + float duration = std::max(aStyle.GetTransitionDuration(transitionIdx).ToMilliseconds(), 0.0f); // If the combined duration of this transition is 0 or less don't start a // transition. diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs index bf06761d6f00..e09fb9e9af05 100644 --- a/servo/components/style/gecko/wrapper.rs +++ b/servo/components/style/gecko/wrapper.rs @@ -858,7 +858,7 @@ impl<'le> GeckoElement<'le> { fn needs_transitions_update_per_property( &self, longhand_id: LonghandId, - combined_duration: f32, + combined_duration_seconds: f32, before_change_style: &ComputedValues, after_change_style: &ComputedValues, existing_transitions: &FxHashMap>, @@ -884,7 +884,7 @@ impl<'le> GeckoElement<'le> { debug_assert_eq!(to.is_some(), from.is_some()); - combined_duration > 0.0f32 && + combined_duration_seconds > 0.0f32 && from != to && from.unwrap() .animate( @@ -1533,7 +1533,7 @@ impl<'le> TElement for GeckoElement<'le> { transitions_to_keep.insert(physical_longhand); if self.needs_transitions_update_per_property( physical_longhand, - after_change_ui_style.transition_combined_duration_at(transition_property.index), + after_change_ui_style.transition_combined_duration_at(transition_property.index).seconds(), before_change_style, after_change_style, &existing_transitions, diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index c799ebdb03f9..bb134a64ac98 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -39,8 +39,7 @@ use servo_arc::{Arc, RawOffsetArc, UniqueArc}; use std::mem::{forget, MaybeUninit}; use std::{cmp, ops, ptr}; use crate::values::{self, CustomIdent, KeyframesName}; -use crate::values::computed::{Percentage, TransitionProperty}; -use crate::values::computed::BorderStyle; +use crate::values::computed::{BorderStyle, Percentage, Time, TransitionProperty}; use crate::values::computed::font::FontSize; use crate::values::generics::column::ColumnCount; @@ -1038,14 +1037,13 @@ fn static_assert() { self.gecko.m${type.capitalize()}${gecko_ffi_name}Count = input_len as u32; for (gecko, servo) in self.gecko.m${type.capitalize()}s.iter_mut().take(input_len as usize).zip(v) { - gecko.m${gecko_ffi_name} = servo.seconds() * 1000.; + gecko.m${gecko_ffi_name} = servo; } } #[allow(non_snake_case)] pub fn ${type}_${ident}_at(&self, index: usize) -> longhands::${type}_${ident}::computed_value::SingleComputedValue { - use crate::values::computed::Time; - Time::from_seconds(self.gecko.m${type.capitalize()}s[index].m${gecko_ffi_name} / 1000.) + self.gecko.m${type.capitalize()}s[index].m${gecko_ffi_name} } ${impl_animation_or_transition_count(type, ident, gecko_ffi_name)} ${impl_copy_animation_or_transition_value(type, ident, gecko_ffi_name)} @@ -1772,10 +1770,12 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask- ${impl_transition_time_value('duration', 'Duration')} ${impl_animation_or_transition_timing_function('transition')} - pub fn transition_combined_duration_at(&self, index: usize) -> f32 { + pub fn transition_combined_duration_at(&self, index: usize) -> Time { // https://drafts.csswg.org/css-transitions/#transition-combined-duration - self.gecko.mTransitions[index % self.gecko.mTransitionDurationCount as usize].mDuration.max(0.0) - + self.gecko.mTransitions[index % self.gecko.mTransitionDelayCount as usize].mDelay + Time::from_seconds( + self.transition_duration_at(index).seconds().max(0.0) + + self.transition_delay_at(index).seconds() + ) } pub fn set_transition_property(&mut self, v: I) @@ -1818,7 +1818,7 @@ mask-mode mask-repeat mask-clip mask-origin mask-composite mask-position-x mask- use crate::gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_all_properties; if self.gecko.mTransitionPropertyCount == 1 && self.gecko.mTransitions[0].mProperty == eCSSPropertyExtra_all_properties && - self.transition_combined_duration_at(0) <= 0.0f32 { + self.transition_combined_duration_at(0).seconds() <= 0.0f32 { return false; } diff --git a/servo/components/style/values/computed/time.rs b/servo/components/style/values/computed/time.rs index 5681f6fab5e6..1f0a6df018ba 100644 --- a/servo/components/style/values/computed/time.rs +++ b/servo/components/style/values/computed/time.rs @@ -11,6 +11,7 @@ use style_traits::{CssWriter, ToCss}; /// A computed `