style: Split LengthPercentage again.

This is needed to support min() / max() / clamp(), etc, as those need to be a
tree of values and thus need heap storage.

This unfortunately grows LengthPercentage to be two pointers, which is bad as
it blows up the size of nsStylePosition enough to trigger the size assertions.

This patch comments out the assertion for now, the follow-up patches will
uncomment them.

Differential Revision: https://phabricator.services.mozilla.com/D58700
This commit is contained in:
Emilio Cobos Álvarez 2020-01-13 13:21:58 +00:00
parent ec37e7a5b8
commit 61f3ff1de3
No known key found for this signature in database
GPG key ID: E1152D0994E4BF8A
6 changed files with 304 additions and 177 deletions

View file

@ -138,8 +138,7 @@ impl Device {
/// Set the font size of the root element (for rem) /// Set the font size of the root element (for rem)
pub fn set_root_font_size(&self, size: Au) { pub fn set_root_font_size(&self, size: Au) {
self.root_font_size self.root_font_size.store(size.0 as isize, Ordering::Relaxed)
.store(size.0 as isize, Ordering::Relaxed)
} }
/// Sets the body text color for the "inherit color from body" quirk. /// Sets the body text color for the "inherit color from body" quirk.

View file

@ -5,7 +5,7 @@
//! Animation implementation for various length-related types. //! Animation implementation for various length-related types.
use super::{Animate, Procedure}; use super::{Animate, Procedure};
use crate::values::computed::length::LengthPercentage; use crate::values::computed::length::{LengthPercentage, CalcLengthPercentage};
use crate::values::computed::Percentage; use crate::values::computed::Percentage;
/// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc> /// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc>
@ -26,10 +26,9 @@ impl Animate for LengthPercentage {
.animate(&other.unclamped_length(), procedure)?; .animate(&other.unclamped_length(), procedure)?;
let percentage = let percentage =
animate_percentage_half(self.specified_percentage(), other.specified_percentage())?; animate_percentage_half(self.specified_percentage(), other.specified_percentage())?;
Ok(Self::with_clamping_mode(
length, // Gets clamped as needed after the animation, so no need to specify any
percentage, // particular AllowedNumericType.
self.clamping_mode, Ok(CalcLengthPercentage::new(length, percentage).to_length_percentge())
))
} }
} }

View file

@ -424,6 +424,16 @@ impl ToAnimatedZero for i32 {
} }
} }
impl<T> ToAnimatedZero for Box<T>
where
T: ToAnimatedZero,
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Ok(Box::new((**self).to_animated_zero()?))
}
}
impl<T> ToAnimatedZero for Option<T> impl<T> ToAnimatedZero for Option<T>
where where
T: ToAnimatedZero, T: ToAnimatedZero,

View file

