Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor a few CSS properties #17095

Merged
merged 3 commits into from May 31, 2017
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Make use of generics for transform-origin

This allows us to preserve keywords during serialisation.
  • Loading branch information
nox committed May 31, 2017
commit 5d70580813db0538ebe2fcbf6ea95b41ca7ee151
@@ -2076,120 +2076,13 @@ ${helpers.single_keyword("transform-style",
flags="CREATES_STACKING_CONTEXT FIXPOS_CB",
animation_value_type="discrete")}

<%helpers:longhand name="transform-origin" animation_value_type="ComputedValue" extra_prefixes="moz webkit" boxed="True"
spec="https://drafts.csswg.org/css-transforms/#transform-origin-property">
use app_units::Au;
use std::fmt;
use style_traits::ToCss;
use values::specified::{NoCalcLength, LengthOrPercentage, Percentage};

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>
${helpers.predefined_type("transform-origin",
"TransformOrigin",
"computed::TransformOrigin::initial_value()",
animation_value_type="ComputedValue",
extra_prefixes="moz webkit",
boxed=True,
spec="https://drafts.csswg.org/css-transforms/#transform-origin-property")}

// 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`,
@@ -429,96 +429,6 @@ ${helpers.predefined_type("clip",
}
</%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",
"""normal multiply screen overlay darken lighten color-dodge
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.
#[allow(missing_docs)]
pub mod longhands {
use cssparser::Parser;
use parser::{Parse, ParserContext};
use values::specified;

<%include file="/longhand/background.mako.rs" />
<%include file="/longhand/border.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::{MaxLength, MozLength};
pub use self::position::Position;
pub use self::transform::TransformOrigin;

pub mod background;
pub mod basic_shape;
@@ -46,6 +47,7 @@ pub mod image;
pub mod length;
pub mod position;
pub mod rect;
pub mod transform;

/// A `Context` is all the data a specified value could ever need to compute
/// itself and be transformed to a computed value.
@@ -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 position;
pub mod rect;
pub mod transform;

// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
define_css_keyword_enum! { SymbolsType:
@@ -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::{MaxLength, MozLength};
pub use self::position::{Position, PositionComponent};
pub use self::transform::TransformOrigin;

#[cfg(feature = "gecko")]
pub mod align;
@@ -55,6 +56,7 @@ pub mod image;
pub mod length;
pub mod position;
pub mod rect;
pub mod transform;

/// Common handling for the specified value CSS url() values.
pub mod url {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.