Refactor Position

A specified position is now a struct made of two values of different types,
the first one being PositionComponent<X>, and the second one PositionComponent<Y>.

A position component is represented by the new enum PositionComponent<Side>,
with the three values Center, Length(LengthOrPercentage), and
Side(Side, Option<LengthOrPercentage>).

Side keywords are represented by the X and Y enums, which don't include a value
for the center keyword anymore. They are accompanied by the Side trait, which
allows us to determine whether a side keyword is "left" or "top".

This refactor simplified the parsing and serialisation code and exposed bugs in it,
where it would reject valid <position> values followed by arbitrary tokens,
and where it would fail to prefer "left" to "right" when serialising positions
in basic shapes.
This commit is contained in:
Anthony Ramine 2017-05-08 03:09:26 +02:00
parent 0040160b38
commit 70ec61cf01
22 changed files with 484 additions and 887 deletions

View file

@ -10,39 +10,28 @@
use std::fmt;
use style_traits::ToCss;
use values::computed::LengthOrPercentage;
use values::generics::position::{Position as GenericPosition, PositionWithKeyword};
use values::generics::position::HorizontalPosition as GenericHorizontalPosition;
use values::generics::position::VerticalPosition as GenericVerticalPosition;
use values::generics::position::Position as GenericPosition;
/// The computed value of a CSS `<position>`
pub type Position = PositionWithKeyword<LengthOrPercentage>;
pub type Position = GenericPosition<HorizontalPosition, VerticalPosition>;
impl Copy for Position {}
/// The computed value of a CSS horizontal position.
pub type HorizontalPosition = LengthOrPercentage;
/// The computed value for `<position>` values without a keyword.
pub type OriginPosition = GenericPosition<LengthOrPercentage, LengthOrPercentage>;
impl Copy for OriginPosition {}
impl OriginPosition {
#[inline]
/// The initial value for `perspective-origin`
pub fn center() -> OriginPosition {
GenericPosition {
horizontal: LengthOrPercentage::Percentage(0.5),
vertical: LengthOrPercentage::Percentage(0.5),
}
}
}
/// The computed value of a CSS vertical position.
pub type VerticalPosition = LengthOrPercentage;
impl Position {
/// `50% 50%`
#[inline]
pub fn center() -> Self {
Self::new(LengthOrPercentage::Percentage(0.5), LengthOrPercentage::Percentage(0.5))
}
/// `0% 0%`
#[inline]
/// Construct a position at (0, 0)
pub fn zero() -> Self {
Position {
horizontal: GenericHorizontalPosition(LengthOrPercentage::zero()),
vertical: GenericVerticalPosition(LengthOrPercentage::zero()),
}
Self::new(LengthOrPercentage::zero(), LengthOrPercentage::zero())
}
}
@ -53,29 +42,3 @@ impl ToCss for Position {
self.vertical.to_css(dest)
}
}
/// The computed value of a horizontal `<position>`
pub type HorizontalPosition = GenericHorizontalPosition<LengthOrPercentage>;
impl Copy for HorizontalPosition {}
impl HorizontalPosition {
#[inline]
/// Create a zero position value.
pub fn zero() -> HorizontalPosition {
GenericHorizontalPosition(LengthOrPercentage::Percentage(0.0))
}
}
/// The computed value of a vertical `<position>`
pub type VerticalPosition = GenericVerticalPosition<LengthOrPercentage>;
impl Copy for VerticalPosition {}
impl VerticalPosition {
#[inline]
/// Create a zero position value.
pub fn zero() -> VerticalPosition {
GenericVerticalPosition(LengthOrPercentage::Percentage(0.0))
}
}