aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Chiou <boris.chiou@gmail.com>2017-07-19 19:45:24 +0800
committerBoris Chiou <boris.chiou@gmail.com>2017-08-04 14:21:21 +0800
commit4cc97746f239b70a196ce2929e38c1d4ffe353ef (patch)
tree1bd794d95c7919bb44d8940a5161edaeedef6d8b
parent50c9797ddd7b206c96f9436c634d915efe4acc17 (diff)
downloadservo-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.rs4
-rw-r--r--components/style/properties/gecko.mako.rs6
-rw-r--r--components/style/properties/helpers/animated_properties.mako.rs48
-rw-r--r--components/style/properties/longhand/inherited_svg.mako.rs7
-rw-r--r--components/style/properties/longhand/position.mako.rs12
-rw-r--r--components/style/properties/longhand/xul.mako.rs4
-rw-r--r--components/style/properties/shorthand/position.mako.rs17
-rw-r--r--components/style/values/animated/mod.rs30
-rw-r--r--components/style/values/computed/mod.rs35
-rw-r--r--components/style/values/generics/mod.rs10
-rw-r--r--components/style/values/specified/mod.rs28
-rw-r--r--tests/unit/style/properties/serialization.rs6
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());