Move specified and computed angles to submodules

This commit is contained in:
Anthony Ramine 2017-08-16 11:15:23 +02:00
parent 4d10d39e8f
commit 1bd12bf91a
5 changed files with 279 additions and 238 deletions

View file

@ -25,6 +25,7 @@ use values::computed::ComputedValueAsSpecified;
use values::specified::calc::CalcNode;
pub use properties::animated_properties::TransitionProperty;
pub use self::angle::Angle;
#[cfg(feature = "gecko")]
pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
pub use self::background::BackgroundSize;
@ -54,6 +55,7 @@ pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateCompo
#[cfg(feature = "gecko")]
pub mod align;
pub mod angle;
pub mod background;
pub mod basic_shape;
pub mod border;
@ -152,146 +154,6 @@ pub fn parse_number_with_clamping_mode<'i, 't>(context: &ParserContext,
})
}
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
/// An angle consisting of a value and a unit.
///
/// Computed Angle is essentially same as specified angle except calc
/// value serialization. Therefore we are using computed Angle enum
/// to hold the value and unit type.
pub struct Angle {
value: computed::Angle,
was_calc: bool,
}
impl ToCss for Angle {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if self.was_calc {
dest.write_str("calc(")?;
}
self.value.to_css(dest)?;
if self.was_calc {
dest.write_str(")")?;
}
Ok(())
}
}
impl ToComputedValue for Angle {
type ComputedValue = computed::Angle;
fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue {
self.value
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
Angle {
value: *computed,
was_calc: false,
}
}
}
impl Angle {
/// Returns an angle with the given value in degrees.
pub fn from_degrees(value: CSSFloat, was_calc: bool) -> Self {
Angle { value: computed::Angle::Degree(value), was_calc: was_calc }
}
/// Returns an angle with the given value in gradians.
pub fn from_gradians(value: CSSFloat, was_calc: bool) -> Self {
Angle { value: computed::Angle::Gradian(value), was_calc: was_calc }
}
/// Returns an angle with the given value in turns.
pub fn from_turns(value: CSSFloat, was_calc: bool) -> Self {
Angle { value: computed::Angle::Turn(value), was_calc: was_calc }
}
/// Returns an angle with the given value in radians.
pub fn from_radians(value: CSSFloat, was_calc: bool) -> Self {
Angle { value: computed::Angle::Radian(value), was_calc: was_calc }
}
#[inline]
#[allow(missing_docs)]
pub fn radians(self) -> f32 {
self.value.radians()
}
/// Returns an angle value that represents zero.
pub fn zero() -> Self {
Self::from_degrees(0.0, false)
}
/// Returns an `Angle` parsed from a `calc()` expression.
pub fn from_calc(radians: CSSFloat) -> Self {
Angle {
value: computed::Angle::Radian(radians),
was_calc: true,
}
}
}
impl Parse for Angle {
/// Parses an angle according to CSS-VALUES § 6.1.
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
// FIXME: remove clone() when lifetimes are non-lexical
let token = input.next()?.clone();
match token {
Token::Dimension { value, ref unit, .. } => {
Angle::parse_dimension(value, unit, /* from_calc = */ false)
}
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
}
_ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
}
}
impl Angle {
/// Parse an `<angle>` value given a value and an unit.
pub fn parse_dimension(
value: CSSFloat,
unit: &str,
from_calc: bool)
-> Result<Angle, ()>
{
let angle = match_ignore_ascii_case! { unit,
"deg" => Angle::from_degrees(value, from_calc),
"grad" => Angle::from_gradians(value, from_calc),
"turn" => Angle::from_turns(value, from_calc),
"rad" => Angle::from_radians(value, from_calc),
_ => return Err(())
};
Ok(angle)
}
/// Parse an angle, including unitless 0 degree.
///
/// Note that numbers without any AngleUnit, including unitless 0 angle,
/// should be invalid. However, some properties still accept unitless 0
/// angle and stores it as '0deg'.
///
/// We can remove this and get back to the unified version Angle::parse once
/// https://github.com/w3c/csswg-drafts/issues/1162 is resolved.
pub fn parse_with_unitless<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Self, ParseError<'i>> {
// FIXME: remove clone() when lifetimes are non-lexical
let token = input.next()?.clone();
match token {
Token::Dimension { value, ref unit, .. } => {
Angle::parse_dimension(value, unit, /* from_calc = */ false)
}
Token::Number { value, .. } if value == 0. => Ok(Angle::zero()),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
}
_ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into())
}
}
// The integer values here correspond to the border conflict resolution rules in CSS 2.1 §
// 17.6.2.1. Higher values override lower values.
define_numbered_css_keyword_enum! { BorderStyle: