mirror of
https://github.com/servo/servo.git
synced 2025-06-23 16:44:33 +01:00
style: Make numbers keep track of whether they were specified as calc().
This commit is contained in:
parent
c20bbb920c
commit
c7ce2ff483
9 changed files with 271 additions and 119 deletions
|
@ -65,7 +65,8 @@ impl From<SpecifiedTimingFunction> for nsTimingFunction {
|
|||
tf.set_as_step(nsTimingFunction_Type::StepEnd, steps);
|
||||
},
|
||||
SpecifiedTimingFunction::CubicBezier(p1, p2) => {
|
||||
tf.set_as_cubic_bezier(p1, p2);
|
||||
tf.set_as_cubic_bezier(Point2D::new(p1.x.value, p1.y.value),
|
||||
Point2D::new(p2.x.value, p2.y.value));
|
||||
},
|
||||
SpecifiedTimingFunction::Keyword(keyword) => {
|
||||
match keyword {
|
||||
|
|
|
@ -1283,7 +1283,7 @@ fn static_assert() {
|
|||
use properties::longhands::font_size_adjust::computed_value::T;
|
||||
match v {
|
||||
T::None => self.gecko.mFont.sizeAdjust = -1.0 as f32,
|
||||
T::Number(n) => self.gecko.mFont.sizeAdjust = n.0 as f32,
|
||||
T::Number(n) => self.gecko.mFont.sizeAdjust = n,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1293,11 +1293,10 @@ fn static_assert() {
|
|||
|
||||
pub fn clone_font_size_adjust(&self) -> longhands::font_size_adjust::computed_value::T {
|
||||
use properties::longhands::font_size_adjust::computed_value::T;
|
||||
use values::specified::Number;
|
||||
|
||||
match self.gecko.mFont.sizeAdjust {
|
||||
-1.0 => T::None,
|
||||
_ => T::Number(Number(self.gecko.mFont.sizeAdjust)),
|
||||
_ => T::Number(self.gecko.mFont.sizeAdjust),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
|
|||
|
||||
#[inline]
|
||||
pub fn get_initial_specified_value() -> SpecifiedValue {
|
||||
SpecifiedValue(vec![Either::Second(Number(0.0))])
|
||||
SpecifiedValue(vec![Either::Second(Number::new(0.0))])
|
||||
}
|
||||
|
||||
impl ToComputedValue for SpecifiedValue {
|
||||
|
@ -486,7 +486,7 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
|
|||
|
||||
#[inline]
|
||||
pub fn get_initial_specified_value() -> SpecifiedValue {
|
||||
SpecifiedValue(vec![SingleSpecifiedValue::Number(Number(1.0))])
|
||||
SpecifiedValue(vec![SingleSpecifiedValue::Number(Number::new(1.0))])
|
||||
}
|
||||
|
||||
impl ToComputedValue for SpecifiedValue {
|
||||
|
|
|
@ -440,7 +440,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
|||
extra_prefixes="moz webkit"
|
||||
spec="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function">
|
||||
use self::computed_value::StartEnd;
|
||||
|
||||
use values::specified::Number;
|
||||
use euclid::point::{Point2D, TypedPoint2D};
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
|
@ -450,31 +450,31 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
|||
#[inline(always)]
|
||||
fn ease() -> computed_value::T {
|
||||
computed_value::T::CubicBezier(TypedPoint2D::new(0.25, 0.1),
|
||||
TypedPoint2D::new(0.25, 1.0))
|
||||
TypedPoint2D::new(0.25, 1.0))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn linear() -> computed_value::T {
|
||||
computed_value::T::CubicBezier(TypedPoint2D::new(0.0, 0.0),
|
||||
TypedPoint2D::new(1.0, 1.0))
|
||||
TypedPoint2D::new(1.0, 1.0))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ease_in() -> computed_value::T {
|
||||
computed_value::T::CubicBezier(TypedPoint2D::new(0.42, 0.0),
|
||||
TypedPoint2D::new(1.0, 1.0))
|
||||
TypedPoint2D::new(1.0, 1.0))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ease_out() -> computed_value::T {
|
||||
computed_value::T::CubicBezier(TypedPoint2D::new(0.0, 0.0),
|
||||
TypedPoint2D::new(0.58, 1.0))
|
||||
TypedPoint2D::new(0.58, 1.0))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ease_in_out() -> computed_value::T {
|
||||
computed_value::T::CubicBezier(TypedPoint2D::new(0.42, 0.0),
|
||||
TypedPoint2D::new(0.58, 1.0))
|
||||
TypedPoint2D::new(0.58, 1.0))
|
||||
}
|
||||
|
||||
static STEP_START: computed_value::T =
|
||||
|
@ -547,7 +547,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
|||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum SpecifiedValue {
|
||||
CubicBezier(Point2D<f32>, Point2D<f32>),
|
||||
CubicBezier(Point2D<Number>, Point2D<Number>),
|
||||
Steps(u32, StartEnd),
|
||||
Keyword(FunctionKeyword),
|
||||
}
|
||||
|
@ -557,7 +557,8 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
|||
if let Ok(function_name) = input.try(|input| input.expect_function()) {
|
||||
return match_ignore_ascii_case! { &function_name,
|
||||
"cubic-bezier" => {
|
||||
let (mut p1x, mut p1y, mut p2x, mut p2y) = (0.0, 0.0, 0.0, 0.0);
|
||||
let (mut p1x, mut p1y, mut p2x, mut p2y) =
|
||||
(Number::new(0.0), Number::new(0.0), Number::new(0.0), Number::new(0.0));
|
||||
try!(input.parse_nested_block(|input| {
|
||||
p1x = try!(specified::parse_number(input));
|
||||
try!(input.expect_comma());
|
||||
|
@ -568,7 +569,8 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
|||
p2y = try!(specified::parse_number(input));
|
||||
Ok(())
|
||||
}));
|
||||
if p1x < 0.0 || p1x > 1.0 || p2x < 0.0 || p2x > 1.0 {
|
||||
if p1x.value < 0.0 || p1x.value > 1.0 ||
|
||||
p2x.value < 0.0 || p2x.value > 1.0 {
|
||||
return Err(())
|
||||
}
|
||||
|
||||
|
@ -651,10 +653,12 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
|||
type ComputedValue = computed_value::T;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _context: &Context) -> computed_value::T {
|
||||
fn to_computed_value(&self, context: &Context) -> computed_value::T {
|
||||
match *self {
|
||||
SpecifiedValue::CubicBezier(p1, p2) => {
|
||||
computed_value::T::CubicBezier(p1, p2)
|
||||
computed_value::T::CubicBezier(
|
||||
Point2D::new(p1.x.to_computed_value(context), p1.y.to_computed_value(context)),
|
||||
Point2D::new(p2.x.to_computed_value(context), p2.y.to_computed_value(context)))
|
||||
},
|
||||
SpecifiedValue::Steps(count, start_end) => {
|
||||
computed_value::T::Steps(count, start_end)
|
||||
|
@ -676,7 +680,11 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
|
|||
fn from_computed_value(computed: &computed_value::T) -> Self {
|
||||
match *computed {
|
||||
computed_value::T::CubicBezier(p1, p2) => {
|
||||
SpecifiedValue::CubicBezier(p1, p2)
|
||||
SpecifiedValue::CubicBezier(
|
||||
Point2D::new(Number::from_computed_value(&p1.x),
|
||||
Number::from_computed_value(&p1.y)),
|
||||
Point2D::new(Number::from_computed_value(&p2.x),
|
||||
Number::from_computed_value(&p2.y)))
|
||||
},
|
||||
computed_value::T::Steps(count, start_end) => {
|
||||
SpecifiedValue::Steps(count, start_end)
|
||||
|
@ -1083,6 +1091,7 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
fixpos_cb="True"
|
||||
spec="https://drafts.csswg.org/css-transforms/#propdef-transform">
|
||||
use app_units::Au;
|
||||
use values::specified::Number;
|
||||
use style_traits::ToCss;
|
||||
use values::CSSFloat;
|
||||
use values::HasViewportPercentage;
|
||||
|
@ -1131,7 +1140,60 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
pub struct T(pub Option<Vec<ComputedOperation>>);
|
||||
}
|
||||
|
||||
pub use self::computed_value::ComputedMatrix as SpecifiedMatrix;
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct SpecifiedMatrix {
|
||||
pub m11: Number, pub m12: Number, pub m13: Number, pub m14: Number,
|
||||
pub m21: Number, pub m22: Number, pub m23: Number, pub m24: Number,
|
||||
pub m31: Number, pub m32: Number, pub m33: Number, pub m34: Number,
|
||||
pub m41: Number, pub m42: Number, pub m43: Number, pub m44: Number,
|
||||
}
|
||||
|
||||
impl ToComputedValue for SpecifiedMatrix {
|
||||
type ComputedValue = computed_value::ComputedMatrix;
|
||||
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
computed_value::ComputedMatrix {
|
||||
m11: self.m11.to_computed_value(context),
|
||||
m12: self.m12.to_computed_value(context),
|
||||
m13: self.m13.to_computed_value(context),
|
||||
m14: self.m14.to_computed_value(context),
|
||||
m21: self.m21.to_computed_value(context),
|
||||
m22: self.m22.to_computed_value(context),
|
||||
m23: self.m23.to_computed_value(context),
|
||||
m24: self.m24.to_computed_value(context),
|
||||
m31: self.m31.to_computed_value(context),
|
||||
m32: self.m32.to_computed_value(context),
|
||||
m33: self.m33.to_computed_value(context),
|
||||
m34: self.m34.to_computed_value(context),
|
||||
m41: self.m41.to_computed_value(context),
|
||||
m42: self.m42.to_computed_value(context),
|
||||
m43: self.m43.to_computed_value(context),
|
||||
m44: self.m44.to_computed_value(context),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||
SpecifiedMatrix {
|
||||
m11: Number::from_computed_value(&computed.m11),
|
||||
m12: Number::from_computed_value(&computed.m12),
|
||||
m13: Number::from_computed_value(&computed.m13),
|
||||
m14: Number::from_computed_value(&computed.m14),
|
||||
m21: Number::from_computed_value(&computed.m21),
|
||||
m22: Number::from_computed_value(&computed.m22),
|
||||
m23: Number::from_computed_value(&computed.m23),
|
||||
m24: Number::from_computed_value(&computed.m24),
|
||||
m31: Number::from_computed_value(&computed.m31),
|
||||
m32: Number::from_computed_value(&computed.m32),
|
||||
m33: Number::from_computed_value(&computed.m33),
|
||||
m34: Number::from_computed_value(&computed.m34),
|
||||
m41: Number::from_computed_value(&computed.m41),
|
||||
m42: Number::from_computed_value(&computed.m42),
|
||||
m43: Number::from_computed_value(&computed.m43),
|
||||
m44: Number::from_computed_value(&computed.m44),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_two_lengths_or_percentages(context: &ParserContext, input: &mut Parser)
|
||||
-> Result<(specified::LengthOrPercentage,
|
||||
|
@ -1144,7 +1206,7 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
Ok((first, second))
|
||||
}
|
||||
|
||||
fn parse_two_floats(input: &mut Parser) -> Result<(CSSFloat,CSSFloat),()> {
|
||||
fn parse_two_numbers(input: &mut Parser) -> Result<(Number, Number), ()> {
|
||||
let first = try!(specified::parse_number(input));
|
||||
let second = input.try(|input| {
|
||||
try!(input.expect_comma());
|
||||
|
@ -1182,8 +1244,8 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
specified::LengthOrPercentage,
|
||||
specified::LengthOrPercentage,
|
||||
specified::Length),
|
||||
Scale(CSSFloat, CSSFloat, CSSFloat),
|
||||
Rotate(CSSFloat, CSSFloat, CSSFloat, specified::Angle),
|
||||
Scale(Number, Number, Number),
|
||||
Rotate(Number, Number, Number, specified::Angle),
|
||||
Perspective(specified::Length),
|
||||
}
|
||||
|
||||
|
@ -1323,31 +1385,29 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
if values.len() != 6 {
|
||||
return Err(())
|
||||
}
|
||||
result.push(SpecifiedOperation::Matrix(
|
||||
SpecifiedMatrix {
|
||||
m11: values[0], m12: values[1], m13: 0.0, m14: 0.0,
|
||||
m21: values[2], m22: values[3], m23: 0.0, m24: 0.0,
|
||||
m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0,
|
||||
m41: values[4], m42: values[5], m43: 0.0, m44: 1.0
|
||||
}));
|
||||
let matrix = SpecifiedMatrix {
|
||||
m11: values[0], m12: values[1], m13: Number::new(0.0), m14: Number::new(0.0),
|
||||
m21: values[2], m22: values[3], m23: Number::new(0.0), m24: Number::new(0.0),
|
||||
m31: Number::new(0.0), m32: Number::new(0.0), m33: Number::new(1.0), m34: Number::new(0.0),
|
||||
m41: values[4], m42: values[5], m43: Number::new(0.0), m44: Number::new(1.0),
|
||||
};
|
||||
result.push(SpecifiedOperation::Matrix(matrix));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
"matrix3d" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let values = try!(input.parse_comma_separated(|input| {
|
||||
specified::parse_number(input)
|
||||
}));
|
||||
let values = try!(input.parse_comma_separated(specified::parse_number));
|
||||
if values.len() != 16 {
|
||||
return Err(())
|
||||
}
|
||||
result.push(SpecifiedOperation::Matrix(
|
||||
SpecifiedMatrix {
|
||||
m11: values[ 0], m12: values[ 1], m13: values[ 2], m14: values[ 3],
|
||||
m21: values[ 4], m22: values[ 5], m23: values[ 6], m24: values[ 7],
|
||||
m31: values[ 8], m32: values[ 9], m33: values[10], m34: values[11],
|
||||
m41: values[12], m42: values[13], m43: values[14], m44: values[15]
|
||||
}));
|
||||
SpecifiedMatrix {
|
||||
m11: values[ 0], m12: values[ 1], m13: values[ 2], m14: values[ 3],
|
||||
m21: values[ 4], m22: values[ 5], m23: values[ 6], m24: values[ 7],
|
||||
m31: values[ 8], m32: values[ 9], m33: values[10], m34: values[11],
|
||||
m41: values[12], m42: values[13], m43: values[14], m44: values[15]
|
||||
}));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
|
@ -1412,29 +1472,37 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
},
|
||||
"scale" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let (sx, sy) = try!(parse_two_floats(input));
|
||||
result.push(SpecifiedOperation::Scale(sx, sy, 1.0));
|
||||
let (sx, sy) = try!(parse_two_numbers(input));
|
||||
result.push(SpecifiedOperation::Scale(sx,
|
||||
sy,
|
||||
Number::new(1.0)));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
"scalex" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let sx = try!(specified::parse_number(input));
|
||||
result.push(SpecifiedOperation::Scale(sx, 1.0, 1.0));
|
||||
result.push(SpecifiedOperation::Scale(sx,
|
||||
Number::new(1.0),
|
||||
Number::new(1.0)));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
"scaley" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let sy = try!(specified::parse_number(input));
|
||||
result.push(SpecifiedOperation::Scale(1.0, sy, 1.0));
|
||||
result.push(SpecifiedOperation::Scale(Number::new(1.0),
|
||||
sy,
|
||||
Number::new(1.0)));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
"scalez" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let sz = try!(specified::parse_number(input));
|
||||
result.push(SpecifiedOperation::Scale(1.0, 1.0, sz));
|
||||
result.push(SpecifiedOperation::Scale(Number::new(1.0),
|
||||
Number::new(1.0),
|
||||
sz));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
|
@ -1452,28 +1520,40 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
"rotate" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let theta = try!(specified::Angle::parse(context,input));
|
||||
result.push(SpecifiedOperation::Rotate(0.0, 0.0, 1.0, theta));
|
||||
result.push(SpecifiedOperation::Rotate(Number::new(0.0),
|
||||
Number::new(0.0),
|
||||
Number::new(1.0),
|
||||
theta));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
"rotatex" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let theta = try!(specified::Angle::parse(context,input));
|
||||
result.push(SpecifiedOperation::Rotate(1.0, 0.0, 0.0, theta));
|
||||
result.push(SpecifiedOperation::Rotate(Number::new(1.0),
|
||||
Number::new(0.0),
|
||||
Number::new(0.0),
|
||||
theta));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
"rotatey" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let theta = try!(specified::Angle::parse(context,input));
|
||||
result.push(SpecifiedOperation::Rotate(0.0, 1.0, 0.0, theta));
|
||||
result.push(SpecifiedOperation::Rotate(Number::new(0.0),
|
||||
Number::new(1.0),
|
||||
Number::new(0.0),
|
||||
theta));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
"rotatez" => {
|
||||
try!(input.parse_nested_block(|input| {
|
||||
let theta = try!(specified::Angle::parse(context,input));
|
||||
result.push(SpecifiedOperation::Rotate(0.0, 0.0, 1.0, theta));
|
||||
result.push(SpecifiedOperation::Rotate(Number::new(0.0),
|
||||
Number::new(0.0),
|
||||
Number::new(1.0),
|
||||
theta));
|
||||
Ok(())
|
||||
}))
|
||||
},
|
||||
|
@ -1543,7 +1623,7 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
for operation in &self.0 {
|
||||
match *operation {
|
||||
SpecifiedOperation::Matrix(ref matrix) => {
|
||||
result.push(computed_value::ComputedOperation::Matrix(*matrix));
|
||||
result.push(computed_value::ComputedOperation::Matrix(matrix.to_computed_value(context)));
|
||||
}
|
||||
SpecifiedOperation::Translate(_, ref tx, ref ty, ref tz) => {
|
||||
result.push(computed_value::ComputedOperation::Translate(tx.to_computed_value(context),
|
||||
|
@ -1551,9 +1631,15 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
tz.to_computed_value(context)));
|
||||
}
|
||||
SpecifiedOperation::Scale(sx, sy, sz) => {
|
||||
let sx = sx.to_computed_value(context);
|
||||
let sy = sy.to_computed_value(context);
|
||||
let sz = sz.to_computed_value(context);
|
||||
result.push(computed_value::ComputedOperation::Scale(sx, sy, sz));
|
||||
}
|
||||
SpecifiedOperation::Rotate(ax, ay, az, theta) => {
|
||||
let ax = ax.to_computed_value(context);
|
||||
let ay = ay.to_computed_value(context);
|
||||
let az = az.to_computed_value(context);
|
||||
let len = (ax * ax + ay * ay + az * az).sqrt();
|
||||
result.push(computed_value::ComputedOperation::Rotate(ax / len, ay / len, az / len, theta));
|
||||
}
|
||||
|
@ -1576,7 +1662,7 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
for operation in computed {
|
||||
match *operation {
|
||||
computed_value::ComputedOperation::Matrix(ref matrix) => {
|
||||
result.push(SpecifiedOperation::Matrix(*matrix));
|
||||
result.push(SpecifiedOperation::Matrix(SpecifiedMatrix::from_computed_value(matrix)));
|
||||
}
|
||||
computed_value::ComputedOperation::Translate(ref tx, ref ty, ref tz) => {
|
||||
// XXXManishearth we lose information here; perhaps we should try to
|
||||
|
@ -1586,11 +1672,18 @@ ${helpers.predefined_type("scroll-snap-coordinate",
|
|||
ToComputedValue::from_computed_value(ty),
|
||||
ToComputedValue::from_computed_value(tz)));
|
||||
}
|
||||
computed_value::ComputedOperation::Scale(sx, sy, sz) => {
|
||||
result.push(SpecifiedOperation::Scale(sx, sy, sz));
|
||||
computed_value::ComputedOperation::Scale(ref sx, ref sy, ref sz) => {
|
||||
result.push(SpecifiedOperation::Scale(
|
||||
Number::from_computed_value(sx),
|
||||
Number::from_computed_value(sy),
|
||||
Number::from_computed_value(sz)));
|
||||
}
|
||||
computed_value::ComputedOperation::Rotate(ax, ay, az, theta) => {
|
||||
result.push(SpecifiedOperation::Rotate(ax, ay, az, theta));
|
||||
computed_value::ComputedOperation::Rotate(ref ax, ref ay, ref az, theta) => {
|
||||
result.push(SpecifiedOperation::Rotate(
|
||||
Number::from_computed_value(ax),
|
||||
Number::from_computed_value(ay),
|
||||
Number::from_computed_value(az),
|
||||
theta));
|
||||
}
|
||||
computed_value::ComputedOperation::Skew(theta_x, theta_y) => {
|
||||
result.push(SpecifiedOperation::Skew(theta_x, theta_y));
|
||||
|
|
|
@ -655,30 +655,65 @@ ${helpers.single_keyword("font-variant-caps",
|
|||
|
||||
<%helpers:longhand products="gecko" name="font-size-adjust" animatable="True"
|
||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::HasViewportPercentage;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
use values::specified::Number;
|
||||
|
||||
impl ComputedValueAsSpecified for SpecifiedValue {}
|
||||
no_viewport_percentage!(SpecifiedValue);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum SpecifiedValue {
|
||||
None,
|
||||
Number(Number),
|
||||
Number(specified::Number),
|
||||
}
|
||||
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
SpecifiedValue::None => dest.write_str("none"),
|
||||
SpecifiedValue::Number(number) => number.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToComputedValue for SpecifiedValue {
|
||||
type ComputedValue = computed_value::T;
|
||||
|
||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||
match *self {
|
||||
SpecifiedValue::None => computed_value::T::None,
|
||||
SpecifiedValue::Number(ref n) => computed_value::T::Number(n.to_computed_value(context)),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_computed_value(computed: &computed_value::T) -> Self {
|
||||
match *computed {
|
||||
computed_value::T::None => SpecifiedValue::None,
|
||||
computed_value::T::Number(ref v) => SpecifiedValue::Number(specified::Number::from_computed_value(v)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod computed_value {
|
||||
use style_traits::ToCss;
|
||||
use std::fmt;
|
||||
use properties::animated_properties::Interpolate;
|
||||
use values::specified::Number;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::CSSFloat;
|
||||
|
||||
pub use super::SpecifiedValue as T;
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum T {
|
||||
None,
|
||||
Number(CSSFloat),
|
||||
}
|
||||
|
||||
impl ToCss for T {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write,
|
||||
{
|
||||
match *self {
|
||||
T::None => dest.write_str("none"),
|
||||
T::Number(number) => number.to_css(dest),
|
||||
|
@ -690,14 +725,15 @@ ${helpers.single_keyword("font-variant-caps",
|
|||
fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
|
||||
match (*self, *other) {
|
||||
(T::Number(ref number), T::Number(ref other)) =>
|
||||
Ok(T::Number(Number(try!(number.0.interpolate(&other.0, time))))),
|
||||
Ok(T::Number(try!(number.interpolate(other, time)))),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline] pub fn get_initial_value() -> computed_value::T {
|
||||
#[inline]
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T::None
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::{CSSFloat, HasViewportPercentage};
|
||||
use values::HasViewportPercentage;
|
||||
|
||||
impl HasViewportPercentage for SpecifiedValue {
|
||||
fn has_viewport_percentage(&self) -> bool {
|
||||
|
@ -28,7 +28,7 @@
|
|||
% if product == "gecko":
|
||||
MozBlockHeight,
|
||||
% endif
|
||||
Number(CSSFloat),
|
||||
Number(specified::Number),
|
||||
LengthOrPercentage(specified::LengthOrPercentage),
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
|||
SpecifiedValue::MozBlockHeight => dest.write_str("-moz-block-height"),
|
||||
% endif
|
||||
SpecifiedValue::LengthOrPercentage(ref value) => value.to_css(dest),
|
||||
SpecifiedValue::Number(number) => write!(dest, "{}", number),
|
||||
SpecifiedValue::Number(number) => number.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,24 +52,24 @@
|
|||
// parsed as a plain Number rather than a Length (0px); this matches the behaviour
|
||||
// of all major browsers
|
||||
input.try(specified::Number::parse_non_negative)
|
||||
.map(|n| SpecifiedValue::Number(n.0))
|
||||
.or_else(|()| {
|
||||
input.try(specified::LengthOrPercentage::parse_non_negative)
|
||||
.map(SpecifiedValue::LengthOrPercentage)
|
||||
.map(SpecifiedValue::Number)
|
||||
.or_else(|()| {
|
||||
match try!(input.next()) {
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("normal") => {
|
||||
Ok(SpecifiedValue::Normal)
|
||||
input.try(specified::LengthOrPercentage::parse_non_negative)
|
||||
.map(SpecifiedValue::LengthOrPercentage)
|
||||
.or_else(|()| {
|
||||
match try!(input.next()) {
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("normal") => {
|
||||
Ok(SpecifiedValue::Normal)
|
||||
}
|
||||
% if product == "gecko":
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("-moz-block-height") => {
|
||||
Ok(SpecifiedValue::MozBlockHeight)
|
||||
}
|
||||
% endif
|
||||
_ => Err(()),
|
||||
}
|
||||
% if product == "gecko":
|
||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("-moz-block-height") => {
|
||||
Ok(SpecifiedValue::MozBlockHeight)
|
||||
}
|
||||
% endif
|
||||
_ => Err(()),
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
pub mod computed_value {
|
||||
use app_units::Au;
|
||||
|
@ -116,7 +116,7 @@
|
|||
% if product == "gecko":
|
||||
SpecifiedValue::MozBlockHeight => computed_value::T::MozBlockHeight,
|
||||
% endif
|
||||
SpecifiedValue::Number(value) => computed_value::T::Number(value),
|
||||
SpecifiedValue::Number(value) => computed_value::T::Number(value.to_computed_value(context)),
|
||||
SpecifiedValue::LengthOrPercentage(ref value) => {
|
||||
match *value {
|
||||
specified::LengthOrPercentage::Length(ref value) =>
|
||||
|
@ -144,7 +144,9 @@
|
|||
% if product == "gecko":
|
||||
computed_value::T::MozBlockHeight => SpecifiedValue::MozBlockHeight,
|
||||
% endif
|
||||
computed_value::T::Number(value) => SpecifiedValue::Number(value),
|
||||
computed_value::T::Number(ref value) => {
|
||||
SpecifiedValue::Number(specified::Number::from_computed_value(value))
|
||||
},
|
||||
computed_value::T::Length(au) => {
|
||||
SpecifiedValue::LengthOrPercentage(specified::LengthOrPercentage::Length(
|
||||
ToComputedValue::from_computed_value(&au)
|
||||
|
|
|
@ -70,8 +70,8 @@
|
|||
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(Longhands {
|
||||
flex_grow: Number(0.0),
|
||||
flex_shrink: Number(0.0),
|
||||
flex_grow: Number::new(0.0),
|
||||
flex_shrink: Number::new(0.0),
|
||||
% if product == "gecko":
|
||||
flex_basis: LengthOrPercentageOrAuto::Auto
|
||||
% else:
|
||||
|
@ -105,8 +105,8 @@
|
|||
return Err(())
|
||||
}
|
||||
Ok(Longhands {
|
||||
flex_grow: grow.unwrap_or(Number(1.0)),
|
||||
flex_shrink: shrink.unwrap_or(Number(1.0)),
|
||||
flex_grow: grow.unwrap_or(Number::new(1.0)),
|
||||
flex_shrink: shrink.unwrap_or(Number::new(1.0)),
|
||||
% if product == "gecko":
|
||||
flex_basis: basis.unwrap_or(LengthOrPercentageOrAuto::Length(NoCalcLength::zero()))
|
||||
% else:
|
||||
|
|
|
@ -219,17 +219,15 @@ pub fn parse_integer(input: &mut Parser) -> Result<CSSInteger, ()> {
|
|||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub fn parse_number(input: &mut Parser) -> Result<f32, ()> {
|
||||
pub fn parse_number(input: &mut Parser) -> Result<Number, ()> {
|
||||
use std::f32;
|
||||
|
||||
match try!(input.next()) {
|
||||
Token::Number(ref value) => {
|
||||
use std::f32;
|
||||
if value.value.is_finite() {
|
||||
Ok(value.value)
|
||||
} else if value.value.is_sign_positive() {
|
||||
Ok(f32::MAX)
|
||||
} else {
|
||||
Ok(f32::MIN)
|
||||
}
|
||||
Ok(Number {
|
||||
value: value.value.min(f32::MAX).max(f32::MIN),
|
||||
was_calc: false,
|
||||
})
|
||||
},
|
||||
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||
let ast = try!(input.parse_nested_block(|i| CalcLengthOrPercentage::parse_sum(i, CalcUnit::Number)));
|
||||
|
@ -245,7 +243,12 @@ pub fn parse_number(input: &mut Parser) -> Result<f32, ()> {
|
|||
}
|
||||
|
||||
match result {
|
||||
Some(result) => Ok(result),
|
||||
Some(result) => {
|
||||
Ok(Number {
|
||||
value: result.min(f32::MAX).max(f32::MIN),
|
||||
was_calc: true,
|
||||
})
|
||||
},
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
@ -525,24 +528,39 @@ impl ToCss for Time {
|
|||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[allow(missing_docs)]
|
||||
pub struct Number(pub CSSFloat);
|
||||
pub struct Number {
|
||||
/// The numeric value itself.
|
||||
pub value: CSSFloat,
|
||||
/// Whether this came from a `calc()` expression. This is needed for
|
||||
/// serialization purposes, since `calc(1)` should still serialize to
|
||||
/// `calc(1)`, not just `1`.
|
||||
was_calc: bool,
|
||||
}
|
||||
|
||||
no_viewport_percentage!(Number);
|
||||
|
||||
impl Parse for Number {
|
||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
parse_number(input).map(Number)
|
||||
parse_number(input)
|
||||
}
|
||||
}
|
||||
|
||||
impl Number {
|
||||
fn parse_with_minimum(input: &mut Parser, min: CSSFloat) -> Result<Number, ()> {
|
||||
match parse_number(input) {
|
||||
Ok(value) if value >= min => Ok(Number(value)),
|
||||
Ok(value) if value.value >= min => Ok(value),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a new number with the value `val`.
|
||||
pub fn new(val: CSSFloat) -> Self {
|
||||
Number {
|
||||
value: val,
|
||||
was_calc: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub fn parse_non_negative(input: &mut Parser) -> Result<Number, ()> {
|
||||
Number::parse_with_minimum(input, 0.0)
|
||||
|
@ -558,17 +576,27 @@ impl ToComputedValue for Number {
|
|||
type ComputedValue = CSSFloat;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _: &Context) -> CSSFloat { self.0 }
|
||||
fn to_computed_value(&self, _: &Context) -> CSSFloat { self.value }
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &CSSFloat) -> Self {
|
||||
Number(*computed)
|
||||
Number {
|
||||
value: *computed,
|
||||
was_calc: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for Number {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
self.0.to_css(dest)
|
||||
if self.was_calc {
|
||||
dest.write_str("calc(")?;
|
||||
}
|
||||
self.value.to_css(dest)?;
|
||||
if self.was_calc {
|
||||
dest.write_str(")")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,7 +634,7 @@ impl ToCss for NumberOrPercentage {
|
|||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
#[allow(missing_docs)]
|
||||
pub struct Opacity(pub CSSFloat);
|
||||
pub struct Opacity(Number);
|
||||
|
||||
no_viewport_percentage!(Opacity);
|
||||
|
||||
|
@ -620,19 +648,13 @@ impl ToComputedValue for Opacity {
|
|||
type ComputedValue = CSSFloat;
|
||||
|
||||
#[inline]
|
||||
fn to_computed_value(&self, _: &Context) -> CSSFloat {
|
||||
if self.0 < 0.0 {
|
||||
0.0
|
||||
} else if self.0 > 1.0 {
|
||||
1.0
|
||||
} else {
|
||||
self.0
|
||||
}
|
||||
fn to_computed_value(&self, context: &Context) -> CSSFloat {
|
||||
self.0.to_computed_value(context).min(1.0).max(0.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_computed_value(computed: &CSSFloat) -> Self {
|
||||
Opacity(*computed)
|
||||
Opacity(Number::from_computed_value(computed))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -573,15 +573,14 @@ mod shorthand_serialization {
|
|||
|
||||
#[test]
|
||||
fn flex_should_serialize_all_available_properties() {
|
||||
use style::values::specified::Number as NumberContainer;
|
||||
use style::values::specified::Percentage as PercentageContainer;
|
||||
use style::values::specified::{Number, Percentage};
|
||||
|
||||
let mut properties = Vec::new();
|
||||
|
||||
let grow = NumberContainer(2f32);
|
||||
let shrink = NumberContainer(3f32);
|
||||
let grow = Number::new(2f32);
|
||||
let shrink = Number::new(3f32);
|
||||
let basis =
|
||||
LengthOrPercentageOrAutoOrContent::Percentage(PercentageContainer(0.5f32));
|
||||
LengthOrPercentageOrAutoOrContent::Percentage(Percentage(0.5f32));
|
||||
|
||||
properties.push(PropertyDeclaration::FlexGrow(grow));
|
||||
properties.push(PropertyDeclaration::FlexShrink(shrink));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue