Bug 1374233 - Part 4: Add NonNegativeLengthOr{Auto|Normal|Number}.
Add NonNegativeLength, which could be computed to NonNegativeAu. So we
can declare Either<NonNegativeLength, X>, 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
--- a/servo/components/style/gecko/values.rs
+++ b/servo/components/style/gecko/values.rs
@@ -12,17 +12,17 @@ use cssparser::RGBA;
use gecko_bindings::structs::{CounterStylePtr, nsStyleCoord};
use gecko_bindings::structs::{StyleGridTrackBreadth, StyleShapeRadius};
use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
use media_queries::Device;
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::basic_shape::ShapeRadius;
use values::generics::gecko::ScrollSnapPoint;
use values::generics::grid::{TrackBreadth, TrackKeyword};
/// A trait that defines an interface to convert from and to `nsStyleCoord`s.
@@ -129,16 +129,26 @@ impl GeckoStyleCoordConvertible for Au {
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Coord(coord) => Some(Au(coord)),
_ => None,
}
}
}
+impl GeckoStyleCoordConvertible for NonNegativeAu {
+ fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
+ self.0.to_gecko_style_coord(coord);
+ }
+
+ fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
+ Au::from_gecko_style_coord(coord).map(NonNegativeAu)
+ }
+}
+
impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
LengthOrPercentageOrAuto::Length(au) => CoordDataValue::Coord(au.0),
LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p.0),
LengthOrPercentageOrAuto::Auto => CoordDataValue::Auto,
LengthOrPercentageOrAuto::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -905,16 +905,18 @@ impl Clone for ${style_struct.gecko_stru
force_stub = [];
# These have unusual representations in gecko.
force_stub += ["list-style-type"]
# Types used with predefined_type()-defined properties that we can auto-generate.
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_wrapper,
"Length": impl_absolute_length,
"Position": impl_position,
"LengthOrPercentage": impl_style_coord,
"LengthOrPercentageOrAuto": impl_style_coord,
"LengthOrPercentageOrNone": impl_style_coord,
"LengthOrNone": impl_style_coord,
"LengthOrNormal": impl_style_coord,
@@ -4196,32 +4198,33 @@ fn static_assert() {
'mWebkitTextStrokeWidth',
need_clone=True)"></%call>
#[allow(non_snake_case)]
pub fn set__moz_tab_size(&mut self, v: longhands::_moz_tab_size::computed_value::T) {
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);
}
}
}
#[allow(non_snake_case)]
pub fn clone__moz_tab_size(&self) -> longhands::_moz_tab_size::computed_value::T {
use values::Either;
+ use values::computed::NonNegativeNumber;
match self.gecko.mTabSize.as_value() {
- CoordDataValue::Coord(coord) => Either::First(Au(coord)),
- CoordDataValue::Factor(number) => Either::Second(number),
+ CoordDataValue::Coord(coord) => Either::First(NonNegativeAu(Au(coord))),
+ CoordDataValue::Factor(number) => Either::Second(NonNegativeNumber(number)),
_ => unreachable!(),
}
}
<%call expr="impl_coord_copy('_moz_tab_size', 'mTabSize')"></%call>
</%self:impl_trait>
<%self:impl_trait style_struct_name="Text"
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -40,16 +40,18 @@ use values::animated::effects::BoxShadow
use values::animated::effects::Filter as AnimatedFilter;
use values::animated::effects::FilterList as AnimatedFilterList;
use values::animated::effects::TextShadowList as AnimatedTextShadowList;
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::{GreaterThanOrEqualToOneNumber, NonNegativeAu, NonNegativeNumber};
+use values::computed::length::{NonNegativeLengthOrAuto, NonNegativeLengthOrNormal};
+use values::computed::length::NonNegativeLengthOrNumber;
use values::generics::{SVGPaint, SVGPaintKind};
use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
use values::generics::effects::Filter;
use values::generics::position as generic_position;
/// A trait used to implement various procedures used during animation.
pub trait Animatable: Sized {
/// Performs a weighted sum of this value and |other|. This is used for
--- a/servo/components/style/properties/longhand/column.mako.rs
+++ b/servo/components/style/properties/longhand/column.mako.rs
@@ -2,43 +2,41 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
<%namespace name="helpers" file="/helpers.mako.rs" />
<% 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")}
${helpers.predefined_type("column-count",
"IntegerOrAuto",
"Either::Second(Auto)",
parse_method="parse_positive",
initial_specified_value="Either::Second(Auto)",
experimental="True",
animation_value_type="ComputedValue",
extra_prefixes="moz",
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",
products="gecko", animation_value_type="discrete",
spec="https://drafts.csswg.org/css-multicol/#propdef-column-fill")}
${helpers.predefined_type("column-rule-width",
"BorderSideWidth",
--- a/servo/components/style/properties/longhand/inherited_text.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_text.mako.rs
@@ -709,20 +709,19 @@
"computed_value::T::currentcolor()",
initial_specified_value="specified::Color::currentcolor()",
products="gecko", animation_value_type="IntermediateColor",
need_clone=True, ignored_when_colors_disabled=True,
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-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(::values::computed::NonNegativeNumber(8.0))",
+ products="gecko", animation_value_type="NonNegativeLengthOrNumber",
spec="https://drafts.csswg.org/css-text-3/#tab-size-property")}
// CSS Compatibility
// https://compat.spec.whatwg.org
${helpers.predefined_type(
"-webkit-text-fill-color", "Color",
"computed_value::T::currentcolor()",
--- a/servo/components/style/values/computed/length.rs
+++ b/servo/components/style/values/computed/length.rs
@@ -6,16 +6,17 @@
use app_units::{Au, AU_PER_PX};
use ordered_float::NotNaN;
use std::fmt;
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;
pub use super::image::Image;
pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone};
/// A computed `<percentage>` value.
///
@@ -96,16 +97,30 @@ impl ToComputedValue for specified::Leng
}
#[inline]
fn from_computed_value(computed: &Au) -> Self {
specified::Length::NoCalc(specified::NoCalcLength::from_computed_value(computed))
}
}
+impl ToComputedValue for specified::length::NonNegativeLength {
+ type ComputedValue = NonNegativeLength;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
+ NonNegativeAu(self.0.to_computed_value(context))
+ }
+
+ #[inline]
+ fn from_computed_value(computed: &Self::ComputedValue) -> Self {
+ specified::length::NonNegativeLength(ToComputedValue::from_computed_value(&computed.0))
+ }
+}
+
#[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[allow(missing_docs)]
pub struct CalcLengthOrPercentage {
pub clamping_mode: AllowedLengthType,
length: Au,
pub percentage: Option<Percentage>,
}
@@ -555,16 +570,28 @@ impl LengthOrNumber {
pub fn zero() -> Self {
Either::Second(0.)
}
}
/// Either a computed `<length>` or the `normal` keyword.
pub type LengthOrNormal = Either<Length, Normal>;
+/// 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<NonNegativeLength, Auto>;
+
+/// Either a computed NonNegativeLength or the `normal` keyword.
+pub type NonNegativeLengthOrNormal = Either<NonNegativeLength, Normal>;
+
+/// Either a computed NonNegativeLength or a NonNegativeNumber value.
+pub type NonNegativeLengthOrNumber = Either<NonNegativeLength, NonNegativeNumber>;
+
/// A value suitable for a `min-width`, `min-height`, `width` or `height` property.
/// See specified/values/length.rs for more details.
#[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, PartialEq, ToCss)]
pub enum MozLength {
LengthOrPercentageOrAuto(LengthOrPercentageOrAuto),
ExtremumLength(ExtremumLength),
--- a/servo/components/style/values/specified/length.rs
+++ b/servo/components/style/values/specified/length.rs
@@ -17,16 +17,17 @@ use std::ops::Mul;
use style_traits::{HasViewportPercentage, ToCss, ParseError, StyleParseError};
use style_traits::values::specified::{AllowedLengthType, AllowedNumericType};
use stylesheets::CssRuleType;
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::specified::calc::CalcNode;
+use values::specified::NonNegativeNumber;
pub use values::specified::calc::CalcLengthOrPercentage;
pub use super::image::{ColorStop, EndingShape as GradientEndingShape, Gradient};
pub use super::image::{GradientKind, Image};
/// Number of app units per pixel
pub const AU_PER_PX: CSSFloat = 60.;
/// Number of app units per inch
@@ -695,16 +696,41 @@ impl<T: Parse> Either<Length, T> {
-> Result<Self, ParseError<'i>> {
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(Either::First)
}
}
+/// A wrapper of Length, whose value must be >= 0.
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)]
+pub struct NonNegativeLength(pub Length);
+
+impl<T: Parse> Parse for Either<NonNegativeLength, T> {
+ #[inline]
+ fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
+ 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(NonNegativeLength).map(Either::First)
+ }
+}
+
+/// Either a NonNegativeLength or the `normal` keyword.
+pub type NonNegativeLengthOrNormal = Either<NonNegativeLength, Normal>;
+
+/// Either a NonNegativeLength or the `auto` keyword.
+pub type NonNegativeLengthOrAuto = Either<NonNegativeLength, Auto>;
+
+/// Either a NonNegativeLength or a NonNegativeNumber value.
+pub type NonNegativeLengthOrNumber = Either<NonNegativeLength, NonNegativeNumber>;
+
/// A percentage value.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Percentage {
/// The percentage value as a float.
///
/// [0 .. 100%] maps to [0.0 .. 1.0]
value: CSSFloat,