/* 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 http://mozilla.org/MPL/2.0/. */ //! Specified types for box properties. use Atom; use cssparser::Parser; use parser::{Parse, ParserContext}; use std::fmt; use style_traits::{ParseError, ToCss}; use values::KeyframesName; use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use values::generics::box_::VerticalAlign as GenericVerticalAlign; use values::specified::{AllowQuirks, Number}; use values::specified::length::LengthOrPercentage; /// A specified value for the `vertical-align` property. pub type VerticalAlign = GenericVerticalAlign; impl Parse for VerticalAlign { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_quirky(context, i, AllowQuirks::Yes)) { return Ok(GenericVerticalAlign::Length(lop)); } try_match_ident_ignore_ascii_case! { input, "baseline" => Ok(GenericVerticalAlign::Baseline), "sub" => Ok(GenericVerticalAlign::Sub), "super" => Ok(GenericVerticalAlign::Super), "top" => Ok(GenericVerticalAlign::Top), "text-top" => Ok(GenericVerticalAlign::TextTop), "middle" => Ok(GenericVerticalAlign::Middle), "bottom" => Ok(GenericVerticalAlign::Bottom), "text-bottom" => Ok(GenericVerticalAlign::TextBottom), #[cfg(feature = "gecko")] "-moz-middle-with-baseline" => { Ok(GenericVerticalAlign::MozMiddleWithBaseline) }, } } } /// https://drafts.csswg.org/css-animations/#animation-iteration-count pub type AnimationIterationCount = GenericAnimationIterationCount; impl Parse for AnimationIterationCount { fn parse<'i, 't>( context: &ParserContext, input: &mut ::cssparser::Parser<'i, 't>, ) -> Result> { if input.try(|input| input.expect_ident_matching("infinite")).is_ok() { return Ok(GenericAnimationIterationCount::Infinite) } let number = Number::parse_non_negative(context, input)?; Ok(GenericAnimationIterationCount::Number(number)) } } impl AnimationIterationCount { /// Returns the value `1.0`. #[inline] pub fn one() -> Self { GenericAnimationIterationCount::Number(Number::new(1.0)) } } /// A value for the `animation-name` property. #[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)] pub struct AnimationName(pub Option); impl AnimationName { /// Get the name of the animation as an `Atom`. pub fn as_atom(&self) -> Option<&Atom> { self.0.as_ref().map(|n| n.as_atom()) } /// Returns the `none` value. pub fn none() -> Self { AnimationName(None) } } impl ToCss for AnimationName { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write, { match self.0 { Some(ref name) => name.to_css(dest), None => dest.write_str("none"), } } } impl Parse for AnimationName { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't> ) -> Result> { if let Ok(name) = input.try(|input| KeyframesName::parse(context, input)) { return Ok(AnimationName(Some(name))); } input.expect_ident_matching("none")?; Ok(AnimationName(None)) } } define_css_keyword_enum! { ScrollSnapType: "none" => None, "mandatory" => Mandatory, "proximity" => Proximity, } add_impls_for_keyword_enum!(ScrollSnapType);