diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 83c3f26c4ce..4fb05ac1c18 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -429,7 +429,7 @@ impl Interpolate for f64 { } } -/// https://drafts.csswg.org/css-transitions/#animtype-number +/// https://drafts.csswg.org/css-transitions/#animtype-integer impl Interpolate for i32 { #[inline] fn interpolate(&self, other: &i32, progress: f64) -> Result { diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index f6e6ea2aa3b..be26554948f 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -11,7 +11,7 @@ use media_queries::Device; use properties::ComputedValues; use std::fmt; use style_traits::ToCss; -use super::{CSSFloat, RGBA, specified}; +use super::{CSSFloat, CSSInteger, RGBA, specified}; use super::specified::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize}; pub use cssparser::Color as CSSColor; @@ -267,6 +267,23 @@ pub type Number = CSSFloat; /// A type used for opacity. pub type Opacity = CSSFloat; +/// A `` value. +pub type Integer = CSSInteger; + +/// | auto +pub type IntegerOrAuto = Either; + +impl IntegerOrAuto { + /// Returns the integer value if it is an integer, otherwise return + /// the given value. + pub fn integer_or(&self, auto_value: CSSInteger) -> CSSInteger { + match *self { + Either::First(n) => n, + Either::Second(Auto) => auto_value, + } + } +} + /// An SVG paint value /// diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index ee9dc0d288e..f5c5186ca5d 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -66,6 +66,9 @@ pub mod specified; /// A CSS float value. pub type CSSFloat = f32; +/// A CSS integer value. +pub type CSSInteger = i32; + /// The default font size. pub const FONT_MEDIUM_PX: i32 = 16; diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 0e7ec2eb34a..f21a28a9f16 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -17,7 +17,7 @@ use std::f32::consts::PI; use std::fmt; use std::ops::Mul; use style_traits::ToCss; -use super::{Auto, CSSFloat, HasViewportPercentage, Either, None_}; +use super::{Auto, CSSFloat, CSSInteger, HasViewportPercentage, Either, None_}; use super::computed::{ComputedValueAsSpecified, Context}; use super::computed::{Shadow as ComputedShadow, ToComputedValue}; @@ -167,7 +167,7 @@ impl<'a> Mul for &'a SimplifiedValueNode { } #[allow(missing_docs)] -pub fn parse_integer(input: &mut Parser) -> Result { +pub fn parse_integer(input: &mut Parser) -> Result { match try!(input.next()) { Token::Number(ref value) => value.int_value.ok_or(()), Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { @@ -178,7 +178,7 @@ pub fn parse_integer(input: &mut Parser) -> Result { for ref node in ast.products { match try!(CalcLengthOrPercentage::simplify_product(node)) { SimplifiedValueNode::Number(val) => - result = Some(result.unwrap_or(0) + val as i32), + result = Some(result.unwrap_or(0) + val as CSSInteger), _ => unreachable!() } } @@ -576,6 +576,69 @@ impl ToCss for Opacity { } } +#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] +pub struct Integer(pub CSSInteger); + +no_viewport_percentage!(Integer); + +impl Parse for Integer { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + parse_integer(input).map(Integer) + } +} + +impl Integer { + fn parse_with_minimum(input: &mut Parser, min: i32) -> Result { + match parse_integer(input) { + Ok(value) if value < min => Err(()), + value => value.map(Integer), + } + } + + #[allow(missing_docs)] + pub fn parse_non_negative(input: &mut Parser) -> Result { + Integer::parse_with_minimum(input, 0) + } + + #[allow(missing_docs)] + pub fn parse_positive(input: &mut Parser) -> Result { + Integer::parse_with_minimum(input, 1) + } +} + +impl ToComputedValue for Integer { + type ComputedValue = i32; + + #[inline] + fn to_computed_value(&self, _: &Context) -> i32 { self.0 } + + #[inline] + fn from_computed_value(computed: &i32) -> Self { + Integer(*computed) + } +} + +impl ToCss for Integer { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + write!(dest, "{}", self.0) + } +} + +/// | auto +pub type IntegerOrAuto = Either; + +impl IntegerOrAuto { + #[allow(missing_docs)] + pub fn parse_positive(context: &ParserContext, input: &mut Parser) -> Result { + match IntegerOrAuto::parse(context, input) { + Ok(Either::First(Integer(value))) if value <= 0 => Err(()), + result => result, + } + } +} + #[allow(missing_docs)] pub type UrlOrNone = Either;