From 76de9792314c3a9156daa28b398db51fe392dac8 Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Wed, 30 Nov 2016 16:14:47 -0500 Subject: [PATCH 1/2] Implement a MinLength type Implement an ExtremumLength type which contains all the enumerated keyword values for min-width, min-height, max-width, and max-height. Then, implement a MinLength which can be used for min-width and min-height. So far this just maps to Gecko values. Refs #13821. --- components/style/gecko/values.rs | 52 ++++++++++++++++- components/style/properties/gecko.mako.rs | 1 + .../helpers/animated_properties.mako.rs | 15 +++++ .../properties/longhand/position.mako.rs | 25 +++++--- components/style/values/computed/length.rs | 57 ++++++++++++++++++- components/style/values/computed/mod.rs | 1 + components/style/values/mod.rs | 8 +++ components/style/values/specified/length.rs | 49 ++++++++++++++++ components/style/values/specified/mod.rs | 1 + 9 files changed, 199 insertions(+), 10 deletions(-) diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 6d3f374c430..814633e4517 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -11,9 +11,10 @@ use cssparser::RGBA; use gecko_bindings::structs::{nsStyleCoord, StyleGridTrackBreadth, StyleShapeRadius}; use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; use std::cmp::max; -use values::{Auto, Either, None_, Normal}; +use values::{Auto, Either, ExtremumLength, None_, Normal}; use values::computed::{Angle, LengthOrPercentageOrNone, Number}; use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; +use values::computed::MinLength; use values::computed::basic_shape::ShapeRadius; use values::specified::grid::{TrackBreadth, TrackKeyword}; @@ -271,6 +272,55 @@ impl GeckoStyleCoordConvertible for Normal { } } +impl GeckoStyleCoordConvertible for ExtremumLength { + fn to_gecko_style_coord(&self, coord: &mut T) { + use gecko_bindings::structs::{NS_STYLE_WIDTH_AVAILABLE, NS_STYLE_WIDTH_FIT_CONTENT}; + use gecko_bindings::structs::{NS_STYLE_WIDTH_MAX_CONTENT, NS_STYLE_WIDTH_MIN_CONTENT}; + coord.set_value(CoordDataValue::Enumerated( + match *self { + ExtremumLength::MaxContent => NS_STYLE_WIDTH_MAX_CONTENT, + ExtremumLength::MinContent => NS_STYLE_WIDTH_MIN_CONTENT, + ExtremumLength::FitContent => NS_STYLE_WIDTH_FIT_CONTENT, + ExtremumLength::FillAvailable => NS_STYLE_WIDTH_AVAILABLE, + } + )) + } + + fn from_gecko_style_coord(coord: &T) -> Option { + use gecko_bindings::structs::{NS_STYLE_WIDTH_AVAILABLE, NS_STYLE_WIDTH_FIT_CONTENT}; + use gecko_bindings::structs::{NS_STYLE_WIDTH_MAX_CONTENT, NS_STYLE_WIDTH_MIN_CONTENT}; + match coord.as_value() { + CoordDataValue::Enumerated(NS_STYLE_WIDTH_MAX_CONTENT) => + Some(ExtremumLength::MaxContent), + CoordDataValue::Enumerated(NS_STYLE_WIDTH_MIN_CONTENT) => + Some(ExtremumLength::MinContent), + CoordDataValue::Enumerated(NS_STYLE_WIDTH_FIT_CONTENT) => + Some(ExtremumLength::FitContent), + CoordDataValue::Enumerated(NS_STYLE_WIDTH_AVAILABLE) => Some(ExtremumLength::FillAvailable), + _ => None, + } + } +} + +impl GeckoStyleCoordConvertible for MinLength { + fn to_gecko_style_coord(&self, coord: &mut T) { + match *self { + MinLength::LengthOrPercentage(ref lop) => lop.to_gecko_style_coord(coord), + MinLength::Auto => coord.set_value(CoordDataValue::Auto), + MinLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord), + } + } + + fn from_gecko_style_coord(coord: &T) -> Option { + LengthOrPercentage::from_gecko_style_coord(coord).map(MinLength::LengthOrPercentage) + .or_else(|| ExtremumLength::from_gecko_style_coord(coord).map(MinLength::ExtremumLength)) + .or_else(|| match coord.as_value() { + CoordDataValue::Auto => Some(MinLength::Auto), + _ => None, + }) + } +} + /// Convert a given RGBA value to `nscolor`. pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 { ((rgba.alpha as u32) << 24) | diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 34f6981925b..a5c9504fb7a 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -635,6 +635,7 @@ impl Debug for ${style_struct.gecko_struct_name} { "LengthOrPercentageOrAuto": impl_style_coord, "LengthOrPercentageOrNone": impl_style_coord, "LengthOrNone": impl_style_coord, + "MinLength": impl_style_coord, "Number": impl_simple, "Opacity": impl_simple, "CSSColor": impl_color, diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 0c2b59eb2da..4340e1870cc 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -33,6 +33,7 @@ use values::Either; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{BorderRadiusSize, ClipRect, LengthOrNone}; use values::computed::{CalcLengthOrPercentage, Context, LengthOrPercentage}; +use values::computed::MinLength; use values::computed::position::{HorizontalPosition, Position, VerticalPosition}; use values::computed::ToComputedValue; use values::specified::Angle as SpecifiedAngle; @@ -630,6 +631,20 @@ impl Interpolate for LengthOrPercentageOrNone { } } +/// https://drafts.csswg.org/css-transitions/#animtype-lpcalc +impl Interpolate for MinLength { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result { + match (*self, *other) { + (MinLength::LengthOrPercentage(ref this), + MinLength::LengthOrPercentage(ref other)) => { + this.interpolate(other, progress).map(MinLength::LengthOrPercentage) + } + _ => Err(()), + } + } +} + /// https://drafts.csswg.org/css-transitions/#animtype-number /// https://drafts.csswg.org/css-transitions/#animtype-length impl Interpolate for LineHeight { diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 97b8d150365..ba33367227a 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -218,14 +218,23 @@ ${helpers.predefined_type("flex-basis", spec=spec % size, animatable=True, logical = logical)} - // min-width, min-height, min-block-size, min-inline-size - ${helpers.predefined_type("min-%s" % size, - "LengthOrPercentage", - "computed::LengthOrPercentage::Length(Au(0))", - "parse_non_negative", - needs_context=False, - spec=spec % ("min-%s" % size), - animatable=True, logical = logical)} + % if product == "gecko": + // min-width, min-height, min-block-size, min-inline-size + ${helpers.predefined_type("min-%s" % size, + "MinLength", + "computed::MinLength::LengthOrPercentage(" + + "computed::LengthOrPercentage::Length(Au(0)))", + spec=spec % ("min-%s" % size), + animatable=True, logical = logical)} + % else: + ${helpers.predefined_type("min-%s" % size, + "LengthOrPercentage", + "computed::LengthOrPercentage::Length(Au(0))", + "parse_non_negative", + needs_context=False, + spec=spec % ("min-%s" % size), + animatable=True, logical = logical)} + % endif // max-width, max-height, max-block-size, max-inline-size ${helpers.predefined_type("max-%s" % size, diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 492bbfb4bc0..d3065f29761 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -9,7 +9,7 @@ use ordered_float::NotNaN; use std::fmt; use style_traits::ToCss; use super::{Number, ToComputedValue, Context}; -use values::{Auto, CSSFloat, Either, None_, Normal, specified}; +use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified}; use values::specified::length::{FontRelativeLength, ViewportPercentageLength}; pub use cssparser::Color as CSSColor; @@ -546,3 +546,58 @@ pub type LengthOrNumber = Either; /// Either a computed `` or the `normal` keyword. pub type LengthOrNormal = Either; + +/// A value suitable for a `min-width` or `min-height` property. +/// See specified/values/length.rs for more details. +#[derive(Debug, Copy, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] +pub enum MinLength { + LengthOrPercentage(LengthOrPercentage), + Auto, + ExtremumLength(ExtremumLength), +} + +impl ToComputedValue for specified::MinLength { + type ComputedValue = MinLength; + + #[inline] + fn to_computed_value(&self, context: &Context) -> MinLength { + match *self { + specified::MinLength::LengthOrPercentage(ref lop) => { + MinLength::LengthOrPercentage(lop.to_computed_value(context)) + } + specified::MinLength::Auto => { + MinLength::Auto + } + specified::MinLength::ExtremumLength(ref ext) => { + MinLength::ExtremumLength(ext.clone()) + } + } + } + + #[inline] + fn from_computed_value(computed: &MinLength) -> Self { + match *computed { + MinLength::Auto => + specified::MinLength::Auto, + MinLength::LengthOrPercentage(ref lop) => + specified::MinLength::LengthOrPercentage(specified::LengthOrPercentage::from_computed_value(&lop)), + MinLength::ExtremumLength(ref ext) => + specified::MinLength::ExtremumLength(ext.clone()), + } + } +} + +impl ToCss for MinLength { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + MinLength::LengthOrPercentage(lop) => + lop.to_css(dest), + MinLength::Auto => + dest.write_str("auto"), + MinLength::ExtremumLength(ext) => + ext.to_css(dest), + } + } +} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index bacb11be012..206ee3ae5c9 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -23,6 +23,7 @@ pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone}; pub use super::specified::url::{SpecifiedUrl, UrlExtraData}; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone}; +pub use self::length::MinLength; pub use self::position::Position; pub mod basic_shape; diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index a1885f7552e..59460b49f43 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -185,3 +185,11 @@ impl ToComputedValue for Either { } } } + +// A type for possible values for min- and max- flavors of width, +// height, block-size, and inline-size. +define_css_keyword_enum!(ExtremumLength: + "max-content" => MaxContent, + "min-content" => MinContent, + "fit-content" => FitContent, + "fill-available" => FillAvailable); diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 0744aa9aafb..8ffb12058a5 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -18,6 +18,7 @@ use style_traits::ToCss; use style_traits::values::specified::AllowedNumericType; use super::{Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time}; use values::{Auto, CSSFloat, Either, FONT_MEDIUM_PX, HasViewportPercentage, None_, Normal}; +use values::ExtremumLength; use values::computed::Context; pub use super::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient}; @@ -1304,3 +1305,51 @@ impl LengthOrNumber { } } } + +/// A value suitable for a `min-width` or `min-height` property. +/// Unlike `max-width` or `max-height` properties, a MinLength can be +/// `auto`, and cannot be `none`. +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] +pub enum MinLength { + LengthOrPercentage(LengthOrPercentage), + Auto, + ExtremumLength(ExtremumLength), +} + +impl HasViewportPercentage for MinLength { + fn has_viewport_percentage(&self) -> bool { + match *self { + MinLength::LengthOrPercentage(ref lop) => lop.has_viewport_percentage(), + _ => false + } + } +} + +impl ToCss for MinLength { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + MinLength::LengthOrPercentage(ref lop) => + lop.to_css(dest), + MinLength::Auto => + dest.write_str("auto"), + MinLength::ExtremumLength(ref ext) => + ext.to_css(dest), + } + } +} + +impl Parse for MinLength { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + input.try(ExtremumLength::parse).map(MinLength::ExtremumLength) + .or_else(|()| input.try(LengthOrPercentage::parse_non_negative).map(MinLength::LengthOrPercentage)) + .or_else(|()| { + match_ignore_ascii_case! { try!(input.expect_ident()), + "auto" => + Ok(MinLength::Auto), + _ => Err(()) + } + }) + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 1d58af7cf06..5a7dfffc090 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -30,6 +30,7 @@ pub use self::image::{SizeKeyword, VerticalDirection}; pub use self::length::{FontRelativeLength, ViewportPercentageLength, CharacterWidth, Length, CalcLengthOrPercentage}; pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength, CalcUnit}; +pub use self::length::MinLength; pub use self::position::{HorizontalPosition, Position, VerticalPosition}; #[cfg(feature = "gecko")] From dd4f33160360664dd68ac44da15fcce94ce7411c Mon Sep 17 00:00:00 2001 From: Ethan Glasser-Camp Date: Fri, 17 Feb 2017 12:09:00 -0500 Subject: [PATCH 2/2] Add support for MaxLength This builds on the ExtremumLength type from the previous commit. --- components/style/gecko/values.rs | 21 ++++++- components/style/properties/gecko.mako.rs | 1 + .../helpers/animated_properties.mako.rs | 16 +++++- .../properties/longhand/position.mako.rs | 22 +++++--- components/style/values/computed/length.rs | 55 +++++++++++++++++++ components/style/values/computed/mod.rs | 2 +- components/style/values/specified/length.rs | 46 ++++++++++++++++ components/style/values/specified/mod.rs | 2 +- 8 files changed, 154 insertions(+), 11 deletions(-) diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 814633e4517..cccb5ca697f 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -14,7 +14,7 @@ use std::cmp::max; use values::{Auto, Either, ExtremumLength, None_, Normal}; use values::computed::{Angle, LengthOrPercentageOrNone, Number}; use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; -use values::computed::MinLength; +use values::computed::{MaxLength, MinLength}; use values::computed::basic_shape::ShapeRadius; use values::specified::grid::{TrackBreadth, TrackKeyword}; @@ -321,6 +321,25 @@ impl GeckoStyleCoordConvertible for MinLength { } } +impl GeckoStyleCoordConvertible for MaxLength { + fn to_gecko_style_coord(&self, coord: &mut T) { + match *self { + MaxLength::LengthOrPercentage(ref lop) => lop.to_gecko_style_coord(coord), + MaxLength::None => coord.set_value(CoordDataValue::None), + MaxLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord), + } + } + + fn from_gecko_style_coord(coord: &T) -> Option { + LengthOrPercentage::from_gecko_style_coord(coord).map(MaxLength::LengthOrPercentage) + .or_else(|| ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength)) + .or_else(|| match coord.as_value() { + CoordDataValue::None => Some(MaxLength::None), + _ => None, + }) + } +} + /// Convert a given RGBA value to `nscolor`. pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 { ((rgba.alpha as u32) << 24) | diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index a5c9504fb7a..e5062de0f4e 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -635,6 +635,7 @@ impl Debug for ${style_struct.gecko_struct_name} { "LengthOrPercentageOrAuto": impl_style_coord, "LengthOrPercentageOrNone": impl_style_coord, "LengthOrNone": impl_style_coord, + "MaxLength": impl_style_coord, "MinLength": impl_style_coord, "Number": 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 4340e1870cc..e145420befd 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -33,7 +33,7 @@ use values::Either; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{BorderRadiusSize, ClipRect, LengthOrNone}; use values::computed::{CalcLengthOrPercentage, Context, LengthOrPercentage}; -use values::computed::MinLength; +use values::computed::{MaxLength, MinLength}; use values::computed::position::{HorizontalPosition, Position, VerticalPosition}; use values::computed::ToComputedValue; use values::specified::Angle as SpecifiedAngle; @@ -645,6 +645,20 @@ impl Interpolate for MinLength { } } +/// https://drafts.csswg.org/css-transitions/#animtype-lpcalc +impl Interpolate for MaxLength { + #[inline] + fn interpolate(&self, other: &Self, progress: f64) -> Result { + match (*self, *other) { + (MaxLength::LengthOrPercentage(ref this), + MaxLength::LengthOrPercentage(ref other)) => { + this.interpolate(other, progress).map(MaxLength::LengthOrPercentage) + } + _ => Err(()), + } + } +} + /// https://drafts.csswg.org/css-transitions/#animtype-number /// https://drafts.csswg.org/css-transitions/#animtype-length impl Interpolate for LineHeight { diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index ba33367227a..c9431031b3f 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -237,13 +237,21 @@ ${helpers.predefined_type("flex-basis", % endif // max-width, max-height, max-block-size, max-inline-size - ${helpers.predefined_type("max-%s" % size, - "LengthOrPercentageOrNone", - "computed::LengthOrPercentageOrNone::None", - "parse_non_negative", - needs_context=False, - spec=spec % ("max-%s" % size), - animatable=True, logical = logical)} + % if product == "gecko": + ${helpers.predefined_type("max-%s" % size, + "MaxLength", + "computed::MaxLength::None", + spec=spec % ("max-%s" % size), + animatable=True, logical = logical)} + % else: + ${helpers.predefined_type("max-%s" % size, + "LengthOrPercentageOrNone", + "computed::LengthOrPercentageOrNone::None", + "parse_non_negative", + needs_context=False, + spec=spec % ("max-%s" % size), + animatable=True, logical = logical)} + % endif % endfor ${helpers.single_keyword("box-sizing", diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index d3065f29761..e512a623492 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -601,3 +601,58 @@ impl ToCss for MinLength { } } } + +/// A value suitable for a `max-width` or `max-height` property. +/// See specified/values/length.rs for more details. +#[derive(Debug, Copy, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] +pub enum MaxLength { + LengthOrPercentage(LengthOrPercentage), + None, + ExtremumLength(ExtremumLength), +} + +impl ToComputedValue for specified::MaxLength { + type ComputedValue = MaxLength; + + #[inline] + fn to_computed_value(&self, context: &Context) -> MaxLength { + match *self { + specified::MaxLength::LengthOrPercentage(ref lop) => { + MaxLength::LengthOrPercentage(lop.to_computed_value(context)) + } + specified::MaxLength::None => { + MaxLength::None + } + specified::MaxLength::ExtremumLength(ref ext) => { + MaxLength::ExtremumLength(ext.clone()) + } + } + } + + #[inline] + fn from_computed_value(computed: &MaxLength) -> Self { + match *computed { + MaxLength::None => + specified::MaxLength::None, + MaxLength::LengthOrPercentage(ref lop) => + specified::MaxLength::LengthOrPercentage(specified::LengthOrPercentage::from_computed_value(&lop)), + MaxLength::ExtremumLength(ref ext) => + specified::MaxLength::ExtremumLength(ext.clone()), + } + } +} + +impl ToCss for MaxLength { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + MaxLength::LengthOrPercentage(lop) => + lop.to_css(dest), + MaxLength::None => + dest.write_str("none"), + MaxLength::ExtremumLength(ext) => + ext.to_css(dest), + } + } +} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 206ee3ae5c9..323927cdf88 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -23,7 +23,7 @@ pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone}; pub use super::specified::url::{SpecifiedUrl, UrlExtraData}; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone}; -pub use self::length::MinLength; +pub use self::length::{MaxLength, MinLength}; pub use self::position::Position; pub mod basic_shape; diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 8ffb12058a5..ba344eff300 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -1353,3 +1353,49 @@ impl Parse for MinLength { }) } } + +/// A value suitable for a `max-width` or `max-height` property. +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[allow(missing_docs)] +pub enum MaxLength { + LengthOrPercentage(LengthOrPercentage), + None, + ExtremumLength(ExtremumLength), +} + +impl HasViewportPercentage for MaxLength { + fn has_viewport_percentage(&self) -> bool { + match *self { + MaxLength::LengthOrPercentage(ref lop) => lop.has_viewport_percentage(), + _ => false + } + } +} + +impl ToCss for MaxLength { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + MaxLength::LengthOrPercentage(ref lop) => + lop.to_css(dest), + MaxLength::None => + dest.write_str("none"), + MaxLength::ExtremumLength(ref ext) => + ext.to_css(dest), + } + } +} + +impl Parse for MaxLength { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + input.try(ExtremumLength::parse).map(MaxLength::ExtremumLength) + .or_else(|()| input.try(LengthOrPercentage::parse_non_negative).map(MaxLength::LengthOrPercentage)) + .or_else(|()| { + match_ignore_ascii_case! { try!(input.expect_ident()), + "none" => + Ok(MaxLength::None), + _ => Err(()) + } + }) + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 5a7dfffc090..af127a15249 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -30,7 +30,7 @@ pub use self::image::{SizeKeyword, VerticalDirection}; pub use self::length::{FontRelativeLength, ViewportPercentageLength, CharacterWidth, Length, CalcLengthOrPercentage}; pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength, CalcUnit}; -pub use self::length::MinLength; +pub use self::length::{MaxLength, MinLength}; pub use self::position::{HorizontalPosition, Position, VerticalPosition}; #[cfg(feature = "gecko")]