diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 2ca775ed345..ed652138d69 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -4,7 +4,6 @@ //! Element nodes. -use app_units::Au; use cssparser::Color; use devtools_traits::AttrInfo; use dom::activation::Activatable; @@ -455,18 +454,13 @@ impl LayoutElementHelpers for LayoutJS { font_family)]))))); } - let font_size = if let Some(this) = self.downcast::() { - this.get_size() - } else { - None - }; + let font_size = self.downcast::().and_then(|this| this.get_size()); if let Some(font_size) = font_size { hints.push(from_declaration( PropertyDeclaration::FontSize( DeclaredValue::Value( - font_size::SpecifiedValue( - LengthOrPercentage::Length(font_size)))))) + font_size::SpecifiedValue(font_size.into()))))) } let cellspacing = if let Some(this) = self.downcast::() { @@ -476,7 +470,7 @@ impl LayoutElementHelpers for LayoutJS { }; if let Some(cellspacing) = cellspacing { - let width_value = specified::Length::Absolute(Au::from_px(cellspacing as i32)); + let width_value = specified::Length::from_px(cellspacing as f32); hints.push(from_declaration( PropertyDeclaration::BorderSpacing(DeclaredValue::Value( border_spacing::SpecifiedValue { @@ -509,13 +503,12 @@ impl LayoutElementHelpers for LayoutJS { }; if let Some(size) = size { - let value = specified::Length::ServoCharacterWidth(specified::CharacterWidth(size)); + let value = specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(size)); hints.push(from_declaration( PropertyDeclaration::Width(DeclaredValue::Value( specified::LengthOrPercentageOrAuto::Length(value))))); } - let width = if let Some(this) = self.downcast::() { this.get_width() } else if let Some(this) = self.downcast::() { @@ -541,7 +534,7 @@ impl LayoutElementHelpers for LayoutJS { } LengthOrPercentageOrAuto::Length(length) => { let width_value = specified::LengthOrPercentageOrAuto::Length( - specified::Length::Absolute(length)); + specified::NoCalcLength::Absolute(length)); hints.push(from_declaration( PropertyDeclaration::Width(DeclaredValue::Value(width_value)))); } @@ -566,7 +559,7 @@ impl LayoutElementHelpers for LayoutJS { } LengthOrPercentageOrAuto::Length(length) => { let height_value = specified::LengthOrPercentageOrAuto::Length( - specified::Length::Absolute(length)); + specified::NoCalcLength::Absolute(length)); hints.push(from_declaration( PropertyDeclaration::Height(DeclaredValue::Value(height_value)))); } @@ -588,13 +581,12 @@ impl LayoutElementHelpers for LayoutJS { // scrollbar size into consideration (but we don't have a scrollbar yet!) // // https://html.spec.whatwg.org/multipage/#textarea-effective-width - let value = specified::Length::ServoCharacterWidth(specified::CharacterWidth(cols)); + let value = specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(cols)); hints.push(from_declaration( PropertyDeclaration::Width(DeclaredValue::Value( specified::LengthOrPercentageOrAuto::Length(value))))); } - let rows = if let Some(this) = self.downcast::() { match this.get_rows() { 0 => None, @@ -608,7 +600,7 @@ impl LayoutElementHelpers for LayoutJS { // TODO(mttr) This should take scrollbar size into consideration. // // https://html.spec.whatwg.org/multipage/#textarea-effective-height - let value = specified::Length::FontRelative(specified::FontRelativeLength::Em(rows as CSSFloat)); + let value = specified::NoCalcLength::FontRelative(specified::FontRelativeLength::Em(rows as CSSFloat)); hints.push(from_declaration( PropertyDeclaration::Height(DeclaredValue::Value( specified::LengthOrPercentageOrAuto::Length(value))))); @@ -622,8 +614,7 @@ impl LayoutElementHelpers for LayoutJS { }; if let Some(border) = border { - let width_value = specified::BorderWidth::from_length( - specified::Length::Absolute(Au::from_px(border as i32))); + let width_value = specified::BorderWidth::from_length(specified::Length::from_px(border as f32)); hints.push(from_declaration( PropertyDeclaration::BorderTopWidth(DeclaredValue::Value(width_value.clone())))); hints.push(from_declaration( diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 342baa002f1..dd9f5a19643 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -236,8 +236,7 @@ impl MediaExpressionValue { nsMediaFeature_ValueType::eLength => { debug_assert!(css_value.mUnit == nsCSSUnit::eCSSUnit_Pixel); let pixels = css_value.float_unchecked(); - Some(MediaExpressionValue::Length( - specified::Length::Absolute(Au::from_f32_px(pixels)))) + Some(MediaExpressionValue::Length(specified::Length::from_px(pixels))) } nsMediaFeature_ValueType::eInteger => { let i = css_value.integer_unchecked(); diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 754afaf164d..1558e597ead 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -1328,7 +1328,7 @@ ${helpers.single_keyword("animation-fill-mode", result.push(SpecifiedOperation::Translate(TranslateKind::Translate, tx, ty, - specified::Length::Absolute(Au(0)))); + specified::Length::zero())); Ok(()) })) }, @@ -1339,7 +1339,7 @@ ${helpers.single_keyword("animation-fill-mode", TranslateKind::TranslateX, tx, specified::LengthOrPercentage::zero(), - specified::Length::Absolute(Au(0)))); + specified::Length::zero())); Ok(()) })) }, @@ -1350,7 +1350,7 @@ ${helpers.single_keyword("animation-fill-mode", TranslateKind::TranslateY, specified::LengthOrPercentage::zero(), ty, - specified::Length::Absolute(Au(0)))); + specified::Length::zero())); Ok(()) })) }, @@ -1761,7 +1761,7 @@ ${helpers.single_keyword("transform-style", use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::specified::{Length, LengthOrPercentage, Percentage}; + use values::specified::{NoCalcLength, LengthOrPercentage, Percentage}; pub mod computed_value { use properties::animated_properties::Interpolate; @@ -1799,7 +1799,7 @@ ${helpers.single_keyword("transform-style", pub struct SpecifiedValue { horizontal: LengthOrPercentage, vertical: LengthOrPercentage, - depth: Length, + depth: NoCalcLength, } impl ToCss for computed_value::T { @@ -1836,7 +1836,7 @@ ${helpers.single_keyword("transform-style", Ok(SpecifiedValue { horizontal: result.horizontal.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.5))), vertical: result.vertical.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.5))), - depth: result.depth.unwrap_or(Length::Absolute(Au(0))), + depth: result.depth.unwrap_or(NoCalcLength::zero()), }) } diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index 3da52aa3db2..9bc62bc5e7d 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -280,10 +280,10 @@ ${helpers.predefined_type("opacity", left = try!(parse_argument(context, input)); } Ok(SpecifiedValue(Some(SpecifiedClipRect { - top: top.unwrap_or(Length::Absolute(Au(0))), + top: top.unwrap_or(Length::zero()), right: right, bottom: bottom, - left: left.unwrap_or(Length::Absolute(Au(0))), + left: left.unwrap_or(Length::zero()), }))) }) } @@ -613,7 +613,7 @@ ${helpers.predefined_type("opacity", pub struct OriginParseResult { pub horizontal: Option, pub vertical: Option, - pub depth: Option + pub depth: Option } pub fn parse_origin(context: &ParserContext, input: &mut Parser) -> Result { diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index d143398b2d8..b25d40fefea 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -329,7 +329,7 @@ ${helpers.single_keyword("font-variant-caps", use std::fmt; use style_traits::ToCss; use values::{FONT_MEDIUM_PX, HasViewportPercentage}; - use values::specified::{LengthOrPercentage, Length, Percentage}; + use values::specified::{LengthOrPercentage, Length, NoCalcLength, Percentage}; impl ToCss for SpecifiedValue { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { @@ -363,10 +363,10 @@ ${helpers.single_keyword("font-variant-caps", #[inline] fn to_computed_value(&self, context: &Context) -> computed_value::T { match self.0 { - LengthOrPercentage::Length(Length::FontRelative(value)) => { + LengthOrPercentage::Length(NoCalcLength::FontRelative(value)) => { value.to_computed_value(context, /* use inherited */ true) } - LengthOrPercentage::Length(Length::ServoCharacterWidth(value)) => { + LengthOrPercentage::Length(NoCalcLength::ServoCharacterWidth(value)) => { value.to_computed_value(context.inherited_style().get_font().clone_font_size()) } LengthOrPercentage::Length(ref l) => { @@ -397,11 +397,10 @@ ${helpers.single_keyword("font-variant-caps", input.try(specified::LengthOrPercentage::parse_non_negative) .or_else(|()| { let ident = try!(input.expect_ident()); - specified::Length::from_str(&ident as &str) - .ok_or(()) - .map(specified::LengthOrPercentage::Length) - }) - .map(SpecifiedValue) + NoCalcLength::from_str(&ident as &str) + .ok_or(()) + .map(specified::LengthOrPercentage::Length) + }).map(SpecifiedValue) } diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index db83c7308df..9c63fd45686 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -113,13 +113,14 @@ specified::LengthOrPercentage::Length(ref value) => computed_value::T::Length(value.to_computed_value(context)), specified::LengthOrPercentage::Percentage(specified::Percentage(value)) => { - let fr = specified::Length::FontRelative(specified::FontRelativeLength::Em(value)); + let fr = specified::Length::NoCalc(specified::NoCalcLength::FontRelative( + specified::FontRelativeLength::Em(value))); computed_value::T::Length(fr.to_computed_value(context)) }, specified::LengthOrPercentage::Calc(ref calc) => { let calc = calc.to_computed_value(context); let fr = specified::FontRelativeLength::Em(calc.percentage()); - let fr = specified::Length::FontRelative(fr); + let fr = specified::Length::NoCalc(specified::NoCalcLength::FontRelative(fr)); computed_value::T::Length(calc.length() + fr.to_computed_value(context)) } } @@ -681,9 +682,7 @@ ${helpers.single_keyword("text-align-last", fn parse_one_text_shadow(context: &ParserContext, input: &mut Parser) -> Result { use app_units::Au; - let mut lengths = [specified::Length::Absolute(Au(0)), - specified::Length::Absolute(Au(0)), - specified::Length::Absolute(Au(0))]; + let mut lengths = [specified::Length::zero(), specified::Length::zero(), specified::Length::zero()]; let mut lengths_parsed = false; let mut color = None; diff --git a/components/style/properties/shorthand/inherited_text.mako.rs b/components/style/properties/shorthand/inherited_text.mako.rs index a75e6d8925d..f97c129590d 100644 --- a/components/style/properties/shorthand/inherited_text.mako.rs +++ b/components/style/properties/shorthand/inherited_text.mako.rs @@ -74,7 +74,6 @@ pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { use values::specified::{BorderWidth, Length}; - use app_units::Au; let mut color = None; let mut width = None; @@ -99,7 +98,7 @@ Ok(Longhands { _webkit_text_stroke_color: color.or(Some(CSSColor { parsed: CSSParserColor::CurrentColor, authored: None })), - _webkit_text_stroke_width: width.or(Some(BorderWidth::from_length(Length::Absolute(Au::from_px(0))))), + _webkit_text_stroke_width: width.or(Some(BorderWidth::from_length(Length::zero()))), }) } else { Err(()) diff --git a/components/style/properties/shorthand/position.mako.rs b/components/style/properties/shorthand/position.mako.rs index 807bcadb5df..b5673925996 100644 --- a/components/style/properties/shorthand/position.mako.rs +++ b/components/style/properties/shorthand/position.mako.rs @@ -57,8 +57,7 @@ <%helpers:shorthand name="flex" sub_properties="flex-grow flex-shrink flex-basis" extra_prefixes="webkit" spec="https://drafts.csswg.org/css-flexbox/#flex-property"> use parser::Parse; - use app_units::Au; - use values::specified::{Number, Length, LengthOrPercentageOrAutoOrContent}; + use values::specified::{Number, NoCalcLength, LengthOrPercentageOrAutoOrContent}; pub fn parse_flexibility(input: &mut Parser) -> Result<(Number, Option),()> { @@ -102,7 +101,7 @@ Ok(Longhands { flex_grow: grow.or(Some(Number(1.0))), flex_shrink: shrink.or(Some(Number(1.0))), - flex_basis: basis.or(Some(LengthOrPercentageOrAutoOrContent::Length(Length::Absolute(Au(0))))) + flex_basis: basis.or(Some(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero()))) }) } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index b2a3a983e0d..74c9fd6287f 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -17,6 +17,45 @@ pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Ima pub use super::image::{LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone}; +impl ToComputedValue for specified::NoCalcLength { + type ComputedValue = Au; + + #[inline] + fn to_computed_value(&self, context: &Context) -> Au { + match *self { + specified::NoCalcLength::Absolute(length) => length, + specified::NoCalcLength::FontRelative(length) => + length.to_computed_value(context, /* use inherited */ false), + specified::NoCalcLength::ViewportPercentage(length) => + length.to_computed_value(context.viewport_size()), + specified::NoCalcLength::ServoCharacterWidth(length) => + length.to_computed_value(context.style().get_font().clone_font_size()) + } + } + + #[inline] + fn from_computed_value(computed: &Au) -> Self { + specified::NoCalcLength::Absolute(*computed) + } +} + +impl ToComputedValue for specified::Length { + type ComputedValue = Au; + + #[inline] + fn to_computed_value(&self, context: &Context) -> Au { + match *self { + specified::Length::NoCalc(l) => l.to_computed_value(context), + specified::Length::Calc(ref calc, range) => range.clamp(calc.to_computed_value(context).length()), + } + } + + #[inline] + fn from_computed_value(computed: &Au) -> Self { + specified::Length::NoCalc(specified::NoCalcLength::from_computed_value(computed)) + } +} + #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 15aa9ceaf25..a653d18918c 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -121,30 +121,6 @@ impl ToComputedValue for specified::CSSColor { impl ComputedValueAsSpecified for specified::BorderStyle {} -impl ToComputedValue for specified::Length { - type ComputedValue = Au; - - #[inline] - fn to_computed_value(&self, context: &Context) -> Au { - match *self { - specified::Length::Absolute(length) => length, - specified::Length::Calc(ref calc, range) => range.clamp(calc.to_computed_value(context).length()), - specified::Length::FontRelative(length) => - length.to_computed_value(context, /* use inherited */ false), - specified::Length::ViewportPercentage(length) => - length.to_computed_value(context.viewport_size()), - specified::Length::ServoCharacterWidth(length) => - length.to_computed_value(context.style().get_font().clone_font_size()) - } - } - - #[inline] - fn from_computed_value(computed: &Au) -> Self { - specified::Length::Absolute(*computed) - } -} - - #[derive(Debug, PartialEq, Clone, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs index d89f926dee4..7f77337218c 100644 --- a/components/style/values/specified/basic_shape.rs +++ b/components/style/values/specified/basic_shape.rs @@ -299,7 +299,6 @@ impl ToComputedValue for InsetRect { /// the keywords are folded into the percentages fn serialize_basicshape_position(position: &Position, dest: &mut W) -> fmt::Result where W: fmt::Write { - use values::specified::Length; use values::specified::position::Keyword; // keyword-percentage pairs can be folded into a single percentage @@ -327,7 +326,7 @@ fn serialize_basicshape_position(position: &Position, dest: &mut W) // 0 length should be replaced with 0% fn replace_with_percent(input: LengthOrPercentage) -> LengthOrPercentage { match input { - LengthOrPercentage::Length(Length::Absolute(au)) if au.0 == 0 => { + LengthOrPercentage::Length(ref l) if l.is_zero() => { LengthOrPercentage::Percentage(Percentage(0.0)) } _ => { diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 5f53376bb09..601056d6447 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -24,6 +24,14 @@ pub use super::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingSh pub use super::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use super::image::{SizeKeyword, VerticalDirection}; +const AU_PER_PX: CSSFloat = 60.; +const AU_PER_IN: CSSFloat = AU_PER_PX * 96.; +const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54; +const AU_PER_MM: CSSFloat = AU_PER_IN / 25.4; +const AU_PER_Q: CSSFloat = AU_PER_MM / 4.; +const AU_PER_PT: CSSFloat = AU_PER_IN / 72.; +const AU_PER_PC: CSSFloat = AU_PER_PT * 12.; + #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// A font relative length. @@ -205,12 +213,12 @@ impl CharacterWidth { } } -/// A length. +/// A `` without taking `calc` expressions into account /// /// https://drafts.csswg.org/css-values/#lengths -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub enum Length { +pub enum NoCalcLength { /// An absolute length: https://drafts.csswg.org/css-values/#absolute-length Absolute(Au), // application units @@ -229,7 +237,114 @@ pub enum Length { /// This cannot be specified by the user directly and is only generated by /// `Stylist::synthesize_rules_for_legacy_attributes()`. ServoCharacterWidth(CharacterWidth), +} +impl HasViewportPercentage for NoCalcLength { + fn has_viewport_percentage(&self) -> bool { + match *self { + NoCalcLength::ViewportPercentage(_) => true, + _ => false, + } + } +} + +impl ToCss for NoCalcLength { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + NoCalcLength::Absolute(length) => write!(dest, "{}px", length.to_f32_px()), + NoCalcLength::FontRelative(length) => length.to_css(dest), + NoCalcLength::ViewportPercentage(length) => length.to_css(dest), + /* This should only be reached from style dumping code */ + NoCalcLength::ServoCharacterWidth(CharacterWidth(i)) => write!(dest, "CharWidth({})", i), + } + } +} + +impl Mul for NoCalcLength { + type Output = NoCalcLength; + + #[inline] + fn mul(self, scalar: CSSFloat) -> NoCalcLength { + match self { + NoCalcLength::Absolute(Au(v)) => NoCalcLength::Absolute(Au(((v as f32) * scalar) as i32)), + NoCalcLength::FontRelative(v) => NoCalcLength::FontRelative(v * scalar), + NoCalcLength::ViewportPercentage(v) => NoCalcLength::ViewportPercentage(v * scalar), + NoCalcLength::ServoCharacterWidth(_) => panic!("Can't multiply ServoCharacterWidth!"), + } + } +} + +impl NoCalcLength { + /// https://drafts.csswg.org/css-fonts-3/#font-size-prop + pub fn from_str(s: &str) -> Option { + Some(match_ignore_ascii_case! { s, + "xx-small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 5), + "x-small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 4), + "small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 8 / 9), + "medium" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX)), + "large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 6 / 5), + "x-large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 2), + "xx-large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 2), + + // https://github.com/servo/servo/issues/3423#issuecomment-56321664 + "smaller" => NoCalcLength::FontRelative(FontRelativeLength::Em(0.85)), + "larger" => NoCalcLength::FontRelative(FontRelativeLength::Em(1.2)), + _ => return None + }) + } + + /// Parse a given absolute or relative dimension. + pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result { + match_ignore_ascii_case! { unit, + "px" => Ok(NoCalcLength::Absolute(Au((value * AU_PER_PX) as i32))), + "in" => Ok(NoCalcLength::Absolute(Au((value * AU_PER_IN) as i32))), + "cm" => Ok(NoCalcLength::Absolute(Au((value * AU_PER_CM) as i32))), + "mm" => Ok(NoCalcLength::Absolute(Au((value * AU_PER_MM) as i32))), + "q" => Ok(NoCalcLength::Absolute(Au((value * AU_PER_Q) as i32))), + "pt" => Ok(NoCalcLength::Absolute(Au((value * AU_PER_PT) as i32))), + "pc" => Ok(NoCalcLength::Absolute(Au((value * AU_PER_PC) as i32))), + // font-relative + "em" => Ok(NoCalcLength::FontRelative(FontRelativeLength::Em(value))), + "ex" => Ok(NoCalcLength::FontRelative(FontRelativeLength::Ex(value))), + "ch" => Ok(NoCalcLength::FontRelative(FontRelativeLength::Ch(value))), + "rem" => Ok(NoCalcLength::FontRelative(FontRelativeLength::Rem(value))), + // viewport percentages + "vw" => Ok(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(value))), + "vh" => Ok(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vh(value))), + "vmin" => Ok(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vmin(value))), + "vmax" => Ok(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vmax(value))), + _ => Err(()) + } + } + + #[inline] + /// Returns a `zero` length. + pub fn zero() -> NoCalcLength { + NoCalcLength::Absolute(Au(0)) + } + + #[inline] + /// Checks whether the length value is zero. + pub fn is_zero(&self) -> bool { + *self == NoCalcLength::Absolute(Au(0)) + } + + /// Get an absolute length from a px value. + #[inline] + pub fn from_px(px_value: CSSFloat) -> NoCalcLength { + NoCalcLength::Absolute(Au((px_value * AU_PER_PX) as i32)) + } +} + +/// An extension to `NoCalcLength` to parse `calc` expressions. +/// This is commonly used for the `` values. +/// +/// https://drafts.csswg.org/css-values/#lengths +#[derive(Clone, PartialEq, Debug)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum Length { + /// The internal length type that cannot parse `calc` + NoCalc(NoCalcLength), /// A calc expression. /// /// https://drafts.csswg.org/css-values/#calc-notation @@ -242,9 +357,8 @@ pub enum Length { impl HasViewportPercentage for Length { fn has_viewport_percentage(&self) -> bool { match *self { - Length::ViewportPercentage(_) => true, + Length::NoCalc(ref inner) => inner.has_viewport_percentage(), Length::Calc(ref calc, _) => calc.has_viewport_percentage(), - _ => false } } } @@ -252,12 +366,8 @@ impl HasViewportPercentage for Length { impl ToCss for Length { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { - Length::Absolute(length) => write!(dest, "{}px", length.to_f32_px()), - Length::FontRelative(length) => length.to_css(dest), - Length::ViewportPercentage(length) => length.to_css(dest), + Length::NoCalc(ref inner) => inner.to_css(dest), Length::Calc(ref calc, _) => calc.to_css(dest), - /* This should only be reached from style dumping code */ - Length::ServoCharacterWidth(CharacterWidth(i)) => write!(dest, "CharWidth({})", i), } } } @@ -268,11 +378,8 @@ impl Mul for Length { #[inline] fn mul(self, scalar: CSSFloat) -> Length { match self { - Length::Absolute(Au(v)) => Length::Absolute(Au(((v as f32) * scalar) as i32)), - Length::FontRelative(v) => Length::FontRelative(v * scalar), - Length::ViewportPercentage(v) => Length::ViewportPercentage(v * scalar), + Length::NoCalc(inner) => Length::NoCalc(inner * scalar), Length::Calc(..) => panic!("Can't multiply Calc!"), - Length::ServoCharacterWidth(_) => panic!("Can't multiply ServoCharacterWidth!"), } } } @@ -305,31 +412,21 @@ impl Mul for ViewportPercentageLength { } } -const AU_PER_PX: CSSFloat = 60.; -const AU_PER_IN: CSSFloat = AU_PER_PX * 96.; -const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54; -const AU_PER_MM: CSSFloat = AU_PER_IN / 25.4; -const AU_PER_Q: CSSFloat = AU_PER_MM / 4.; -const AU_PER_PT: CSSFloat = AU_PER_IN / 72.; -const AU_PER_PC: CSSFloat = AU_PER_PT * 12.; - impl Length { + #[inline] + /// Returns a `zero` length. + pub fn zero() -> Length { + Length::NoCalc(NoCalcLength::zero()) + } + /// https://drafts.csswg.org/css-fonts-3/#font-size-prop pub fn from_str(s: &str) -> Option { - Some(match_ignore_ascii_case! { s, - "xx-small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 5), - "x-small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 4), - "small" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 8 / 9), - "medium" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX)), - "large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 6 / 5), - "x-large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 2), - "xx-large" => Length::Absolute(Au::from_px(FONT_MEDIUM_PX) * 2), + NoCalcLength::from_str(s).map(Length::NoCalc) + } - // https://github.com/servo/servo/issues/3423#issuecomment-56321664 - "smaller" => Length::FontRelative(FontRelativeLength::Em(0.85)), - "larger" => Length::FontRelative(FontRelativeLength::Em(1.2)), - _ => return None - }) + /// Parse a given absolute or relative dimension. + pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result { + NoCalcLength::parse_dimension(value, unit).map(Length::NoCalc) } #[inline] @@ -337,8 +434,7 @@ impl Length { match try!(input.next()) { Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => Length::parse_dimension(value.value, unit), - Token::Number(ref value) if value.value == 0. => - Ok(Length::Absolute(Au(0))), + Token::Number(ref value) if value.value == 0. => Ok(Length::zero()), Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => input.parse_nested_block(|input| { CalcLengthOrPercentage::parse_length(input, context) @@ -352,34 +448,10 @@ impl Length { Length::parse_internal(input, AllowedNumericType::NonNegative) } - /// Parse a given absolute or relative dimension. - pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result { - match_ignore_ascii_case! { unit, - "px" => Ok(Length::from_px(value)), - "in" => Ok(Length::Absolute(Au((value * AU_PER_IN) as i32))), - "cm" => Ok(Length::Absolute(Au((value * AU_PER_CM) as i32))), - "mm" => Ok(Length::Absolute(Au((value * AU_PER_MM) as i32))), - "q" => Ok(Length::Absolute(Au((value * AU_PER_Q) as i32))), - "pt" => Ok(Length::Absolute(Au((value * AU_PER_PT) as i32))), - "pc" => Ok(Length::Absolute(Au((value * AU_PER_PC) as i32))), - // font-relative - "em" => Ok(Length::FontRelative(FontRelativeLength::Em(value))), - "ex" => Ok(Length::FontRelative(FontRelativeLength::Ex(value))), - "ch" => Ok(Length::FontRelative(FontRelativeLength::Ch(value))), - "rem" => Ok(Length::FontRelative(FontRelativeLength::Rem(value))), - // viewport percentages - "vw" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vw(value))), - "vh" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vh(value))), - "vmin" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmin(value))), - "vmax" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmax(value))), - _ => Err(()) - } - } - - /// Get an absolute length from a px values. + /// Get an absolute length from a px value. #[inline] pub fn from_px(px_value: CSSFloat) -> Length { - Length::Absolute(Au((px_value * AU_PER_PX) as i32)) + Length::NoCalc(NoCalcLength::from_px(px_value)) } /// Extract inner length without a clone, replacing it with a 0 Au @@ -387,8 +459,7 @@ impl Length { /// Use when you need to move out of a length array without cloning #[inline] pub fn take(&mut self) -> Self { - let new = Length::Absolute(Au(0)); - mem::replace(self, new) + mem::replace(self, Length::zero()) } } @@ -424,7 +495,7 @@ pub struct CalcProductNode { #[derive(Clone, Debug)] #[allow(missing_docs)] pub enum CalcValueNode { - Length(Length), + Length(NoCalcLength), Angle(Angle), Time(Time), Percentage(CSSFloat), @@ -517,7 +588,7 @@ impl CalcLengthOrPercentage { (Token::Number(ref value), _) => Ok(CalcValueNode::Number(value.value)), (Token::Dimension(ref value, ref unit), CalcUnit::Length) | (Token::Dimension(ref value, ref unit), CalcUnit::LengthOrPercentage) => { - Length::parse_dimension(value.value, unit).map(CalcValueNode::Length) + NoCalcLength::parse_dimension(value.value, unit).map(CalcValueNode::Length) } (Token::Dimension(ref value, ref unit), CalcUnit::Angle) => { Angle::parse_dimension(value.value, unit).map(CalcValueNode::Angle) @@ -648,9 +719,9 @@ impl CalcLengthOrPercentage { match value { SimplifiedValueNode::Percentage(p) => percentage = Some(percentage.unwrap_or(0.) + p), - SimplifiedValueNode::Length(Length::Absolute(Au(au))) => + SimplifiedValueNode::Length(NoCalcLength::Absolute(Au(au))) => absolute = Some(absolute.unwrap_or(0) + au), - SimplifiedValueNode::Length(Length::ViewportPercentage(v)) => + SimplifiedValueNode::Length(NoCalcLength::ViewportPercentage(v)) => match v { ViewportPercentageLength::Vw(val) => vw = Some(vw.unwrap_or(0.) + val), @@ -661,7 +732,7 @@ impl CalcLengthOrPercentage { ViewportPercentageLength::Vmax(val) => vmax = Some(vmax.unwrap_or(0.) + val), }, - SimplifiedValueNode::Length(Length::FontRelative(f)) => + SimplifiedValueNode::Length(NoCalcLength::FontRelative(f)) => match f { FontRelativeLength::Em(val) => em = Some(em.unwrap_or(0.) + val), @@ -833,11 +904,20 @@ impl Parse for Percentage { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum LengthOrPercentage { - Length(Length), + Length(NoCalcLength), Percentage(Percentage), Calc(Box), } +impl From for LengthOrPercentage { + fn from(len: Length) -> LengthOrPercentage { + match len { + Length::NoCalc(l) => LengthOrPercentage::Length(l), + Length::Calc(l, _) => LengthOrPercentage::Calc(l), + } + } +} + impl HasViewportPercentage for LengthOrPercentage { fn has_viewport_percentage(&self) -> bool { match *self { @@ -860,7 +940,7 @@ impl ToCss for LengthOrPercentage { impl LengthOrPercentage { /// Returns a `zero` length. pub fn zero() -> LengthOrPercentage { - LengthOrPercentage::Length(Length::Absolute(Au(0))) + LengthOrPercentage::Length(NoCalcLength::zero()) } fn parse_internal(input: &mut Parser, context: AllowedNumericType) @@ -868,11 +948,11 @@ impl LengthOrPercentage { { match try!(input.next()) { Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => - Length::parse_dimension(value.value, unit).map(LengthOrPercentage::Length), + NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentage::Length), Token::Percentage(ref value) if context.is_ok(value.unit_value) => Ok(LengthOrPercentage::Percentage(Percentage(value.unit_value))), Token::Number(ref value) if value.value == 0. => - Ok(LengthOrPercentage::Length(Length::Absolute(Au(0)))), + Ok(LengthOrPercentage::zero()), Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage)); Ok(LengthOrPercentage::Calc(Box::new(calc))) @@ -892,8 +972,7 @@ impl LengthOrPercentage { /// Use when you need to move out of a length array without cloning #[inline] pub fn take(&mut self) -> Self { - let new = LengthOrPercentage::Length(Length::Absolute(Au(0))); - mem::replace(self, new) + mem::replace(self, LengthOrPercentage::zero()) } } @@ -910,7 +989,7 @@ impl Parse for LengthOrPercentage { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum LengthOrPercentageOrAuto { - Length(Length), + Length(NoCalcLength), Percentage(Percentage), Auto, Calc(Box), @@ -943,11 +1022,11 @@ impl LengthOrPercentageOrAuto { { match try!(input.next()) { Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => - Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrAuto::Length), + NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAuto::Length), Token::Percentage(ref value) if context.is_ok(value.unit_value) => Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))), Token::Number(ref value) if value.value == 0. => - Ok(LengthOrPercentageOrAuto::Length(Length::Absolute(Au(0)))), + Ok(LengthOrPercentageOrAuto::Length(NoCalcLength::zero())), Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => Ok(LengthOrPercentageOrAuto::Auto), Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { @@ -978,7 +1057,7 @@ impl Parse for LengthOrPercentageOrAuto { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum LengthOrPercentageOrNone { - Length(Length), + Length(NoCalcLength), Percentage(Percentage), Calc(Box), None, @@ -1010,11 +1089,11 @@ impl LengthOrPercentageOrNone { { match try!(input.next()) { Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => - Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrNone::Length), + NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrNone::Length), Token::Percentage(ref value) if context.is_ok(value.unit_value) => Ok(LengthOrPercentageOrNone::Percentage(Percentage(value.unit_value))), Token::Number(ref value) if value.value == 0. => - Ok(LengthOrPercentageOrNone::Length(Length::Absolute(Au(0)))), + Ok(LengthOrPercentageOrNone::Length(NoCalcLength::zero())), Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage)); Ok(LengthOrPercentageOrNone::Calc(Box::new(calc))) @@ -1055,7 +1134,7 @@ pub type LengthOrAuto = Either; #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum LengthOrPercentageOrAutoOrContent { /// A ``. - Length(Length), + Length(NoCalcLength), /// A percentage. Percentage(Percentage), /// A `calc` node. @@ -1093,11 +1172,11 @@ impl Parse for LengthOrPercentageOrAutoOrContent { let context = AllowedNumericType::NonNegative; match try!(input.next()) { Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => - Length::parse_dimension(value.value, unit).map(LengthOrPercentageOrAutoOrContent::Length), + NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAutoOrContent::Length), Token::Percentage(ref value) if context.is_ok(value.unit_value) => Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))), Token::Number(ref value) if value.value == 0. => - Ok(LengthOrPercentageOrAutoOrContent::Length(Length::Absolute(Au(0)))), + Ok(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero())), Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => Ok(LengthOrPercentageOrAutoOrContent::Auto), Token::Ident(ref value) if value.eq_ignore_ascii_case("content") => diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 1a5b9807405..076324cebe6 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -26,7 +26,7 @@ pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, pub use self::image::{SizeKeyword, VerticalDirection}; pub use self::length::{FontRelativeLength, ViewportPercentageLength, CharacterWidth, Length, CalcLengthOrPercentage}; pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; -pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, CalcUnit}; +pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength, CalcUnit}; pub mod basic_shape; pub mod grid; @@ -109,13 +109,14 @@ impl<'a> Mul for &'a SimplifiedSumNode { #[derive(Clone, Debug)] #[allow(missing_docs)] pub enum SimplifiedValueNode { - Length(Length), + Length(NoCalcLength), Angle(Angle), Time(Time), Percentage(CSSFloat), Number(CSSFloat), Sum(Box), } + impl<'a> Mul for &'a SimplifiedValueNode { type Output = SimplifiedValueNode; @@ -197,8 +198,8 @@ impl NoViewportPercentage for BorderRadiusSize {} impl BorderRadiusSize { #[allow(missing_docs)] pub fn zero() -> BorderRadiusSize { - let zero = LengthOrPercentage::Length(Length::Absolute(Au(0))); - BorderRadiusSize(Size2D::new(zero.clone(), zero)) + let zero = LengthOrPercentage::Length(NoCalcLength::zero()); + BorderRadiusSize(Size2D::new(zero.clone(), zero)) } #[allow(missing_docs)] @@ -291,11 +292,11 @@ pub fn parse_border_radius(context: &ParserContext, input: &mut Parser) -> Resul input.try(|i| BorderRadiusSize::parse(context, i)).or_else(|_| { match_ignore_ascii_case! { try!(input.expect_ident()), "thin" => Ok(BorderRadiusSize::circle( - LengthOrPercentage::Length(Length::from_px(1.)))), + LengthOrPercentage::Length(NoCalcLength::from_px(1.)))), "medium" => Ok(BorderRadiusSize::circle( - LengthOrPercentage::Length(Length::from_px(3.)))), + LengthOrPercentage::Length(NoCalcLength::from_px(3.)))), "thick" => Ok(BorderRadiusSize::circle( - LengthOrPercentage::Length(Length::from_px(5.)))), + LengthOrPercentage::Length(NoCalcLength::from_px(5.)))), _ => Err(()) } }) @@ -604,12 +605,8 @@ impl Shadow { // disable_spread_and_inset is for filter: drop-shadow(...) #[allow(missing_docs)] pub fn parse(context: &ParserContext, input: &mut Parser, disable_spread_and_inset: bool) -> Result { - use app_units::Au; let length_count = if disable_spread_and_inset { 3 } else { 4 }; - let mut lengths = [Length::Absolute(Au(0)), - Length::Absolute(Au(0)), - Length::Absolute(Au(0)), - Length::Absolute(Au(0))]; + let mut lengths = [Length::zero(), Length::zero(), Length::zero(), Length::zero()]; let mut lengths_parsed = false; let mut color = None; let mut inset = false; @@ -661,7 +658,7 @@ impl Shadow { offset_x: lengths[0].take(), offset_y: lengths[1].take(), blur_radius: lengths[2].take(), - spread_radius: if disable_spread_and_inset { Length::Absolute(Au(0)) } else { lengths[3].take() }, + spread_radius: if disable_spread_and_inset { Length::zero() } else { lengths[3].take() }, color: color, inset: inset, }) diff --git a/components/style/viewport.rs b/components/style/viewport.rs index 7e98b7e2460..30ba3c0e7ab 100644 --- a/components/style/viewport.rs +++ b/components/style/viewport.rs @@ -25,7 +25,7 @@ use style_traits::ToCss; use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom}; use stylesheets::{Stylesheet, Origin}; use values::computed::{Context, ToComputedValue}; -use values::specified::{Length, LengthOrPercentageOrAuto, ViewportPercentageLength}; +use values::specified::{NoCalcLength, LengthOrPercentageOrAuto, ViewportPercentageLength}; macro_rules! declare_viewport_descriptor { ( $( $variant_name: expr => $variant: ident($data: ident), )+ ) => { @@ -150,14 +150,14 @@ impl FromMeta for ViewportLength { Some(match value { v if v.eq_ignore_ascii_case("device-width") => - specified!(Length::ViewportPercentage(ViewportPercentageLength::Vw(100.))), + specified!(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(100.))), v if v.eq_ignore_ascii_case("device-height") => - specified!(Length::ViewportPercentage(ViewportPercentageLength::Vh(100.))), + specified!(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vh(100.))), _ => { match value.parse::() { - Ok(n) if n >= 0. => specified!(Length::from_px(n.max(1.).min(10000.))), + Ok(n) if n >= 0. => specified!(NoCalcLength::from_px(n.max(1.).min(10000.))), Ok(_) => return None, - Err(_) => specified!(Length::from_px(1.)) + Err(_) => specified!(NoCalcLength::from_px(1.)) } } }) diff --git a/tests/unit/style/media_queries.rs b/tests/unit/style/media_queries.rs index d6e32a9e5a5..11e1987928a 100644 --- a/tests/unit/style/media_queries.rs +++ b/tests/unit/style/media_queries.rs @@ -2,7 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use app_units::Au; use cssparser::{Parser, SourcePosition}; use euclid::size::TypedSize2D; use servo_url::ServoUrl; @@ -207,7 +206,7 @@ fn test_mq_default_expressions() { assert!(q.media_type == MediaQueryType::All, css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { - ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(100))), + ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)), _ => panic!("wrong expression type"), } }); @@ -219,7 +218,7 @@ fn test_mq_default_expressions() { assert!(q.media_type == MediaQueryType::All, css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { - ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(43))), + ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(43.)), _ => panic!("wrong expression type"), } }); @@ -234,7 +233,7 @@ fn test_mq_expressions() { assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { - ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(100))), + ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)), _ => panic!("wrong expression type"), } }); @@ -246,7 +245,7 @@ fn test_mq_expressions() { assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { - ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(43))), + ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(43.)), _ => panic!("wrong expression type"), } }); @@ -258,7 +257,7 @@ fn test_mq_expressions() { assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { - ExpressionKind::Width(Range::Eq(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(43))), + ExpressionKind::Width(Range::Eq(ref w)) => assert!(*w == specified::Length::from_px(43.)), _ => panic!("wrong expression type"), } }); @@ -270,7 +269,7 @@ fn test_mq_expressions() { assert!(q.media_type == MediaQueryType::Unknown(Atom::from("fridge")), css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { - ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(52))), + ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(52.)), _ => panic!("wrong expression type"), } }); @@ -295,11 +294,11 @@ fn test_mq_multiple_expressions() { assert!(q.media_type == MediaQueryType::All, css.to_owned()); assert!(q.expressions.len() == 2, css.to_owned()); match *q.expressions[0].kind_for_testing() { - ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(100))), + ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)), _ => panic!("wrong expression type"), } match *q.expressions[1].kind_for_testing() { - ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(200))), + ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(200.)), _ => panic!("wrong expression type"), } }); @@ -311,11 +310,11 @@ fn test_mq_multiple_expressions() { assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); assert!(q.expressions.len() == 2, css.to_owned()); match *q.expressions[0].kind_for_testing() { - ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(100))), + ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)), _ => panic!("wrong expression type"), } match *q.expressions[1].kind_for_testing() { - ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::Absolute(Au::from_px(200))), + ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(200.)), _ => panic!("wrong expression type"), } }); diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index ec608fa6ccb..4d83aad5905 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -5,7 +5,7 @@ pub use std::sync::Arc; pub use style::computed_values::display::T::inline_block; pub use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance, PropertyId}; -pub use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length}; +pub use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length, NoCalcLength}; pub use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent}; pub use style::properties::longhands::outline_color::computed_value::T as ComputedColor; pub use style::values::RGBA; @@ -19,15 +19,15 @@ fn property_declaration_block_should_serialize_correctly() { let declarations = vec![ (PropertyDeclaration::Width( - DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(70f32)))), + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)))), Importance::Normal), (PropertyDeclaration::MinHeight( - DeclaredValue::Value(LengthOrPercentage::Length(Length::from_px(20f32)))), + DeclaredValue::Value(LengthOrPercentage::Length(NoCalcLength::from_px(20f32)))), Importance::Normal), (PropertyDeclaration::Height( - DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(20f32)))), + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), Importance::Important), (PropertyDeclaration::Display( @@ -113,7 +113,7 @@ mod shorthand_serialization { fn all_equal_properties_should_serialize_to_one_value() { let mut properties = Vec::new(); - let px_70 = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(70f32))); + let px_70 = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32))); properties.push(PropertyDeclaration::MarginTop(px_70.clone())); properties.push(PropertyDeclaration::MarginRight(px_70.clone())); properties.push(PropertyDeclaration::MarginBottom(px_70.clone())); @@ -127,8 +127,8 @@ mod shorthand_serialization { fn equal_vertical_and_equal_horizontal_properties_should_serialize_to_two_value() { let mut properties = Vec::new(); - let vertical_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(10f32))); - let horizontal_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(5f32))); + let vertical_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(10f32))); + let horizontal_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(5f32))); properties.push(PropertyDeclaration::MarginTop(vertical_px.clone())); properties.push(PropertyDeclaration::MarginRight(horizontal_px.clone())); @@ -143,9 +143,9 @@ mod shorthand_serialization { fn different_vertical_and_equal_horizontal_properties_should_serialize_to_three_values() { let mut properties = Vec::new(); - let top_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(8f32))); - let bottom_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(10f32))); - let horizontal_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(5f32))); + let top_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(8f32))); + let bottom_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(10f32))); + let horizontal_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(5f32))); properties.push(PropertyDeclaration::MarginTop(top_px)); properties.push(PropertyDeclaration::MarginRight(horizontal_px.clone())); @@ -160,10 +160,10 @@ mod shorthand_serialization { fn different_properties_should_serialize_to_four_values() { let mut properties = Vec::new(); - let top_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(8f32))); - let right_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(12f32))); - let bottom_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(10f32))); - let left_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(Length::from_px(14f32))); + let top_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(8f32))); + let right_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(12f32))); + let bottom_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(10f32))); + let left_px = DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(14f32))); properties.push(PropertyDeclaration::MarginTop(top_px)); properties.push(PropertyDeclaration::MarginRight(right_px)); @@ -178,8 +178,8 @@ mod shorthand_serialization { fn padding_should_serialize_correctly() { let mut properties = Vec::new(); - let px_10 = DeclaredValue::Value(LengthOrPercentage::Length(Length::from_px(10f32))); - let px_15 = DeclaredValue::Value(LengthOrPercentage::Length(Length::from_px(15f32))); + let px_10 = DeclaredValue::Value(LengthOrPercentage::Length(NoCalcLength::from_px(10f32))); + let px_15 = DeclaredValue::Value(LengthOrPercentage::Length(NoCalcLength::from_px(15f32))); properties.push(PropertyDeclaration::PaddingTop(px_10.clone())); properties.push(PropertyDeclaration::PaddingRight(px_15.clone())); properties.push(PropertyDeclaration::PaddingBottom(px_10)); @@ -637,7 +637,7 @@ mod shorthand_serialization { let font_variant = DeclaredValue::Value(FontVariant::normal); let font_weight = DeclaredValue::Value(FontWeight::Bolder); let font_size = DeclaredValue::Value(FontSizeContainer( - LengthOrPercentage::Length(Length::from_px(4f32))) + LengthOrPercentage::Length(NoCalcLength::from_px(4f32))) ); let font_stretch = DeclaredValue::Value(FontStretch::expanded); let line_height = DeclaredValue::Value(LineHeight::Number(3f32)); @@ -718,14 +718,14 @@ mod shorthand_serialization { let position_x = single_vec_value_typedef!(position_x, HorizontalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))), } ); let position_y = single_vec_value_typedef!(position_y, VerticalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(4f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))), } ); @@ -738,8 +738,8 @@ mod shorthand_serialization { let size = single_vec_variant_value!(size, size::single_value::SpecifiedValue::Explicit( size::single_value::ExplicitSize { - width: LengthOrPercentageOrAuto::Length(Length::from_px(70f32)), - height: LengthOrPercentageOrAuto::Length(Length::from_px(50f32)) + width: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)), + height: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(50f32)) } ) ); @@ -778,14 +778,14 @@ mod shorthand_serialization { let position_x = single_vec_value_typedef!(position_x, HorizontalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))), } ); let position_y = single_vec_value_typedef!(position_y, VerticalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(4f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))), } ); @@ -798,8 +798,8 @@ mod shorthand_serialization { let size = single_vec_variant_value!(size, size::single_value::SpecifiedValue::Explicit( size::single_value::ExplicitSize { - width: LengthOrPercentageOrAuto::Length(Length::from_px(70f32)), - height: LengthOrPercentageOrAuto::Length(Length::from_px(50f32)) + width: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)), + height: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(50f32)) } ) ); @@ -837,14 +837,14 @@ mod shorthand_serialization { let position_x = single_vec_value_typedef!(position_x, HorizontalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(0f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(0f32))), } ); let position_y = single_vec_value_typedef!(position_y, VerticalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(0f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(0f32))), } ); @@ -922,11 +922,11 @@ mod shorthand_serialization { Position { horizontal: HorizontalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))), }, vertical: VerticalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(4f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))), }, } ); @@ -934,8 +934,8 @@ mod shorthand_serialization { let size = single_vec_variant_value!(size, size::single_value::SpecifiedValue::Explicit( size::single_value::ExplicitSize { - width: LengthOrPercentageOrAuto::Length(Length::from_px(70f32)), - height: LengthOrPercentageOrAuto::Length(Length::from_px(50f32)) + width: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)), + height: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(50f32)) } ) ); @@ -976,11 +976,11 @@ mod shorthand_serialization { Position { horizontal: HorizontalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(7f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(7f32))), }, vertical: VerticalPosition { keyword: None, - position: Some(LengthOrPercentage::Length(Length::from_px(4f32))), + position: Some(LengthOrPercentage::Length(NoCalcLength::from_px(4f32))), }, } ); @@ -988,8 +988,8 @@ mod shorthand_serialization { let size = single_vec_variant_value!(size, size::single_value::SpecifiedValue::Explicit( size::single_value::ExplicitSize { - width: LengthOrPercentageOrAuto::Length(Length::from_px(70f32)), - height: LengthOrPercentageOrAuto::Length(Length::from_px(50f32)) + width: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)), + height: LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(50f32)) } ) ); diff --git a/tests/unit/style/properties/viewport.rs b/tests/unit/style/properties/viewport.rs index 221e7d568bb..7e036a6e95d 100644 --- a/tests/unit/style/properties/viewport.rs +++ b/tests/unit/style/properties/viewport.rs @@ -6,21 +6,21 @@ use app_units::Au; use style::properties::{DeclaredValue, PropertyDeclaration}; use style::properties::longhands::border_top_width; use style::values::HasViewportPercentage; -use style::values::specified::{Length, ViewportPercentageLength}; +use style::values::specified::{Length, NoCalcLength, ViewportPercentageLength}; #[test] fn has_viewport_percentage_for_specified_value() { //TODO: test all specified value with a HasViewportPercentage impl let pvw = PropertyDeclaration::BorderTopWidth( DeclaredValue::Value(border_top_width::SpecifiedValue::from_length( - Length::ViewportPercentage(ViewportPercentageLength::Vw(100.)) + Length::NoCalc(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(100.))) )) ); assert!(pvw.has_viewport_percentage()); let pabs = PropertyDeclaration::BorderTopWidth( DeclaredValue::Value(border_top_width::SpecifiedValue::from_length( - Length::Absolute(Au(100)) + Length::NoCalc(NoCalcLength::Absolute(Au(100))) )) ); assert!(!pabs.has_viewport_percentage()); diff --git a/tests/unit/style/value.rs b/tests/unit/style/value.rs index 4f9944e324d..472a5177d30 100644 --- a/tests/unit/style/value.rs +++ b/tests/unit/style/value.rs @@ -5,14 +5,14 @@ use app_units::Au; use cssparser::Parser; use style::values::HasViewportPercentage; -use style::values::specified::{ViewportPercentageLength, Length}; +use style::values::specified::{ViewportPercentageLength, NoCalcLength}; use style::values::specified::length::{CalcLengthOrPercentage, CalcUnit}; #[test] fn length_has_viewport_percentage() { - let l = Length::ViewportPercentage(ViewportPercentageLength::Vw(100.)); + let l = NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(100.)); assert!(l.has_viewport_percentage()); - let l = Length::Absolute(Au(100)); + let l = NoCalcLength::Absolute(Au(100)); assert!(!l.has_viewport_percentage()); } diff --git a/tests/unit/style/viewport.rs b/tests/unit/style/viewport.rs index dce0deafca8..d01a00363bf 100644 --- a/tests/unit/style/viewport.rs +++ b/tests/unit/style/viewport.rs @@ -12,8 +12,8 @@ use style::error_reporting::ParseErrorReporter; use style::media_queries::{Device, MediaType}; use style::parser::{ParserContext, ParserContextExtraData}; use style::stylesheets::{Stylesheet, Origin}; -use style::values::specified::Length::{self, ViewportPercentage}; use style::values::specified::LengthOrPercentageOrAuto::{self, Auto}; +use style::values::specified::NoCalcLength::{self, ViewportPercentage}; use style::values::specified::ViewportPercentageLength::Vw; use style::viewport::*; use style_traits::viewport::*; @@ -80,7 +80,7 @@ macro_rules! assert_decl_len { macro_rules! viewport_length { ($value:expr, px) => { - ViewportLength::Specified(LengthOrPercentageOrAuto::Length(Length::from_px($value))) + ViewportLength::Specified(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px($value))) }; ($value:expr, vw) => { ViewportLength::Specified(LengthOrPercentageOrAuto::Length(ViewportPercentage(Vw($value))))