diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2019-01-27 01:03:44 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2019-02-10 07:11:46 +0100 |
commit | a68bc29b96ac1c42d3940434c6c3239ee0f42a7a (patch) | |
tree | a80b2b0d9122026d67a71805636fe469f4bd9986 /components/style | |
parent | 8dad956513eba5cea9ce895c6f5351ff9f95c835 (diff) | |
download | servo-a68bc29b96ac1c42d3940434c6c3239ee0f42a7a.tar.gz servo-a68bc29b96ac1c42d3940434c6c3239ee0f42a7a.zip |
style: Derive more length stuff, and shrink MaxLength / MozLength's repr(C) representation.
This patch:
* Makes LengthPercentageOrAuto generic, and removes a bunch of code fo
LengthPercentageOrNone, which was used only for servo and now can use the
normal MaxLength (with a cfg() guard for the ExtremumLength variant).
* Shrinks MaxLength / MozLength's repr(C) reperesentation by reducing enum
nesting. The shrinking is in preparation for using them from C++ too, though
that'd be a different bug.
* Moves NonNegative usage to the proper places so that stuff for them can be
derived.
I did this on top of bug 1523071 to prove both that it could be possible and
that stuff wasn't too messy. It got a bit messy, but just because of a bug I
had fixed in bindgen long time ago already, so this updates bindgen's patch
version to grab a fix instead of ugly workarounds :)
Differential Revision: https://phabricator.services.mozilla.com/D17762
Diffstat (limited to 'components/style')
-rw-r--r-- | components/style/cbindgen.toml | 2 | ||||
-rw-r--r-- | components/style/gecko/conversions.rs | 11 | ||||
-rw-r--r-- | components/style/gecko/values.rs | 58 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 5 | ||||
-rw-r--r-- | components/style/properties/longhands/position.mako.rs | 48 | ||||
-rw-r--r-- | components/style/properties/properties.mako.rs | 12 | ||||
-rw-r--r-- | components/style/stylesheets/viewport_rule.rs | 17 | ||||
-rw-r--r-- | components/style/values/animated/length.rs | 52 | ||||
-rw-r--r-- | components/style/values/computed/background.rs | 9 | ||||
-rw-r--r-- | components/style/values/computed/length.rs | 224 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/generics/background.rs | 12 | ||||
-rw-r--r-- | components/style/values/generics/length.rs | 99 | ||||
-rw-r--r-- | components/style/values/specified/background.rs | 6 | ||||
-rw-r--r-- | components/style/values/specified/gecko.rs | 12 | ||||
-rw-r--r-- | components/style/values/specified/length.rs | 280 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 2 |
17 files changed, 334 insertions, 517 deletions
diff --git a/components/style/cbindgen.toml b/components/style/cbindgen.toml index d76a57c9541..4c0b631d31d 100644 --- a/components/style/cbindgen.toml +++ b/components/style/cbindgen.toml @@ -99,7 +99,7 @@ item_types = ["enums", "structs", "typedefs"] template<typename T> inline nscoord ResolveWith(T aPercentageGetter) const; """ -"LengthPercentageOrAuto" = """ +"GenericLengthPercentageOrAuto" = """ inline const StyleLengthPercentage& AsLengthPercentage() const; inline bool HasPercent() const; inline bool ConvertsToLength() const; diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index 0f6ac89c9f2..ccaa16c844c 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -27,6 +27,7 @@ use crate::values::computed::{LengthPercentageOrAuto, NonNegativeLengthPercentag use crate::values::generics::box_::VerticalAlign; use crate::values::generics::grid::{TrackListValue, TrackSize}; use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; +use crate::values::generics::length::LengthPercentageOrAuto as GenericLengthPercentageOrAuto; use crate::values::generics::rect::Rect; use crate::values::generics::NonNegative; use app_units::Au; @@ -62,19 +63,19 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentage { } } -impl LengthPercentageOrAuto { +impl NonNegativeLengthPercentageOrAuto { /// Convert this value in an appropriate `nsStyleCoord::CalcValue`. pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> { match *self { - LengthPercentageOrAuto::LengthPercentage(len) => Some(From::from(len)), - LengthPercentageOrAuto::Auto => None, + GenericLengthPercentageOrAuto::LengthPercentage(ref len) => Some(From::from(len.0)), + GenericLengthPercentageOrAuto::Auto => None, } } } impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto { fn from(other: nsStyleCoord_CalcValue) -> LengthPercentageOrAuto { - LengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other)) + GenericLengthPercentageOrAuto::LengthPercentage(LengthPercentage::from(other)) } } @@ -82,7 +83,7 @@ impl From<nsStyleCoord_CalcValue> for LengthPercentageOrAuto { // disappear as we move more stuff to cbindgen. impl From<nsStyleCoord_CalcValue> for NonNegativeLengthPercentageOrAuto { fn from(other: nsStyleCoord_CalcValue) -> Self { - NonNegative(LengthPercentageOrAuto::LengthPercentage( + GenericLengthPercentageOrAuto::LengthPercentage(NonNegative( LengthPercentage::with_clamping_mode( Au(other.mLength).into(), if other.mHasPercent { diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 42177bf0858..ac3495a7504 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -14,15 +14,15 @@ use crate::media_queries::Device; use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; use crate::values::computed::FlexBasis as ComputedFlexBasis; use crate::values::computed::{Angle, ExtremumLength, Length, LengthPercentage}; -use crate::values::computed::{LengthPercentageOrAuto, Percentage}; -use crate::values::computed::{LengthPercentageOrNone, Number, NumberOrPercentage}; use crate::values::computed::{MaxLength as ComputedMaxLength, MozLength as ComputedMozLength}; +use crate::values::computed::{NonNegativeLengthPercentage, Percentage}; +use crate::values::computed::{Number, NumberOrPercentage}; use crate::values::generics::basic_shape::ShapeRadius; use crate::values::generics::box_::Perspective; use crate::values::generics::flex::FlexBasis; use crate::values::generics::gecko::ScrollSnapPoint; use crate::values::generics::grid::{TrackBreadth, TrackKeyword}; -use crate::values::generics::length::{MaxLength, MozLength}; +use crate::values::generics::length::{LengthPercentageOrAuto, MaxLength, MozLength}; use crate::values::generics::{CounterStyleOrNone, NonNegative}; use crate::values::{Auto, Either, None_, Normal}; use crate::Atom; @@ -183,7 +183,10 @@ impl GeckoStyleCoordConvertible for Length { } } -impl GeckoStyleCoordConvertible for LengthPercentageOrAuto { +impl<LengthPercentage> GeckoStyleCoordConvertible for LengthPercentageOrAuto<LengthPercentage> +where + LengthPercentage: GeckoStyleCoordConvertible, +{ fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { match *self { LengthPercentageOrAuto::Auto => coord.set_value(CoordDataValue::Auto), @@ -200,23 +203,6 @@ impl GeckoStyleCoordConvertible for LengthPercentageOrAuto { } } -impl GeckoStyleCoordConvertible for LengthPercentageOrNone { - fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { - match *self { - LengthPercentageOrNone::None => coord.set_value(CoordDataValue::None), - LengthPercentageOrNone::LengthPercentage(ref lp) => lp.to_gecko_style_coord(coord), - } - } - - fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - match coord.as_value() { - CoordDataValue::None => Some(LengthPercentageOrNone::None), - _ => LengthPercentage::from_gecko_style_coord(coord) - .map(LengthPercentageOrNone::LengthPercentage), - } - } -} - impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth<L> { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { match *self { @@ -367,34 +353,40 @@ impl GeckoStyleCoordConvertible for ExtremumLength { impl GeckoStyleCoordConvertible for ComputedMozLength { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { match *self { - MozLength::LengthPercentageOrAuto(ref lpoa) => lpoa.to_gecko_style_coord(coord), + MozLength::LengthPercentage(ref lpoa) => lpoa.to_gecko_style_coord(coord), + MozLength::Auto => coord.set_value(CoordDataValue::Auto), MozLength::ExtremumLength(ref e) => e.to_gecko_style_coord(coord), } } fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { - LengthPercentageOrAuto::from_gecko_style_coord(coord) - .map(MozLength::LengthPercentageOrAuto) - .or_else(|| { - ExtremumLength::from_gecko_style_coord(coord).map(MozLength::ExtremumLength) - }) + if let CoordDataValue::Auto = coord.as_value() { + return Some(MozLength::Auto); + } + if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) { + return Some(MozLength::LengthPercentage(lp)); + } + ExtremumLength::from_gecko_style_coord(coord).map(MozLength::ExtremumLength) } } impl GeckoStyleCoordConvertible for ComputedMaxLength { fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { match *self { - MaxLength::LengthPercentageOrNone(ref lpon) => lpon.to_gecko_style_coord(coord), + MaxLength::LengthPercentage(ref lpon) => lpon.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<T: CoordData>(coord: &T) -> Option<Self> { - LengthPercentageOrNone::from_gecko_style_coord(coord) - .map(MaxLength::LengthPercentageOrNone) - .or_else(|| { - ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength) - }) + if let CoordDataValue::None = coord.as_value() { + return Some(MaxLength::None); + } + if let Some(lp) = NonNegativeLengthPercentage::from_gecko_style_coord(coord) { + return Some(MaxLength::LengthPercentage(lp)); + } + ExtremumLength::from_gecko_style_coord(coord).map(MaxLength::ExtremumLength) } } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 798e39adb27..297357446a2 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1390,7 +1390,6 @@ impl Clone for ${style_struct.gecko_struct_name} { "LengthOrNormal": impl_style_coord, "LengthPercentage": impl_simple, "LengthPercentageOrAuto": impl_style_coord, - "LengthPercentageOrNone": impl_style_coord, "MaxLength": impl_style_coord, "MozLength": impl_style_coord, "MozScriptMinSize": impl_absolute_length, @@ -3831,11 +3830,11 @@ fn static_assert() { BackgroundSize::Explicit { width: explicit_width, height: explicit_height } => { let mut w_type = nsStyleImageLayers_Size_DimensionType::eAuto; let mut h_type = nsStyleImageLayers_Size_DimensionType::eAuto; - if let Some(w) = explicit_width.0.to_calc_value() { + if let Some(w) = explicit_width.to_calc_value() { width = w; w_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; } - if let Some(h) = explicit_height.0.to_calc_value() { + if let Some(h) = explicit_height.to_calc_value() { height = h; h_type = nsStyleImageLayers_Size_DimensionType::eLengthPercentage; } diff --git a/components/style/properties/longhands/position.mako.rs b/components/style/properties/longhands/position.mako.rs index cc5515dbac7..2a0f86d056a 100644 --- a/components/style/properties/longhands/position.mako.rs +++ b/components/style/properties/longhands/position.mako.rs @@ -13,7 +13,7 @@ ${helpers.predefined_type( side, "LengthPercentageOrAuto", - "computed::LengthPercentageOrAuto::Auto", + "computed::LengthPercentageOrAuto::auto()", spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side, flags="GETCS_NEEDS_LAYOUT_FLUSH", animation_value_type="ComputedValue", @@ -27,7 +27,7 @@ ${helpers.predefined_type( "inset-%s" % side, "LengthPercentageOrAuto", - "computed::LengthPercentageOrAuto::Auto", + "computed::LengthPercentageOrAuto::auto()", spec="https://drafts.csswg.org/css-logical-props/#propdef-inset-%s" % side, flags="GETCS_NEEDS_LAYOUT_FLUSH", alias="offset-%s:layout.css.offset-logical-properties.enabled" % side, @@ -270,24 +270,12 @@ ${helpers.predefined_type( animation_value_type="MozLength", servo_restyle_damage="reflow", )} - ${helpers.predefined_type( - "max-%s" % size, - "MaxLength", - "computed::MaxLength::none()", - logical=logical, - logical_group="max-size", - allow_quirks=not logical, - spec=spec % size, - animation_value_type="MaxLength", - servo_restyle_damage="reflow", - )} % else: // servo versions (no keyword support) ${helpers.predefined_type( size, - "LengthPercentageOrAuto", - "computed::LengthPercentageOrAuto::Auto", - "parse_non_negative", + "NonNegativeLengthPercentageOrAuto", + "computed::NonNegativeLengthPercentageOrAuto::auto()", spec=spec % size, logical_group="size", allow_quirks=not logical, @@ -296,9 +284,8 @@ ${helpers.predefined_type( )} ${helpers.predefined_type( "min-%s" % size, - "LengthPercentage", - "computed::LengthPercentage::zero()", - "parse_non_negative", + "NonNegativeLengthPercentage", + "computed::NonNegativeLengthPercentage::zero()", spec=spec % ("min-%s" % size), logical_group="min-size", animation_value_type="ComputedValue", @@ -306,19 +293,18 @@ ${helpers.predefined_type( allow_quirks=not logical, servo_restyle_damage="reflow", )} - ${helpers.predefined_type( - "max-%s" % size, - "LengthPercentageOrNone", - "computed::LengthPercentageOrNone::None", - "parse_non_negative", - spec=spec % ("max-%s" % size), - logical_group="max-size", - animation_value_type="ComputedValue", - logical=logical, - allow_quirks=not logical, - servo_restyle_damage="reflow", - )} % endif + ${helpers.predefined_type( + "max-%s" % size, + "MaxLength", + "computed::MaxLength::none()", + logical=logical, + logical_group="max-size", + allow_quirks=not logical, + spec=spec % size, + animation_value_type="MaxLength", + servo_restyle_damage="reflow", + )} % endfor ${helpers.single_keyword( diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 0e7364d445c..62d27922ccb 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -3016,7 +3016,7 @@ impl ComputedValuesInner { /// Get the logical computed inline size. #[inline] - pub fn content_inline_size(&self) -> computed::LengthPercentageOrAuto { + pub fn content_inline_size(&self) -> computed::NonNegativeLengthPercentageOrAuto { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.height @@ -3027,35 +3027,35 @@ impl ComputedValuesInner { /// Get the logical computed block size. #[inline] - pub fn content_block_size(&self) -> computed::LengthPercentageOrAuto { + pub fn content_block_size(&self) -> computed::NonNegativeLengthPercentageOrAuto { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.width } else { position_style.height } } /// Get the logical computed min inline size. #[inline] - pub fn min_inline_size(&self) -> computed::LengthPercentage { + pub fn min_inline_size(&self) -> computed::NonNegativeLengthPercentage { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.min_height } else { position_style.min_width } } /// Get the logical computed min block size. #[inline] - pub fn min_block_size(&self) -> computed::LengthPercentage { + pub fn min_block_size(&self) -> computed::NonNegativeLengthPercentage { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.min_width } else { position_style.min_height } } /// Get the logical computed max inline size. #[inline] - pub fn max_inline_size(&self) -> computed::LengthPercentageOrNone { + pub fn max_inline_size(&self) -> computed::MaxLength { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.max_height } else { position_style.max_width } } /// Get the logical computed max block size. #[inline] - pub fn max_block_size(&self) -> computed::LengthPercentageOrNone { + pub fn max_block_size(&self) -> computed::MaxLength { let position_style = self.get_position(); if self.writing_mode.is_vertical() { position_style.max_width } else { position_style.max_height } } diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs index 862399e065c..8325216519d 100644 --- a/components/style/stylesheets/viewport_rule.rs +++ b/components/style/stylesheets/viewport_rule.rs @@ -11,16 +11,17 @@ use crate::context::QuirksMode; use crate::error_reporting::ContextualParseError; use crate::font_metrics::get_metrics_provider_for_product; use crate::media_queries::Device; -use crate::parser::ParserContext; +use crate::parser::{Parse, ParserContext}; use crate::properties::StyleBuilder; use crate::rule_cache::RuleCacheConditions; use crate::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard}; use crate::str::CssStringWriter; use crate::stylesheets::{Origin, StylesheetInDocument}; use crate::values::computed::{Context, ToComputedValue}; -use crate::values::specified::{ - self, LengthPercentageOrAuto, NoCalcLength, ViewportPercentageLength, -}; +use crate::values::generics::length::LengthPercentageOrAuto; +use crate::values::generics::NonNegative; +use crate::values::specified::{self, NoCalcLength}; +use crate::values::specified::{NonNegativeLengthPercentageOrAuto, ViewportPercentageLength}; use app_units::Au; use cssparser::CowRcStr; use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; @@ -151,7 +152,7 @@ trait FromMeta: Sized { #[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[derive(Clone, Debug, PartialEq, ToCss)] pub enum ViewportLength { - Specified(LengthPercentageOrAuto), + Specified(NonNegativeLengthPercentageOrAuto), ExtendToZoom, } @@ -159,9 +160,9 @@ impl FromMeta for ViewportLength { fn from_meta(value: &str) -> Option<ViewportLength> { macro_rules! specified { ($value:expr) => { - ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage( + ViewportLength::Specified(LengthPercentageOrAuto::LengthPercentage(NonNegative( specified::LengthPercentage::Length($value), - )) + ))) }; } @@ -188,7 +189,7 @@ impl ViewportLength { ) -> Result<Self, ParseError<'i>> { // we explicitly do not accept 'extend-to-zoom', since it is a UA // internal value for <META> viewport translation - LengthPercentageOrAuto::parse_non_negative(context, input).map(ViewportLength::Specified) + NonNegativeLengthPercentageOrAuto::parse(context, input).map(ViewportLength::Specified) } } diff --git a/components/style/values/animated/length.rs b/components/style/values/animated/length.rs index dd678f5c395..73957618cea 100644 --- a/components/style/values/animated/length.rs +++ b/components/style/values/animated/length.rs @@ -4,10 +4,8 @@ //! Animation implementation for various length-related types. -use super::{Animate, Procedure, ToAnimatedValue}; +use super::{Animate, Procedure}; use crate::values::computed::length::LengthPercentage; -use crate::values::computed::MaxLength as ComputedMaxLength; -use crate::values::computed::MozLength as ComputedMozLength; use crate::values::computed::Percentage; /// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc> @@ -38,51 +36,3 @@ impl Animate for LengthPercentage { )) } } - -// FIXME(emilio): These should use NonNegative<> instead. -impl ToAnimatedValue for ComputedMaxLength { - type AnimatedValue = Self; - - #[inline] - fn to_animated_value(self) -> Self { - self - } - - #[inline] - fn from_animated_value(animated: Self::AnimatedValue) -> Self { - use crate::values::computed::LengthPercentageOrNone; - use crate::values::generics::length::MaxLength as GenericMaxLength; - match animated { - GenericMaxLength::LengthPercentageOrNone(lpn) => { - let result = match lpn { - LengthPercentageOrNone::LengthPercentage(len) => { - LengthPercentageOrNone::LengthPercentage(len.clamp_to_non_negative()) - }, - LengthPercentageOrNone::None => lpn, - }; - GenericMaxLength::LengthPercentageOrNone(result) - }, - _ => animated, - } - } -} - -impl ToAnimatedValue for ComputedMozLength { - type AnimatedValue = Self; - - #[inline] - fn to_animated_value(self) -> Self { - self - } - - #[inline] - fn from_animated_value(animated: Self::AnimatedValue) -> Self { - use crate::values::generics::length::MozLength as GenericMozLength; - match animated { - GenericMozLength::LengthPercentageOrAuto(lpa) => { - GenericMozLength::LengthPercentageOrAuto(lpa.clamp_to_non_negative()) - }, - _ => animated, - } - } -} diff --git a/components/style/values/computed/background.rs b/components/style/values/computed/background.rs index 08f10c9c1ec..dc23915a74b 100644 --- a/components/style/values/computed/background.rs +++ b/components/style/values/computed/background.rs @@ -4,20 +4,21 @@ //! Computed types for CSS values related to backgrounds. -use crate::values::computed::length::NonNegativeLengthPercentageOrAuto; +use crate::values::computed::length::NonNegativeLengthPercentage; use crate::values::generics::background::BackgroundSize as GenericBackgroundSize; +use crate::values::generics::length::LengthPercentageOrAuto; pub use crate::values::specified::background::BackgroundRepeat; /// A computed value for the `background-size` property. -pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentageOrAuto>; +pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>; impl BackgroundSize { /// Returns `auto auto`. pub fn auto() -> Self { GenericBackgroundSize::Explicit { - width: NonNegativeLengthPercentageOrAuto::auto(), - height: NonNegativeLengthPercentageOrAuto::auto(), + width: LengthPercentageOrAuto::auto(), + height: LengthPercentageOrAuto::auto(), } } } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index c779594202b..313b4151d2b 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -7,13 +7,15 @@ use super::{Context, Number, Percentage, ToComputedValue}; use crate::values::animated::ToAnimatedValue; use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; -use crate::values::generics::length::MaxLength as GenericMaxLength; -use crate::values::generics::length::MozLength as GenericMozLength; +use crate::values::generics::length as generics; +use crate::values::generics::length::{ + MaxLength as GenericMaxLength, MozLength as GenericMozLength, +}; use crate::values::generics::transform::IsZeroLength; use crate::values::generics::NonNegative; use crate::values::specified::length::ViewportPercentageLength; use crate::values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; -use crate::values::{specified, Auto, CSSFloat, Either, IsAuto, Normal}; +use crate::values::{specified, Auto, CSSFloat, Either, Normal}; use app_units::Au; use ordered_float::NotNan; use std::fmt::{self, Write}; @@ -452,151 +454,61 @@ impl IsZeroLength for LengthPercentage { } } -#[allow(missing_docs)] -#[css(derive_debug)] -#[derive( - Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss, -)] -#[repr(C, u8)] -pub enum LengthPercentageOrAuto { - LengthPercentage(LengthPercentage), - Auto, -} - -impl LengthPercentageOrAuto { - /// Returns the `0` value. - #[inline] - pub fn zero() -> Self { - LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero()) - } -} - -/// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. -pub type NonNegativeLengthPercentageOrAuto = NonNegative<LengthPercentageOrAuto>; +/// Some boilerplate to share between negative and non-negative +/// length-percentage or auto. +macro_rules! computed_length_percentage_or_auto { + ($inner:ty) => { + /// Returns the `0` value. + #[inline] + pub fn zero() -> Self { + generics::LengthPercentageOrAuto::LengthPercentage(<$inner>::zero()) + } -impl IsAuto for NonNegativeLengthPercentageOrAuto { - #[inline] - fn is_auto(&self) -> bool { - *self == Self::auto() - } -} + /// Returns the used value. + #[inline] + pub fn to_used_value(&self, percentage_basis: Au) -> Option<Au> { + match *self { + generics::GenericLengthPercentageOrAuto::Auto => None, + generics::GenericLengthPercentageOrAuto::LengthPercentage(ref lp) => { + Some(lp.to_used_value(percentage_basis)) + } + } + } -impl NonNegativeLengthPercentageOrAuto { - /// `auto` - #[inline] - pub fn auto() -> Self { - NonNegative(LengthPercentageOrAuto::Auto) + /// Returns true if the computed value is absolute 0 or 0%. + #[inline] + pub fn is_definitely_zero(&self) -> bool { + use values::generics::length::LengthPercentageOrAuto::*; + match *self { + LengthPercentage(ref l) => l.is_definitely_zero(), + Auto => false, + } + } } } -impl ToAnimatedValue for NonNegativeLengthPercentageOrAuto { - type AnimatedValue = LengthPercentageOrAuto; - - #[inline] - fn to_animated_value(self) -> Self::AnimatedValue { - self.0 - } - - #[inline] - fn from_animated_value(animated: Self::AnimatedValue) -> Self { - NonNegative(animated.clamp_to_non_negative()) - } -} +/// A computed type for `<length-percentage> | auto`. +pub type LengthPercentageOrAuto = generics::GenericLengthPercentageOrAuto<LengthPercentage>; impl LengthPercentageOrAuto { - /// Returns true if the computed value is absolute 0 or 0%. - #[inline] - pub fn is_definitely_zero(&self) -> bool { - use self::LengthPercentageOrAuto::*; - match *self { - LengthPercentage(ref l) => l.is_definitely_zero(), - Auto => false, - } - } - /// Clamps the value to a non-negative value. pub fn clamp_to_non_negative(self) -> Self { - use self::LengthPercentageOrAuto::*; + use values::generics::length::LengthPercentageOrAuto::*; match self { LengthPercentage(l) => LengthPercentage(l.clamp_to_non_negative()), Auto => Auto, } } -} - -impl ToComputedValue for specified::LengthPercentageOrAuto { - type ComputedValue = LengthPercentageOrAuto; - - #[inline] - fn to_computed_value(&self, context: &Context) -> LengthPercentageOrAuto { - match *self { - specified::LengthPercentageOrAuto::LengthPercentage(ref value) => { - LengthPercentageOrAuto::LengthPercentage(value.to_computed_value(context)) - }, - specified::LengthPercentageOrAuto::Auto => LengthPercentageOrAuto::Auto, - } - } - - #[inline] - fn from_computed_value(computed: &LengthPercentageOrAuto) -> Self { - match *computed { - LengthPercentageOrAuto::Auto => specified::LengthPercentageOrAuto::Auto, - LengthPercentageOrAuto::LengthPercentage(ref value) => { - specified::LengthPercentageOrAuto::LengthPercentage( - ToComputedValue::from_computed_value(value), - ) - }, - } - } -} -#[allow(missing_docs)] -#[css(derive_debug)] -#[derive( - Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss, -)] -pub enum LengthPercentageOrNone { - LengthPercentage(LengthPercentage), - None, -} - -impl LengthPercentageOrNone { - /// Returns the used value. - pub fn to_used_value(&self, containing_length: Au) -> Option<Au> { - match *self { - LengthPercentageOrNone::None => None, - LengthPercentageOrNone::LengthPercentage(ref lp) => { - Some(lp.to_used_value(containing_length)) - }, - } - } + computed_length_percentage_or_auto!(LengthPercentage); } -// FIXME(emilio): Derive this. -impl ToComputedValue for specified::LengthPercentageOrNone { - type ComputedValue = LengthPercentageOrNone; - - #[inline] - fn to_computed_value(&self, context: &Context) -> LengthPercentageOrNone { - match *self { - specified::LengthPercentageOrNone::LengthPercentage(ref value) => { - LengthPercentageOrNone::LengthPercentage(value.to_computed_value(context)) - }, - specified::LengthPercentageOrNone::None => LengthPercentageOrNone::None, - } - } +/// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. +pub type NonNegativeLengthPercentageOrAuto = + generics::LengthPercentageOrAuto<NonNegativeLengthPercentage>; - #[inline] - fn from_computed_value(computed: &LengthPercentageOrNone) -> Self { - match *computed { - LengthPercentageOrNone::None => specified::LengthPercentageOrNone::None, - LengthPercentageOrNone::LengthPercentage(value) => { - specified::LengthPercentageOrNone::LengthPercentage( - ToComputedValue::from_computed_value(&value), - ) - }, - } - } +impl NonNegativeLengthPercentageOrAuto { + computed_length_percentage_or_auto!(NonNegativeLengthPercentage); } /// A wrapper of LengthPercentage, whose value must be >= 0. @@ -630,13 +542,6 @@ impl From<LengthPercentage> for NonNegativeLengthPercentage { } } -impl From<NonNegativeLengthPercentage> for LengthPercentage { - #[inline] - fn from(lp: NonNegativeLengthPercentage) -> LengthPercentage { - lp.0 - } -} - // TODO(emilio): This is a really generic impl which is only needed to implement // Animated and co for Spacing<>. Get rid of this, probably? impl From<Au> for LengthPercentage { @@ -650,7 +555,7 @@ impl NonNegativeLengthPercentage { /// Get zero value. #[inline] pub fn zero() -> Self { - NonNegative::<LengthPercentage>(LengthPercentage::zero()) + NonNegative(LengthPercentage::zero()) } /// Returns true if the computed value is absolute 0 or 0%. @@ -662,7 +567,26 @@ impl NonNegativeLengthPercentage { /// Returns the used value. #[inline] pub fn to_used_value(&self, containing_length: Au) -> Au { - self.0.to_used_value(containing_length) + let resolved = self.0.to_used_value(containing_length); + ::std::cmp::max(resolved, Au(0)) + } + + /// Convert the computed value into used value. + #[inline] + pub fn maybe_to_used_value(&self, containing_length: Option<Au>) -> Option<Au> { + let resolved = self.0.maybe_to_used_value(containing_length)?; + Some(::std::cmp::max(resolved, Au(0))) + } +} + +#[cfg(feature = "servo")] +impl MaxLength { + /// Convert the computed value into used value. + pub fn to_used_value(&self, percentage_basis: Au) -> Option<Au> { + match *self { + GenericMaxLength::None => None, + GenericMaxLength::LengthPercentage(ref lp) => Some(lp.to_used_value(percentage_basis)), + } } } @@ -881,6 +805,8 @@ pub type NonNegativeLengthPercentageOrNormal = Either<NonNegativeLengthPercentag Parse, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, + ToAnimatedZero, ToComputedValue, ToCss, )] @@ -895,23 +821,7 @@ pub enum ExtremumLength { } /// A computed value for `min-width`, `min-height`, `width` or `height` property. -pub type MozLength = GenericMozLength<LengthPercentageOrAuto>; - -impl MozLength { - /// Returns the `auto` value. - #[inline] - pub fn auto() -> Self { - GenericMozLength::LengthPercentageOrAuto(LengthPercentageOrAuto::Auto) - } -} +pub type MozLength = GenericMozLength<NonNegativeLengthPercentage>; /// A computed value for `max-width` or `min-height` property. -pub type MaxLength = GenericMaxLength<LengthPercentageOrNone>; - -impl MaxLength { - /// Returns the `none` value. - #[inline] - pub fn none() -> Self { - GenericMaxLength::LengthPercentageOrNone(LengthPercentageOrNone::None) - } -} +pub type MaxLength = GenericMaxLength<NonNegativeLengthPercentage>; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 02ccf01e25e..ab8edd2b746 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -62,7 +62,7 @@ pub use self::gecko::ScrollSnapPoint; pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect}; pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength}; pub use self::length::{Length, LengthOrNumber, LengthPercentage}; -pub use self::length::{LengthPercentageOrAuto, LengthPercentageOrNone, MaxLength, MozLength}; +pub use self::length::{LengthPercentageOrAuto, MaxLength, MozLength}; pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto}; #[cfg(feature = "gecko")] pub use self::list::ListStyleType; diff --git a/components/style/values/generics/background.rs b/components/style/values/generics/background.rs index 4a7ee4b9b95..d739329e4fc 100644 --- a/components/style/values/generics/background.rs +++ b/components/style/values/generics/background.rs @@ -4,7 +4,7 @@ //! Generic types for CSS values related to backgrounds. -use crate::values::IsAuto; +use crate::values::generics::length::LengthPercentageOrAuto; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; @@ -22,13 +22,13 @@ use style_traits::{CssWriter, ToCss}; ToAnimatedZero, ToComputedValue, )] -pub enum BackgroundSize<LengthPercentageOrAuto> { +pub enum BackgroundSize<LengthPercentage> { /// `<width> <height>` Explicit { /// Explicit width. - width: LengthPercentageOrAuto, + width: LengthPercentageOrAuto<LengthPercentage>, /// Explicit height. - height: LengthPercentageOrAuto, + height: LengthPercentageOrAuto<LengthPercentage>, }, /// `cover` #[animation(error)] @@ -38,9 +38,9 @@ pub enum BackgroundSize<LengthPercentageOrAuto> { Contain, } -impl<LengthPercentageOrAuto> ToCss for BackgroundSize<LengthPercentageOrAuto> +impl<LengthPercentage> ToCss for BackgroundSize<LengthPercentage> where - LengthPercentageOrAuto: ToCss + IsAuto, + LengthPercentage: ToCss, { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where diff --git a/components/style/values/generics/length.rs b/components/style/values/generics/length.rs index 006739462aa..61be27e4fd2 100644 --- a/components/style/values/generics/length.rs +++ b/components/style/values/generics/length.rs @@ -4,7 +4,75 @@ //! Generic types for CSS values related to length. +use crate::parser::{Parse, ParserContext}; use crate::values::computed::ExtremumLength; +use cssparser::Parser; +use style_traits::ParseError; + +/// A `<length-percentage> | auto` value. +#[allow(missing_docs)] +#[derive( + Animate, + Clone, + ComputeSquaredDistance, + Copy, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToAnimatedZero, + ToComputedValue, + ToCss, +)] +#[repr(C, u8)] +pub enum GenericLengthPercentageOrAuto<LengthPercent> { + LengthPercentage(LengthPercent), + Auto, +} + +pub use self::GenericLengthPercentageOrAuto as LengthPercentageOrAuto; + +impl<LengthPercentage> LengthPercentageOrAuto<LengthPercentage> { + /// `auto` value. + #[inline] + pub fn auto() -> Self { + LengthPercentageOrAuto::Auto + } + + /// Whether this is the `auto` value. + #[inline] + pub fn is_auto(&self) -> bool { + matches!(*self, LengthPercentageOrAuto::Auto) + } + + /// A helper function to parse this with quirks or not and so forth. + pub fn parse_with<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + parser: impl FnOnce( + &ParserContext, + &mut Parser<'i, 't>, + ) -> Result<LengthPercentage, ParseError<'i>>, + ) -> Result<Self, ParseError<'i>> { + if input.try(|i| i.expect_ident_matching("auto")).is_ok() { + return Ok(LengthPercentageOrAuto::Auto); + } + + Ok(LengthPercentageOrAuto::LengthPercentage(parser( + context, input, + )?)) + } +} + +impl<LengthPercentage: Parse> Parse for LengthPercentageOrAuto<LengthPercentage> { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + Self::parse_with(context, input, LengthPercentage::parse) + } +} /// A generic value for the `width`, `height`, `min-width`, or `min-height` property. /// @@ -13,25 +81,35 @@ use crate::values::computed::ExtremumLength; /// /// Note that it only accepts non-negative values. #[allow(missing_docs)] -#[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[derive( Animate, Clone, ComputeSquaredDistance, Copy, Debug, + MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss, )] -pub enum MozLength<LengthPercentageOrAuto> { - LengthPercentageOrAuto(LengthPercentageOrAuto), +pub enum MozLength<LengthPercentage> { + LengthPercentage(LengthPercentage), + Auto, #[animation(error)] ExtremumLength(ExtremumLength), } +impl<LengthPercentage> MozLength<LengthPercentage> { + /// `auto` value. + #[inline] + pub fn auto() -> Self { + MozLength::Auto + } +} + /// A generic value for the `max-width` or `max-height` property. #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(MallocSizeOf))] @@ -43,12 +121,23 @@ pub enum MozLength<LengthPercentageOrAuto> { Debug, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss, )] -pub enum MaxLength<LengthPercentageOrNone> { - LengthPercentageOrNone(LengthPercentageOrNone), +pub enum MaxLength<LengthPercentage> { + LengthPercentage(LengthPercentage), + None, + #[cfg(feature = "gecko")] #[animation(error)] ExtremumLength(ExtremumLength), } + +impl<LengthPercentage> MaxLength<LengthPercentage> { + /// `none` value. + #[inline] + pub fn none() -> Self { + MaxLength::None + } +} diff --git a/components/style/values/specified/background.rs b/components/style/values/specified/background.rs index 47c66feaef6..b53669abfa8 100644 --- a/components/style/values/specified/background.rs +++ b/components/style/values/specified/background.rs @@ -6,14 +6,16 @@ use crate::parser::{Parse, ParserContext}; use crate::values::generics::background::BackgroundSize as GenericBackgroundSize; -use crate::values::specified::length::NonNegativeLengthPercentageOrAuto; +use crate::values::specified::length::{ + NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto, +}; use cssparser::Parser; use selectors::parser::SelectorParseErrorKind; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, ToCss}; /// A specified value for the `background-size` property. -pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentageOrAuto>; +pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>; impl Parse for BackgroundSize { fn parse<'i, 't>( diff --git a/components/style/values/specified/gecko.rs b/components/style/values/specified/gecko.rs index 8259430bf20..42ca5e3e2bf 100644 --- a/components/style/values/specified/gecko.rs +++ b/components/style/values/specified/gecko.rs @@ -5,8 +5,8 @@ //! Specified types for legacy Gecko-only properties. use crate::parser::{Parse, ParserContext}; -use crate::values::computed::{self, LengthPercentage}; use crate::values::computed::length::CSSPixelLength; +use crate::values::computed::{self, LengthPercentage}; use crate::values::generics::gecko::ScrollSnapPoint as GenericScrollSnapPoint; use crate::values::generics::rect::Rect; use crate::values::specified::length::LengthPercentage as SpecifiedLengthPercentage; @@ -28,8 +28,8 @@ impl Parse for ScrollSnapPoint { } input.expect_function_matching("repeat")?; // FIXME(emilio): This won't clamp properly when animating. - let length = - input.parse_nested_block(|i| SpecifiedLengthPercentage::parse_non_negative(context, i))?; + let length = input + .parse_nested_block(|i| SpecifiedLengthPercentage::parse_non_negative(context, i))?; Ok(GenericScrollSnapPoint::Repeat(length)) } } @@ -49,9 +49,9 @@ fn parse_pixel_or_percent<'i, 't>( _ => Err(()), } }, - Token::Percentage { unit_value, .. } => Ok( - LengthPercentage::new_percent(computed::Percentage(unit_value)) - ), + Token::Percentage { unit_value, .. } => Ok(LengthPercentage::new_percent( + computed::Percentage(unit_value), + )), _ => Err(()), }; value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index e83abebc37c..9da17990078 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -10,12 +10,14 @@ use super::{AllowQuirks, Number, Percentage, ToComputedValue}; use crate::font_metrics::FontMetricsQueryResult; use crate::parser::{Parse, ParserContext}; use crate::values::computed::{self, CSSPixelLength, Context, ExtremumLength}; -use crate::values::generics::length::MaxLength as GenericMaxLength; -use crate::values::generics::length::MozLength as GenericMozLength; +use crate::values::generics::length as generics; +use crate::values::generics::length::{ + MaxLength as GenericMaxLength, MozLength as GenericMozLength, +}; use crate::values::generics::transform::IsZeroLength; use crate::values::generics::NonNegative; use crate::values::specified::calc::CalcNode; -use crate::values::{Auto, CSSFloat, Either, IsAuto, Normal}; +use crate::values::{Auto, CSSFloat, Either, Normal}; use app_units::Au; use cssparser::{Parser, Token}; use euclid::Size2D; @@ -785,6 +787,16 @@ impl From<computed::Percentage> for LengthPercentage { } } +impl Parse for LengthPercentage { + #[inline] + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Self, ParseError<'i>> { + Self::parse_quirky(context, input, AllowQuirks::No) + } +} + impl LengthPercentage { #[inline] /// Returns a `zero` length. @@ -844,12 +856,26 @@ impl LengthPercentage { Ok(LengthPercentage::Calc(Box::new(calc))) } + /// Parses allowing the unitless length quirk. + /// <https://quirks.spec.whatwg.org/#the-unitless-length-quirk> + #[inline] + pub fn parse_quirky<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + allow_quirks: AllowQuirks, + ) -> Result<Self, ParseError<'i>> { + Self::parse_internal(context, input, AllowedNumericType::All, allow_quirks) + } + /// Parse a non-negative length. + /// + /// FIXME(emilio): This should be not public and we should use + /// NonNegativeLengthPercentage instead. #[inline] pub fn parse_non_negative<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, - ) -> Result<LengthPercentage, ParseError<'i>> { + ) -> Result<Self, ParseError<'i>> { Self::parse_non_negative_quirky(context, input, AllowQuirks::No) } @@ -859,7 +885,7 @@ impl LengthPercentage { context: &ParserContext, input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, - ) -> Result<LengthPercentage, ParseError<'i>> { + ) -> Result<Self, ParseError<'i>> { Self::parse_internal( context, input, @@ -869,29 +895,6 @@ impl LengthPercentage { } } -impl Parse for LengthPercentage { - #[inline] - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - Self::parse_quirky(context, input, AllowQuirks::No) - } -} - -impl LengthPercentage { - /// Parses a length or a percentage, allowing the unitless length quirk. - /// <https://quirks.spec.whatwg.org/#the-unitless-length-quirk> - #[inline] - pub fn parse_quirky<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - allow_quirks: AllowQuirks, - ) -> Result<Self, ParseError<'i>> { - Self::parse_internal(context, input, AllowedNumericType::All, allow_quirks) - } -} - impl IsZeroLength for LengthPercentage { #[inline] fn is_zero_length(&self) -> bool { @@ -903,189 +906,64 @@ impl IsZeroLength for LengthPercentage { } } -/// Either a `<length>`, a `<percentage>`, or the `auto` keyword. -#[allow(missing_docs)] -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] -pub enum LengthPercentageOrAuto { - LengthPercentage(LengthPercentage), - Auto, -} +/// A specified type for `<length-percentage> | auto`. +pub type LengthPercentageOrAuto = generics::LengthPercentageOrAuto<LengthPercentage>; impl LengthPercentageOrAuto { - fn parse_internal<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - num_context: AllowedNumericType, - allow_quirks: AllowQuirks, - ) -> Result<Self, ParseError<'i>> { - if input.try(|i| i.expect_ident_matching("auto")).is_ok() { - return Ok(LengthPercentageOrAuto::Auto); - } - - Ok(LengthPercentageOrAuto::LengthPercentage( - LengthPercentage::parse_internal(context, input, num_context, allow_quirks)?, - )) - } - - /// Parse a non-negative length, percentage, or auto. - #[inline] - pub fn parse_non_negative<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<LengthPercentageOrAuto, ParseError<'i>> { - Self::parse_non_negative_quirky(context, input, AllowQuirks::No) - } - - /// Parse a non-negative length, percentage, or auto. - #[inline] - pub fn parse_non_negative_quirky<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - allow_quirks: AllowQuirks, - ) -> Result<Self, ParseError<'i>> { - Self::parse_internal( - context, - input, - AllowedNumericType::NonNegative, - allow_quirks, - ) - } - - /// Returns the `auto` value. - pub fn auto() -> Self { - LengthPercentageOrAuto::Auto - } - /// Returns a value representing a `0` length. pub fn zero() -> Self { - LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero()) + generics::LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero()) } /// Returns a value representing `0%`. #[inline] pub fn zero_percent() -> Self { - LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero_percent()) + generics::LengthPercentageOrAuto::LengthPercentage(LengthPercentage::zero_percent()) } - /// Parses, with quirks. + /// Parses a length or a percentage, allowing the unitless length quirk. + /// <https://quirks.spec.whatwg.org/#the-unitless-length-quirk> #[inline] pub fn parse_quirky<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result<Self, ParseError<'i>> { - Self::parse_internal(context, input, AllowedNumericType::All, allow_quirks) - } -} - -impl Parse for LengthPercentageOrAuto { - #[inline] - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - Self::parse_quirky(context, input, AllowQuirks::No) + Self::parse_with(context, input, |context, input| { + LengthPercentage::parse_quirky(context, input, allow_quirks) + }) } } /// A wrapper of LengthPercentageOrAuto, whose value must be >= 0. -pub type NonNegativeLengthPercentageOrAuto = NonNegative<LengthPercentageOrAuto>; - -impl IsAuto for NonNegativeLengthPercentageOrAuto { - #[inline] - fn is_auto(&self) -> bool { - *self == Self::auto() - } -} +pub type NonNegativeLengthPercentageOrAuto = + generics::LengthPercentageOrAuto<NonNegativeLengthPercentage>; impl NonNegativeLengthPercentageOrAuto { - /// 0 - #[inline] + /// Returns a value representing a `0` length. pub fn zero() -> Self { - NonNegative(LengthPercentageOrAuto::zero()) + generics::LengthPercentageOrAuto::LengthPercentage(NonNegativeLengthPercentage::zero()) } - /// 0% + /// Returns a value representing `0%`. #[inline] pub fn zero_percent() -> Self { - NonNegative(LengthPercentageOrAuto::zero_percent()) - } - - /// `auto` - #[inline] - pub fn auto() -> Self { - NonNegative(LengthPercentageOrAuto::Auto) - } -} - -impl Parse for NonNegativeLengthPercentageOrAuto { - #[inline] - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - Ok(NonNegative(LengthPercentageOrAuto::parse_non_negative( - context, input, - )?)) - } -} - -/// Either a `<length>`, a `<percentage>`, or the `none` keyword. -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] -#[allow(missing_docs)] -pub enum LengthPercentageOrNone { - LengthPercentage(LengthPercentage), - None, -} - -impl LengthPercentageOrNone { - fn parse_internal<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - num_context: AllowedNumericType, - allow_quirks: AllowQuirks, - ) -> Result<Self, ParseError<'i>> { - if input.try(|i| i.expect_ident_matching("none")).is_ok() { - return Ok(LengthPercentageOrNone::None); - } - - Ok(LengthPercentageOrNone::LengthPercentage( - LengthPercentage::parse_internal(context, input, num_context, allow_quirks)?, - )) - } - - /// Parse a non-negative LengthPercentageOrNone. - #[inline] - pub fn parse_non_negative<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result<Self, ParseError<'i>> { - Self::parse_non_negative_quirky(context, input, AllowQuirks::No) - } - - /// Parse a non-negative LengthPercentageOrNone, with quirks. - #[inline] - pub fn parse_non_negative_quirky<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - allow_quirks: AllowQuirks, - ) -> Result<Self, ParseError<'i>> { - Self::parse_internal( - context, - input, - AllowedNumericType::NonNegative, - allow_quirks, + generics::LengthPercentageOrAuto::LengthPercentage( + NonNegativeLengthPercentage::zero_percent(), ) } -} -impl Parse for LengthPercentageOrNone { + /// Parses a non-negative length-percentage, allowing the unitless length + /// quirk. #[inline] - fn parse<'i, 't>( + pub fn parse_quirky<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, + allow_quirks: AllowQuirks, ) -> Result<Self, ParseError<'i>> { - Self::parse_internal(context, input, AllowedNumericType::All, AllowQuirks::No) + Self::parse_with(context, input, |context, input| { + NonNegativeLengthPercentage::parse_quirky(context, input, allow_quirks) + }) } } @@ -1101,7 +979,7 @@ pub type NonNegativeLengthPercentageOrNormal = Either<NonNegativeLengthPercentag impl From<NoCalcLength> for NonNegativeLengthPercentage { #[inline] fn from(len: NoCalcLength) -> Self { - NonNegative::<LengthPercentage>(LengthPercentage::from(len)) + NonNegative(LengthPercentage::from(len)) } } @@ -1111,7 +989,7 @@ impl Parse for NonNegativeLengthPercentage { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<Self, ParseError<'i>> { - LengthPercentage::parse_non_negative(context, input).map(NonNegative::<LengthPercentage>) + Self::parse_quirky(context, input, AllowQuirks::No) } } @@ -1119,7 +997,13 @@ impl NonNegativeLengthPercentage { #[inline] /// Returns a `zero` length. pub fn zero() -> Self { - NonNegative::<LengthPercentage>(LengthPercentage::zero()) + NonNegative(LengthPercentage::zero()) + } + + #[inline] + /// Returns a `0%` value. + pub fn zero_percent() -> Self { + NonNegative(LengthPercentage::zero_percent()) } /// Parses a length or a percentage, allowing the unitless length quirk. @@ -1130,8 +1014,7 @@ impl NonNegativeLengthPercentage { input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result<Self, ParseError<'i>> { - LengthPercentage::parse_non_negative_quirky(context, input, allow_quirks) - .map(NonNegative::<LengthPercentage>) + LengthPercentage::parse_non_negative_quirky(context, input, allow_quirks).map(NonNegative) } } @@ -1168,7 +1051,7 @@ impl LengthOrNumber { } /// A specified value for `min-width`, `min-height`, `width` or `height` property. -pub type MozLength = GenericMozLength<LengthPercentageOrAuto>; +pub type MozLength = GenericMozLength<NonNegativeLengthPercentage>; impl Parse for MozLength { fn parse<'i, 't>( @@ -1190,26 +1073,23 @@ impl MozLength { return Ok(GenericMozLength::ExtremumLength(l)); } - let length = - LengthPercentageOrAuto::parse_non_negative_quirky(context, input, allow_quirks)?; - Ok(GenericMozLength::LengthPercentageOrAuto(length)) - } + if input.try(|i| i.expect_ident_matching("auto")).is_ok() { + return Ok(GenericMozLength::Auto); + } - /// Returns `auto`. - #[inline] - pub fn auto() -> Self { - GenericMozLength::LengthPercentageOrAuto(LengthPercentageOrAuto::auto()) + let length = NonNegativeLengthPercentage::parse_quirky(context, input, allow_quirks)?; + Ok(GenericMozLength::LengthPercentage(length)) } /// Returns `0%`. #[inline] pub fn zero_percent() -> Self { - GenericMozLength::LengthPercentageOrAuto(LengthPercentageOrAuto::zero_percent()) + GenericMozLength::LengthPercentage(NonNegativeLengthPercentage::zero_percent()) } } /// A specified value for `max-width` or `max-height` property. -pub type MaxLength = GenericMaxLength<LengthPercentageOrNone>; +pub type MaxLength = GenericMaxLength<NonNegativeLengthPercentage>; impl Parse for MaxLength { fn parse<'i, 't>( @@ -1227,12 +1107,18 @@ impl MaxLength { input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result<Self, ParseError<'i>> { - if let Ok(l) = input.try(ExtremumLength::parse) { - return Ok(GenericMaxLength::ExtremumLength(l)); + #[cfg(feature = "gecko")] + { + if let Ok(l) = input.try(ExtremumLength::parse) { + return Ok(GenericMaxLength::ExtremumLength(l)); + } + } + + if input.try(|i| i.expect_ident_matching("none")).is_ok() { + return Ok(GenericMaxLength::None); } - let length = - LengthPercentageOrNone::parse_non_negative_quirky(context, input, allow_quirks)?; - Ok(GenericMaxLength::LengthPercentageOrNone(length)) + let length = NonNegativeLengthPercentage::parse_quirky(context, input, allow_quirks)?; + Ok(GenericMaxLength::LengthPercentage(length)) } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 2cb267045ac..b37d2554c34 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -59,7 +59,7 @@ pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRec pub use self::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth}; pub use self::length::{FontRelativeLength, Length, LengthOrNumber}; pub use self::length::{LengthPercentage, LengthPercentageOrAuto}; -pub use self::length::{LengthPercentageOrNone, MaxLength, MozLength}; +pub use self::length::{MaxLength, MozLength}; pub use self::length::{NoCalcLength, ViewportPercentageLength}; pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto}; #[cfg(feature = "gecko")] |