diff options
author | Boris Chiou <boris.chiou@gmail.com> | 2017-07-19 19:45:24 +0800 |
---|---|---|
committer | Boris Chiou <boris.chiou@gmail.com> | 2017-08-04 14:21:21 +0800 |
commit | 4cc97746f239b70a196ce2929e38c1d4ffe353ef (patch) | |
tree | 1bd794d95c7919bb44d8940a5161edaeedef6d8b | |
parent | 50c9797ddd7b206c96f9436c634d915efe4acc17 (diff) | |
download | servo-4cc97746f239b70a196ce2929e38c1d4ffe353ef.tar.gz servo-4cc97746f239b70a196ce2929e38c1d4ffe353ef.zip |
Bug 1374233 - Part 1: Add NonNegativeNumber and GreaterThanOrEqualToOneNumber.
NonNegativeNumber: for -moz-box-flex, flex-grow, and flex-shrink.
GreaterThanOrEqualToOneNumber: for stroke-miterlimit.
MozReview-Commit-ID: Kgbt99BPdVA
-rw-r--r-- | components/layout/flex.rs | 4 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 6 | ||||
-rw-r--r-- | components/style/properties/helpers/animated_properties.mako.rs | 48 | ||||
-rw-r--r-- | components/style/properties/longhand/inherited_svg.mako.rs | 7 | ||||
-rw-r--r-- | components/style/properties/longhand/position.mako.rs | 12 | ||||
-rw-r--r-- | components/style/properties/longhand/xul.mako.rs | 4 | ||||
-rw-r--r-- | components/style/properties/shorthand/position.mako.rs | 17 | ||||
-rw-r--r-- | components/style/values/animated/mod.rs | 30 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 35 | ||||
-rw-r--r-- | components/style/values/generics/mod.rs | 10 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 28 | ||||
-rw-r--r-- | tests/unit/style/properties/serialization.rs | 6 |
12 files changed, 181 insertions, 26 deletions
diff --git a/components/layout/flex.rs b/components/layout/flex.rs index 353c939f58b..577e9a167de 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -137,8 +137,8 @@ impl FlexItem { min_size: Au(0), max_size: MAX_AU, index: index, - flex_grow: flex_grow, - flex_shrink: flex_shrink, + flex_grow: flex_grow.into(), + flex_shrink: flex_shrink.into(), order: order, is_frozen: false, is_strut: false diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 839fdeb1dc7..e256394dea5 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -397,14 +397,14 @@ impl ${style_struct.gecko_struct_name} { <%def name="impl_simple_setter(ident, gecko_ffi_name)"> #[allow(non_snake_case)] pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { - ${set_gecko_property(gecko_ffi_name, "v")} + ${set_gecko_property(gecko_ffi_name, "From::from(v)")} } </%def> <%def name="impl_simple_clone(ident, gecko_ffi_name)"> #[allow(non_snake_case)] pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - self.gecko.${gecko_ffi_name} + From::from(self.gecko.${gecko_ffi_name}) } </%def> @@ -1088,6 +1088,7 @@ impl Clone for ${style_struct.gecko_struct_name} { predefined_types = { "length::LengthOrAuto": impl_style_coord, "length::LengthOrNormal": impl_style_coord, + "GreaterThanOrEqualToOneNumber": impl_simple, "Length": impl_absolute_length, "Position": impl_position, "LengthOrPercentage": impl_style_coord, @@ -1097,6 +1098,7 @@ impl Clone for ${style_struct.gecko_struct_name} { "LengthOrNormal": impl_style_coord, "MaxLength": impl_style_coord, "MozLength": impl_style_coord, + "NonNegativeNumber": impl_simple, "Number": impl_simple, "Integer": impl_simple, "Opacity": impl_simple, diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 4419e2921fe..1957c7d3268 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -43,6 +43,8 @@ use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone use values::computed::{BorderCornerRadius, ClipRect}; use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified}; use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToComputedValue}; +use values::computed::NonNegativeNumber; +use values::generics::{GreaterThanOrEqualToOne, NonNegative}; use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use values::generics::effects::Filter; use values::generics::position as generic_position; @@ -3366,3 +3368,49 @@ sorted_shorthands = [(p, position) for position, p in enumerate(sorted_shorthand % endfor } } + +impl<T> Animatable for NonNegative<T> + where T: Animatable + Clone +{ + #[inline] + fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> { + self.0.add_weighted(&other.0, self_portion, other_portion).map(NonNegative::<T>) + } + + #[inline] + fn compute_distance(&self, other: &Self) -> Result<f64, ()> { + self.0.compute_distance(&other.0) + } +} + +impl<T> ToAnimatedZero for NonNegative<T> + where T: ToAnimatedZero +{ + #[inline] + fn to_animated_zero(&self) -> Result<Self, ()> { + self.0.to_animated_zero().map(NonNegative::<T>) + } +} + +impl<T> Animatable for GreaterThanOrEqualToOne<T> + where T: Animatable + Clone +{ + #[inline] + fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> { + self.0.add_weighted(&other.0, self_portion, other_portion).map(GreaterThanOrEqualToOne::<T>) + } + + #[inline] + fn compute_distance(&self, other: &Self) -> Result<f64, ()> { + self.0.compute_distance(&other.0) + } +} + +impl<T> ToAnimatedZero for GreaterThanOrEqualToOne<T> + where T: ToAnimatedZero +{ + #[inline] + fn to_animated_zero(&self) -> Result<Self, ()> { + self.0.to_animated_zero().map(GreaterThanOrEqualToOne::<T>) + } +} diff --git a/components/style/properties/longhand/inherited_svg.mako.rs b/components/style/properties/longhand/inherited_svg.mako.rs index a5bd2fdb35e..9828ca030dd 100644 --- a/components/style/properties/longhand/inherited_svg.mako.rs +++ b/components/style/properties/longhand/inherited_svg.mako.rs @@ -80,9 +80,10 @@ ${helpers.single_keyword("stroke-linejoin", "miter round bevel", products="gecko", animation_value_type="discrete", spec="https://www.w3.org/TR/SVG11/painting.html#StrokeLinejoinProperty")} -${helpers.predefined_type("stroke-miterlimit", "Number", "4.0", - "parse_at_least_one", products="gecko", - animation_value_type="ComputedValue", +${helpers.predefined_type("stroke-miterlimit", "GreaterThanOrEqualToOneNumber", + "From::from(4.0)", + products="gecko", + animation_value_type="::values::computed::GreaterThanOrEqualToOneNumber", spec="https://www.w3.org/TR/SVG11/painting.html#StrokeMiterlimitProperty")} ${helpers.predefined_type("stroke-opacity", "SVGOpacity", "Default::default()", diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index dd1cb9d5724..c5e06f235cd 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -117,17 +117,17 @@ ${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse", % endif // Flex item properties -${helpers.predefined_type("flex-grow", "Number", - "0.0", "parse_non_negative", +${helpers.predefined_type("flex-grow", "NonNegativeNumber", + "From::from(0.0)", spec="https://drafts.csswg.org/css-flexbox/#flex-grow-property", extra_prefixes="webkit", - animation_value_type="ComputedValue")} + animation_value_type="NonNegativeNumber")} -${helpers.predefined_type("flex-shrink", "Number", - "1.0", "parse_non_negative", +${helpers.predefined_type("flex-shrink", "NonNegativeNumber", + "From::from(1.0)", spec="https://drafts.csswg.org/css-flexbox/#flex-shrink-property", extra_prefixes="webkit", - animation_value_type="ComputedValue")} + animation_value_type="NonNegativeNumber")} // https://drafts.csswg.org/css-align/#align-self-property % if product == "servo": diff --git a/components/style/properties/longhand/xul.mako.rs b/components/style/properties/longhand/xul.mako.rs index 5d9ec6623e2..6802f60460c 100644 --- a/components/style/properties/longhand/xul.mako.rs +++ b/components/style/properties/longhand/xul.mako.rs @@ -24,9 +24,9 @@ ${helpers.single_keyword("-moz-box-direction", "normal reverse", alias="-webkit-box-direction", spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-direction)")} -${helpers.predefined_type("-moz-box-flex", "Number", "0.0", "parse_non_negative", +${helpers.predefined_type("-moz-box-flex", "NonNegativeNumber", "From::from(0.)", products="gecko", gecko_ffi_name="mBoxFlex", - animation_value_type="ComputedValue", + animation_value_type="NonNegativeNumber", alias="-webkit-box-flex", spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-flex)")} diff --git a/components/style/properties/shorthand/position.mako.rs b/components/style/properties/shorthand/position.mako.rs index c7653a48e15..acc98a990a3 100644 --- a/components/style/properties/shorthand/position.mako.rs +++ b/components/style/properties/shorthand/position.mako.rs @@ -46,12 +46,13 @@ extra_prefixes="webkit" derive_serialize="True" spec="https://drafts.csswg.org/css-flexbox/#flex-property"> - use values::specified::Number; + use parser::Parse; + use values::specified::NonNegativeNumber; fn parse_flexibility<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<(Number, Option<Number>),ParseError<'i>> { - let grow = Number::parse_non_negative(context, input)?; - let shrink = input.try(|i| Number::parse_non_negative(context, i)).ok(); + -> Result<(NonNegativeNumber, Option<NonNegativeNumber>),ParseError<'i>> { + let grow = NonNegativeNumber::parse(context, input)?; + let shrink = input.try(|i| NonNegativeNumber::parse(context, i)).ok(); Ok((grow, shrink)) } @@ -63,8 +64,8 @@ if input.try(|input| input.expect_ident_matching("none")).is_ok() { return Ok(expanded! { - flex_grow: Number::new(0.0), - flex_shrink: Number::new(0.0), + flex_grow: NonNegativeNumber::new(0.0), + flex_shrink: NonNegativeNumber::new(0.0), flex_basis: longhands::flex_basis::SpecifiedValue::auto(), }) } @@ -89,8 +90,8 @@ return Err(StyleParseError::UnspecifiedError.into()) } Ok(expanded! { - flex_grow: grow.unwrap_or(Number::new(1.0)), - flex_shrink: shrink.unwrap_or(Number::new(1.0)), + flex_grow: grow.unwrap_or(NonNegativeNumber::new(1.0)), + flex_shrink: shrink.unwrap_or(NonNegativeNumber::new(1.0)), // Per spec, this should be SpecifiedValue::zero(), but all // browsers currently agree on using `0%`. This is a spec // change which hasn't been adopted by browsers: diff --git a/components/style/values/animated/mod.rs b/components/style/values/animated/mod.rs index 63d85254598..d6a4acea1b0 100644 --- a/components/style/values/animated/mod.rs +++ b/components/style/values/animated/mod.rs @@ -10,6 +10,8 @@ use app_units::Au; use values::computed::Angle as ComputedAngle; +use values::computed::GreaterThanOrEqualToOneNumber as ComputedGreaterThanOrEqualToOneNumber; +use values::computed::NonNegativeNumber as ComputedNonNegativeNumber; use values::specified::url::SpecifiedUrl; pub mod effects; @@ -88,6 +90,34 @@ where } } +impl ToAnimatedValue for ComputedNonNegativeNumber { + type AnimatedValue = Self; + + #[inline] + fn to_animated_value(self) -> Self { + self + } + + #[inline] + fn from_animated_value(animated: Self::AnimatedValue) -> Self { + animated.0.max(0.).into() + } +} + +impl ToAnimatedValue for ComputedGreaterThanOrEqualToOneNumber { + type AnimatedValue = Self; + + #[inline] + fn to_animated_value(self) -> Self { + self + } + + #[inline] + fn from_animated_value(animated: Self::AnimatedValue) -> Self { + animated.0.max(1.).into() + } +} + /// Returns a value similar to `self` that represents zero. pub trait ToAnimatedZero: Sized { /// Returns a value that, when added with an underlying value, will produce the underlying diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index d2b49ef5e22..f492279a559 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -18,6 +18,7 @@ use std::f64::consts::PI; use std::fmt; use style_traits::ToCss; use super::{CSSFloat, CSSInteger}; +use super::generics::{GreaterThanOrEqualToOne, NonNegative}; use super::generics::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize}; use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; use super::generics::grid::TrackList as GenericTrackList; @@ -425,6 +426,40 @@ impl ComputedValueAsSpecified for specified::BorderStyle {} /// A `<number>` value. pub type Number = CSSFloat; +/// A wrapper of Number, but the value >= 0. +pub type NonNegativeNumber = NonNegative<CSSFloat>; + +impl From<CSSFloat> for NonNegativeNumber { + #[inline] + fn from(number: CSSFloat) -> NonNegativeNumber { + NonNegative::<CSSFloat>(number) + } +} + +impl From<NonNegativeNumber> for CSSFloat { + #[inline] + fn from(number: NonNegativeNumber) -> CSSFloat { + number.0 + } +} + +/// A wrapper of Number, but the value >= 1. +pub type GreaterThanOrEqualToOneNumber = GreaterThanOrEqualToOne<CSSFloat>; + +impl From<CSSFloat> for GreaterThanOrEqualToOneNumber { + #[inline] + fn from(number: CSSFloat) -> GreaterThanOrEqualToOneNumber { + GreaterThanOrEqualToOne::<CSSFloat>(number) + } +} + +impl From<GreaterThanOrEqualToOneNumber> for CSSFloat { + #[inline] + fn from(number: GreaterThanOrEqualToOneNumber) -> CSSFloat { + number.0 + } +} + #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, Copy, Debug, PartialEq, ToCss)] diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index 9456f0061c5..f87b7a88de5 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -252,3 +252,13 @@ impl ToCss for FontSettingTagFloat { self.0.to_css(dest) } } + +/// A wrapper of Non-negative values. +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd, ToComputedValue, ToCss)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] +pub struct NonNegative<T>(pub T); + +/// A wrapper of greater-than-or-equal-to-one values. +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd, ToComputedValue, ToCss)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] +pub struct GreaterThanOrEqualToOne<T>(pub T); diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 1728d4113d4..11183126df1 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -18,6 +18,7 @@ use style_traits::{ToCss, ParseError, StyleParseError}; use style_traits::values::specified::AllowedNumericType; use super::{Auto, CSSFloat, CSSInteger, Either, None_}; use super::computed::{self, Context, ToComputedValue}; +use super::generics::{GreaterThanOrEqualToOne, NonNegative}; use super::generics::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as GenericTrackSize}; use super::generics::grid::TrackList as GenericTrackList; use values::computed::ComputedValueAsSpecified; @@ -509,6 +510,33 @@ impl ToCss for Number { } } +/// A Number which is >= 0.0. +pub type NonNegativeNumber = NonNegative<Number>; + +impl Parse for NonNegativeNumber { + fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { + parse_number_with_clamping_mode(context, input, AllowedNumericType::NonNegative) + .map(NonNegative::<Number>) + } +} + +impl NonNegativeNumber { + /// Returns a new non-negative number with the value `val`. + pub fn new(val: CSSFloat) -> Self { + NonNegative::<Number>(Number::new(val.max(0.))) + } +} + +/// A Number which is >= 1.0. +pub type GreaterThanOrEqualToOneNumber = GreaterThanOrEqualToOne<Number>; + +impl Parse for GreaterThanOrEqualToOneNumber { + fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { + parse_number_with_clamping_mode(context, input, AllowedNumericType::AtLeastOne) + .map(GreaterThanOrEqualToOne::<Number>) + } +} + /// <number> | <percentage> /// /// Accepts only non-negative numbers. diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index 59013d1a01e..9e5f639f8e7 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -556,12 +556,12 @@ mod shorthand_serialization { #[test] fn flex_should_serialize_all_available_properties() { - use style::values::specified::{Number, Percentage}; + use style::values::specified::{NonNegativeNumber, Percentage}; let mut properties = Vec::new(); - let grow = Number::new(2f32); - let shrink = Number::new(3f32); + let grow = NonNegativeNumber::new(2f32); + let shrink = NonNegativeNumber::new(3f32); let basis = FlexBasis::Length(Percentage::new(0.5f32).into()); |