aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko/conversions.rs97
-rw-r--r--components/style/gecko/values.rs56
-rw-r--r--components/style/gecko_bindings/sugar/ns_css_value.rs20
-rw-r--r--components/style/properties/gecko.mako.rs15
-rw-r--r--components/style/properties/longhands/inherited_text.mako.rs2
-rw-r--r--components/style/properties/longhands/margin.mako.rs2
-rw-r--r--components/style/stylesheets/viewport_rule.rs16
-rw-r--r--components/style/values/animated/length.rs63
-rw-r--r--components/style/values/animated/mod.rs4
-rw-r--r--components/style/values/animated/svg.rs16
-rw-r--r--components/style/values/animated/transform.rs25
-rw-r--r--components/style/values/computed/image.rs13
-rw-r--r--components/style/values/computed/length.rs467
-rw-r--r--components/style/values/computed/mod.rs2
-rw-r--r--components/style/values/computed/position.rs4
-rw-r--r--components/style/values/computed/transform.rs4
-rw-r--r--components/style/values/generics/text.rs5
-rw-r--r--components/style/values/generics/transform.rs10
-rw-r--r--components/style/values/specified/font.rs4
-rw-r--r--components/style/values/specified/length.rs128
-rw-r--r--components/style/values/specified/position.rs27
-rw-r--r--components/style/values/specified/transform.rs4
22 files changed, 339 insertions, 645 deletions
diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs
index 266ebbd750a..08d0557f896 100644
--- a/components/style/gecko/conversions.rs
+++ b/components/style/gecko/conversions.rs
@@ -20,7 +20,7 @@ use crate::stylesheets::{Origin, RulesMutateError};
use crate::values::computed::image::LineDirection;
use crate::values::computed::transform::Matrix3D;
use crate::values::computed::url::ComputedImageUrl;
-use crate::values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
+use crate::values::computed::{Angle, Gradient, Image};
use crate::values::computed::{Integer, LengthOrPercentage};
use crate::values::computed::{LengthOrPercentageOrAuto, NonNegativeLengthOrPercentageOrAuto};
use crate::values::computed::{Percentage, TextAlign};
@@ -31,9 +31,10 @@ use crate::values::generics::rect::Rect;
use crate::values::generics::NonNegative;
use app_units::Au;
use std::f32::consts::PI;
+use style_traits::values::specified::AllowedNumericType;
-impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
- fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
+impl From<LengthOrPercentage> for nsStyleCoord_CalcValue {
+ fn from(other: LengthOrPercentage) -> nsStyleCoord_CalcValue {
let has_percentage = other.percentage.is_some();
nsStyleCoord_CalcValue {
mLength: other.unclamped_length().to_i32_au(),
@@ -43,32 +44,19 @@ impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
}
}
-impl From<nsStyleCoord_CalcValue> for CalcLengthOrPercentage {
- fn from(other: nsStyleCoord_CalcValue) -> CalcLengthOrPercentage {
+impl From<nsStyleCoord_CalcValue> for LengthOrPercentage {
+ fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentage {
let percentage = if other.mHasPercent {
Some(Percentage(other.mPercent))
} else {
None
};
- Self::new(Au(other.mLength).into(), percentage)
- }
-}
-
-impl From<LengthOrPercentage> for nsStyleCoord_CalcValue {
- fn from(other: LengthOrPercentage) -> nsStyleCoord_CalcValue {
- match other {
- LengthOrPercentage::Length(px) => nsStyleCoord_CalcValue {
- mLength: px.to_i32_au(),
- mPercent: 0.0,
- mHasPercent: false,
- },
- LengthOrPercentage::Percentage(pc) => nsStyleCoord_CalcValue {
- mLength: 0,
- mPercent: pc.0,
- mHasPercent: true,
- },
- LengthOrPercentage::Calc(calc) => calc.into(),
- }
+ Self::with_clamping_mode(
+ Au(other.mLength).into(),
+ percentage,
+ AllowedNumericType::All,
+ /* was_calc = */ true,
+ )
}
}
@@ -76,39 +64,15 @@ impl LengthOrPercentageOrAuto {
/// Convert this value in an appropriate `nsStyleCoord::CalcValue`.
pub fn to_calc_value(&self) -> Option<nsStyleCoord_CalcValue> {
match *self {
- LengthOrPercentageOrAuto::Length(px) => Some(nsStyleCoord_CalcValue {
- mLength: px.to_i32_au(),
- mPercent: 0.0,
- mHasPercent: false,
- }),
- LengthOrPercentageOrAuto::Percentage(pc) => Some(nsStyleCoord_CalcValue {
- mLength: 0,
- mPercent: pc.0,
- mHasPercent: true,
- }),
- LengthOrPercentageOrAuto::Calc(calc) => Some(calc.into()),
+ LengthOrPercentageOrAuto::LengthOrPercentage(len) => Some(From::from(len)),
LengthOrPercentageOrAuto::Auto => None,
}
}
}
-impl From<nsStyleCoord_CalcValue> for LengthOrPercentage {
- fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentage {
- match (other.mHasPercent, other.mLength) {
- (false, _) => LengthOrPercentage::Length(Au(other.mLength).into()),
- (true, 0) => LengthOrPercentage::Percentage(Percentage(other.mPercent)),
- _ => LengthOrPercentage::Calc(other.into()),
- }
- }
-}
-
impl From<nsStyleCoord_CalcValue> for LengthOrPercentageOrAuto {
fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentageOrAuto {
- match (other.mHasPercent, other.mLength) {
- (false, _) => LengthOrPercentageOrAuto::Length(Au(other.mLength).into()),
- (true, 0) => LengthOrPercentageOrAuto::Percentage(Percentage(other.mPercent)),
- _ => LengthOrPercentageOrAuto::Calc(other.into()),
- }
+ LengthOrPercentageOrAuto::LengthOrPercentage(LengthOrPercentage::from(other))
}
}
@@ -116,9 +80,8 @@ impl From<nsStyleCoord_CalcValue> for LengthOrPercentageOrAuto {
// disappear as we move more stuff to cbindgen.
impl From<nsStyleCoord_CalcValue> for NonNegativeLengthOrPercentageOrAuto {
fn from(other: nsStyleCoord_CalcValue) -> Self {
- use style_traits::values::specified::AllowedNumericType;
- NonNegative(if other.mLength < 0 || other.mPercent < 0. {
- LengthOrPercentageOrAuto::Calc(CalcLengthOrPercentage::with_clamping_mode(
+ NonNegative(
+ LengthOrPercentageOrAuto::LengthOrPercentage(LengthOrPercentage::with_clamping_mode(
Au(other.mLength).into(),
if other.mHasPercent {
Some(Percentage(other.mPercent))
@@ -126,10 +89,9 @@ impl From<nsStyleCoord_CalcValue> for NonNegativeLengthOrPercentageOrAuto {
None
},
AllowedNumericType::NonNegative,
+ /* was_calc = */ true,
))
- } else {
- other.into()
- })
+ )
}
}
@@ -143,20 +105,13 @@ fn line_direction(horizontal: LengthOrPercentage, vertical: LengthOrPercentage)
use crate::values::computed::position::Position;
use crate::values::specified::position::{X, Y};
- let horizontal_percentage = match horizontal {
- LengthOrPercentage::Percentage(percentage) => Some(percentage.0),
- _ => None,
- };
-
- let vertical_percentage = match vertical {
- LengthOrPercentage::Percentage(percentage) => Some(percentage.0),
- _ => None,
- };
+ let horizontal_percentage = horizontal.as_percentage();
+ let vertical_percentage = vertical.as_percentage();
let horizontal_as_corner = horizontal_percentage.and_then(|percentage| {
- if percentage == 0.0 {
+ if percentage.0 == 0.0 {
Some(X::Left)
- } else if percentage == 1.0 {
+ } else if percentage.0 == 1.0 {
Some(X::Right)
} else {
None
@@ -164,9 +119,9 @@ fn line_direction(horizontal: LengthOrPercentage, vertical: LengthOrPercentage)
});
let vertical_as_corner = vertical_percentage.and_then(|percentage| {
- if percentage == 0.0 {
+ if percentage.0 == 0.0 {
Some(Y::Top)
- } else if percentage == 1.0 {
+ } else if percentage.0 == 1.0 {
Some(Y::Bottom)
} else {
None
@@ -178,13 +133,13 @@ fn line_direction(horizontal: LengthOrPercentage, vertical: LengthOrPercentage)
}
if let Some(hc) = horizontal_as_corner {
- if vertical_percentage == Some(0.5) {
+ if vertical_percentage == Some(Percentage(0.5)) {
return LineDirection::Horizontal(hc);
}
}
if let Some(vc) = vertical_as_corner {
- if horizontal_percentage == Some(0.5) {
+ if horizontal_percentage == Some(Percentage(0.5)) {
return LineDirection::Vertical(vc);
}
}
diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs
index 39a5ac2de89..3c11d11e311 100644
--- a/components/style/gecko/values.rs
+++ b/components/style/gecko/values.rs
@@ -148,19 +148,21 @@ impl GeckoStyleCoordConvertible for NumberOrPercentage {
impl GeckoStyleCoordConvertible for LengthOrPercentage {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
- let value = match *self {
- LengthOrPercentage::Length(px) => CoordDataValue::Coord(px.to_i32_au()),
- LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p.0),
- LengthOrPercentage::Calc(calc) => CoordDataValue::Calc(calc.into()),
- };
- coord.set_value(value);
+ if self.was_calc {
+ return coord.set_value(CoordDataValue::Calc((*self).into()))
+ }
+ debug_assert!(self.percentage.is_none() || self.unclamped_length() == Length::zero());
+ if let Some(p) = self.percentage {
+ return coord.set_value(CoordDataValue::Percent(p.0));
+ }
+ coord.set_value(CoordDataValue::Coord(self.unclamped_length().to_i32_au()))
}
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
- CoordDataValue::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord).into())),
- CoordDataValue::Percent(p) => Some(LengthOrPercentage::Percentage(Percentage(p))),
- CoordDataValue::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())),
+ CoordDataValue::Coord(coord) => Some(LengthOrPercentage::new(Au(coord).into(), None)),
+ CoordDataValue::Percent(p) => Some(LengthOrPercentage::new(Au(0).into(), Some(Percentage(p)))),
+ CoordDataValue::Calc(calc) => Some(calc.into()),
_ => None,
}
}
@@ -181,48 +183,32 @@ impl GeckoStyleCoordConvertible for Length {
impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
- let value = match *self {
- LengthOrPercentageOrAuto::Length(px) => CoordDataValue::Coord(px.to_i32_au()),
- LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p.0),
- LengthOrPercentageOrAuto::Auto => CoordDataValue::Auto,
- LengthOrPercentageOrAuto::Calc(calc) => CoordDataValue::Calc(calc.into()),
- };
- coord.set_value(value);
+ match *self {
+ LengthOrPercentageOrAuto::Auto => coord.set_value(CoordDataValue::Auto),
+ LengthOrPercentageOrAuto::LengthOrPercentage(ref lop) => lop.to_gecko_style_coord(coord),
+ }
}
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
- CoordDataValue::Coord(coord) => {
- Some(LengthOrPercentageOrAuto::Length(Au(coord).into()))
- },
- CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(Percentage(p))),
CoordDataValue::Auto => Some(LengthOrPercentageOrAuto::Auto),
- CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())),
- _ => None,
+ _ => LengthOrPercentage::from_gecko_style_coord(coord).map(LengthOrPercentageOrAuto::LengthOrPercentage),
}
}
}
impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
- let value = match *self {
- LengthOrPercentageOrNone::Length(px) => CoordDataValue::Coord(px.to_i32_au()),
- LengthOrPercentageOrNone::Percentage(p) => CoordDataValue::Percent(p.0),
- LengthOrPercentageOrNone::None => CoordDataValue::None,
- LengthOrPercentageOrNone::Calc(calc) => CoordDataValue::Calc(calc.into()),
- };
- coord.set_value(value);
+ match *self {
+ LengthOrPercentageOrNone::None => coord.set_value(CoordDataValue::None),
+ LengthOrPercentageOrNone::LengthOrPercentage(ref lop) => lop.to_gecko_style_coord(coord),
+ }
}
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
- CoordDataValue::Coord(coord) => {
- Some(LengthOrPercentageOrNone::Length(Au(coord).into()))
- },
- CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(Percentage(p))),
CoordDataValue::None => Some(LengthOrPercentageOrNone::None),
- CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
- _ => None,
+ _ => LengthOrPercentage::from_gecko_style_coord(coord).map(LengthOrPercentageOrNone::LengthOrPercentage),
}
}
}
diff --git a/components/style/gecko_bindings/sugar/ns_css_value.rs b/components/style/gecko_bindings/sugar/ns_css_value.rs
index aa4f9947cd2..f9ed43f7a3d 100644
--- a/components/style/gecko_bindings/sugar/ns_css_value.rs
+++ b/components/style/gecko_bindings/sugar/ns_css_value.rs
@@ -69,11 +69,14 @@ impl nsCSSValue {
/// Sets LengthOrPercentage value to this nsCSSValue.
pub unsafe fn set_lop(&mut self, lop: LengthOrPercentage) {
- match lop {
- LengthOrPercentage::Length(px) => self.set_px(px.px()),
- LengthOrPercentage::Percentage(pc) => self.set_percentage(pc.0),
- LengthOrPercentage::Calc(calc) => bindings::Gecko_CSSValue_SetCalc(self, calc.into()),
+ if lop.was_calc {
+ return bindings::Gecko_CSSValue_SetCalc(self, lop.into())
}
+ debug_assert!(lop.percentage.is_none() || lop.unclamped_length() == Length::zero());
+ if let Some(p) = lop.percentage {
+ return self.set_percentage(p.0);
+ }
+ self.set_px(lop.unclamped_length().px());
}
/// Sets a px value to this nsCSSValue.
@@ -90,13 +93,16 @@ impl nsCSSValue {
pub unsafe fn get_lop(&self) -> LengthOrPercentage {
match self.mUnit {
nsCSSUnit::eCSSUnit_Pixel => {
- LengthOrPercentage::Length(Length::new(bindings::Gecko_CSSValue_GetNumber(self)))
+ LengthOrPercentage::new(
+ Length::new(bindings::Gecko_CSSValue_GetNumber(self)),
+ None,
+ )
},
- nsCSSUnit::eCSSUnit_Percent => LengthOrPercentage::Percentage(Percentage(
+ nsCSSUnit::eCSSUnit_Percent => LengthOrPercentage::new_percent(Percentage(
bindings::Gecko_CSSValue_GetPercentage(self),
)),
nsCSSUnit::eCSSUnit_Calc => {
- LengthOrPercentage::Calc(bindings::Gecko_CSSValue_GetCalc(self).into())
+ bindings::Gecko_CSSValue_GetCalc(self).into()
},
_ => panic!("Unexpected unit"),
}
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index d969f14f54a..036653d218e 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -558,18 +558,16 @@ def set_gecko_property(ffi_name, expr):
},
CoordDataValue::Coord(coord) => {
SvgLengthOrPercentageOrNumber::LengthOrPercentage(
- LengthOrPercentage::Length(Au(coord).into())
+ LengthOrPercentage::new(Au(coord).into(), None)
)
},
CoordDataValue::Percent(p) => {
SvgLengthOrPercentageOrNumber::LengthOrPercentage(
- LengthOrPercentage::Percentage(Percentage(p))
+ LengthOrPercentage::new(Au(0).into(), Some(Percentage(p)))
)
},
CoordDataValue::Calc(calc) => {
- SvgLengthOrPercentageOrNumber::LengthOrPercentage(
- LengthOrPercentage::Calc(calc.into())
- )
+ SvgLengthOrPercentageOrNumber::LengthOrPercentage(calc.into())
},
_ => unreachable!("Unexpected coordinate in ${ident}"),
};
@@ -5062,6 +5060,7 @@ clip-path
pub fn clone_stroke_dasharray(&self) -> longhands::stroke_dasharray::computed_value::T {
use crate::gecko_bindings::structs::nsStyleSVG_STROKE_DASHARRAY_CONTEXT as CONTEXT_VALUE;
use crate::values::computed::LengthOrPercentage;
+ use crate::values::generics::NonNegative;
use crate::values::generics::svg::{SVGStrokeDashArray, SvgLengthOrPercentageOrNumber};
if self.gecko.mContextFlags & CONTEXT_VALUE != 0 {
@@ -5075,13 +5074,13 @@ clip-path
vec.push(SvgLengthOrPercentageOrNumber::Number(number.into())),
CoordDataValue::Coord(coord) =>
vec.push(SvgLengthOrPercentageOrNumber::LengthOrPercentage(
- LengthOrPercentage::Length(Au(coord).into()).into())),
+ NonNegative(LengthOrPercentage::new(Au(coord).into(), None).into()))),
CoordDataValue::Percent(p) =>
vec.push(SvgLengthOrPercentageOrNumber::LengthOrPercentage(
- LengthOrPercentage::Percentage(Percentage(p)).into())),
+ NonNegative(LengthOrPercentage::new_percent(Percentage(p)).into()))),
CoordDataValue::Calc(calc) =>
vec.push(SvgLengthOrPercentageOrNumber::LengthOrPercentage(
- LengthOrPercentage::Calc(calc.into()).into())),
+ NonNegative(LengthOrPercentage::from(calc).clamp_to_non_negative()))),
_ => unreachable!(),
}
}
diff --git a/components/style/properties/longhands/inherited_text.mako.rs b/components/style/properties/longhands/inherited_text.mako.rs
index 5a7b88e3823..3eded4ea7ac 100644
--- a/components/style/properties/longhands/inherited_text.mako.rs
+++ b/components/style/properties/longhands/inherited_text.mako.rs
@@ -54,7 +54,7 @@ ${helpers.single_keyword(
${helpers.predefined_type(
"text-indent",
"LengthOrPercentage",
- "computed::LengthOrPercentage::Length(computed::Length::new(0.))",
+ "computed::LengthOrPercentage::zero()",
animation_value_type="ComputedValue",
spec="https://drafts.csswg.org/css-text/#propdef-text-indent",
allow_quirks=True,
diff --git a/components/style/properties/longhands/margin.mako.rs b/components/style/properties/longhands/margin.mako.rs
index 822fbf798a7..7762be1a23a 100644
--- a/components/style/properties/longhands/margin.mako.rs
+++ b/components/style/properties/longhands/margin.mako.rs
@@ -15,7 +15,7 @@
${helpers.predefined_type(
"margin-%s" % side[0],
"LengthOrPercentageOrAuto",
- "computed::LengthOrPercentageOrAuto::Length(computed::Length::new(0.))",
+ "computed::LengthOrPercentageOrAuto::zero()",
alias=maybe_moz_logical_alias(product, side, "-moz-margin-%s"),
allow_quirks=not side[1],
animation_value_type="ComputedValue",
diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs
index 4df576a15ab..209243228df 100644
--- a/components/style/stylesheets/viewport_rule.rs
+++ b/components/style/stylesheets/viewport_rule.rs
@@ -18,7 +18,7 @@ use crate::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard
use crate::str::CssStringWriter;
use crate::stylesheets::{Origin, StylesheetInDocument};
use crate::values::computed::{Context, ToComputedValue};
-use crate::values::specified::{LengthOrPercentageOrAuto, NoCalcLength, ViewportPercentageLength};
+use crate::values::specified::{self, LengthOrPercentageOrAuto, NoCalcLength, ViewportPercentageLength};
use app_units::Au;
use cssparser::CowRcStr;
use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
@@ -157,7 +157,9 @@ impl FromMeta for ViewportLength {
fn from_meta(value: &str) -> Option<ViewportLength> {
macro_rules! specified {
($value:expr) => {
- ViewportLength::Specified(LengthOrPercentageOrAuto::Length($value))
+ ViewportLength::Specified(LengthOrPercentageOrAuto::LengthOrPercentage(
+ specified::LengthOrPercentage::Length($value)
+ ))
};
}
@@ -752,16 +754,10 @@ impl MaybeNew for ViewportConstraints {
if let Some($value) = $value {
match *$value {
ViewportLength::Specified(ref length) => match *length {
- LengthOrPercentageOrAuto::Length(ref value) => {
- Some(Au::from(value.to_computed_value(&context)))
- },
- LengthOrPercentageOrAuto::Percentage(value) => {
- Some(initial_viewport.$dimension.scale_by(value.0))
- },
LengthOrPercentageOrAuto::Auto => None,
- LengthOrPercentageOrAuto::Calc(ref calc) => calc
+ LengthOrPercentageOrAuto::LengthOrPercentage(ref lop) => Some(lop
.to_computed_value(&context)
- .to_used_value(Some(initial_viewport.$dimension)),
+ .to_used_value(initial_viewport.$dimension)),
},
ViewportLength::ExtendToZoom => {
// $extend_to will be 'None' if 'extend-to-zoom' is 'auto'
diff --git a/components/style/values/animated/length.rs b/components/style/values/animated/length.rs
index e303d2fcfce..b0d717b0e49 100644
--- a/components/style/values/animated/length.rs
+++ b/components/style/values/animated/length.rs
@@ -4,15 +4,14 @@
//! Animation implementation for various length-related types.
-use super::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
-use crate::values::computed::length::{CalcLengthOrPercentage, Length};
-use crate::values::computed::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
+use super::{Animate, Procedure, ToAnimatedValue};
+use crate::values::computed::length::LengthOrPercentage;
use crate::values::computed::MaxLength as ComputedMaxLength;
use crate::values::computed::MozLength as ComputedMozLength;
use crate::values::computed::Percentage;
/// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc>
-impl Animate for CalcLengthOrPercentage {
+impl Animate for LengthOrPercentage {
#[inline]
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
let animate_percentage_half = |this: Option<Percentage>, other: Option<Percentage>| {
@@ -28,42 +27,17 @@ impl Animate for CalcLengthOrPercentage {
.unclamped_length()
.animate(&other.unclamped_length(), procedure)?;
let percentage = animate_percentage_half(self.percentage, other.percentage)?;
- Ok(CalcLengthOrPercentage::with_clamping_mode(
+ let is_calc = self.was_calc || other.was_calc || self.percentage.is_some() != other.percentage.is_some();
+ Ok(Self::with_clamping_mode(
length,
percentage,
self.clamping_mode,
+ is_calc,
))
}
}
-impl ToAnimatedZero for LengthOrPercentageOrAuto {
- #[inline]
- fn to_animated_zero(&self) -> Result<Self, ()> {
- match *self {
- LengthOrPercentageOrAuto::Length(_) |
- LengthOrPercentageOrAuto::Percentage(_) |
- LengthOrPercentageOrAuto::Calc(_) => {
- Ok(LengthOrPercentageOrAuto::Length(Length::new(0.)))
- },
- LengthOrPercentageOrAuto::Auto => Err(()),
- }
- }
-}
-
-impl ToAnimatedZero for LengthOrPercentageOrNone {
- #[inline]
- fn to_animated_zero(&self) -> Result<Self, ()> {
- match *self {
- LengthOrPercentageOrNone::Length(_) |
- LengthOrPercentageOrNone::Percentage(_) |
- LengthOrPercentageOrNone::Calc(_) => {
- Ok(LengthOrPercentageOrNone::Length(Length::new(0.)))
- },
- LengthOrPercentageOrNone::None => Err(()),
- }
- }
-}
-
+// FIXME(emilio): These should use NonNegative<> instead.
impl ToAnimatedValue for ComputedMaxLength {
type AnimatedValue = Self;
@@ -74,18 +48,15 @@ impl ToAnimatedValue for ComputedMaxLength {
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
- use crate::values::computed::{Length, LengthOrPercentageOrNone, Percentage};
+ use crate::values::computed::LengthOrPercentageOrNone;
use crate::values::generics::length::MaxLength as GenericMaxLength;
match animated {
GenericMaxLength::LengthOrPercentageOrNone(lopn) => {
let result = match lopn {
- LengthOrPercentageOrNone::Length(px) => {
- LengthOrPercentageOrNone::Length(Length::new(px.px().max(0.)))
+ LengthOrPercentageOrNone::LengthOrPercentage(len) => {
+ LengthOrPercentageOrNone::LengthOrPercentage(len.clamp_to_non_negative())
},
- LengthOrPercentageOrNone::Percentage(percentage) => {
- LengthOrPercentageOrNone::Percentage(Percentage(percentage.0.max(0.)))
- },
- _ => lopn,
+ LengthOrPercentageOrNone::None => lopn,
};
GenericMaxLength::LengthOrPercentageOrNone(result)
},
@@ -104,20 +75,10 @@ impl ToAnimatedValue for ComputedMozLength {
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
- use crate::values::computed::{Length, LengthOrPercentageOrAuto, Percentage};
use crate::values::generics::length::MozLength as GenericMozLength;
match animated {
GenericMozLength::LengthOrPercentageOrAuto(lopa) => {
- let result = match lopa {
- LengthOrPercentageOrAuto::Length(px) => {
- LengthOrPercentageOrAuto::Length(Length::new(px.px().max(0.)))
- },
- LengthOrPercentageOrAuto::Percentage(percentage) => {
- LengthOrPercentageOrAuto::Percentage(Percentage(percentage.0.max(0.)))
- },
- _ => lopa,
- };
- GenericMozLength::LengthOrPercentageOrAuto(result)
+ GenericMozLength::LengthOrPercentageOrAuto(lopa.clamp_to_non_negative())
},
_ => animated,
}
diff --git a/components/style/values/animated/mod.rs b/components/style/values/animated/mod.rs
index a7c947f810a..1655f2eaa26 100644
--- a/components/style/values/animated/mod.rs
+++ b/components/style/values/animated/mod.rs
@@ -9,7 +9,7 @@
//! module's raison d'être is to ultimately contain all these types.
use crate::properties::PropertyId;
-use crate::values::computed::length::CalcLengthOrPercentage;
+use crate::values::computed::length::LengthOrPercentage;
use crate::values::computed::url::ComputedUrl;
use crate::values::computed::Angle as ComputedAngle;
use crate::values::computed::Image;
@@ -335,7 +335,7 @@ macro_rules! trivial_to_animated_value {
}
trivial_to_animated_value!(Au);
-trivial_to_animated_value!(CalcLengthOrPercentage);
+trivial_to_animated_value!(LengthOrPercentage);
trivial_to_animated_value!(ComputedAngle);
trivial_to_animated_value!(ComputedUrl);
trivial_to_animated_value!(bool);
diff --git a/components/style/values/animated/svg.rs b/components/style/values/animated/svg.rs
index 1d8be90fb6e..7123542aef8 100644
--- a/components/style/values/animated/svg.rs
+++ b/components/style/values/animated/svg.rs
@@ -32,10 +32,16 @@ fn to_number_or_percentage(
value: &SvgLengthOrPercentageOrNumber<LengthOrPercentage, Number>,
) -> Result<NumberOrPercentage, ()> {
Ok(match *value {
- SvgLengthOrPercentageOrNumber::LengthOrPercentage(ref l) => match *l {
- LengthOrPercentage::Length(ref l) => NumberOrPercentage::Number(l.px()),
- LengthOrPercentage::Percentage(ref p) => NumberOrPercentage::Percentage(*p),
- LengthOrPercentage::Calc(..) => return Err(()),
+ SvgLengthOrPercentageOrNumber::LengthOrPercentage(ref l) => {
+ match l.percentage {
+ Some(p) => {
+ if l.unclamped_length().px() != 0. {
+ return Err(());
+ }
+ NumberOrPercentage::Percentage(p)
+ }
+ None => NumberOrPercentage::Number(l.length().px())
+ }
},
SvgLengthOrPercentageOrNumber::Number(ref n) => NumberOrPercentage::Number(*n),
})
@@ -55,7 +61,7 @@ impl Animate for SvgLengthOrPercentageOrNumber<LengthOrPercentage, Number> {
NumberOrPercentage::Percentage(ref this),
NumberOrPercentage::Percentage(ref other),
) => Ok(SvgLengthOrPercentageOrNumber::LengthOrPercentage(
- LengthOrPercentage::Percentage(this.animate(other, procedure)?),
+ LengthOrPercentage::new_percent(this.animate(other, procedure)?),
)),
_ => Err(()),
}
diff --git a/components/style/values/animated/transform.rs b/components/style/values/animated/transform.rs
index 5223a195075..2804f4c0890 100644
--- a/components/style/values/animated/transform.rs
+++ b/components/style/values/animated/transform.rs
@@ -1167,17 +1167,6 @@ impl Animate for ComputedTransformOperation {
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1318591#c0.
impl ComputeSquaredDistance for ComputedTransformOperation {
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
- // For translate, We don't want to require doing layout in order to calculate the result, so
- // drop the percentage part. However, dropping percentage makes us impossible to
- // compute the distance for the percentage-percentage case, but Gecko uses the
- // same formula, so it's fine for now.
- // Note: We use pixel value to compute the distance for translate, so we have to
- // convert Au into px.
- let extract_pixel_length = |lop: &LengthOrPercentage| match *lop {
- LengthOrPercentage::Length(px) => px.px(),
- LengthOrPercentage::Percentage(_) => 0.,
- LengthOrPercentage::Calc(calc) => calc.length().px(),
- };
match (self, other) {
(&TransformOperation::Matrix3D(ref this), &TransformOperation::Matrix3D(ref other)) => {
this.compute_squared_distance(other)
@@ -1199,10 +1188,16 @@ impl ComputeSquaredDistance for ComputedTransformOperation {
&TransformOperation::Translate3D(ref fx, ref fy, ref fz),
&TransformOperation::Translate3D(ref tx, ref ty, ref tz),
) => {
- let fx = extract_pixel_length(&fx);
- let fy = extract_pixel_length(&fy);
- let tx = extract_pixel_length(&tx);
- let ty = extract_pixel_length(&ty);
+ // For translate, We don't want to require doing layout in order
+ // to calculate the result, so drop the percentage part.
+ //
+ // However, dropping percentage makes us impossible to compute
+ // the distance for the percentage-percentage case, but Gecko
+ // uses the same formula, so it's fine for now.
+ let fx = fx.length_component().px();
+ let fy = fy.length_component().px();
+ let tx = tx.length_component().px();
+ let ty = ty.length_component().px();
Ok(fx.compute_squared_distance(&tx)? +
fy.compute_squared_distance(&ty)? +
diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs
index ba18e4b30c8..1c573ac3a2b 100644
--- a/components/style/values/computed/image.rs
+++ b/components/style/values/computed/image.rs
@@ -9,8 +9,6 @@
use crate::values::computed::position::Position;
use crate::values::computed::url::ComputedImageUrl;
-#[cfg(feature = "gecko")]
-use crate::values::computed::Percentage;
use crate::values::computed::{Angle, Color, Context};
use crate::values::computed::{Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue};
use crate::values::generics::image::{self as generic, CompatMode};
@@ -73,15 +71,10 @@ impl generic::LineDirection for LineDirection {
LineDirection::Vertical(Y::Top) if compat_mode != CompatMode::Modern => true,
LineDirection::Corner(..) => false,
#[cfg(feature = "gecko")]
- LineDirection::MozPosition(
- Some(Position {
- horizontal: LengthOrPercentage::Percentage(Percentage(x)),
- vertical: LengthOrPercentage::Percentage(Percentage(y)),
- }),
- None,
- ) => {
+ LineDirection::MozPosition(Some(Position { ref vertical, ref horizontal }), None) => {
// `50% 0%` is the default value for line direction.
- x == 0.5 && y == 0.0
+ horizontal.as_percentage().map_or(false, |p| p.0 == 0.5) &&
+ vertical.as_percentage().map_or(false, |p| p.0 == 0.0)
},
_ => false,
}
diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs
index 240b5ceb1ee..8a9425ee631 100644
--- a/components/style/values/computed/length.rs
+++ b/components/style/values/computed/length.rs
@@ -5,7 +5,7 @@
//! `<length>` computed values, and related ones.
use super::{Context, Number, Percentage, ToComputedValue};
-use crate::values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
+use crate::values::animated::{ToAnimatedValue};
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
use crate::values::generics::length::MaxLength as GenericMaxLength;
use crate::values::generics::length::MozLength as GenericMozLength;
@@ -68,15 +68,38 @@ impl ToComputedValue for specified::Length {
}
#[allow(missing_docs)]
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedZero)]
-pub struct CalcLengthOrPercentage {
+#[derive(Clone, Copy, Debug, MallocSizeOf, ToAnimatedZero)]
+pub struct LengthOrPercentage {
#[animation(constant)]
pub clamping_mode: AllowedNumericType,
length: Length,
pub percentage: Option<Percentage>,
+ /// Whether this was from a calc() expression. This is needed because right
+ /// now we don't treat calc() the same way as non-calc everywhere, but
+ /// that's a bug in most cases.
+ ///
+ /// Please don't add new uses of this that aren't for converting to Gecko's
+ /// representation, or to interpolate values.
+ ///
+ /// See https://github.com/w3c/csswg-drafts/issues/3482.
+ #[animation(constant)]
+ pub was_calc: bool,
}
-impl ComputeSquaredDistance for CalcLengthOrPercentage {
+// FIXME(emilio): This is a bit of a hack that can disappear as soon as we share
+// representation of LengthOrPercentage with Gecko. The issue here is that Gecko
+// uses CalcValue to represent position components, so they always come back as
+// was_calc == true, and we mess up in the transitions code.
+//
+// This was a pre-existing bug, though arguably so only in pretty obscure cases
+// like calc(0px + 5%) and such.
+impl PartialEq for LengthOrPercentage {
+ fn eq(&self, other: &Self) -> bool {
+ self.length == other.length && self.percentage == other.percentage
+ }
+}
+
+impl ComputeSquaredDistance for LengthOrPercentage {
#[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
// FIXME(nox): This looks incorrect to me, to add a distance between lengths
@@ -89,24 +112,36 @@ impl ComputeSquaredDistance for CalcLengthOrPercentage {
}
}
-impl CalcLengthOrPercentage {
- /// Returns a new `CalcLengthOrPercentage`.
+impl LengthOrPercentage {
+ /// Returns a new `LengthOrPercentage`.
#[inline]
pub fn new(length: Length, percentage: Option<Percentage>) -> Self {
- Self::with_clamping_mode(length, percentage, AllowedNumericType::All)
+ Self::with_clamping_mode(
+ length,
+ percentage,
+ AllowedNumericType::All,
+ /* was_calc = */ false,
+ )
+ }
+
+ /// Returns a new `LengthOrPercentage` with zero length and some percentage.
+ pub fn new_percent(percentage: Percentage) -> Self {
+ Self::new(Length::zero(), Some(percentage))
}
- /// Returns a new `CalcLengthOrPercentage` with a specific clamping mode.
+ /// Returns a new `LengthOrPercentage` with a specific clamping mode.
#[inline]
pub fn with_clamping_mode(
length: Length,
percentage: Option<Percentage>,
clamping_mode: AllowedNumericType,
+ was_calc: bool,
) -> Self {
Self {
clamping_mode,
length,
percentage,
+ was_calc,
}
}
@@ -131,22 +166,38 @@ impl CalcLengthOrPercentage {
self.length
}
+
/// Return the percentage value as CSSFloat.
#[inline]
pub fn percentage(&self) -> CSSFloat {
self.percentage.map_or(0., |p| p.0)
}
+ /// Returns the percentage component if this could be represented as a
+ /// non-calc percentage.
+ pub fn as_percentage(&self) -> Option<Percentage> {
+ if self.length.px() != 0. {
+ return None;
+ }
+
+ let p = self.percentage?;
+ if self.clamping_mode.clamp(p.0) != p.0 {
+ return None;
+ }
+
+ Some(p)
+ }
+
/// Convert the computed value into used value.
#[inline]
- pub fn to_used_value(&self, container_len: Option<Au>) -> Option<Au> {
- self.to_pixel_length(container_len).map(Au::from)
+ pub fn maybe_to_used_value(&self, container_len: Option<Au>) -> Option<Au> {
+ self.maybe_to_pixel_length(container_len).map(Au::from)
}
/// If there are special rules for computing percentages in a value (e.g.
/// the height property), they apply whenever a calc() expression contains
/// percentages.
- pub fn to_pixel_length(&self, container_len: Option<Au>) -> Option<Length> {
+ pub fn maybe_to_pixel_length(&self, container_len: Option<Au>) -> Option<Length> {
match (container_len, self.percentage) {
(Some(len), Some(percent)) => {
let pixel = self.length.px() + len.scale_by(percent.0).to_f32_px();
@@ -158,81 +209,12 @@ impl CalcLengthOrPercentage {
}
}
-impl From<LengthOrPercentage> for CalcLengthOrPercentage {
- fn from(len: LengthOrPercentage) -> CalcLengthOrPercentage {
- match len {
- LengthOrPercentage::Percentage(this) => {
- CalcLengthOrPercentage::new(Length::new(0.), Some(this))
- },
- LengthOrPercentage::Length(this) => CalcLengthOrPercentage::new(this, None),
- LengthOrPercentage::Calc(this) => this,
- }
- }
-}
-
-impl From<LengthOrPercentageOrAuto> for Option<CalcLengthOrPercentage> {
- fn from(len: LengthOrPercentageOrAuto) -> Option<CalcLengthOrPercentage> {
- match len {
- LengthOrPercentageOrAuto::Percentage(this) => {
- Some(CalcLengthOrPercentage::new(Length::new(0.), Some(this)))
- },
- LengthOrPercentageOrAuto::Length(this) => Some(CalcLengthOrPercentage::new(this, None)),
- LengthOrPercentageOrAuto::Calc(this) => Some(this),
- LengthOrPercentageOrAuto::Auto => None,
- }
- }
-}
-
-impl From<LengthOrPercentageOrNone> for Option<CalcLengthOrPercentage> {
- fn from(len: LengthOrPercentageOrNone) -> Option<CalcLengthOrPercentage> {
- match len {
- LengthOrPercentageOrNone::Percentage(this) => {
- Some(CalcLengthOrPercentage::new(Length::new(0.), Some(this)))
- },
- LengthOrPercentageOrNone::Length(this) => Some(CalcLengthOrPercentage::new(this, None)),
- LengthOrPercentageOrNone::Calc(this) => Some(this),
- LengthOrPercentageOrNone::None => None,
- }
- }
-}
-
-impl ToCss for CalcLengthOrPercentage {
+impl ToCss for LengthOrPercentage {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
- use num_traits::Zero;
-
- let length = self.unclamped_length();
- match self.percentage {
- Some(p) => {
- if length.px() == 0. && self.clamping_mode.clamp(p.0) == p.0 {
- return p.to_css(dest);
- }
- },
- None => {
- if self.clamping_mode.clamp(length.px()) == length.px() {
- return length.to_css(dest);
- }
- },
- }
-
- dest.write_str("calc(")?;
- if let Some(percentage) = self.percentage {
- percentage.to_css(dest)?;
- if length.px() != 0. {
- dest.write_str(if length.px() < Zero::zero() {
- " - "
- } else {
- " + "
- })?;
- length.abs().to_css(dest)?;
- }
- } else {
- length.to_css(dest)?;
- }
-
- dest.write_str(")")
+ specified::LengthOrPercentage::from_computed_value(self).to_css(dest)
}
}
@@ -243,7 +225,7 @@ impl specified::CalcLengthOrPercentage {
context: &Context,
zoom_fn: F,
base_size: FontBaseSize,
- ) -> CalcLengthOrPercentage
+ ) -> LengthOrPercentage
where
F: Fn(Length) -> Length,
{
@@ -277,10 +259,11 @@ impl specified::CalcLengthOrPercentage {
}
}
- CalcLengthOrPercentage {
+ LengthOrPercentage {
clamping_mode: self.clamping_mode,
length: Length::new(length.min(f32::MAX).max(f32::MIN)),
percentage: self.percentage,
+ was_calc: true,
}
}
@@ -289,7 +272,7 @@ impl specified::CalcLengthOrPercentage {
&self,
context: &Context,
base_size: FontBaseSize,
- ) -> CalcLengthOrPercentage {
+ ) -> LengthOrPercentage {
self.to_computed_value_with_zoom(
context,
|abs| context.maybe_zoom_text(abs.into()).0,
@@ -324,15 +307,15 @@ impl specified::CalcLengthOrPercentage {
}
impl ToComputedValue for specified::CalcLengthOrPercentage {
- type ComputedValue = CalcLengthOrPercentage;
+ type ComputedValue = LengthOrPercentage;
- fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
+ fn to_computed_value(&self, context: &Context) -> LengthOrPercentage {
// normal properties don't zoom, and compute em units against the current style's font-size
self.to_computed_value_with_zoom(context, |abs| abs, FontBaseSize::CurrentStyle)
}
#[inline]
- fn from_computed_value(computed: &CalcLengthOrPercentage) -> Self {
+ fn from_computed_value(computed: &LengthOrPercentage) -> Self {
specified::CalcLengthOrPercentage {
clamping_mode: computed.clamping_mode,
absolute: Some(AbsoluteLength::from_computed_value(&computed.length)),
@@ -342,95 +325,33 @@ impl ToComputedValue for specified::CalcLengthOrPercentage {
}
}
-#[allow(missing_docs)]
-#[animate(fallback = "Self::animate_fallback")]
-#[css(derive_debug)]
-#[derive(
- Animate,
- Clone,
- ComputeSquaredDistance,
- Copy,
- MallocSizeOf,
- PartialEq,
- ToAnimatedValue,
- ToAnimatedZero,
- ToCss,
-)]
-#[distance(fallback = "Self::compute_squared_distance_fallback")]
-pub enum LengthOrPercentage {
- Length(Length),
- Percentage(Percentage),
- Calc(CalcLengthOrPercentage),
-}
-
-impl LengthOrPercentage {
- /// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc>
- fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
- // Special handling for zero values since these should not require calc().
- if self.is_definitely_zero() {
- return other.to_animated_zero()?.animate(other, procedure);
- }
- if other.is_definitely_zero() {
- return self.animate(&self.to_animated_zero()?, procedure);
- }
-
- let this = CalcLengthOrPercentage::from(*self);
- let other = CalcLengthOrPercentage::from(*other);
- Ok(LengthOrPercentage::Calc(this.animate(&other, procedure)?))
- }
-
- #[inline]
- fn compute_squared_distance_fallback(&self, other: &Self) -> Result<SquaredDistance, ()> {
- CalcLengthOrPercentage::compute_squared_distance(&(*self).into(), &(*other).into())
- }
-}
-
-impl From<Au> for LengthOrPercentage {
- #[inline]
- fn from(length: Au) -> Self {
- LengthOrPercentage::Length(length.into())
- }
-}
-
impl LengthOrPercentage {
#[inline]
#[allow(missing_docs)]
pub fn zero() -> LengthOrPercentage {
- LengthOrPercentage::Length(Length::new(0.))
+ LengthOrPercentage::new(Length::new(0.), None)
}
- #[inline]
/// 1px length value for SVG defaults
+ #[inline]
pub fn one() -> LengthOrPercentage {
- LengthOrPercentage::Length(Length::new(1.))
+ LengthOrPercentage::new(Length::new(1.), None)
}
/// Returns true if the computed value is absolute 0 or 0%.
- ///
- /// (Returns false for calc() values, even if ones that may resolve to zero.)
#[inline]
pub fn is_definitely_zero(&self) -> bool {
- use self::LengthOrPercentage::*;
- match *self {
- Length(l) => l.px() == 0.0,
- Percentage(p) => p.0 == 0.0,
- Calc(_) => false,
- }
+ self.unclamped_length().px() == 0.0 && self.percentage.map_or(true, |p| p.0 == 0.0)
}
// CSSFloat doesn't implement Hash, so does CSSPixelLength. Therefore, we still use Au as the
// hash key.
#[allow(missing_docs)]
pub fn to_hash_key(&self) -> (Au, NotNan<f32>) {
- use self::LengthOrPercentage::*;
- match *self {
- Length(l) => (Au::from(l), NotNan::new(0.0).unwrap()),
- Percentage(p) => (Au(0), NotNan::new(p.0).unwrap()),
- Calc(c) => (
- Au::from(c.unclamped_length()),
- NotNan::new(c.percentage()).unwrap(),
- ),
- }
+ (
+ Au::from(self.unclamped_length()),
+ NotNan::new(self.percentage()).unwrap(),
+ )
}
/// Returns the used value.
@@ -440,27 +361,40 @@ impl LengthOrPercentage {
/// Returns the used value as CSSPixelLength.
pub fn to_pixel_length(&self, containing_length: Au) -> Length {
- match *self {
- LengthOrPercentage::Length(length) => length,
- LengthOrPercentage::Percentage(p) => containing_length.scale_by(p.0).into(),
- LengthOrPercentage::Calc(ref calc) => {
- calc.to_pixel_length(Some(containing_length)).unwrap()
- },
- }
+ self.maybe_to_pixel_length(Some(containing_length)).unwrap()
}
/// Returns the clamped non-negative values.
+ ///
+ /// TODO(emilio): It's a bit unfortunate that this depends on whether the
+ /// value was a `calc()` value or not. Should it?
#[inline]
pub fn clamp_to_non_negative(self) -> Self {
- match self {
- LengthOrPercentage::Length(length) => {
- LengthOrPercentage::Length(length.clamp_to_non_negative())
- },
- LengthOrPercentage::Percentage(percentage) => {
- LengthOrPercentage::Percentage(percentage.clamp_to_non_negative())
- },
- _ => self,
- }
+ if self.was_calc {
+ return Self::with_clamping_mode(
+ self.length,
+ self.percentage,
+ AllowedNumericType::NonNegative,
+ self.was_calc,
+ )
+ }
+
+ debug_assert!(self.percentage.is_none() || self.unclamped_length() == Length::zero());
+ if let Some(p) = self.percentage {
+ return Self::with_clamping_mode(
+ Length::zero(),
+ Some(p.clamp_to_non_negative()),
+ AllowedNumericType::NonNegative,
+ self.was_calc,
+ );
+ }
+
+ Self::with_clamping_mode(
+ self.length.clamp_to_non_negative(),
+ None,
+ AllowedNumericType::NonNegative,
+ self.was_calc,
+ )
}
}
@@ -470,71 +404,57 @@ impl ToComputedValue for specified::LengthOrPercentage {
fn to_computed_value(&self, context: &Context) -> LengthOrPercentage {
match *self {
specified::LengthOrPercentage::Length(ref value) => {
- LengthOrPercentage::Length(value.to_computed_value(context))
+ LengthOrPercentage::new(value.to_computed_value(context), None)
},
specified::LengthOrPercentage::Percentage(value) => {
- LengthOrPercentage::Percentage(value)
+ LengthOrPercentage::new_percent(value)
},
specified::LengthOrPercentage::Calc(ref calc) => {
- LengthOrPercentage::Calc((**calc).to_computed_value(context))
+ (**calc).to_computed_value(context)
},
}
}
fn from_computed_value(computed: &LengthOrPercentage) -> Self {
- match *computed {
- LengthOrPercentage::Length(value) => {
- specified::LengthOrPercentage::Length(ToComputedValue::from_computed_value(&value))
- },
- LengthOrPercentage::Percentage(value) => {
- specified::LengthOrPercentage::Percentage(value)
- },
- LengthOrPercentage::Calc(ref calc) => specified::LengthOrPercentage::Calc(Box::new(
- ToComputedValue::from_computed_value(calc),
- )),
+ let length = computed.unclamped_length();
+ if let Some(p) = computed.as_percentage() {
+ return specified::LengthOrPercentage::Percentage(p)
+ }
+
+ let percentage = computed.percentage;
+ if percentage.is_none() &&
+ computed.clamping_mode.clamp(length.px()) == length.px() {
+ return specified::LengthOrPercentage::Length(
+ ToComputedValue::from_computed_value(&length)
+ )
}
+
+ specified::LengthOrPercentage::Calc(Box::new(
+ ToComputedValue::from_computed_value(computed),
+ ))
}
}
impl IsZeroLength for LengthOrPercentage {
#[inline]
fn is_zero_length(&self) -> bool {
- match *self {
- LengthOrPercentage::Length(l) => l.0 == 0.0,
- LengthOrPercentage::Percentage(p) => p.0 == 0.0,
- LengthOrPercentage::Calc(c) => c.unclamped_length().0 == 0.0 && c.percentage() == 0.0,
- }
+ self.is_definitely_zero()
}
}
#[allow(missing_docs)]
-#[animate(fallback = "Self::animate_fallback")]
#[css(derive_debug)]
-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToCss)]
-#[distance(fallback = "Self::compute_squared_distance_fallback")]
+#[derive(Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss)]
pub enum LengthOrPercentageOrAuto {
- Length(Length),
- Percentage(Percentage),
+ LengthOrPercentage(LengthOrPercentage),
Auto,
- Calc(CalcLengthOrPercentage),
}
impl LengthOrPercentageOrAuto {
- /// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc>
- fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
- let this = <Option<CalcLengthOrPercentage>>::from(*self);
- let other = <Option<CalcLengthOrPercentage>>::from(*other);
- Ok(LengthOrPercentageOrAuto::Calc(
- this.animate(&other, procedure)?.ok_or(())?,
- ))
- }
-
+ /// Returns the `0` value.
#[inline]
- fn compute_squared_distance_fallback(&self, other: &Self) -> Result<SquaredDistance, ()> {
- <Option<CalcLengthOrPercentage>>::compute_squared_distance(
- &(*self).into(),
- &(*other).into(),
- )
+ pub fn zero() -> Self {
+ LengthOrPercentageOrAuto::LengthOrPercentage(LengthOrPercentage::zero())
}
}
@@ -572,24 +492,21 @@ impl ToAnimatedValue for NonNegativeLengthOrPercentageOrAuto {
impl LengthOrPercentageOrAuto {
/// Returns true if the computed value is absolute 0 or 0%.
- ///
- /// (Returns false for calc() values, even if ones that may resolve to zero.)
#[inline]
pub fn is_definitely_zero(&self) -> bool {
use self::LengthOrPercentageOrAuto::*;
match *self {
- Length(l) => l.px() == 0.0,
- Percentage(p) => p.0 == 0.0,
- Calc(_) | Auto => false,
+ LengthOrPercentage(ref l) => l.is_definitely_zero(),
+ Auto => false,
}
}
- fn clamp_to_non_negative(self) -> Self {
+ /// Clamps the value to a non-negative value.
+ pub fn clamp_to_non_negative(self) -> Self {
use self::LengthOrPercentageOrAuto::*;
match self {
- Length(l) => Length(l.clamp_to_non_negative()),
- Percentage(p) => Percentage(p.clamp_to_non_negative()),
- _ => self,
+ LengthOrPercentage(l) => LengthOrPercentage(l.clamp_to_non_negative()),
+ Auto => Auto,
}
}
}
@@ -600,16 +517,12 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto {
#[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto {
match *self {
- specified::LengthOrPercentageOrAuto::Length(ref value) => {
- LengthOrPercentageOrAuto::Length(value.to_computed_value(context))
- },
- specified::LengthOrPercentageOrAuto::Percentage(value) => {
- LengthOrPercentageOrAuto::Percentage(value)
+ specified::LengthOrPercentageOrAuto::LengthOrPercentage(ref value) => {
+ LengthOrPercentageOrAuto::LengthOrPercentage(
+ value.to_computed_value(context),
+ )
},
specified::LengthOrPercentageOrAuto::Auto => LengthOrPercentageOrAuto::Auto,
- specified::LengthOrPercentageOrAuto::Calc(ref calc) => {
- LengthOrPercentageOrAuto::Calc((**calc).to_computed_value(context))
- },
}
}
@@ -617,78 +530,44 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto {
fn from_computed_value(computed: &LengthOrPercentageOrAuto) -> Self {
match *computed {
LengthOrPercentageOrAuto::Auto => specified::LengthOrPercentageOrAuto::Auto,
- LengthOrPercentageOrAuto::Length(value) => specified::LengthOrPercentageOrAuto::Length(
- ToComputedValue::from_computed_value(&value),
- ),
- LengthOrPercentageOrAuto::Percentage(value) => {
- specified::LengthOrPercentageOrAuto::Percentage(value)
+ LengthOrPercentageOrAuto::LengthOrPercentage(ref value) => {
+ specified::LengthOrPercentageOrAuto::LengthOrPercentage(
+ ToComputedValue::from_computed_value(value),
+ )
},
- LengthOrPercentageOrAuto::Calc(calc) => specified::LengthOrPercentageOrAuto::Calc(
- Box::new(ToComputedValue::from_computed_value(&calc)),
- ),
}
}
}
#[allow(missing_docs)]
-#[animate(fallback = "Self::animate_fallback")]
-#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
#[css(derive_debug)]
-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, PartialEq, ToCss)]
-#[distance(fallback = "Self::compute_squared_distance_fallback")]
+#[derive(Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss)]
pub enum LengthOrPercentageOrNone {
- Length(Length),
- Percentage(Percentage),
- Calc(CalcLengthOrPercentage),
+ LengthOrPercentage(LengthOrPercentage),
None,
}
impl LengthOrPercentageOrNone {
- /// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc>
- fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
- let this = <Option<CalcLengthOrPercentage>>::from(*self);
- let other = <Option<CalcLengthOrPercentage>>::from(*other);
- Ok(LengthOrPercentageOrNone::Calc(
- this.animate(&other, procedure)?.ok_or(())?,
- ))
- }
-
- fn compute_squared_distance_fallback(&self, other: &Self) -> Result<SquaredDistance, ()> {
- <Option<CalcLengthOrPercentage>>::compute_squared_distance(
- &(*self).into(),
- &(*other).into(),
- )
- }
-}
-
-impl LengthOrPercentageOrNone {
/// Returns the used value.
pub fn to_used_value(&self, containing_length: Au) -> Option<Au> {
match *self {
LengthOrPercentageOrNone::None => None,
- LengthOrPercentageOrNone::Length(length) => Some(Au::from(length)),
- LengthOrPercentageOrNone::Percentage(percent) => {
- Some(containing_length.scale_by(percent.0))
+ LengthOrPercentageOrNone::LengthOrPercentage(ref lop) => {
+ Some(lop.to_used_value(containing_length))
},
- LengthOrPercentageOrNone::Calc(ref calc) => calc.to_used_value(Some(containing_length)),
}
}
}
+// FIXME(emilio): Derive this.
impl ToComputedValue for specified::LengthOrPercentageOrNone {
type ComputedValue = LengthOrPercentageOrNone;
#[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone {
match *self {
- specified::LengthOrPercentageOrNone::Length(ref value) => {
- LengthOrPercentageOrNone::Length(value.to_computed_value(context))
- },
- specified::LengthOrPercentageOrNone::Percentage(value) => {
- LengthOrPercentageOrNone::Percentage(value)
- },
- specified::LengthOrPercentageOrNone::Calc(ref calc) => {
- LengthOrPercentageOrNone::Calc((**calc).to_computed_value(context))
+ specified::LengthOrPercentageOrNone::LengthOrPercentage(ref value) => {
+ LengthOrPercentageOrNone::LengthOrPercentage(value.to_computed_value(context))
},
specified::LengthOrPercentageOrNone::None => LengthOrPercentageOrNone::None,
}
@@ -698,15 +577,11 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone {
fn from_computed_value(computed: &LengthOrPercentageOrNone) -> Self {
match *computed {
LengthOrPercentageOrNone::None => specified::LengthOrPercentageOrNone::None,
- LengthOrPercentageOrNone::Length(value) => specified::LengthOrPercentageOrNone::Length(
- ToComputedValue::from_computed_value(&value),
- ),
- LengthOrPercentageOrNone::Percentage(value) => {
- specified::LengthOrPercentageOrNone::Percentage(value)
+ LengthOrPercentageOrNone::LengthOrPercentage(value) => {
+ specified::LengthOrPercentageOrNone::LengthOrPercentage(
+ ToComputedValue::from_computed_value(&value),
+ )
},
- LengthOrPercentageOrNone::Calc(calc) => specified::LengthOrPercentageOrNone::Calc(
- Box::new(ToComputedValue::from_computed_value(&calc)),
- ),
}
}
}
@@ -719,19 +594,19 @@ impl ToAnimatedValue for NonNegativeLengthOrPercentage {
#[inline]
fn to_animated_value(self) -> Self::AnimatedValue {
- self.into()
+ self.0
}
#[inline]
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
- animated.clamp_to_non_negative().into()
+ NonNegative(animated.clamp_to_non_negative())
}
}
impl From<NonNegativeLength> for NonNegativeLengthOrPercentage {
#[inline]
fn from(length: NonNegativeLength) -> Self {
- LengthOrPercentage::Length(length.0).into()
+ LengthOrPercentage::new(length.0, None).into()
}
}
@@ -749,6 +624,15 @@ impl From<NonNegativeLengthOrPercentage> for LengthOrPercentage {
}
}
+// TODO(emilio): This is a really generic impl which is only needed to implement
+// Animated and co for Spacing<>. Get rid of this, probably?
+impl From<Au> for LengthOrPercentage {
+ #[inline]
+ fn from(length: Au) -> Self {
+ LengthOrPercentage::new(length.into(), None)
+ }
+}
+
impl NonNegativeLengthOrPercentage {
/// Get zero value.
#[inline]
@@ -798,11 +682,6 @@ impl CSSPixelLength {
self.0
}
- #[inline]
- fn clamp_to_non_negative(self) -> Self {
- Self::new(self.px().max(0.))
- }
-
/// Return the length with app_unit i32 type.
#[inline]
pub fn to_i32_au(&self) -> i32 {
@@ -810,11 +689,19 @@ impl CSSPixelLength {
}
/// Return the absolute value of this length.
+ #[inline]
pub fn abs(self) -> Self {
CSSPixelLength::new(self.0.abs())
}
+ /// Return the clamped value of this length.
+ #[inline]
+ pub fn clamp_to_non_negative(self) -> Self {
+ CSSPixelLength::new(self.0.max(0.))
+ }
+
/// Zero value
+ #[inline]
pub fn zero() -> Self {
CSSPixelLength::new(0.)
}
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
index 4051511e28e..7877fddc192 100644
--- a/components/style/values/computed/mod.rs
+++ b/components/style/values/computed/mod.rs
@@ -62,7 +62,7 @@ pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier,
pub use self::gecko::ScrollSnapPoint;
pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength};
-pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage};
+pub use self::length::{Length, LengthOrNumber, LengthOrPercentage};
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength};
pub use self::length::{NonNegativeLengthOrPercentage, NonNegativeLengthOrPercentageOrAuto};
#[cfg(feature = "gecko")]
diff --git a/components/style/values/computed/position.rs b/components/style/values/computed/position.rs
index 8c7976886d8..7bcdb59f89e 100644
--- a/components/style/values/computed/position.rs
+++ b/components/style/values/computed/position.rs
@@ -28,8 +28,8 @@ impl Position {
#[inline]
pub fn center() -> Self {
Self::new(
- LengthOrPercentage::Percentage(Percentage(0.5)),
- LengthOrPercentage::Percentage(Percentage(0.5)),
+ LengthOrPercentage::new_percent(Percentage(0.5)),
+ LengthOrPercentage::new_percent(Percentage(0.5)),
)
}
diff --git a/components/style/values/computed/transform.rs b/components/style/values/computed/transform.rs
index e3493131544..14115295213 100644
--- a/components/style/values/computed/transform.rs
+++ b/components/style/values/computed/transform.rs
@@ -31,8 +31,8 @@ impl TransformOrigin {
#[inline]
pub fn initial_value() -> Self {
Self::new(
- LengthOrPercentage::Percentage(Percentage(0.5)),
- LengthOrPercentage::Percentage(Percentage(0.5)),
+ LengthOrPercentage::new_percent(Percentage(0.5)),
+ LengthOrPercentage::new_percent(Percentage(0.5)),
Length::new(0.),
)
}
diff --git a/components/style/values/generics/text.rs b/components/style/values/generics/text.rs
index 090c3c1f687..2ee92513cf9 100644
--- a/components/style/values/generics/text.rs
+++ b/components/style/values/generics/text.rs
@@ -103,10 +103,7 @@ where
}
}
-impl<V> ToAnimatedZero for Spacing<V>
-where
- V: From<Au>,
-{
+impl<V> ToAnimatedZero for Spacing<V> {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Err(())
diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs
index 158b7456c76..d4b69b02e72 100644
--- a/components/style/values/generics/transform.rs
+++ b/components/style/values/generics/transform.rs
@@ -288,18 +288,14 @@ impl ToAbsoluteLength for ComputedLength {
impl ToAbsoluteLength for ComputedLengthOrPercentage {
#[inline]
fn to_pixel_length(&self, containing_len: Option<Au>) -> Result<CSSFloat, ()> {
- let extract_pixel_length = |lop: &ComputedLengthOrPercentage| match *lop {
- ComputedLengthOrPercentage::Length(px) => px.px(),
- ComputedLengthOrPercentage::Percentage(_) => 0.,
- ComputedLengthOrPercentage::Calc(calc) => calc.length().px(),
- };
-
match containing_len {
Some(relative_len) => Ok(self.to_pixel_length(relative_len).px()),
// If we don't have reference box, we cannot resolve the used value,
// so only retrieve the length part. This will be used for computing
// distance without any layout info.
- None => Ok(extract_pixel_length(self)),
+ //
+ // FIXME(emilio): This looks wrong.
+ None => Ok(self.length_component().px()),
}
}
}
diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs
index e5699742b14..57d7835e416 100644
--- a/components/style/values/specified/font.rs
+++ b/components/style/values/specified/font.rs
@@ -916,9 +916,7 @@ impl FontSize {
info = parent.keyword_info.map(|i| i.compose(ratio, abs.into()));
}
let calc = calc.to_computed_value_zoomed(context, base_size);
- calc.to_used_value(Some(base_size.resolve(context)))
- .unwrap()
- .into()
+ calc.to_used_value(base_size.resolve(context)).into()
},
FontSize::Keyword(i) => {
// As a specified keyword, this is keyword derived
diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs
index e64385472a0..4be179212c8 100644
--- a/components/style/values/specified/length.rs
+++ b/components/style/values/specified/length.rs
@@ -789,6 +789,12 @@ impl LengthOrPercentage {
LengthOrPercentage::Length(NoCalcLength::zero())
}
+ #[inline]
+ /// Returns a `0%` value.
+ pub fn zero_percent() -> LengthOrPercentage {
+ LengthOrPercentage::Percentage(computed::Percentage::zero())
+ }
+
fn parse_internal<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
@@ -898,24 +904,8 @@ impl IsZeroLength for LengthOrPercentage {
#[allow(missing_docs)]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
pub enum LengthOrPercentageOrAuto {
- Length(NoCalcLength),
- Percentage(computed::Percentage),
+ LengthOrPercentage(LengthOrPercentage),
Auto,
- Calc(Box<CalcLengthOrPercentage>),
-}
-
-impl From<NoCalcLength> for LengthOrPercentageOrAuto {
- #[inline]
- fn from(len: NoCalcLength) -> Self {
- LengthOrPercentageOrAuto::Length(len)
- }
-}
-
-impl From<computed::Percentage> for LengthOrPercentageOrAuto {
- #[inline]
- fn from(pc: computed::Percentage) -> Self {
- LengthOrPercentageOrAuto::Percentage(pc)
- }
}
impl LengthOrPercentageOrAuto {
@@ -925,48 +915,16 @@ impl LengthOrPercentageOrAuto {
num_context: AllowedNumericType,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
- // FIXME: remove early returns when lifetimes are non-lexical
- {
- let location = input.current_source_location();
- let token = input.next()?;
- match *token {
- Token::Dimension {
- value, ref unit, ..
- } if num_context.is_ok(context.parsing_mode, value) => {
- return NoCalcLength::parse_dimension(context, value, unit)
- .map(LengthOrPercentageOrAuto::Length)
- .map_err(|()| location.new_unexpected_token_error(token.clone()));
- },
- Token::Percentage { unit_value, .. }
- if num_context.is_ok(context.parsing_mode, unit_value) =>
- {
- return Ok(LengthOrPercentageOrAuto::Percentage(computed::Percentage(
- unit_value,
- )));
- }
- Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
- if value != 0. &&
- !context.parsing_mode.allows_unitless_lengths() &&
- !allow_quirks.allowed(context.quirks_mode)
- {
- return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
- }
- return Ok(LengthOrPercentageOrAuto::Length(NoCalcLength::Absolute(
- AbsoluteLength::Px(value),
- )));
- },
- Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => {
- return Ok(LengthOrPercentageOrAuto::Auto);
- },
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
- _ => return Err(location.new_unexpected_token_error(token.clone())),
- }
+ if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
+ return Ok(LengthOrPercentageOrAuto::Auto);
}
- let calc = input.parse_nested_block(|i| {
- CalcNode::parse_length_or_percentage(context, i, num_context)
- })?;
- Ok(LengthOrPercentageOrAuto::Calc(Box::new(calc)))
+ Ok(LengthOrPercentageOrAuto::LengthOrPercentage(LengthOrPercentage::parse_internal(
+ context,
+ input,
+ num_context,
+ allow_quirks,
+ )?))
}
/// Parse a non-negative length, percentage, or auto.
@@ -1000,13 +958,13 @@ impl LengthOrPercentageOrAuto {
/// Returns a value representing a `0` length.
pub fn zero() -> Self {
- LengthOrPercentageOrAuto::Length(NoCalcLength::zero())
+ LengthOrPercentageOrAuto::LengthOrPercentage(LengthOrPercentage::zero())
}
/// Returns a value representing `0%`.
#[inline]
pub fn zero_percent() -> Self {
- LengthOrPercentageOrAuto::Percentage(computed::Percentage::zero())
+ LengthOrPercentageOrAuto::LengthOrPercentage(LengthOrPercentage::zero_percent())
}
/// Parses, with quirks.
@@ -1076,9 +1034,7 @@ impl Parse for NonNegativeLengthOrPercentageOrAuto {
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)]
#[allow(missing_docs)]
pub enum LengthOrPercentageOrNone {
- Length(NoCalcLength),
- Percentage(computed::Percentage),
- Calc(Box<CalcLengthOrPercentage>),
+ LengthOrPercentage(LengthOrPercentage),
None,
}
@@ -1089,48 +1045,16 @@ impl LengthOrPercentageOrNone {
num_context: AllowedNumericType,
allow_quirks: AllowQuirks,
) -> Result<Self, ParseError<'i>> {
- // FIXME: remove early returns when lifetimes are non-lexical
- {
- let location = input.current_source_location();
- let token = input.next()?;
- match *token {
- Token::Dimension {
- value, ref unit, ..
- } if num_context.is_ok(context.parsing_mode, value) => {
- return NoCalcLength::parse_dimension(context, value, unit)
- .map(LengthOrPercentageOrNone::Length)
- .map_err(|()| location.new_unexpected_token_error(token.clone()));
- },
- Token::Percentage { unit_value, .. }
- if num_context.is_ok(context.parsing_mode, unit_value) =>
- {
- return Ok(LengthOrPercentageOrNone::Percentage(computed::Percentage(
- unit_value,
- )));
- }
- Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => {
- if value != 0. &&
- !context.parsing_mode.allows_unitless_lengths() &&
- !allow_quirks.allowed(context.quirks_mode)
- {
- return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
- }
- return Ok(LengthOrPercentageOrNone::Length(NoCalcLength::Absolute(
- AbsoluteLength::Px(value),
- )));
- },
- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
- Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => {
- return Ok(LengthOrPercentageOrNone::None);
- },
- _ => return Err(location.new_unexpected_token_error(token.clone())),
- }
+ if input.try(|i| i.expect_ident_matching("none")).is_ok() {
+ return Ok(LengthOrPercentageOrNone::None);
}
- let calc = input.parse_nested_block(|i| {
- CalcNode::parse_length_or_percentage(context, i, num_context)
- })?;
- Ok(LengthOrPercentageOrNone::Calc(Box::new(calc)))
+ Ok(LengthOrPercentageOrNone::LengthOrPercentage(LengthOrPercentage::parse_internal(
+ context,
+ input,
+ num_context,
+ allow_quirks,
+ )?))
}
/// Parse a non-negative LengthOrPercentageOrNone.
diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs
index e2865071eeb..a7c6c9f41d6 100644
--- a/components/style/values/specified/position.rs
+++ b/components/style/values/specified/position.rs
@@ -10,7 +10,6 @@
use crate::hash::FxHashMap;
use crate::parser::{Parse, ParserContext};
use crate::str::HTML_SPACE_CHARACTERS;
-use crate::values::computed::CalcLengthOrPercentage;
use crate::values::computed::LengthOrPercentage as ComputedLengthOrPercentage;
use crate::values::computed::{Context, Percentage, ToComputedValue};
use crate::values::generics::position::Position as GenericPosition;
@@ -255,25 +254,21 @@ impl<S: Side> ToComputedValue for PositionComponent<S> {
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
- PositionComponent::Center => ComputedLengthOrPercentage::Percentage(Percentage(0.5)),
+ PositionComponent::Center => ComputedLengthOrPercentage::new_percent(Percentage(0.5)),
PositionComponent::Side(ref keyword, None) => {
let p = Percentage(if keyword.is_start() { 0. } else { 1. });
- ComputedLengthOrPercentage::Percentage(p)
+ ComputedLengthOrPercentage::new_percent(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(Percentage::hundred())),
- ),
- ComputedLengthOrPercentage::Percentage(p) => {
- ComputedLengthOrPercentage::Percentage(Percentage(1.0 - p.0))
- },
- ComputedLengthOrPercentage::Calc(calc) => {
- let p = Percentage(1. - calc.percentage.map_or(0., |p| p.0));
- let l = -calc.unclamped_length();
- ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage::new(l, Some(p)))
- },
- }
+ let length = length.to_computed_value(context);
+ let p = Percentage(1. - length.percentage());
+ let l = -length.unclamped_length();
+ ComputedLengthOrPercentage::with_clamping_mode(
+ l,
+ Some(p),
+ length.clamping_mode,
+ length.was_calc,
+ )
},
PositionComponent::Side(_, Some(ref length)) |
PositionComponent::Length(ref length) => length.to_computed_value(context),
diff --git a/components/style/values/specified/transform.rs b/components/style/values/specified/transform.rs
index a5b36a24db5..bc8737ca95b 100644
--- a/components/style/values/specified/transform.rs
+++ b/components/style/values/specified/transform.rs
@@ -323,12 +323,12 @@ where
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
OriginComponent::Center => {
- ComputedLengthOrPercentage::Percentage(ComputedPercentage(0.5))
+ ComputedLengthOrPercentage::new_percent(ComputedPercentage(0.5))
},
OriginComponent::Length(ref length) => length.to_computed_value(context),
OriginComponent::Side(ref keyword) => {
let p = ComputedPercentage(if keyword.is_start() { 0. } else { 1. });
- ComputedLengthOrPercentage::Percentage(p)
+ ComputedLengthOrPercentage::new_percent(p)
},
}
}