From 2ef38ce67ae62415bd52b2bd2e09766cf3b28808 Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Thu, 20 Jul 2017 16:27:35 +0800 Subject: [PATCH] Bug 1374233 - Part 4: Add NonNegativeLengthOr{Auto|Normal|Number}. Add NonNegativeLength, which could be computed to NonNegativeAu. So we can declare Either, X=Auto, Normal, or Number. NonNegativeLengthOrAuto is for column-width. NonNegativeLengthOrNormal is for column-gap. NonNegativeLengthOrNumber is for -moz-tab-size. MozReview-Commit-ID: AfU8XpA1um0 --- components/layout/multicol.rs | 4 +-- components/style/gecko/values.rs | 14 +++++++++-- components/style/properties/gecko.mako.rs | 14 ++++++----- .../helpers/animated_properties.mako.rs | 1 + .../style/properties/longhand/column.mako.rs | 10 +++----- .../longhand/inherited_text.mako.rs | 7 +++--- components/style/values/computed/length.rs | 13 ++++++++++ components/style/values/specified/length.rs | 25 +++++++++++++++++++ 8 files changed, 68 insertions(+), 20 deletions(-) diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index cdc6b2de08a0..888fe8b9d06d 100644 --- a/components/layout/multicol.rs +++ b/components/layout/multicol.rs @@ -98,14 +98,14 @@ impl Flow for MulticolFlow { let column_style = self.block_flow.fragment.style.get_column(); let column_gap = match column_style.column_gap { - Either::First(len) => len, + Either::First(len) => len.0, Either::Second(_normal) => self.block_flow.fragment.style.get_font().font_size.0, }; let mut column_count; if let Either::First(column_width) = column_style.column_width { column_count = - max(1, (content_inline_size + column_gap).0 / (column_width + column_gap).0); + max(1, (content_inline_size + column_gap).0 / (column_width.0 + column_gap).0); if let Either::First(specified_column_count) = column_style.column_count { column_count = min(column_count, specified_column_count as i32); } diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index a48152224094..e2ae1f538f13 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -17,10 +17,10 @@ use nsstring::{nsACString, nsCString}; use std::cmp::max; use values::{Auto, Either, ExtremumLength, None_, Normal}; use values::computed::{Angle, LengthOrPercentage, LengthOrPercentageOrAuto}; -use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage}; +use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage, NonNegativeAu}; use values::computed::{MaxLength, MozLength, Percentage}; use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; -use values::generics::CounterStyleOrNone; +use values::generics::{CounterStyleOrNone, NonNegative}; use values::generics::basic_shape::ShapeRadius; use values::generics::gecko::ScrollSnapPoint; use values::generics::grid::{TrackBreadth, TrackKeyword}; @@ -134,6 +134,16 @@ impl GeckoStyleCoordConvertible for Au { } } +impl GeckoStyleCoordConvertible for NonNegativeAu { + fn to_gecko_style_coord(&self, coord: &mut T) { + self.0.to_gecko_style_coord(coord); + } + + fn from_gecko_style_coord(coord: &T) -> Option { + Au::from_gecko_style_coord(coord).map(NonNegative::) + } +} + impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto { fn to_gecko_style_coord(&self, coord: &mut T) { let value = match *self { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index c8c2c0806f3c..e4f80f9a5c18 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1089,6 +1089,8 @@ impl Clone for ${style_struct.gecko_struct_name} { predefined_types = { "length::LengthOrAuto": impl_style_coord, "length::LengthOrNormal": impl_style_coord, + "length::NonNegativeLengthOrAuto": impl_style_coord, + "length::NonNegativeLengthOrNormal": impl_style_coord, "GreaterThanOrEqualToOneNumber": impl_simple, "Length": impl_absolute_length, "Position": impl_position, @@ -4797,11 +4799,11 @@ fn static_assert() { use values::Either; match v { - Either::Second(number) => { - self.gecko.mTabSize.set_value(CoordDataValue::Factor(number)); + Either::Second(non_negative_number) => { + self.gecko.mTabSize.set_value(CoordDataValue::Factor(non_negative_number.0)); } - Either::First(au) => { - self.gecko.mTabSize.set(au); + Either::First(non_negative_au) => { + self.gecko.mTabSize.set(non_negative_au.0); } } } @@ -4811,8 +4813,8 @@ fn static_assert() { use values::Either; match self.gecko.mTabSize.as_value() { - CoordDataValue::Coord(coord) => Either::First(Au(coord)), - CoordDataValue::Factor(number) => Either::Second(number), + CoordDataValue::Coord(coord) => Either::First(Au(coord).into()), + CoordDataValue::Factor(number) => Either::Second(From::from(number)), _ => unreachable!(), } } diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 64d94e871a72..78609e6376a5 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -44,6 +44,7 @@ use values::computed::{BorderCornerRadius, ClipRect}; use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified}; use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToComputedValue}; use values::computed::{NonNegativeAu, NonNegativeNumber}; +use values::computed::length::{NonNegativeLengthOrAuto, NonNegativeLengthOrNormal}; use values::generics::{GreaterThanOrEqualToOne, NonNegative}; use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use values::generics::effects::Filter; diff --git a/components/style/properties/longhand/column.mako.rs b/components/style/properties/longhand/column.mako.rs index 38668734fce8..5929b42addcf 100644 --- a/components/style/properties/longhand/column.mako.rs +++ b/components/style/properties/longhand/column.mako.rs @@ -7,12 +7,11 @@ <% data.new_style_struct("Column", inherited=False) %> ${helpers.predefined_type("column-width", - "length::LengthOrAuto", + "length::NonNegativeLengthOrAuto", "Either::Second(Auto)", initial_specified_value="Either::Second(Auto)", - parse_method="parse_non_negative_length", extra_prefixes="moz", - animation_value_type="ComputedValue", + animation_value_type="NonNegativeLengthOrAuto", experimental=True, spec="https://drafts.csswg.org/css-multicol/#propdef-column-width")} @@ -28,12 +27,11 @@ ${helpers.predefined_type("column-count", spec="https://drafts.csswg.org/css-multicol/#propdef-column-count")} ${helpers.predefined_type("column-gap", - "length::LengthOrNormal", + "length::NonNegativeLengthOrNormal", "Either::Second(Normal)", - parse_method='parse_non_negative_length', extra_prefixes="moz", experimental=True, - animation_value_type="ComputedValue", + animation_value_type="NonNegativeLengthOrNormal", spec="https://drafts.csswg.org/css-multicol/#propdef-column-gap")} ${helpers.single_keyword("column-fill", "balance auto", extra_prefixes="moz", diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 9fe339740204..b31c5ec22c77 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -714,10 +714,9 @@ ${helpers.predefined_type("text-emphasis-color", "Color", ${helpers.predefined_type( - "-moz-tab-size", "LengthOrNumber", - "::values::Either::Second(8.0)", - "parse_non_negative", - products="gecko", animation_value_type="ComputedValue", + "-moz-tab-size", "length::NonNegativeLengthOrNumber", + "::values::Either::Second(From::from(8.0))", + products="gecko", animation_value_type="::values::computed::length::NonNegativeLengthOrNumber", spec="https://drafts.csswg.org/css-text-3/#tab-size-property")} diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index b17606036ed0..0f724a12c143 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -11,6 +11,7 @@ use style_traits::ToCss; use style_traits::values::specified::AllowedLengthType; use super::{Number, ToComputedValue, Context}; use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified}; +use values::computed::{NonNegativeAu, NonNegativeNumber}; use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; use values::specified::length::ViewportPercentageLength; @@ -573,6 +574,18 @@ impl LengthOrNumber { /// Either a computed `` or the `normal` keyword. pub type LengthOrNormal = Either; +/// A wrapper of Length, whose value must be >= 0. +pub type NonNegativeLength = NonNegativeAu; + +/// Either a computed NonNegativeLength or the `auto` keyword. +pub type NonNegativeLengthOrAuto = Either; + +/// Either a computed NonNegativeLength or the `normal` keyword. +pub type NonNegativeLengthOrNormal = Either; + +/// Either a computed NonNegativeLength or a NonNegativeNumber value. +pub type NonNegativeLengthOrNumber = Either; + /// A value suitable for a `min-width`, `min-height`, `width` or `height` property. /// See specified/values/length.rs for more details. #[allow(missing_docs)] diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 73c77076ee7c..959e412a112d 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -21,6 +21,8 @@ use super::{AllowQuirks, Number, ToComputedValue}; use values::{Auto, CSSFloat, Either, FONT_MEDIUM_PX, None_, Normal}; use values::ExtremumLength; use values::computed::{self, Context}; +use values::generics::NonNegative; +use values::specified::NonNegativeNumber; use values::specified::calc::CalcNode; pub use values::specified::calc::CalcLengthOrPercentage; @@ -703,6 +705,29 @@ impl Either { } } +/// A wrapper of Length, whose value must be >= 0. +pub type NonNegativeLength = NonNegative; + +impl Parse for Either { + #[inline] + fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + if let Ok(v) = input.try(|input| T::parse(context, input)) { + return Ok(Either::Second(v)); + } + Length::parse_internal(context, input, AllowedLengthType::NonNegative, AllowQuirks::No) + .map(NonNegative::).map(Either::First) + } +} + +/// Either a NonNegativeLength or the `normal` keyword. +pub type NonNegativeLengthOrNormal = Either; + +/// Either a NonNegativeLength or the `auto` keyword. +pub type NonNegativeLengthOrAuto = Either; + +/// Either a NonNegativeLength or a NonNegativeNumber value. +pub type NonNegativeLengthOrNumber = Either; + /// A percentage value. #[derive(Clone, Copy, Debug, Default, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]