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