mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Refactor how calc() clamping is done on computed values (fixes #15296)
This commit is contained in:
parent
f935f2da01
commit
d0b9bd9c64
13 changed files with 173 additions and 154 deletions
|
@ -8,6 +8,7 @@ use app_units::{Au, AU_PER_PX};
|
|||
use ordered_float::NotNaN;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use style_traits::values::specified::AllowedLengthType;
|
||||
use super::{Number, ToComputedValue, Context};
|
||||
use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified};
|
||||
use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength, ViewportPercentageLength};
|
||||
|
@ -48,7 +49,7 @@ impl ToComputedValue for specified::Length {
|
|||
fn to_computed_value(&self, context: &Context) -> Au {
|
||||
match *self {
|
||||
specified::Length::NoCalc(l) => l.to_computed_value(context),
|
||||
specified::Length::Calc(range, ref calc) => range.clamp(calc.to_computed_value(context).length()),
|
||||
specified::Length::Calc(ref calc) => calc.to_computed_value(context).length(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,15 +63,35 @@ impl ToComputedValue for specified::Length {
|
|||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[allow(missing_docs)]
|
||||
pub struct CalcLengthOrPercentage {
|
||||
pub length: Au,
|
||||
pub clamping_mode: AllowedLengthType,
|
||||
length: Au,
|
||||
pub percentage: Option<CSSFloat>,
|
||||
}
|
||||
|
||||
impl CalcLengthOrPercentage {
|
||||
/// Returns a new `CalcLengthOrPercentage`.
|
||||
#[inline]
|
||||
pub fn new(length: Au, percentage: Option<CSSFloat>) -> Self {
|
||||
Self::with_clamping_mode(length, percentage, AllowedLengthType::All)
|
||||
}
|
||||
|
||||
/// Returns a new `CalcLengthOrPercentage` with a specific clamping mode.
|
||||
#[inline]
|
||||
pub fn with_clamping_mode(length: Au,
|
||||
percentage: Option<CSSFloat>,
|
||||
clamping_mode: AllowedLengthType)
|
||||
-> Self {
|
||||
Self {
|
||||
clamping_mode: clamping_mode,
|
||||
length: length,
|
||||
percentage: percentage,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(missing_docs)]
|
||||
pub fn length(&self) -> Au {
|
||||
self.length
|
||||
self.clamping_mode.clamp(self.length)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -81,10 +102,12 @@ impl CalcLengthOrPercentage {
|
|||
|
||||
/// 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_computed(&self, container_len: Option<Au>) -> Option<Au> {
|
||||
pub fn to_used_value(&self, container_len: Option<Au>) -> Option<Au> {
|
||||
match (container_len, self.percentage) {
|
||||
(Some(len), Some(percent)) => Some(self.length + len.scale_by(percent)),
|
||||
(_, None) => Some(self.length),
|
||||
(Some(len), Some(percent)) => {
|
||||
Some(self.clamping_mode.clamp(self.length + len.scale_by(percent)))
|
||||
},
|
||||
(_, None) => Some(self.length()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -94,16 +117,10 @@ impl From<LengthOrPercentage> for CalcLengthOrPercentage {
|
|||
fn from(len: LengthOrPercentage) -> CalcLengthOrPercentage {
|
||||
match len {
|
||||
LengthOrPercentage::Percentage(this) => {
|
||||
CalcLengthOrPercentage {
|
||||
length: Au(0),
|
||||
percentage: Some(this),
|
||||
}
|
||||
CalcLengthOrPercentage::new(Au(0), Some(this))
|
||||
}
|
||||
LengthOrPercentage::Length(this) => {
|
||||
CalcLengthOrPercentage {
|
||||
length: this,
|
||||
percentage: None,
|
||||
}
|
||||
CalcLengthOrPercentage::new(this, None)
|
||||
}
|
||||
LengthOrPercentage::Calc(this) => {
|
||||
this
|
||||
|
@ -116,16 +133,10 @@ impl From<LengthOrPercentageOrAuto> for Option<CalcLengthOrPercentage> {
|
|||
fn from(len: LengthOrPercentageOrAuto) -> Option<CalcLengthOrPercentage> {
|
||||
match len {
|
||||
LengthOrPercentageOrAuto::Percentage(this) => {
|
||||
Some(CalcLengthOrPercentage {
|
||||
length: Au(0),
|
||||
percentage: Some(this),
|
||||
})
|
||||
Some(CalcLengthOrPercentage::new(Au(0), Some(this)))
|
||||
}
|
||||
LengthOrPercentageOrAuto::Length(this) => {
|
||||
Some(CalcLengthOrPercentage {
|
||||
length: this,
|
||||
percentage: None,
|
||||
})
|
||||
Some(CalcLengthOrPercentage::new(this, None))
|
||||
}
|
||||
LengthOrPercentageOrAuto::Calc(this) => {
|
||||
Some(this)
|
||||
|
@ -176,6 +187,7 @@ impl ToComputedValue for specified::CalcLengthOrPercentage {
|
|||
}
|
||||
|
||||
CalcLengthOrPercentage {
|
||||
clamping_mode: self.clamping_mode,
|
||||
length: length,
|
||||
percentage: self.percentage,
|
||||
}
|
||||
|
@ -184,6 +196,7 @@ impl ToComputedValue for specified::CalcLengthOrPercentage {
|
|||
#[inline]
|
||||
fn from_computed_value(computed: &CalcLengthOrPercentage) -> Self {
|
||||
specified::CalcLengthOrPercentage {
|
||||
clamping_mode: computed.clamping_mode,
|
||||
absolute: Some(computed.length),
|
||||
percentage: computed.percentage,
|
||||
..Default::default()
|
||||
|
@ -235,6 +248,17 @@ impl LengthOrPercentage {
|
|||
Calc(c) => (c.length(), NotNaN::new(c.percentage()).unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the used value.
|
||||
pub fn to_used_value(&self, containing_length: Au) -> Au {
|
||||
match *self {
|
||||
LengthOrPercentage::Length(length) => length,
|
||||
LengthOrPercentage::Percentage(p) => containing_length.scale_by(p),
|
||||
LengthOrPercentage::Calc(ref calc) => {
|
||||
calc.to_used_value(Some(containing_length)).unwrap()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for LengthOrPercentage {
|
||||
|
@ -481,6 +505,18 @@ pub enum LengthOrPercentageOrNone {
|
|||
None,
|
||||
}
|
||||
|
||||
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(length),
|
||||
LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent)),
|
||||
LengthOrPercentageOrNone::Calc(ref calc) => calc.to_used_value(Some(containing_length)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for LengthOrPercentageOrNone {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue