mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Make use of generics for transform-origin
This allows us to preserve keywords during serialisation.
This commit is contained in:
parent
b42aaf28df
commit
5d70580813
12 changed files with 241 additions and 221 deletions
|
@ -2076,120 +2076,13 @@ ${helpers.single_keyword("transform-style",
|
||||||
flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
|
flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
|
||||||
animation_value_type="discrete")}
|
animation_value_type="discrete")}
|
||||||
|
|
||||||
<%helpers:longhand name="transform-origin" animation_value_type="ComputedValue" extra_prefixes="moz webkit" boxed="True"
|
${helpers.predefined_type("transform-origin",
|
||||||
spec="https://drafts.csswg.org/css-transforms/#transform-origin-property">
|
"TransformOrigin",
|
||||||
use app_units::Au;
|
"computed::TransformOrigin::initial_value()",
|
||||||
use std::fmt;
|
animation_value_type="ComputedValue",
|
||||||
use style_traits::ToCss;
|
extra_prefixes="moz webkit",
|
||||||
use values::specified::{NoCalcLength, LengthOrPercentage, Percentage};
|
boxed=True,
|
||||||
|
spec="https://drafts.csswg.org/css-transforms/#transform-origin-property")}
|
||||||
pub mod computed_value {
|
|
||||||
use properties::animated_properties::Animatable;
|
|
||||||
use values::computed::{Length, LengthOrPercentage};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
|
||||||
pub struct T {
|
|
||||||
pub horizontal: LengthOrPercentage,
|
|
||||||
pub vertical: LengthOrPercentage,
|
|
||||||
pub depth: Length,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Animatable for T {
|
|
||||||
#[inline]
|
|
||||||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64)
|
|
||||||
-> Result<Self, ()> {
|
|
||||||
Ok(T {
|
|
||||||
horizontal: try!(self.horizontal.add_weighted(&other.horizontal,
|
|
||||||
self_portion, other_portion)),
|
|
||||||
vertical: try!(self.vertical.add_weighted(&other.vertical,
|
|
||||||
self_portion, other_portion)),
|
|
||||||
depth: try!(self.depth.add_weighted(&other.depth, self_portion, other_portion)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
|
||||||
self.compute_squared_distance(other).map(|sd| sd.sqrt())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
|
||||||
Ok(try!(self.horizontal.compute_squared_distance(&other.horizontal)) +
|
|
||||||
try!(self.vertical.compute_squared_distance(&other.vertical)) +
|
|
||||||
try!(self.depth.compute_squared_distance(&other.depth)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
|
||||||
pub struct SpecifiedValue {
|
|
||||||
horizontal: LengthOrPercentage,
|
|
||||||
vertical: LengthOrPercentage,
|
|
||||||
depth: NoCalcLength,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for computed_value::T {
|
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
|
||||||
try!(self.horizontal.to_css(dest));
|
|
||||||
try!(dest.write_str(" "));
|
|
||||||
try!(self.vertical.to_css(dest));
|
|
||||||
try!(dest.write_str(" "));
|
|
||||||
self.depth.to_css(dest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for SpecifiedValue {
|
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
|
||||||
try!(self.horizontal.to_css(dest));
|
|
||||||
try!(dest.write_str(" "));
|
|
||||||
try!(self.vertical.to_css(dest));
|
|
||||||
try!(dest.write_str(" "));
|
|
||||||
self.depth.to_css(dest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_initial_value() -> computed_value::T {
|
|
||||||
computed_value::T {
|
|
||||||
horizontal: computed::LengthOrPercentage::Percentage(0.5),
|
|
||||||
vertical: computed::LengthOrPercentage::Percentage(0.5),
|
|
||||||
depth: Au(0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
|
|
||||||
let result = try!(super::parse_origin(context, input));
|
|
||||||
Ok(SpecifiedValue {
|
|
||||||
horizontal: result.horizontal.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.5))),
|
|
||||||
vertical: result.vertical.unwrap_or(LengthOrPercentage::Percentage(Percentage(0.5))),
|
|
||||||
depth: result.depth.unwrap_or(NoCalcLength::zero()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToComputedValue for SpecifiedValue {
|
|
||||||
type ComputedValue = computed_value::T;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_computed_value(&self, context: &Context) -> computed_value::T {
|
|
||||||
computed_value::T {
|
|
||||||
horizontal: self.horizontal.to_computed_value(context),
|
|
||||||
vertical: self.vertical.to_computed_value(context),
|
|
||||||
depth: self.depth.to_computed_value(context),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_computed_value(computed: &computed_value::T) -> Self {
|
|
||||||
SpecifiedValue {
|
|
||||||
horizontal: ToComputedValue::from_computed_value(&computed.horizontal),
|
|
||||||
vertical: ToComputedValue::from_computed_value(&computed.vertical),
|
|
||||||
depth: ToComputedValue::from_computed_value(&computed.depth),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</%helpers:longhand>
|
|
||||||
|
|
||||||
// FIXME: `size` and `content` values are not implemented and `strict` is implemented
|
// FIXME: `size` and `content` values are not implemented and `strict` is implemented
|
||||||
// like `content`(layout style paint) in gecko. We should implement `size` and `content`,
|
// like `content`(layout style paint) in gecko. We should implement `size` and `content`,
|
||||||
|
|
|
@ -429,96 +429,6 @@ ${helpers.predefined_type("clip",
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
pub struct OriginParseResult {
|
|
||||||
pub horizontal: Option<specified::LengthOrPercentage>,
|
|
||||||
pub vertical: Option<specified::LengthOrPercentage>,
|
|
||||||
pub depth: Option<specified::NoCalcLength>
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_origin(context: &ParserContext, input: &mut Parser) -> Result<OriginParseResult,()> {
|
|
||||||
use values::specified::{LengthOrPercentage, Percentage};
|
|
||||||
let (mut horizontal, mut vertical, mut depth, mut horizontal_is_center) = (None, None, None, false);
|
|
||||||
loop {
|
|
||||||
if let Err(_) = input.try(|input| {
|
|
||||||
let token = try!(input.expect_ident());
|
|
||||||
match_ignore_ascii_case! {
|
|
||||||
&token,
|
|
||||||
"left" => {
|
|
||||||
if horizontal.is_none() {
|
|
||||||
horizontal = Some(LengthOrPercentage::Percentage(Percentage(0.0)))
|
|
||||||
} else if horizontal_is_center && vertical.is_none() {
|
|
||||||
vertical = Some(LengthOrPercentage::Percentage(Percentage(0.5)));
|
|
||||||
horizontal = Some(LengthOrPercentage::Percentage(Percentage(0.0)));
|
|
||||||
} else {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"center" => {
|
|
||||||
if horizontal.is_none() {
|
|
||||||
horizontal_is_center = true;
|
|
||||||
horizontal = Some(LengthOrPercentage::Percentage(Percentage(0.5)))
|
|
||||||
} else if vertical.is_none() {
|
|
||||||
vertical = Some(LengthOrPercentage::Percentage(Percentage(0.5)))
|
|
||||||
} else {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"right" => {
|
|
||||||
if horizontal.is_none() {
|
|
||||||
horizontal = Some(LengthOrPercentage::Percentage(Percentage(1.0)))
|
|
||||||
} else if horizontal_is_center && vertical.is_none() {
|
|
||||||
vertical = Some(LengthOrPercentage::Percentage(Percentage(0.5)));
|
|
||||||
horizontal = Some(LengthOrPercentage::Percentage(Percentage(1.0)));
|
|
||||||
} else {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"top" => {
|
|
||||||
if vertical.is_none() {
|
|
||||||
vertical = Some(LengthOrPercentage::Percentage(Percentage(0.0)))
|
|
||||||
} else {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bottom" => {
|
|
||||||
if vertical.is_none() {
|
|
||||||
vertical = Some(LengthOrPercentage::Percentage(Percentage(1.0)))
|
|
||||||
} else {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => return Err(())
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}) {
|
|
||||||
match input.try(|input| LengthOrPercentage::parse(context, input)) {
|
|
||||||
Ok(value) => {
|
|
||||||
if horizontal.is_none() {
|
|
||||||
horizontal = Some(value);
|
|
||||||
} else if vertical.is_none() {
|
|
||||||
vertical = Some(value);
|
|
||||||
} else if let LengthOrPercentage::Length(length) = value {
|
|
||||||
depth = Some(length);
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if horizontal.is_some() || vertical.is_some() {
|
|
||||||
Ok(OriginParseResult {
|
|
||||||
horizontal: horizontal,
|
|
||||||
vertical: vertical,
|
|
||||||
depth: depth,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
${helpers.single_keyword("mix-blend-mode",
|
${helpers.single_keyword("mix-blend-mode",
|
||||||
"""normal multiply screen overlay darken lighten color-dodge
|
"""normal multiply screen overlay darken lighten color-dodge
|
||||||
color-burn hard-light soft-light difference exclusion hue
|
color-burn hard-light soft-light difference exclusion hue
|
||||||
|
|
|
@ -130,10 +130,6 @@ macro_rules! expanded {
|
||||||
/// A module with all the code for longhand properties.
|
/// A module with all the code for longhand properties.
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod longhands {
|
pub mod longhands {
|
||||||
use cssparser::Parser;
|
|
||||||
use parser::{Parse, ParserContext};
|
|
||||||
use values::specified;
|
|
||||||
|
|
||||||
<%include file="/longhand/background.mako.rs" />
|
<%include file="/longhand/background.mako.rs" />
|
||||||
<%include file="/longhand/border.mako.rs" />
|
<%include file="/longhand/border.mako.rs" />
|
||||||
<%include file="/longhand/box.mako.rs" />
|
<%include file="/longhand/box.mako.rs" />
|
||||||
|
|
|
@ -38,6 +38,7 @@ pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrP
|
||||||
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
||||||
pub use self::length::{MaxLength, MozLength};
|
pub use self::length::{MaxLength, MozLength};
|
||||||
pub use self::position::Position;
|
pub use self::position::Position;
|
||||||
|
pub use self::transform::TransformOrigin;
|
||||||
|
|
||||||
pub mod background;
|
pub mod background;
|
||||||
pub mod basic_shape;
|
pub mod basic_shape;
|
||||||
|
@ -46,6 +47,7 @@ pub mod image;
|
||||||
pub mod length;
|
pub mod length;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
|
pub mod transform;
|
||||||
|
|
||||||
/// A `Context` is all the data a specified value could ever need to compute
|
/// A `Context` is all the data a specified value could ever need to compute
|
||||||
/// itself and be transformed to a computed value.
|
/// itself and be transformed to a computed value.
|
||||||
|
|
49
components/style/values/computed/transform.rs
Normal file
49
components/style/values/computed/transform.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Computed types for CSS values that are related to transformations.
|
||||||
|
|
||||||
|
use properties::animated_properties::Animatable;
|
||||||
|
use values::computed::{Length, LengthOrPercentage};
|
||||||
|
use values::generics::transform::TransformOrigin as GenericTransformOrigin;
|
||||||
|
|
||||||
|
/// The computed value of a CSS `<transform-origin>`
|
||||||
|
pub type TransformOrigin = GenericTransformOrigin<LengthOrPercentage, LengthOrPercentage, Length>;
|
||||||
|
|
||||||
|
impl TransformOrigin {
|
||||||
|
/// Returns the initial computed value for `transform-origin`.
|
||||||
|
#[inline]
|
||||||
|
pub fn initial_value() -> Self {
|
||||||
|
Self::new(
|
||||||
|
LengthOrPercentage::Percentage(0.5),
|
||||||
|
LengthOrPercentage::Percentage(0.5),
|
||||||
|
Length::from_px(0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animatable for TransformOrigin {
|
||||||
|
#[inline]
|
||||||
|
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||||
|
Ok(Self::new(
|
||||||
|
self.horizontal.add_weighted(&other.horizontal, self_portion, other_portion)?,
|
||||||
|
self.vertical.add_weighted(&other.vertical, self_portion, other_portion)?,
|
||||||
|
self.depth.add_weighted(&other.depth, self_portion, other_portion)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||||
|
self.compute_squared_distance(other).map(f64::sqrt)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||||
|
Ok(
|
||||||
|
self.horizontal.compute_squared_distance(&other.horizontal)? +
|
||||||
|
self.vertical.compute_squared_distance(&other.vertical)? +
|
||||||
|
self.depth.compute_squared_distance(&other.depth)?
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ pub mod grid;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
|
pub mod transform;
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
|
// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
|
||||||
define_css_keyword_enum! { SymbolsType:
|
define_css_keyword_enum! { SymbolsType:
|
||||||
|
|
45
components/style/values/generics/transform.rs
Normal file
45
components/style/values/generics/transform.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Generic types for CSS values that are related to transformations.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use style_traits::ToCss;
|
||||||
|
|
||||||
|
/// A generic transform origin.
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)]
|
||||||
|
pub struct TransformOrigin<H, V, Depth> {
|
||||||
|
/// The horizontal origin.
|
||||||
|
pub horizontal: H,
|
||||||
|
/// The vertical origin.
|
||||||
|
pub vertical: V,
|
||||||
|
/// The depth.
|
||||||
|
pub depth: Depth,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<H, V, D> TransformOrigin<H, V, D> {
|
||||||
|
/// Returns a new transform origin.
|
||||||
|
pub fn new(horizontal: H, vertical: V, depth: D) -> Self {
|
||||||
|
Self {
|
||||||
|
horizontal: horizontal,
|
||||||
|
vertical: vertical,
|
||||||
|
depth: depth,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<H, V, D> ToCss for TransformOrigin<H, V, D>
|
||||||
|
where H: ToCss, V: ToCss, D: ToCss,
|
||||||
|
{
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||||
|
where W: fmt::Write,
|
||||||
|
{
|
||||||
|
self.horizontal.to_css(dest)?;
|
||||||
|
dest.write_str(" ")?;
|
||||||
|
self.vertical.to_css(dest)?;
|
||||||
|
dest.write_str(" ")?;
|
||||||
|
self.depth.to_css(dest)
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,7 @@ pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercent
|
||||||
pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength};
|
pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength};
|
||||||
pub use self::length::{MaxLength, MozLength};
|
pub use self::length::{MaxLength, MozLength};
|
||||||
pub use self::position::{Position, PositionComponent};
|
pub use self::position::{Position, PositionComponent};
|
||||||
|
pub use self::transform::TransformOrigin;
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub mod align;
|
pub mod align;
|
||||||
|
@ -55,6 +56,7 @@ pub mod image;
|
||||||
pub mod length;
|
pub mod length;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
|
pub mod transform;
|
||||||
|
|
||||||
/// Common handling for the specified value CSS url() values.
|
/// Common handling for the specified value CSS url() values.
|
||||||
pub mod url {
|
pub mod url {
|
||||||
|
|
132
components/style/values/specified/transform.rs
Normal file
132
components/style/values/specified/transform.rs
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Specified types for CSS values that are related to transformations.
|
||||||
|
|
||||||
|
use cssparser::Parser;
|
||||||
|
use parser::{Parse, ParserContext};
|
||||||
|
use std::fmt;
|
||||||
|
use style_traits::ToCss;
|
||||||
|
use values::computed::{LengthOrPercentage as ComputedLengthOrPercentage, Context, ToComputedValue};
|
||||||
|
use values::generics::transform::TransformOrigin as GenericTransformOrigin;
|
||||||
|
use values::specified::length::{Length, LengthOrPercentage};
|
||||||
|
use values::specified::position::{Side, X, Y};
|
||||||
|
|
||||||
|
/// The specified value of a CSS `<transform-origin>`
|
||||||
|
pub type TransformOrigin = GenericTransformOrigin<OriginComponent<X>, OriginComponent<Y>, Length>;
|
||||||
|
|
||||||
|
/// The specified value of a component of a CSS `<transform-origin>`.
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
||||||
|
pub enum OriginComponent<S> {
|
||||||
|
/// `center`
|
||||||
|
Center,
|
||||||
|
/// `<lop>`
|
||||||
|
Length(LengthOrPercentage),
|
||||||
|
/// `<side>`
|
||||||
|
Side(S),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for TransformOrigin {
|
||||||
|
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
let parse_depth = |input: &mut Parser| {
|
||||||
|
input.try(|i| Length::parse(context, i)).unwrap_or(Length::from_px(0.))
|
||||||
|
};
|
||||||
|
match input.try(|i| OriginComponent::parse(context, i)) {
|
||||||
|
Ok(x_origin @ OriginComponent::Center) => {
|
||||||
|
if let Ok(y_origin) = input.try(|i| OriginComponent::parse(context, i)) {
|
||||||
|
let depth = parse_depth(input);
|
||||||
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
}
|
||||||
|
let y_origin = OriginComponent::Center;
|
||||||
|
if let Ok(x_keyword) = input.try(X::parse) {
|
||||||
|
let x_origin = OriginComponent::Side(x_keyword);
|
||||||
|
let depth = parse_depth(input);
|
||||||
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
}
|
||||||
|
let depth = Length::from_px(0.);
|
||||||
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
},
|
||||||
|
Ok(x_origin) => {
|
||||||
|
if let Ok(y_origin) = input.try(|i| OriginComponent::parse(context, i)) {
|
||||||
|
let depth = parse_depth(input);
|
||||||
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
}
|
||||||
|
let y_origin = OriginComponent::Center;
|
||||||
|
let depth = Length::from_px(0.);
|
||||||
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
},
|
||||||
|
Err(_) => {},
|
||||||
|
}
|
||||||
|
let y_keyword = Y::parse(input)?;
|
||||||
|
let y_origin = OriginComponent::Side(y_keyword);
|
||||||
|
if let Ok(x_keyword) = input.try(X::parse) {
|
||||||
|
let x_origin = OriginComponent::Side(x_keyword);
|
||||||
|
let depth = parse_depth(input);
|
||||||
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
}
|
||||||
|
if input.try(|i| i.expect_ident_matching("center")).is_ok() {
|
||||||
|
let x_origin = OriginComponent::Center;
|
||||||
|
let depth = parse_depth(input);
|
||||||
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
}
|
||||||
|
let x_origin = OriginComponent::Center;
|
||||||
|
let depth = Length::from_px(0.);
|
||||||
|
Ok(Self::new(x_origin, y_origin, depth))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Parse for OriginComponent<S>
|
||||||
|
where S: Parse,
|
||||||
|
{
|
||||||
|
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
if input.try(|i| i.expect_ident_matching("center")).is_ok() {
|
||||||
|
return Ok(OriginComponent::Center);
|
||||||
|
}
|
||||||
|
if let Ok(lop) = input.try(|i| LengthOrPercentage::parse(context, i)) {
|
||||||
|
return Ok(OriginComponent::Length(lop));
|
||||||
|
}
|
||||||
|
let keyword = S::parse(context, input)?;
|
||||||
|
Ok(OriginComponent::Side(keyword))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: ToCss> ToCss for OriginComponent<S>
|
||||||
|
where S: ToCss,
|
||||||
|
{
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||||
|
where W: fmt::Write,
|
||||||
|
{
|
||||||
|
match *self {
|
||||||
|
OriginComponent::Center => dest.write_str("center"),
|
||||||
|
OriginComponent::Length(ref lop) => lop.to_css(dest),
|
||||||
|
OriginComponent::Side(ref keyword) => keyword.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> ToComputedValue for OriginComponent<S>
|
||||||
|
where S: Side,
|
||||||
|
{
|
||||||
|
type ComputedValue = ComputedLengthOrPercentage;
|
||||||
|
|
||||||
|
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||||
|
match *self {
|
||||||
|
OriginComponent::Center => {
|
||||||
|
ComputedLengthOrPercentage::Percentage(0.5)
|
||||||
|
},
|
||||||
|
OriginComponent::Length(ref length) => {
|
||||||
|
length.to_computed_value(context)
|
||||||
|
},
|
||||||
|
OriginComponent::Side(ref keyword) => {
|
||||||
|
let p = if keyword.is_start() { 0. } else { 1. };
|
||||||
|
ComputedLengthOrPercentage::Percentage(p)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
|
OriginComponent::Length(ToComputedValue::from_computed_value(computed))
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use parsing::parse;
|
use parsing::parse;
|
||||||
use style::properties::longhands::{self, perspective_origin, transform_origin};
|
use style::properties::longhands::{perspective_origin, transform_origin};
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -30,16 +30,6 @@ fn test_clip() {
|
||||||
"rect(auto, auto, auto, auto)");
|
"rect(auto, auto, auto, auto)");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_longhands_parse_origin() {
|
|
||||||
assert_parser_exhausted!(longhands::parse_origin, "1px some-rubbish", false);
|
|
||||||
assert_parser_exhausted!(longhands::parse_origin, "1px 2px", true);
|
|
||||||
assert_parser_exhausted!(longhands::parse_origin, "center left", true);
|
|
||||||
assert_parser_exhausted!(longhands::parse_origin, "center right", true);
|
|
||||||
assert_parser_exhausted!(longhands::parse_origin, "center right 1px", true);
|
|
||||||
assert_parser_exhausted!(longhands::parse_origin, "1% right", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_effects_parser_exhaustion() {
|
fn test_effects_parser_exhaustion() {
|
||||||
assert_parser_exhausted!(perspective_origin::parse, "1px 1px", true);
|
assert_parser_exhausted!(perspective_origin::parse, "1px 1px", true);
|
||||||
|
|
|
@ -25454,7 +25454,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"mozilla/calc.html": [
|
"mozilla/calc.html": [
|
||||||
"47507adabc0d3642154b3ed4b1ab64d726fa682d",
|
"a1f441f7fd4b9ab3ae9e1cb5403cfe8de90bb71c",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"mozilla/canvas.initial.reset.2dstate.html": [
|
"mozilla/canvas.initial.reset.2dstate.html": [
|
||||||
|
|
|
@ -141,7 +141,7 @@ numberProperties.forEach(function(prop) {
|
||||||
var otherProperties = [
|
var otherProperties = [
|
||||||
['border-width', 'calc(1px)', 'calc(1px)'],
|
['border-width', 'calc(1px)', 'calc(1px)'],
|
||||||
['border-spacing', 'calc(1px)', 'calc(1px)'],
|
['border-spacing', 'calc(1px)', 'calc(1px)'],
|
||||||
['transform-origin', 'calc(1px + 0%)', 'calc(1px + 0%) 50% 0px'],
|
['transform-origin', 'calc(1px + 0%)', 'calc(1px + 0%) center 0px'],
|
||||||
['perspective-origin', 'calc(1px + 0%)', 'calc(1px + 0%) center'],
|
['perspective-origin', 'calc(1px + 0%)', 'calc(1px + 0%) center'],
|
||||||
['background-size', 'calc(1px + 0%)', 'calc(1px + 0%) auto'],
|
['background-size', 'calc(1px + 0%)', 'calc(1px + 0%) auto'],
|
||||||
['background-position', 'calc(1px + 0%) calc(2px + 0%)', 'calc(1px + 0%) calc(2px + 0%)'],
|
['background-position', 'calc(1px + 0%) calc(2px + 0%)', 'calc(1px + 0%) calc(2px + 0%)'],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue