/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Specified types for properties related to animations and transitions. use crate::parser::{Parse, ParserContext}; use crate::properties::{NonCustomPropertyId, PropertyId, ShorthandId}; use crate::values::generics::animation as generics; use crate::values::specified::{LengthPercentage, NonNegativeNumber, Time}; use crate::values::{CustomIdent, DashedIdent, KeyframesName}; use crate::Atom; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{ CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss, }; /// A given transition property, that is either `All`, a longhand or shorthand /// property, or an unsupported or custom property. #[derive( Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem, )] #[repr(u8)] pub enum TransitionProperty { /// A non-custom property. NonCustom(NonCustomPropertyId), /// A custom property. Custom(Atom), /// Unrecognized property which could be any non-transitionable, custom property, or /// unknown property. Unsupported(CustomIdent), } impl ToCss for TransitionProperty { fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: Write, { match *self { TransitionProperty::NonCustom(ref id) => id.to_css(dest), TransitionProperty::Custom(ref name) => { dest.write_str("--")?; crate::values::serialize_atom_name(name, dest) }, TransitionProperty::Unsupported(ref i) => i.to_css(dest), } } } impl Parse for TransitionProperty { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { let location = input.current_source_location(); let ident = input.expect_ident()?; let id = match PropertyId::parse_ignoring_rule_type(&ident, context) { Ok(id) => id, Err(..) => { // None is not acceptable as a single transition-property. return Ok(TransitionProperty::Unsupported(CustomIdent::from_ident( location, ident, &["none"], )?)); }, }; Ok(match id { PropertyId::NonCustom(id) => TransitionProperty::NonCustom(id.unaliased()), PropertyId::Custom(name) => TransitionProperty::Custom(name), }) } } impl SpecifiedValueInfo for TransitionProperty { fn collect_completion_keywords(f: KeywordsCollectFn) { // `transition-property` can actually accept all properties and // arbitrary identifiers, but `all` is a special one we'd like // to list. f(&["all"]); } } impl TransitionProperty { /// Returns the `none` value. #[inline] pub fn none() -> Self { TransitionProperty::Unsupported(CustomIdent(atom!("none"))) } /// Returns whether we're the `none` value. #[inline] pub fn is_none(&self) -> bool { matches!(*self, TransitionProperty::Unsupported(ref ident) if ident.0 == atom!("none")) } /// Returns `all`. #[inline] pub fn all() -> Self { TransitionProperty::NonCustom(NonCustomPropertyId::from_shorthand(ShorthandId::All)) } /// Returns true if it is `all`. #[inline] pub fn is_all(&self) -> bool { self == &TransitionProperty::NonCustom(NonCustomPropertyId::from_shorthand( ShorthandId::All, )) } } /// A specified value for . /// /// https://drafts.csswg.org/css-transitions-2/#transition-behavior-property #[derive( Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem, )] #[repr(u8)] pub enum TransitionBehavior { /// Transitions will not be started for discrete properties, only for interpolable properties. Normal, /// Transitions will be started for discrete properties as well as interpolable properties. AllowDiscrete, } impl TransitionBehavior { /// Return normal, the initial value. #[inline] pub fn normal() -> Self { Self::Normal } /// Return true if it is normal. #[inline] pub fn is_normal(&self) -> bool { matches!(*self, Self::Normal) } } /// A specified value for the `animation-duration` property. pub type AnimationDuration = generics::GenericAnimationDuration