use crate::derives::*;
use crate::values::generics::length::GenericLengthPercentageOrAuto;
use crate::values::specified::animation::{
ScrollAxis, ScrollFunction, TimelineName, TimelineRangeName,
};
use crate::values::specified::length::EqualsPercentage;
use crate::Zero;
use std::fmt::{self, Write};
use style_traits::{CssString, CssWriter, KeywordValue, ToCss, ToTyped, TypedValue};
use thin_vec::ThinVec;
#[derive(
Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
)]
#[repr(C, u8)]
pub enum GenericAnimationDuration<T> {
Auto,
Time(T),
}
pub use self::GenericAnimationDuration as AnimationDuration;
impl<T> AnimationDuration<T> {
pub fn auto() -> Self {
Self::Auto
}
pub fn is_auto(&self) -> bool {
matches!(*self, Self::Auto)
}
}
impl<T: Zero> Zero for AnimationDuration<T> {
fn zero() -> Self {
Self::Time(T::zero())
}
fn is_zero(&self) -> bool {
match *self {
Self::Time(ref t) => t.is_zero(),
_ => false,
}
}
}
impl<T: ToCss + Zero> ToCss for AnimationDuration<T> {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match *self {
Self::Auto => {
if static_prefs::pref!("layout.css.scroll-driven-animations.enabled") {
dest.write_str("auto")
} else {
Self::Time(T::zero()).to_css(dest)
}
},
Self::Time(ref t) => t.to_css(dest),
}
}
}
impl<T: ToTyped + Zero> ToTyped for AnimationDuration<T> {
fn to_typed(&self, dest: &mut ThinVec<TypedValue>) -> Result<(), ()> {
match *self {
Self::Auto => {
if static_prefs::pref!("layout.css.scroll-driven-animations.enabled") {
dest.push(TypedValue::Keyword(KeywordValue(CssString::from("auto"))));
Ok(())
} else {
Self::Time(T::zero()).to_typed(dest)
}
},
Self::Time(ref t) => t.to_typed(dest),
}
}
}
#[derive(
Clone,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[css(function = "view")]
#[repr(C)]
pub struct GenericViewFunction<LengthPercent> {
#[css(skip_if = "ScrollAxis::is_default")]
pub axis: ScrollAxis,
#[css(skip_if = "GenericViewTimelineInset::is_auto")]
#[css(field_bound)]
pub inset: GenericViewTimelineInset<LengthPercent>,
}
pub use self::GenericViewFunction as ViewFunction;
#[derive(
Clone,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
ToTyped,
)]
#[repr(C, u8)]
#[typed(todo_derive_fields)]
pub enum GenericAnimationTimeline<LengthPercent> {
Auto,
Timeline(TimelineName),
Scroll(ScrollFunction),
View(#[css(field_bound)] GenericViewFunction<LengthPercent>),
}
pub use self::GenericAnimationTimeline as AnimationTimeline;
impl<LengthPercent> AnimationTimeline<LengthPercent> {
pub fn auto() -> Self {
Self::Auto
}
pub fn is_auto(&self) -> bool {
matches!(self, Self::Auto)
}
}
#[derive(
Clone,
Copy,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct GenericViewTimelineInset<LengthPercent> {
pub start: GenericLengthPercentageOrAuto<LengthPercent>,
pub end: GenericLengthPercentageOrAuto<LengthPercent>,
}
pub use self::GenericViewTimelineInset as ViewTimelineInset;
impl<LengthPercent> ViewTimelineInset<LengthPercent> {
#[inline]
fn is_auto(&self) -> bool {
self.start.is_auto() && self.end.is_auto()
}
}
impl<LengthPercent> ToCss for ViewTimelineInset<LengthPercent>
where
LengthPercent: PartialEq + ToCss,
{
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
self.start.to_css(dest)?;
if self.end != self.start {
dest.write_char(' ')?;
self.end.to_css(dest)?;
}
Ok(())
}
}
impl<LengthPercent> ToTyped for ViewTimelineInset<LengthPercent> where
LengthPercent: PartialEq + ToTyped
{
}
impl<LengthPercent> Default for ViewTimelineInset<LengthPercent> {
fn default() -> Self {
Self {
start: GenericLengthPercentageOrAuto::auto(),
end: GenericLengthPercentageOrAuto::auto(),
}
}
}
#[derive(
Clone,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToResolvedValue,
ToShmem,
)]
#[repr(C)]
pub struct GenericAnimationRangeValue<LengthPercent> {
pub name: TimelineRangeName,
pub lp: LengthPercent,
}
pub use self::GenericAnimationRangeValue as AnimationRangeValue;
impl<LengthPercent> AnimationRangeValue<LengthPercent> {
#[inline]
pub fn normal(lp: LengthPercent) -> Self {
Self::new(TimelineRangeName::Normal, lp)
}
#[inline]
pub fn length_percentage(lp: LengthPercent) -> Self {
Self::new(TimelineRangeName::None, lp)
}
#[inline]
pub fn new(name: TimelineRangeName, lp: LengthPercent) -> Self {
Self { name, lp }
}
#[inline]
pub fn is_normal(&self) -> bool {
self.name.is_normal()
}
}
#[derive(
Clone,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToResolvedValue,
ToShmem,
ToTyped,
)]
#[repr(transparent)]
#[typed(todo_derive_fields)]
pub struct GenericAnimationRangeStart<LengthPercent>(pub GenericAnimationRangeValue<LengthPercent>);
pub use self::GenericAnimationRangeStart as AnimationRangeStart;
fn to_css_with_default<LengthPercent, W>(
value: &AnimationRangeValue<LengthPercent>,
dest: &mut CssWriter<W>,
default: f32,
) -> fmt::Result
where
LengthPercent: ToCss + EqualsPercentage,
W: Write,
{
if matches!(value.name, TimelineRangeName::Normal) {
return dest.write_str("normal");
}
if matches!(value.name, TimelineRangeName::None) {
return value.lp.to_css(dest);
}
value.name.to_css(dest)?;
if !value.lp.equals_percentage(default) {
dest.write_char(' ')?;
value.lp.to_css(dest)?;
}
Ok(())
}
impl<LengthPercent: ToCss + EqualsPercentage> ToCss for AnimationRangeStart<LengthPercent> {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
to_css_with_default(&self.0, dest, 0.0)
}
}
#[derive(
Clone,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToResolvedValue,
ToShmem,
ToTyped,
)]
#[repr(transparent)]
#[typed(todo_derive_fields)]
pub struct GenericAnimationRangeEnd<LengthPercent>(pub GenericAnimationRangeValue<LengthPercent>);
pub use self::GenericAnimationRangeEnd as AnimationRangeEnd;
impl<LengthPercent: ToCss + EqualsPercentage> ToCss for AnimationRangeEnd<LengthPercent> {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
to_css_with_default(&self.0, dest, 1.0)
}
}