@ -18,7 +18,6 @@ use crate::values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativ
use crate::values::{specified, CSSFloat}; use crate::values::{specified, CSSFloat};
use crate::Zero; use crate::Zero;
use app_units::Au; use app_units::Au;
use ordered_float::NotNan;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub}; use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub};
use style_traits::values::specified::AllowedNumericType; use style_traits::values::specified::AllowedNumericType;
@ -54,13 +53,13 @@ impl ToComputedValue for specified::NoCalcLength {
} }
impl ToComputedValue for specified::Length { impl ToComputedValue for specified::Length {
type ComputedValue = CSSPixelLength; type ComputedValue = Length;
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self { match *self {
specified::Length::NoCalc(l) => l.to_computed_value(context), specified::Length::NoCalc(l) => l.to_computed_value(context),
specified::Length::Calc(ref calc) => calc.to_computed_value(context).length(), specified::Length::Calc(ref calc) => calc.to_computed_value(context).length_component(),
} }
} }
@ -73,15 +72,32 @@ impl ToComputedValue for specified::Length {
/// A `<length-percentage>` value. This can be either a `<length>`, a /// A `<length-percentage>` value. This can be either a `<length>`, a
/// `<percentage>`, or a combination of both via `calc()`. /// `<percentage>`, or a combination of both via `calc()`.
/// ///
/// cbindgen:private-default-tagged-enum-constructor=false
/// cbindgen:derive-mut-casts=true
///
/// https://drafts.csswg.org/css-values-4/#typedef-length-percentage /// https://drafts.csswg.org/css-values-4/#typedef-length-percentage
#[allow(missing_docs)] #[allow(missing_docs)]
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize, ToAnimatedZero, ToResolvedValue)] #[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize, ToAnimatedZero, ToResolvedValue)]
#[repr(u8)]
pub enum LengthPercentage {
Length(Length),
Percentage(Percentage),
Calc(Box<CalcLengthPercentage>),
}
/// The representation of a calc() function.
#[derive(
Clone, Debug, Deserialize, MallocSizeOf, Serialize, ToAnimatedZero, ToResolvedValue,
)]
#[repr(C)] #[repr(C)]
pub struct LengthPercentage { pub struct CalcLengthPercentage {
length: Length, length: Length,
percentage: Percentage, percentage: Percentage,
#[animation(constant)] #[animation(constant)]
pub clamping_mode: AllowedNumericType, clamping_mode: AllowedNumericType,
/// Whether we specified a percentage or not. /// Whether we specified a percentage or not.
#[animation(constant)] #[animation(constant)]
pub has_percentage: bool, pub has_percentage: bool,
@ -99,7 +115,7 @@ pub struct LengthPercentage {
// We may want to just eagerly-detect whether we can clamp in // We may want to just eagerly-detect whether we can clamp in
// `LengthPercentage::new` and switch to `AllowedNumericType::NonNegative` then, // `LengthPercentage::new` and switch to `AllowedNumericType::NonNegative` then,
// maybe. // maybe.
impl PartialEq for LengthPercentage { impl PartialEq for CalcLengthPercentage {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.length == other.length && self.length == other.length &&
self.percentage == other.percentage && self.percentage == other.percentage &&
@ -115,123 +131,8 @@ impl ComputeSquaredDistance for LengthPercentage {
Ok(self Ok(self
.unclamped_length() .unclamped_length()
.compute_squared_distance(&other.unclamped_length())? + .compute_squared_distance(&other.unclamped_length())? +
self.percentage self.percentage()
.compute_squared_distance(&other.percentage)?) .compute_squared_distance(&other.percentage())?)
}
}
impl LengthPercentage {
/// Returns a new `LengthPercentage`.
#[inline]
pub fn new(length: Length, percentage: Option<Percentage>) -> Self {
Self::with_clamping_mode(length, percentage, AllowedNumericType::All)
}
/// Returns a new `LengthPercentage` with zero length and some percentage.
pub fn new_percent(percentage: Percentage) -> Self {
Self::new(Length::zero(), Some(percentage))
}
/// Returns a new `LengthPercentage` with a specific clamping mode.
#[inline]
pub fn with_clamping_mode(
length: Length,
percentage: Option<Percentage>,
clamping_mode: AllowedNumericType,
) -> Self {
Self {
clamping_mode,
length,
percentage: percentage.unwrap_or_default(),
has_percentage: percentage.is_some(),
}
}
/// Returns this `calc()` as a `<length>`.
///
/// Panics in debug mode if a percentage is present in the expression.
#[inline]
pub fn length(&self) -> CSSPixelLength {
debug_assert!(!self.has_percentage);
self.length_component()
}
/// Returns the length component of this `calc()`
#[inline]
pub fn length_component(&self) -> CSSPixelLength {
CSSPixelLength::new(self.clamping_mode.clamp(self.length.px()))
}
/// Returns the `<length>` component of this `calc()`, unclamped.
#[inline]
pub fn unclamped_length(&self) -> CSSPixelLength {
self.length
}
/// Returns the percentage component of this `calc()`
#[inline]
pub fn percentage_component(&self) -> Percentage {
Percentage(self.clamping_mode.clamp(self.percentage.0))
}
/// Return the percentage value as CSSFloat.
#[inline]
pub fn percentage(&self) -> CSSFloat {
self.percentage.0
}
/// Return the specified percentage if any.
#[inline]
pub fn specified_percentage(&self) -> Option<Percentage> {
if self.has_percentage {
Some(self.percentage)
} else {
None
}
}
/// Returns the length component if this could be represented as a
/// non-calc length.
pub fn as_length(&self) -> Option<Length> {
if !self.has_percentage {
Some(self.length_component())
} else {
None
}
}
/// Returns the percentage component if this could be represented as a
/// non-calc percentage.
pub fn as_percentage(&self) -> Option<Percentage> {
if !self.has_percentage || self.length.px() != 0. {
return None;
}
Some(Percentage(self.clamping_mode.clamp(self.percentage.0)))
}
/// Resolves the percentage.
#[inline]
pub fn percentage_relative_to(&self, basis: Length) -> Length {
let length = self.unclamped_length().0 + basis.0 * self.percentage.0;
Length::new(self.clamping_mode.clamp(length))
}
/// Convert the computed value into used value.
#[inline]
pub fn maybe_to_used_value(&self, container_len: Option<Length>) -> Option<Au> {
self.maybe_percentage_relative_to(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 maybe_percentage_relative_to(&self, container_len: Option<Length>) -> Option<Length> {
if self.has_percentage {
return Some(self.percentage_relative_to(container_len?));
}
Some(self.length())
} }
} }
@ -251,7 +152,7 @@ impl specified::CalcLengthPercentage {
context: &Context, context: &Context,
zoom_fn: F, zoom_fn: F,
base_size: FontBaseSize, base_size: FontBaseSize,
) -> LengthPercentage ) -> CalcLengthPercentage
where where
F: Fn(Length) -> Length, F: Fn(Length) -> Length,
{ {
@ -285,7 +186,7 @@ impl specified::CalcLengthPercentage {
} }
} }
LengthPercentage::with_clamping_mode( CalcLengthPercentage::with_clamping_mode(
Length::new(length.min(f32::MAX).max(f32::MIN)), Length::new(length.min(f32::MAX).max(f32::MIN)),
self.percentage, self.percentage,
self.clamping_mode, self.clamping_mode,
@ -297,7 +198,7 @@ impl specified::CalcLengthPercentage {
&self, &self,
context: &Context, context: &Context,
base_size: FontBaseSize, base_size: FontBaseSize,
) -> LengthPercentage { ) -> CalcLengthPercentage {
self.to_computed_value_with_zoom( self.to_computed_value_with_zoom(
context, context,
|abs| context.maybe_zoom_text(abs.into()), |abs| context.maybe_zoom_text(abs.into()),
@ -329,18 +230,14 @@ impl specified::CalcLengthPercentage {
}, },
} }
} }
}
impl ToComputedValue for specified::CalcLengthPercentage { fn to_computed_value(&self, context: &Context) -> CalcLengthPercentage {
type ComputedValue = LengthPercentage;
fn to_computed_value(&self, context: &Context) -> LengthPercentage {
// normal properties don't zoom, and compute em units against the current style's font-size // 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) self.to_computed_value_with_zoom(context, |abs| abs, FontBaseSize::CurrentStyle)
} }
#[inline] #[inline]
fn from_computed_value(computed: &LengthPercentage) -> Self { fn from_computed_value(computed: &CalcLengthPercentage) -> Self {
specified::CalcLengthPercentage { specified::CalcLengthPercentage {
clamping_mode: computed.clamping_mode, clamping_mode: computed.clamping_mode,
absolute: Some(AbsoluteLength::from_computed_value(&computed.length)), absolute: Some(AbsoluteLength::from_computed_value(&computed.length)),
@ -353,50 +250,262 @@ impl ToComputedValue for specified::CalcLengthPercentage {
impl LengthPercentage { impl LengthPercentage {
/// 1px length value for SVG defaults /// 1px length value for SVG defaults
#[inline] #[inline]
pub fn one() -> LengthPercentage { pub fn one() -> Self {
LengthPercentage::new(Length::new(1.), None) Self::Length(Length::new(1.))
}
/// Constructs a length value.
#[inline]
pub fn new_length(l: Length) -> Self {
Self::Length(l)
}
/// Constructs a percentage value.
#[inline]
pub fn new_percent(p: Percentage) -> Self {
Self::Percentage(p)
}
/// Constructs a `calc()` value.
#[inline]
pub fn new_calc(l: Length, percentage: Percentage) -> Self {
CalcLengthPercentage::new(l, Some(percentage)).to_length_percentge()
} }
/// Returns true if the computed value is absolute 0 or 0%. /// Returns true if the computed value is absolute 0 or 0%.
#[inline] #[inline]
pub fn is_definitely_zero(&self) -> bool { pub fn is_definitely_zero(&self) -> bool {
self.unclamped_length().px() == 0.0 && self.percentage.0 == 0.0 match *self {
Self::Length(l) => l.px() == 0.0,
Self::Percentage(p) => p.0 == 0.0,
Self::Calc(ref c) => c.is_definitely_zero(),
}
} }
// CSSFloat doesn't implement Hash, so does CSSPixelLength. Therefore, we /// Returns the `<length>` component of this `calc()`, unclamped.
// still use Au as the hash key. #[inline]
#[allow(missing_docs)] pub fn unclamped_length(&self) -> Length {
pub fn to_hash_key(&self) -> (Au, NotNan<f32>) { match *self {
( Self::Length(l) => l,
Au::from(self.unclamped_length()), Self::Percentage(..) => Zero::zero(),
NotNan::new(self.percentage.0).unwrap(), Self::Calc(ref c) => c.unclamped_length(),
) }
}
/// Returns this `calc()` as a `<length>`.
///
/// Panics in debug mode if a percentage is present in the expression.
#[inline]
fn length(&self) -> Length {
debug_assert!(!self.has_percentage());
self.length_component()
}
/// Returns the `<length>` component of this `calc()`, clamped.
#[inline]
pub fn length_component(&self) -> Length {
match *self {
Self::Length(l) => l,
Self::Percentage(..) => Zero::zero(),
Self::Calc(ref c) => c.length_component(),
}
}
/// Returns the `<percentage>` component of this `calc()`, unclamped, as a
/// float.
///
/// FIXME: This are very different semantics from length(), we should
/// probably rename this.
#[inline]
pub fn percentage(&self) -> CSSFloat {
match *self {
Self::Length(..) => 0.,
Self::Percentage(p) => p.0,
Self::Calc(ref c) => c.percentage.0,
}
}
/// Returns the `<length>` component of this `calc()`, clamped.
#[inline]
pub fn as_percentage(&self) -> Option<Percentage> {
match *self {
Self::Length(..) => None,
Self::Percentage(p) => Some(p),
Self::Calc(ref c) => c.as_percentage(),
}
}
/// Resolves the percentage.
#[inline]
pub fn resolve(&self, basis: Length) -> Length {
match *self {
Self::Length(l) => l,
Self::Percentage(p) => Length::new(basis.0 * p.0),
Self::Calc(ref c) => c.resolve(basis),
}
}
/// Resolves the percentage. Just an alias of resolve().
#[inline]
pub fn percentage_relative_to(&self, basis: Length) -> Length {
self.resolve(basis)
}
/// Return whether there's any percentage in this value.
#[inline]
pub fn has_percentage(&self) -> bool {
match *self {
Self::Length(..) => false,
Self::Percentage(..) => true,
Self::Calc(ref c) => c.has_percentage,
}
}
/// Return the specified percentage if any.
#[inline]
pub fn specified_percentage(&self) -> Option<Percentage> {
match *self {
Self::Length(..) => None,
Self::Percentage(p) => Some(p),
Self::Calc(ref c) => c.specified_percentage(),
}
} }
/// Returns the used value. /// Returns the used value.
#[inline]
pub fn to_used_value(&self, containing_length: Au) -> Au { pub fn to_used_value(&self, containing_length: Au) -> Au {
Au::from(self.to_pixel_length(containing_length)) Au::from(self.to_pixel_length(containing_length))
} }
/// Returns the used value as CSSPixelLength. /// Returns the used value as CSSPixelLength.
#[inline]
pub fn to_pixel_length(&self, containing_length: Au) -> Length { pub fn to_pixel_length(&self, containing_length: Au) -> Length {
self.percentage_relative_to(containing_length.into()) self.resolve(containing_length.into())
}
/// Convert the computed value into used value.
#[inline]
fn maybe_to_used_value(&self, container_len: Option<Length>) -> Option<Au> {
self.maybe_percentage_relative_to(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 maybe_percentage_relative_to(&self, container_len: Option<Length>) -> Option<Length> {
if self.has_percentage() {
return Some(self.resolve(container_len?));
}
Some(self.length())
} }
/// Returns the clamped non-negative values. /// Returns the clamped non-negative values.
#[inline] #[inline]
pub fn clamp_to_non_negative(self) -> Self { pub fn clamp_to_non_negative(self) -> Self {
if let Some(p) = self.specified_percentage() { match self {
Self::Length(l) => Self::Length(l.clamp_to_non_negative()),
Self::Percentage(p) => Self::Percentage(p.clamp_to_non_negative()),
Self::Calc(c) => c.clamp_to_non_negative().to_length_percentge(),
}
}
}
impl CalcLengthPercentage {
/// Returns a new `LengthPercentage`.
#[inline]
pub fn new(length: Length, percentage: Option<Percentage>) -> Self {
Self::with_clamping_mode(length, percentage, AllowedNumericType::All)
}
/// Converts this to a `LengthPercentage`, simplifying if possible.
#[inline]
pub fn to_length_percentge(self) -> LengthPercentage {
if !self.has_percentage {
return LengthPercentage::Length(self.length_component())
}
if self.length.is_zero() {
return LengthPercentage::Percentage(Percentage(self.clamping_mode.clamp(self.percentage.0)));
}
LengthPercentage::Calc(Box::new(self))
}
fn specified_percentage(&self) -> Option<Percentage> {
if self.has_percentage {
Some(self.percentage)
} else {
None
}
}
/// Returns a new `LengthPercentage` with a specific clamping mode.
#[inline]
fn with_clamping_mode(
length: Length,
percentage: Option<Percentage>,
clamping_mode: AllowedNumericType,
) -> Self {
Self {
clamping_mode,
length,
percentage: percentage.unwrap_or_default(),
has_percentage: percentage.is_some(),
}
}
/// Returns the length component of this `calc()`
#[inline]
fn length_component(&self) -> CSSPixelLength {
Length::new(self.clamping_mode.clamp(self.length.px()))
}
/// Returns the percentage component if this could be represented as a
/// non-calc percentage.
fn as_percentage(&self) -> Option<Percentage> {
if !self.has_percentage || self.length.px() != 0. {
return None;
}
Some(Percentage(self.clamping_mode.clamp(self.percentage.0)))
}
/// Resolves the percentage.
#[inline]
pub fn resolve(&self, basis: Length) -> Length {
let length = self.length.0 + basis.0 * self.percentage.0;
Length::new(self.clamping_mode.clamp(length))
}
/// Resolves the percentage.
#[inline]
pub fn percentage_relative_to(&self, basis: Length) -> Length {
self.resolve(basis)
}
/// Returns the length, without clamping.
#[inline]
pub fn unclamped_length(&self) -> Length {
self.length
}
/// Returns true if the computed value is absolute 0 or 0%.
#[inline]
fn is_definitely_zero(&self) -> bool {
self.length.px() == 0.0 && self.percentage.0 == 0.0
}
/// Returns the clamped non-negative values.
#[inline]
fn clamp_to_non_negative(self) -> Self {
if self.has_percentage {
// If we can eagerly clamp the percentage then just do that. // If we can eagerly clamp the percentage then just do that.
if self.length.is_zero() { if self.length.is_zero() {
return Self::with_clamping_mode( return Self::with_clamping_mode(
Length::zero(), Length::zero(),
Some(p.clamp_to_non_negative()), Some(self.percentage.clamp_to_non_negative()),
AllowedNumericType::NonNegative, AllowedNumericType::NonNegative,
); );
} }
return Self::with_clamping_mode(self.length, Some(self.percentage), AllowedNumericType::NonNegative);
return Self::with_clamping_mode(self.length, Some(p), AllowedNumericType::NonNegative);
} }
Self::with_clamping_mode( Self::with_clamping_mode(
@ -413,31 +522,41 @@ impl ToComputedValue for specified::LengthPercentage {
fn to_computed_value(&self, context: &Context) -> LengthPercentage { fn to_computed_value(&self, context: &Context) -> LengthPercentage {
match *self { match *self {
specified::LengthPercentage::Length(ref value) => { specified::LengthPercentage::Length(ref value) => {
LengthPercentage::new(value.to_computed_value(context), None) LengthPercentage::Length(value.to_computed_value(context))
},
specified::LengthPercentage::Percentage(value) => {
LengthPercentage::Percentage(value)
},
specified::LengthPercentage::Calc(ref calc) => {
(**calc).to_computed_value(context).to_length_percentge()
}, },
specified::LengthPercentage::Percentage(value) => LengthPercentage::new_percent(value),
specified::LengthPercentage::Calc(ref calc) => (**calc).to_computed_value(context),
} }
} }
fn from_computed_value(computed: &LengthPercentage) -> Self { fn from_computed_value(computed: &LengthPercentage) -> Self {
if let Some(p) = computed.as_percentage() { match *computed {
return specified::LengthPercentage::Percentage(p); LengthPercentage::Length(ref l) => {
specified::LengthPercentage::Length(ToComputedValue::from_computed_value(l))
}
LengthPercentage::Percentage(p) => {
specified::LengthPercentage::Percentage(p)
}
LengthPercentage::Calc(ref c) => {
if let Some(p) = c.as_percentage() {
return specified::LengthPercentage::Percentage(p)
}
if !c.has_percentage {
return specified::LengthPercentage::Length(ToComputedValue::from_computed_value(&c.length_component()))
}
specified::LengthPercentage::Calc(Box::new(specified::CalcLengthPercentage::from_computed_value(c)))
}
} }
if !computed.has_percentage {
return specified::LengthPercentage::Length(ToComputedValue::from_computed_value(
&computed.length(),
));
}
specified::LengthPercentage::Calc(Box::new(ToComputedValue::from_computed_value(computed)))
} }
} }
impl Zero for LengthPercentage { impl Zero for LengthPercentage {
fn zero() -> Self { fn zero() -> Self {
LengthPercentage::new(Length::zero(), None) LengthPercentage::Length(Length::zero())
} }
#[inline] #[inline]
@ -541,7 +660,7 @@ impl ToAnimatedValue for NonNegativeLengthPercentage {
impl From<NonNegativeLength> for NonNegativeLengthPercentage { impl From<NonNegativeLength> for NonNegativeLengthPercentage {
#[inline] #[inline]
fn from(length: NonNegativeLength) -> Self { fn from(length: NonNegativeLength) -> Self {
NonNegative(LengthPercentage::new(length.0, None)) NonNegative(LengthPercentage::new_length(length.0))
} }
} }
@ -557,7 +676,7 @@ impl From<LengthPercentage> for NonNegativeLengthPercentage {
impl From<Au> for LengthPercentage { impl From<Au> for LengthPercentage {
#[inline] #[inline]
fn from(length: Au) -> Self { fn from(length: Au) -> Self {
LengthPercentage::new(length.into(), None) LengthPercentage::new_length(length.into())
} }
} }
@ -572,7 +691,7 @@ impl NonNegativeLengthPercentage {
#[inline] #[inline]
pub fn to_used_value(&self, containing_length: Au) -> Au { pub fn to_used_value(&self, containing_length: Au) -> Au {
let resolved = self.0.to_used_value(containing_length); let resolved = self.0.to_used_value(containing_length);
::std::cmp::max(resolved, Au(0)) std::cmp::max(resolved, Au(0))
} }
/// Convert the computed value into used value. /// Convert the computed value into used value.
@ -581,7 +700,7 @@ impl NonNegativeLengthPercentage {
let resolved = self let resolved = self
.0 .0
.maybe_to_used_value(containing_length.map(|v| v.into()))?; .maybe_to_used_value(containing_length.map(|v| v.into()))?;
Some(::std::cmp::max(resolved, Au(0))) Some(std::cmp::max(resolved, Au(0)))
} }
} }

View file

@ -23,7 +23,7 @@ fn parse_pixel_or_percent<'i, 't>(
value, ref unit, .. value, ref unit, ..
} => { } => {
match_ignore_ascii_case! { unit, match_ignore_ascii_case! { unit,
"px" => Ok(LengthPercentage::new(Length::new(value), None)), "px" => Ok(LengthPercentage::new_length(Length::new(value))),
_ => Err(()), _ => Err(()),
} }
}, },

View file

@ -297,7 +297,7 @@ impl<S: Side> ToComputedValue for PositionComponent<S> {
let p = Percentage(1. - length.percentage()); let p = Percentage(1. - length.percentage());
let l = -length.unclamped_length(); let l = -length.unclamped_length();
// We represent `<end-side> <length>` as `calc(100% - <length>)`. // We represent `<end-side> <length>` as `calc(100% - <length>)`.
ComputedLengthPercentage::with_clamping_mode(l, Some(p), length.clamping_mode) ComputedLengthPercentage::new_calc(l, p)
}, },
PositionComponent::Side(_, Some(ref length)) | PositionComponent::Side(_, Some(ref length)) |
PositionComponent::Length(ref length) => length.to_computed_value(context), PositionComponent::Length(ref length) => length.to_computed_value(context),