diff --git a/components/layout/block.rs b/components/layout/block.rs index 0b09b723a43..6a3db5a6141 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -322,7 +322,7 @@ impl CandidateBSizeIterator { let block_size = match (fragment.style.content_block_size(), block_container_block_size) { (LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => { - MaybeAuto::Specified(block_container_block_size.scale_by(percent)) + MaybeAuto::Specified(block_container_block_size.scale_by(percent.0)) } (LengthOrPercentageOrAuto::Calc(calc), _) => { MaybeAuto::from_option(calc.to_used_value(block_container_block_size)) @@ -333,7 +333,7 @@ impl CandidateBSizeIterator { }; let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) { (LengthOrPercentageOrNone::Percentage(percent), Some(block_container_block_size)) => { - Some(block_container_block_size.scale_by(percent)) + Some(block_container_block_size.scale_by(percent.0)) } (LengthOrPercentageOrNone::Calc(calc), _) => { calc.to_used_value(block_container_block_size) @@ -344,7 +344,7 @@ impl CandidateBSizeIterator { }; let min_block_size = match (fragment.style.min_block_size(), block_container_block_size) { (LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => { - block_container_block_size.scale_by(percent) + block_container_block_size.scale_by(percent.0) } (LengthOrPercentage::Calc(calc), _) => { calc.to_used_value(block_container_block_size).unwrap_or(Au(0)) @@ -1178,7 +1178,7 @@ impl BlockFlow { } (LengthOrPercentageOrAuto::Length(length), _) => Some(length), (LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => { - Some(container_size.scale_by(percent)) + Some(container_size.scale_by(percent.0)) } (LengthOrPercentageOrAuto::Percentage(_), None) | (LengthOrPercentageOrAuto::Auto, None) => { diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index d033139e054..1adce80ade2 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -65,6 +65,7 @@ use style::values::generics::image::{Circle, Ellipse, EndingShape as GenericEndi use style::values::generics::image::{GradientItem as GenericGradientItem, GradientKind}; use style::values::generics::image::{Image, ShapeExtent}; use style::values::generics::image::PaintWorklet; +use style::values::specified::length::Percentage; use style::values::specified::position::{X, Y}; use style_traits::CSSPixel; use style_traits::cursor::Cursor; @@ -653,14 +654,14 @@ fn convert_gradient_stops(gradient_items: &[GradientItem], { let first = stop_items.first_mut().unwrap(); if first.position.is_none() { - first.position = Some(LengthOrPercentage::Percentage(0.0)); + first.position = Some(LengthOrPercentage::Percentage(Percentage(0.0))); } } // If the last color stop does not have a position, set its position to 100%. { let last = stop_items.last_mut().unwrap(); if last.position.is_none() { - last.position = Some(LengthOrPercentage::Percentage(1.0)); + last.position = Some(LengthOrPercentage::Percentage(Percentage(1.0))); } } @@ -2871,7 +2872,7 @@ struct StopRun { fn position_to_offset(position: LengthOrPercentage, total_length: Au) -> f32 { match position { LengthOrPercentage::Length(Au(length)) => length as f32 / total_length.0 as f32, - LengthOrPercentage::Percentage(percentage) => percentage as f32, + LengthOrPercentage::Percentage(percentage) => percentage.0 as f32, LengthOrPercentage::Calc(calc) => { calc.to_used_value(Some(total_length)).unwrap().0 as f32 / total_length.0 as f32 }, diff --git a/components/layout/flex.rs b/components/layout/flex.rs index 0abd32b6dc0..e2bd1c0838d 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -46,7 +46,7 @@ impl AxisSize { LengthOrPercentageOrAuto::Length(length) => AxisSize::Definite(length), LengthOrPercentageOrAuto::Percentage(percent) => { match content_size { - Some(size) => AxisSize::Definite(size.scale_by(percent)), + Some(size) => AxisSize::Definite(size.scale_by(percent.0)), None => AxisSize::Infinite } } @@ -74,7 +74,7 @@ fn from_flex_basis(flex_basis: LengthOrPercentageOrAutoOrContent, (LengthOrPercentageOrAutoOrContent::Length(length), _) => MaybeAuto::Specified(length), (LengthOrPercentageOrAutoOrContent::Percentage(percent), Some(size)) => - MaybeAuto::Specified(size.scale_by(percent)), + MaybeAuto::Specified(size.scale_by(percent.0)), (LengthOrPercentageOrAutoOrContent::Percentage(_), None) => MaybeAuto::Auto, (LengthOrPercentageOrAutoOrContent::Calc(calc), _) => diff --git a/components/layout/floats.rs b/components/layout/floats.rs index aa3c02d1d3f..43d05e4bad4 100644 --- a/components/layout/floats.rs +++ b/components/layout/floats.rs @@ -505,7 +505,7 @@ impl SpeculatedFloatPlacement { // might flow around this float. if let LengthOrPercentageOrAuto::Percentage(percentage) = flow.as_block().fragment.style.content_inline_size() { - if percentage > 0.0 { + if percentage.0 > 0.0 { float_inline_size = Au::from_px(1) } } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 207ebc83e32..3eb403b98a9 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -2234,7 +2234,7 @@ impl Fragment { } vertical_align::T::LengthOrPercentage(LengthOrPercentage::Percentage( percentage)) => { - offset -= minimum_line_metrics.space_needed().scale_by(percentage) + offset -= minimum_line_metrics.space_needed().scale_by(percentage.0) } vertical_align::T::LengthOrPercentage(LengthOrPercentage::Calc(formula)) => { offset -= formula.to_used_value(Some(minimum_line_metrics.space_needed())).unwrap() diff --git a/components/layout/model.rs b/components/layout/model.rs index 40ac5849deb..7f564a599ab 100644 --- a/components/layout/model.rs +++ b/components/layout/model.rs @@ -144,7 +144,7 @@ impl MarginCollapseInfo { LengthOrPercentageOrAuto::Auto => true, LengthOrPercentageOrAuto::Length(Au(v)) => v == 0, LengthOrPercentageOrAuto::Percentage(v) => { - v == 0. || containing_block_size.is_none() + v.0 == 0. || containing_block_size.is_none() } LengthOrPercentageOrAuto::Calc(_) => false, }; @@ -154,7 +154,7 @@ impl MarginCollapseInfo { LengthOrPercentage::Length(Au(0)) => { FinalMarginState::MarginsCollapseThrough }, - LengthOrPercentage::Percentage(v) if v == 0. => { + LengthOrPercentage::Percentage(v) if v.0 == 0. => { FinalMarginState::MarginsCollapseThrough }, _ => { @@ -408,7 +408,7 @@ impl MaybeAuto { match length { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, LengthOrPercentageOrAuto::Percentage(percent) => { - MaybeAuto::Specified(containing_length.scale_by(percent)) + MaybeAuto::Specified(containing_length.scale_by(percent.0)) } LengthOrPercentageOrAuto::Calc(calc) => { MaybeAuto::from_option(calc.to_used_value(Some(containing_length))) diff --git a/components/layout/table.rs b/components/layout/table.rs index c3ba52a305b..d199b059a69 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -253,7 +253,7 @@ impl Flow for TableFlow { LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Calc(_) | LengthOrPercentageOrAuto::Length(_) => 0.0, - LengthOrPercentageOrAuto::Percentage(percentage) => percentage, + LengthOrPercentageOrAuto::Percentage(percentage) => percentage.0, }, preferred: Au(0), constrained: false, diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 2fb61a336de..45b47ee8de5 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -310,7 +310,7 @@ impl Flow for TableRowFlow { LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Calc(_) | LengthOrPercentageOrAuto::Length(_) => 0.0, - LengthOrPercentageOrAuto::Percentage(percentage) => percentage, + LengthOrPercentageOrAuto::Percentage(percentage) => percentage.0, }, preferred: child_base.intrinsic_inline_sizes.preferred_inline_size, constrained: match child_specified_inline_size { diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index 4266c61826a..ac87b180953 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -19,13 +19,14 @@ use stylesheets::{Origin, RulesMutateError}; use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use values::generics::image::{CompatMode, Image as GenericImage, GradientItem}; +use values::specified::length::Percentage; impl From for nsStyleCoord_CalcValue { fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue { let has_percentage = other.percentage.is_some(); nsStyleCoord_CalcValue { mLength: other.unclamped_length().0, - mPercent: other.percentage.unwrap_or(0.0), + mPercent: other.percentage.map_or(0., |p| p.0), mHasPercent: has_percentage, } } @@ -34,7 +35,7 @@ impl From for nsStyleCoord_CalcValue { impl From for CalcLengthOrPercentage { fn from(other: nsStyleCoord_CalcValue) -> CalcLengthOrPercentage { let percentage = if other.mHasPercent { - Some(other.mPercent) + Some(Percentage(other.mPercent)) } else { None }; @@ -55,7 +56,7 @@ impl From for nsStyleCoord_CalcValue { LengthOrPercentage::Percentage(pc) => { nsStyleCoord_CalcValue { mLength: 0, - mPercent: pc, + mPercent: pc.0, mHasPercent: true, } }, @@ -78,7 +79,7 @@ impl LengthOrPercentageOrAuto { LengthOrPercentageOrAuto::Percentage(pc) => { Some(nsStyleCoord_CalcValue { mLength: 0, - mPercent: pc, + mPercent: pc.0, mHasPercent: true, }) }, @@ -92,7 +93,7 @@ impl From for LengthOrPercentage { fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentage { match (other.mHasPercent, other.mLength) { (false, _) => LengthOrPercentage::Length(Au(other.mLength)), - (true, 0) => LengthOrPercentage::Percentage(other.mPercent), + (true, 0) => LengthOrPercentage::Percentage(Percentage(other.mPercent)), _ => LengthOrPercentage::Calc(other.into()), } } diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index aacf5373077..cd774901897 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -105,7 +105,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentage { fn to_gecko_style_coord(&self, coord: &mut T) { let value = match *self { LengthOrPercentage::Length(au) => CoordDataValue::Coord(au.0), - LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p), + LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p.0), LengthOrPercentage::Calc(calc) => CoordDataValue::Calc(calc.into()), }; coord.set_value(value); @@ -114,7 +114,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentage { fn from_gecko_style_coord(coord: &T) -> Option { match coord.as_value() { CoordDataValue::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord))), - CoordDataValue::Percent(p) => Some(LengthOrPercentage::Percentage(p)), + CoordDataValue::Percent(p) => Some(LengthOrPercentage::Percentage(Percentage(p))), CoordDataValue::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())), _ => None, } @@ -138,7 +138,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto { fn to_gecko_style_coord(&self, coord: &mut T) { let value = match *self { LengthOrPercentageOrAuto::Length(au) => CoordDataValue::Coord(au.0), - LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p), + LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p.0), LengthOrPercentageOrAuto::Auto => CoordDataValue::Auto, LengthOrPercentageOrAuto::Calc(calc) => CoordDataValue::Calc(calc.into()), }; @@ -148,7 +148,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto { fn from_gecko_style_coord(coord: &T) -> Option { match coord.as_value() { CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrAuto::Length(Au(coord))), - CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(p)), + CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(Percentage(p))), CoordDataValue::Auto => Some(LengthOrPercentageOrAuto::Auto), CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())), _ => None, @@ -160,7 +160,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone { fn to_gecko_style_coord(&self, coord: &mut T) { let value = match *self { LengthOrPercentageOrNone::Length(au) => CoordDataValue::Coord(au.0), - LengthOrPercentageOrNone::Percentage(p) => CoordDataValue::Percent(p), + LengthOrPercentageOrNone::Percentage(p) => CoordDataValue::Percent(p.0), LengthOrPercentageOrNone::None => CoordDataValue::None, LengthOrPercentageOrNone::Calc(calc) => CoordDataValue::Calc(calc.into()), }; @@ -170,7 +170,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone { fn from_gecko_style_coord(coord: &T) -> Option { match coord.as_value() { CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrNone::Length(Au(coord))), - CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)), + CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(Percentage(p))), CoordDataValue::None => Some(LengthOrPercentageOrNone::None), CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())), _ => None, diff --git a/components/style/gecko_bindings/sugar/ns_css_value.rs b/components/style/gecko_bindings/sugar/ns_css_value.rs index 2c70c6ba020..5a4d143125d 100644 --- a/components/style/gecko_bindings/sugar/ns_css_value.rs +++ b/components/style/gecko_bindings/sugar/ns_css_value.rs @@ -15,6 +15,7 @@ use std::mem; use std::ops::{Index, IndexMut}; use std::slice; use values::computed::{Angle, LengthOrPercentage}; +use values::specified::length::Percentage; use values::specified::url::SpecifiedUrl; impl nsCSSValue { @@ -79,7 +80,7 @@ impl nsCSSValue { bindings::Gecko_CSSValue_SetAbsoluteLength(self, au.0) } LengthOrPercentage::Percentage(pc) => { - bindings::Gecko_CSSValue_SetPercentage(self, pc) + bindings::Gecko_CSSValue_SetPercentage(self, pc.0) } LengthOrPercentage::Calc(calc) => { bindings::Gecko_CSSValue_SetCalc(self, calc.into()) @@ -94,7 +95,7 @@ impl nsCSSValue { LengthOrPercentage::Length(Au(bindings::Gecko_CSSValue_GetAbsoluteLength(self))) }, nsCSSUnit::eCSSUnit_Percent => { - LengthOrPercentage::Percentage(bindings::Gecko_CSSValue_GetPercentage(self)) + LengthOrPercentage::Percentage(Percentage(bindings::Gecko_CSSValue_GetPercentage(self))) }, nsCSSUnit::eCSSUnit_Calc => { LengthOrPercentage::Calc(bindings::Gecko_CSSValue_GetCalc(self).into()) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index c7a46b5e560..b0953f9a1d9 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -65,6 +65,7 @@ use stylearc::Arc; use std::cmp; use values::{Auto, CustomIdent, Either, KeyframesName}; use values::computed::{Shadow, ToComputedValue}; +use values::specified::length::Percentage; use computed_values::border_style; pub mod style_structs { @@ -4045,7 +4046,7 @@ clip-path CoordDataValue::Coord(coord) => vec.push(Either::Second(LengthOrPercentage::Length(Au(coord)))), CoordDataValue::Percent(p) => - vec.push(Either::Second(LengthOrPercentage::Percentage(p))), + vec.push(Either::Second(LengthOrPercentage::Percentage(Percentage(p)))), CoordDataValue::Calc(calc) => vec.push(Either::Second(LengthOrPercentage::Calc(calc.into()))), _ => unreachable!(), @@ -4068,7 +4069,7 @@ clip-path match self.gecko.mStrokeDashoffset.as_value() { CoordDataValue::Factor(number) => Either::First(number), CoordDataValue::Coord(coord) => Either::Second(LengthOrPercentage::Length(Au(coord))), - CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(p)), + CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(Percentage(p))), CoordDataValue::Calc(calc) => Either::Second(LengthOrPercentage::Calc(calc.into())), _ => unreachable!(), } @@ -4088,7 +4089,7 @@ clip-path match self.gecko.mStrokeWidth.as_value() { CoordDataValue::Factor(number) => Either::First(number), CoordDataValue::Coord(coord) => Either::Second(LengthOrPercentage::Length(Au(coord))), - CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(p)), + CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(Percentage(p))), CoordDataValue::Calc(calc) => Either::Second(LengthOrPercentage::Calc(calc.into())), _ => unreachable!(), } diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 6e787cafaa3..a14b5f78cdd 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -41,6 +41,7 @@ use values::computed::{LengthOrPercentage, MaxLength, MozLength, Shadow, ToCompu use values::generics::{SVGPaint, SVGPaintKind}; use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use values::generics::position as generic_position; +use values::specified::length::Percentage; /// A longhand property whose animation type is not "none". @@ -941,6 +942,22 @@ impl Animatable for Angle { } } +/// https://drafts.csswg.org/css-transitions/#animtype-percentage +impl Animatable for Percentage { + #[inline] + fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result { + Ok(Percentage((self.0 as f64 * self_portion + other.0 as f64 * other_portion) as f32)) + } + + #[inline] + fn get_zero_value(&self) -> Option { Some(Percentage(0.)) } + + #[inline] + fn compute_distance(&self, other: &Self) -> Result { + Ok((self.0 as f64 - other.0 as f64).abs()) + } +} + /// https://drafts.csswg.org/css-transitions/#animtype-visibility impl Animatable for Visibility { #[inline] @@ -1150,7 +1167,7 @@ impl Animatable for LengthOrPercentage { }, (LengthOrPercentage::Percentage(ref this), LengthOrPercentage::Percentage(ref other)) => { - let diff = (this - other) as f64; + let diff = this.0 as f64 - other.0 as f64; Ok(diff * diff) }, (this, other) => { @@ -1235,7 +1252,7 @@ impl Animatable for LengthOrPercentageOrAuto { }, (LengthOrPercentageOrAuto::Percentage(ref this), LengthOrPercentageOrAuto::Percentage(ref other)) => { - let diff = (this - other) as f64; + let diff = this.0 as f64 - other.0 as f64; Ok(diff * diff) }, (this, other) => { diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 7e765daf623..ba7f73de943 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -11,7 +11,8 @@ 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::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength, ViewportPercentageLength}; +use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; +use values::specified::length::{Percentage, ViewportPercentageLength}; pub use super::image::Image; pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone}; @@ -65,20 +66,20 @@ impl ToComputedValue for specified::Length { pub struct CalcLengthOrPercentage { pub clamping_mode: AllowedLengthType, length: Au, - pub percentage: Option, + pub percentage: Option, } impl CalcLengthOrPercentage { /// Returns a new `CalcLengthOrPercentage`. #[inline] - pub fn new(length: Au, percentage: Option) -> Self { + pub fn new(length: Au, percentage: Option) -> Self { Self::with_clamping_mode(length, percentage, AllowedLengthType::All) } /// Returns a new `CalcLengthOrPercentage` with a specific clamping mode. #[inline] pub fn with_clamping_mode(length: Au, - percentage: Option, + percentage: Option, clamping_mode: AllowedLengthType) -> Self { Self { @@ -106,7 +107,7 @@ impl CalcLengthOrPercentage { #[inline] #[allow(missing_docs)] pub fn percentage(&self) -> CSSFloat { - self.percentage.unwrap_or(0.) + self.percentage.map_or(0., |p| p.0) } /// If there are special rules for computing percentages in a value (e.g. the height property), @@ -114,7 +115,7 @@ impl CalcLengthOrPercentage { pub fn to_used_value(&self, container_len: Option) -> Option { match (container_len, self.percentage) { (Some(len), Some(percent)) => { - Some(self.clamping_mode.clamp(self.length + len.scale_by(percent))) + Some(self.clamping_mode.clamp(self.length + len.scale_by(percent.0))) }, (_, None) => Some(self.length()), _ => None, @@ -179,8 +180,8 @@ impl From for Option { impl ToCss for CalcLengthOrPercentage { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match (self.length, self.percentage) { - (l, Some(p)) if l == Au(0) => write!(dest, "{}%", p * 100.), - (l, Some(p)) => write!(dest, "calc({}px + {}%)", Au::to_px(l), p * 100.), + (l, Some(p)) if l == Au(0) => p.to_css(dest), + (l, Some(p)) => write!(dest, "calc({}px + {}%)", Au::to_px(l), p.0 * 100.), (l, None) => write!(dest, "{}px", Au::to_px(l)), } } @@ -237,7 +238,7 @@ impl ToComputedValue for specified::CalcLengthOrPercentage { #[allow(missing_docs)] pub enum LengthOrPercentage { Length(Au), - Percentage(CSSFloat), + Percentage(Percentage), Calc(CalcLengthOrPercentage), } @@ -269,7 +270,7 @@ impl LengthOrPercentage { use self::LengthOrPercentage::*; match *self { Length(Au(0)) => true, - Percentage(p) => p == 0.0, + Percentage(p) => p.0 == 0.0, Length(_) | Calc(_) => false } } @@ -279,7 +280,7 @@ impl LengthOrPercentage { use self::LengthOrPercentage::*; match *self { Length(l) => (l, NotNaN::new(0.0).unwrap()), - Percentage(p) => (Au(0), NotNaN::new(p).unwrap()), + Percentage(p) => (Au(0), NotNaN::new(p.0).unwrap()), Calc(c) => (c.unclamped_length(), NotNaN::new(c.percentage()).unwrap()), } } @@ -288,7 +289,7 @@ impl LengthOrPercentage { pub fn to_used_value(&self, containing_length: Au) -> Au { match *self { LengthOrPercentage::Length(length) => length, - LengthOrPercentage::Percentage(p) => containing_length.scale_by(p), + LengthOrPercentage::Percentage(p) => containing_length.scale_by(p.0), LengthOrPercentage::Calc(ref calc) => { calc.to_used_value(Some(containing_length)).unwrap() }, @@ -300,7 +301,7 @@ impl fmt::Debug for LengthOrPercentage { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { LengthOrPercentage::Length(length) => write!(f, "{:?}", length), - LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.), + LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.), LengthOrPercentage::Calc(calc) => write!(f, "{:?}", calc), } } @@ -315,7 +316,7 @@ impl ToComputedValue for specified::LengthOrPercentage { LengthOrPercentage::Length(value.to_computed_value(context)) } specified::LengthOrPercentage::Percentage(value) => { - LengthOrPercentage::Percentage(value.0) + LengthOrPercentage::Percentage(value) } specified::LengthOrPercentage::Calc(ref calc) => { LengthOrPercentage::Calc(calc.to_computed_value(context)) @@ -331,7 +332,7 @@ impl ToComputedValue for specified::LengthOrPercentage { ) } LengthOrPercentage::Percentage(value) => { - specified::LengthOrPercentage::Percentage(specified::Percentage(value)) + specified::LengthOrPercentage::Percentage(value) } LengthOrPercentage::Calc(ref calc) => { specified::LengthOrPercentage::Calc( @@ -346,8 +347,7 @@ impl ToCss for LengthOrPercentage { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { LengthOrPercentage::Length(length) => length.to_css(dest), - LengthOrPercentage::Percentage(percentage) - => write!(dest, "{}%", percentage * 100.), + LengthOrPercentage::Percentage(percentage) => percentage.to_css(dest), LengthOrPercentage::Calc(calc) => calc.to_css(dest), } } @@ -358,7 +358,7 @@ impl ToCss for LengthOrPercentage { #[allow(missing_docs)] pub enum LengthOrPercentageOrAuto { Length(Au), - Percentage(CSSFloat), + Percentage(Percentage), Auto, Calc(CalcLengthOrPercentage), } @@ -372,7 +372,7 @@ impl LengthOrPercentageOrAuto { use self::LengthOrPercentageOrAuto::*; match *self { Length(Au(0)) => true, - Percentage(p) => p == 0.0, + Percentage(p) => p.0 == 0.0, Length(_) | Calc(_) | Auto => false } } @@ -382,7 +382,7 @@ impl fmt::Debug for LengthOrPercentageOrAuto { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { LengthOrPercentageOrAuto::Length(length) => write!(f, "{:?}", length), - LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.), + LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.), LengthOrPercentageOrAuto::Auto => write!(f, "auto"), LengthOrPercentageOrAuto::Calc(calc) => write!(f, "{:?}", calc), } @@ -399,7 +399,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto { LengthOrPercentageOrAuto::Length(value.to_computed_value(context)) } specified::LengthOrPercentageOrAuto::Percentage(value) => { - LengthOrPercentageOrAuto::Percentage(value.0) + LengthOrPercentageOrAuto::Percentage(value) } specified::LengthOrPercentageOrAuto::Auto => { LengthOrPercentageOrAuto::Auto @@ -420,7 +420,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto { ) } LengthOrPercentageOrAuto::Percentage(value) => { - specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(value)) + specified::LengthOrPercentageOrAuto::Percentage(value) } LengthOrPercentageOrAuto::Calc(calc) => { specified::LengthOrPercentageOrAuto::Calc( @@ -435,8 +435,7 @@ impl ToCss for LengthOrPercentageOrAuto { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { LengthOrPercentageOrAuto::Length(length) => length.to_css(dest), - LengthOrPercentageOrAuto::Percentage(percentage) - => write!(dest, "{}%", percentage * 100.), + LengthOrPercentageOrAuto::Percentage(percentage) => percentage.to_css(dest), LengthOrPercentageOrAuto::Auto => dest.write_str("auto"), LengthOrPercentageOrAuto::Calc(calc) => calc.to_css(dest), } @@ -448,7 +447,7 @@ impl ToCss for LengthOrPercentageOrAuto { #[allow(missing_docs)] pub enum LengthOrPercentageOrAutoOrContent { Length(Au), - Percentage(CSSFloat), + Percentage(Percentage), Calc(CalcLengthOrPercentage), Auto, Content @@ -458,7 +457,7 @@ impl fmt::Debug for LengthOrPercentageOrAutoOrContent { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { LengthOrPercentageOrAutoOrContent::Length(length) => write!(f, "{:?}", length), - LengthOrPercentageOrAutoOrContent::Percentage(percentage) => write!(f, "{}%", percentage * 100.), + LengthOrPercentageOrAutoOrContent::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.), LengthOrPercentageOrAutoOrContent::Calc(calc) => write!(f, "{:?}", calc), LengthOrPercentageOrAutoOrContent::Auto => write!(f, "auto"), LengthOrPercentageOrAutoOrContent::Content => write!(f, "content") @@ -476,7 +475,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent { LengthOrPercentageOrAutoOrContent::Length(value.to_computed_value(context)) }, specified::LengthOrPercentageOrAutoOrContent::Percentage(value) => { - LengthOrPercentageOrAutoOrContent::Percentage(value.0) + LengthOrPercentageOrAutoOrContent::Percentage(value) }, specified::LengthOrPercentageOrAutoOrContent::Calc(ref calc) => { LengthOrPercentageOrAutoOrContent::Calc(calc.to_computed_value(context)) @@ -506,7 +505,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent { ) } LengthOrPercentageOrAutoOrContent::Percentage(value) => { - specified::LengthOrPercentageOrAutoOrContent::Percentage(specified::Percentage(value)) + specified::LengthOrPercentageOrAutoOrContent::Percentage(value) } LengthOrPercentageOrAutoOrContent::Calc(calc) => { specified::LengthOrPercentageOrAutoOrContent::Calc( @@ -521,8 +520,7 @@ impl ToCss for LengthOrPercentageOrAutoOrContent { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { LengthOrPercentageOrAutoOrContent::Length(length) => length.to_css(dest), - LengthOrPercentageOrAutoOrContent::Percentage(percentage) - => write!(dest, "{}%", percentage * 100.), + LengthOrPercentageOrAutoOrContent::Percentage(percentage) => percentage.to_css(dest), LengthOrPercentageOrAutoOrContent::Calc(calc) => calc.to_css(dest), LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"), LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content") @@ -535,7 +533,7 @@ impl ToCss for LengthOrPercentageOrAutoOrContent { #[allow(missing_docs)] pub enum LengthOrPercentageOrNone { Length(Au), - Percentage(CSSFloat), + Percentage(Percentage), Calc(CalcLengthOrPercentage), None, } @@ -546,7 +544,7 @@ impl LengthOrPercentageOrNone { match *self { LengthOrPercentageOrNone::None => None, LengthOrPercentageOrNone::Length(length) => Some(length), - LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent)), + LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent.0)), LengthOrPercentageOrNone::Calc(ref calc) => calc.to_used_value(Some(containing_length)), } } @@ -556,7 +554,7 @@ impl fmt::Debug for LengthOrPercentageOrNone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { LengthOrPercentageOrNone::Length(length) => write!(f, "{:?}", length), - LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.), + LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.), LengthOrPercentageOrNone::Calc(calc) => write!(f, "{:?}", calc), LengthOrPercentageOrNone::None => write!(f, "none"), } @@ -573,7 +571,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone { LengthOrPercentageOrNone::Length(value.to_computed_value(context)) } specified::LengthOrPercentageOrNone::Percentage(value) => { - LengthOrPercentageOrNone::Percentage(value.0) + LengthOrPercentageOrNone::Percentage(value) } specified::LengthOrPercentageOrNone::Calc(ref calc) => { LengthOrPercentageOrNone::Calc(calc.to_computed_value(context)) @@ -594,7 +592,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone { ) } LengthOrPercentageOrNone::Percentage(value) => { - specified::LengthOrPercentageOrNone::Percentage(specified::Percentage(value)) + specified::LengthOrPercentageOrNone::Percentage(value) } LengthOrPercentageOrNone::Calc(calc) => { specified::LengthOrPercentageOrNone::Calc( @@ -609,8 +607,7 @@ impl ToCss for LengthOrPercentageOrNone { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { LengthOrPercentageOrNone::Length(length) => length.to_css(dest), - LengthOrPercentageOrNone::Percentage(percentage) => - write!(dest, "{}%", percentage * 100.), + LengthOrPercentageOrNone::Percentage(percentage) => percentage.to_css(dest), LengthOrPercentageOrNone::Calc(calc) => calc.to_css(dest), LengthOrPercentageOrNone::None => dest.write_str("none"), } diff --git a/components/style/values/computed/position.rs b/components/style/values/computed/position.rs index 97f14b73f04..98037ca21b9 100644 --- a/components/style/values/computed/position.rs +++ b/components/style/values/computed/position.rs @@ -11,6 +11,7 @@ use std::fmt; use style_traits::ToCss; use values::computed::LengthOrPercentage; use values::generics::position::Position as GenericPosition; +use values::specified::length::Percentage; /// The computed value of a CSS `` pub type Position = GenericPosition; @@ -25,7 +26,10 @@ impl Position { /// `50% 50%` #[inline] pub fn center() -> Self { - Self::new(LengthOrPercentage::Percentage(0.5), LengthOrPercentage::Percentage(0.5)) + Self::new( + LengthOrPercentage::Percentage(Percentage(0.5)), + LengthOrPercentage::Percentage(Percentage(0.5)), + ) } /// `0% 0%` diff --git a/components/style/values/computed/transform.rs b/components/style/values/computed/transform.rs index b64f6d6f277..5354717bc7c 100644 --- a/components/style/values/computed/transform.rs +++ b/components/style/values/computed/transform.rs @@ -8,6 +8,7 @@ use properties::animated_properties::Animatable; use values::computed::{Length, LengthOrPercentage, Number}; use values::generics::transform::TimingFunction as GenericTimingFunction; use values::generics::transform::TransformOrigin as GenericTransformOrigin; +use values::specified::length::Percentage; /// The computed value of a CSS `` pub type TransformOrigin = GenericTransformOrigin; @@ -20,9 +21,9 @@ impl TransformOrigin { #[inline] pub fn initial_value() -> Self { Self::new( - LengthOrPercentage::Percentage(0.5), - LengthOrPercentage::Percentage(0.5), - Length::from_px(0) + LengthOrPercentage::Percentage(Percentage(0.5)), + LengthOrPercentage::Percentage(Percentage(0.5)), + Length::from_px(0), ) } } diff --git a/components/style/values/specified/calc.rs b/components/style/values/specified/calc.rs index f1cf9bc2f61..c4a2bae3f07 100644 --- a/components/style/values/specified/calc.rs +++ b/components/style/values/specified/calc.rs @@ -15,7 +15,8 @@ use style_traits::{HasViewportPercentage, ToCss, ParseError, StyleParseError}; use style_traits::values::specified::AllowedLengthType; use values::{CSSInteger, CSSFloat}; use values::specified::{Angle, Time}; -use values::specified::length::{FontRelativeLength, NoCalcLength, ViewportPercentageLength}; +use values::specified::length::{FontRelativeLength, NoCalcLength}; +use values::specified::length::{Percentage, ViewportPercentageLength}; /// A node inside a `Calc` expression's AST. #[derive(Clone, Debug)] @@ -74,7 +75,7 @@ pub struct CalcLengthOrPercentage { pub ex: Option, pub ch: Option, pub rem: Option, - pub percentage: Option, + pub percentage: Option, #[cfg(feature = "gecko")] pub mozmm: Option, } @@ -128,7 +129,7 @@ impl ToCss for CalcLengthOrPercentage { if let Some(val) = self.percentage { first_value_check!(); - try!(write!(dest, "{}%", val * 100.)); + val.to_css(dest)?; } write!(dest, ")") @@ -298,7 +299,9 @@ impl CalcNode { { match *self { CalcNode::Percentage(pct) => { - ret.percentage = Some(ret.percentage.unwrap_or(0.) + pct * factor) + ret.percentage = Some(Percentage( + ret.percentage.map_or(0., |p| p.0) + pct * factor, + )); } CalcNode::Length(ref l) => { match *l { diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index d0eeacd9581..cc1655ce33e 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -701,7 +701,7 @@ impl Either { /// As of today, only `-moz-image-rect` supports percentages without length. /// This is not a regression, and that's a non-standard extension anyway, so I'm /// not implementing it for now. -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] +#[derive(Clone, Copy, Debug, Default, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Percentage(pub CSSFloat); diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs index 2cd206f2a21..ccbc861b3c1 100644 --- a/components/style/values/specified/position.rs +++ b/components/style/values/specified/position.rs @@ -224,22 +224,22 @@ impl ToComputedValue for PositionComponent { fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { match *self { PositionComponent::Center => { - ComputedLengthOrPercentage::Percentage(0.5) + ComputedLengthOrPercentage::Percentage(Percentage(0.5)) }, PositionComponent::Side(ref keyword, None) => { - let p = if keyword.is_start() { 0. } else { 1. }; + let p = Percentage(if keyword.is_start() { 0. } else { 1. }); ComputedLengthOrPercentage::Percentage(p) }, PositionComponent::Side(ref keyword, Some(ref length)) if !keyword.is_start() => { match length.to_computed_value(context) { ComputedLengthOrPercentage::Length(length) => { - ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage::new(-length, Some(1.0))) + ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage::new(-length, Some(Percentage(1.0)))) }, ComputedLengthOrPercentage::Percentage(p) => { - ComputedLengthOrPercentage::Percentage(1.0 - p) + ComputedLengthOrPercentage::Percentage(Percentage(1.0 - p.0)) }, ComputedLengthOrPercentage::Calc(calc) => { - let p = 1. - calc.percentage.unwrap_or(0.); + let p = Percentage(1. - calc.percentage.map_or(0., |p| p.0)); ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage::new(-calc.unclamped_length(), Some(p))) }, } diff --git a/components/style/values/specified/transform.rs b/components/style/values/specified/transform.rs index d3188e9c876..e4f709ecab9 100644 --- a/components/style/values/specified/transform.rs +++ b/components/style/values/specified/transform.rs @@ -14,7 +14,7 @@ use values::computed::transform::TimingFunction as ComputedTimingFunction; use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction}; use values::generics::transform::{TimingKeyword, TransformOrigin as GenericTransformOrigin}; use values::specified::{Integer, Number}; -use values::specified::length::{Length, LengthOrPercentage}; +use values::specified::length::{Length, LengthOrPercentage, Percentage}; use values::specified::position::{Side, X, Y}; /// The specified value of a CSS `` @@ -107,13 +107,13 @@ impl ToComputedValue for OriginComponent fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { match *self { OriginComponent::Center => { - ComputedLengthOrPercentage::Percentage(0.5) + ComputedLengthOrPercentage::Percentage(Percentage(0.5)) }, OriginComponent::Length(ref length) => { length.to_computed_value(context) }, OriginComponent::Side(ref keyword) => { - let p = if keyword.is_start() { 0. } else { 1. }; + let p = Percentage(if keyword.is_start() { 0. } else { 1. }); ComputedLengthOrPercentage::Percentage(p) }, } diff --git a/tests/unit/style/animated_properties.rs b/tests/unit/style/animated_properties.rs index dd74dc150fb..5a16f1c4cf6 100644 --- a/tests/unit/style/animated_properties.rs +++ b/tests/unit/style/animated_properties.rs @@ -7,6 +7,7 @@ use cssparser::RGBA; use style::properties::animated_properties::{Animatable, IntermediateRGBA}; use style::properties::longhands::transform::computed_value::ComputedOperation as TransformOperation; use style::properties::longhands::transform::computed_value::T as TransformList; +use style::values::specified::length::Percentage; fn interpolate_rgba(from: RGBA, to: RGBA, progress: f64) -> RGBA { let from: IntermediateRGBA = from.into(); @@ -78,25 +79,25 @@ fn test_transform_interpolation_on_translate() { LengthOrPercentage::Length(Au(50)), Au(50))]))); - let from = TransformList(Some(vec![ - TransformOperation::Translate(LengthOrPercentage::Percentage(0.5), - LengthOrPercentage::Percentage(1.0), - Au(25))])); + let from = TransformList(Some(vec![TransformOperation::Translate( + LengthOrPercentage::Percentage(Percentage(0.5)), + LengthOrPercentage::Percentage(Percentage(1.0)), + Au(25), + )])); let to = TransformList(Some(vec![ TransformOperation::Translate(LengthOrPercentage::Length(Au(100)), LengthOrPercentage::Length(Au(50)), Au(75))])); - assert_eq!(from.interpolate(&to, 0.5).unwrap(), - TransformList(Some(vec![ - TransformOperation::Translate(LengthOrPercentage::Calc( - // calc(50px + 25%) - CalcLengthOrPercentage::new(Au(50), - Some(0.25))), - LengthOrPercentage::Calc( - // calc(25px + 50%) - CalcLengthOrPercentage::new(Au(25), - Some(0.5))), - Au(50))]))); + assert_eq!( + from.interpolate(&to, 0.5).unwrap(), + TransformList(Some(vec![TransformOperation::Translate( + // calc(50px + 25%) + LengthOrPercentage::Calc(CalcLengthOrPercentage::new(Au(50), Some(Percentage(0.25)))), + // calc(25px + 50%) + LengthOrPercentage::Calc(CalcLengthOrPercentage::new(Au(25), Some(Percentage(0.5)))), + Au(50), + )])) + ); } #[test] @@ -143,10 +144,12 @@ fn test_transform_interpolation_on_mismatched_lists() { TransformOperation::Translate(LengthOrPercentage::Length(Au(100)), LengthOrPercentage::Length(Au(0)), Au(0))])); - assert_eq!(from.interpolate(&to, 0.5).unwrap(), - TransformList(Some(vec![TransformOperation::InterpolateMatrix { - from_list: from.clone(), - to_list: to.clone(), - progress: Percentage(0.5) - }]))); + assert_eq!( + from.interpolate(&to, 0.5).unwrap(), + TransformList(Some(vec![TransformOperation::InterpolateMatrix { + from_list: from.clone(), + to_list: to.clone(), + progress: Percentage(0.5), + }])) + ); } diff --git a/tests/unit/style/attr.rs b/tests/unit/style/attr.rs index 6bf72a5b969..5f26e1d566e 100644 --- a/tests/unit/style/attr.rs +++ b/tests/unit/style/attr.rs @@ -5,10 +5,11 @@ use app_units::Au; use style::attr::{AttrValue, LengthOrPercentageOrAuto, parse_length}; use style::values::computed::CalcLengthOrPercentage; +use style::values::specified::length::Percentage; #[test] fn test_length_calc() { - let calc = CalcLengthOrPercentage::new(Au(10), Some(0.2)); + let calc = CalcLengthOrPercentage::new(Au(10), Some(Percentage(0.2))); assert_eq!(calc.to_used_value(Some(Au(10))), Some(Au(12))); assert_eq!(calc.to_used_value(Some(Au(0))), Some(Au(10))); assert_eq!(calc.to_used_value(None), None);