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
This commit is contained in:
Boris Chiou 2017-07-19 19:45:24 +08:00
parent 50c9797ddd
commit 4cc97746f2
12 changed files with 181 additions and 26 deletions

View file

@ -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

View file

@ -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,

View file

@ -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>)
}
}

View file

@ -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()",

View file

@ -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":

View file

@ -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)")}

View file

@ -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:

View file

@ -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

View file

@ -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)]

View file

@ -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);

View file

@ -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.

View file

@ -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());