stylo: Implement align-items and justify-items

This commit is contained in:
Matt Brubeck 2017-02-16 11:53:56 -08:00
parent 11396b4dd3
commit 0a0dd11f50
5 changed files with 183 additions and 13 deletions

View file

@ -17,7 +17,7 @@ pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, Gra
pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
pub use super::{Auto, Either, None_};
#[cfg(feature = "gecko")]
pub use super::specified::{AlignJustifyContent, AlignJustifySelf};
pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone};
pub use super::specified::url::UrlExtraData;
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
@ -122,6 +122,32 @@ impl ToComputedValue for specified::CSSColor {
}
}
#[cfg(feature = "gecko")]
impl ToComputedValue for specified::JustifyItems {
type ComputedValue = JustifyItems;
// https://drafts.csswg.org/css-align/#valdef-justify-items-auto
fn to_computed_value(&self, context: &Context) -> JustifyItems {
use values::specified::align;
// If the inherited value of `justify-items` includes the `legacy` keyword, `auto` computes
// to the inherited value.
if self.0 == align::ALIGN_AUTO {
let inherited = context.inherited_style.get_position().clone_justify_items();
if inherited.0.contains(align::ALIGN_LEGACY) {
return inherited
}
}
return *self
}
#[inline]
fn from_computed_value(computed: &JustifyItems) -> Self {
*computed
}
}
#[cfg(feature = "gecko")]
impl ComputedValueAsSpecified for specified::AlignItems {}
#[cfg(feature = "gecko")]
impl ComputedValueAsSpecified for specified::AlignJustifyContent {}
#[cfg(feature = "gecko")]

View file

@ -9,6 +9,7 @@
use cssparser::Parser;
use gecko_bindings::structs;
use parser::{Parse, ParserContext};
use std::ascii::AsciiExt;
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
@ -238,6 +239,86 @@ impl Parse for AlignJustifySelf {
}
}
/// Value of the `align-items` property
///
/// https://drafts.csswg.org/css-align/#self-alignment
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct AlignItems(pub AlignFlags);
impl AlignItems {
/// The initial value 'normal'
#[inline]
pub fn normal() -> Self {
AlignItems(ALIGN_NORMAL)
}
}
no_viewport_percentage!(AlignItems);
impl ToCss for AlignItems {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.0.to_css(dest)
}
}
impl Parse for AlignItems {
// normal | stretch | <baseline-position> |
// [ <overflow-position>? && <self-position> ]
fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
// normal | stretch | <baseline-position>
if let Ok(value) = input.try(parse_normal_stretch_baseline) {
return Ok(AlignItems(value))
}
// [ <overflow-position>? && <self-position> ]
if let Ok(value) = input.try(parse_overflow_self_position) {
return Ok(AlignItems(value))
}
Err(())
}
}
/// Value of the `justify-items` property
///
/// https://drafts.csswg.org/css-align/#justify-items-property
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct JustifyItems(pub AlignFlags);
impl JustifyItems {
/// The initial value 'auto'
#[inline]
pub fn auto() -> Self {
JustifyItems(ALIGN_AUTO)
}
}
no_viewport_percentage!(JustifyItems);
impl ToCss for JustifyItems {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.0.to_css(dest)
}
}
impl Parse for JustifyItems {
// auto | normal | stretch | <baseline-position> |
// [ <overflow-position>? && <self-position> ]
// [ legacy && [ left | right | center ] ]
fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
// auto | normal | stretch | <baseline-position>
if let Ok(value) = input.try(parse_auto_normal_stretch_baseline) {
return Ok(JustifyItems(value))
}
// [ <overflow-position>? && <self-position> ]
if let Ok(value) = input.try(parse_overflow_self_position) {
return Ok(JustifyItems(value))
}
// [ legacy && [ left | right | center ] ]
if let Ok(value) = input.try(parse_legacy) {
return Ok(JustifyItems(value))
}
Err(())
}
}
// auto | normal | stretch | <baseline-position>
fn parse_auto_normal_stretch_baseline(input: &mut Parser) -> Result<AlignFlags, ()> {
@ -251,6 +332,17 @@ fn parse_auto_normal_stretch_baseline(input: &mut Parser) -> Result<AlignFlags,
}
}
// normal | stretch | <baseline-position>
fn parse_normal_stretch_baseline(input: &mut Parser) -> Result<AlignFlags, ()> {
let ident = input.expect_ident()?;
match_ignore_ascii_case! { ident,
"normal" => Ok(ALIGN_NORMAL),
"stretch" => Ok(ALIGN_STRETCH),
"baseline" => Ok(ALIGN_BASELINE),
_ => Err(())
}
}
// normal | <baseline-position>
fn parse_normal_or_baseline(input: &mut Parser) -> Result<AlignFlags, ()> {
let ident = input.expect_ident()?;
@ -350,3 +442,26 @@ fn parse_self_position(input: &mut Parser) -> Result<AlignFlags, ()> {
_ => Err(())
}
}
// [ legacy && [ left | right | center ] ]
fn parse_legacy(input: &mut Parser) -> Result<AlignFlags, ()> {
let a = input.expect_ident()?;
let b = input.expect_ident()?;
if a.eq_ignore_ascii_case("legacy") {
match_ignore_ascii_case! { b,
"left" => Ok(ALIGN_LEGACY | ALIGN_LEFT),
"right" => Ok(ALIGN_LEGACY | ALIGN_RIGHT),
"center" => Ok(ALIGN_LEGACY | ALIGN_CENTER),
_ => Err(())
}
} else if b.eq_ignore_ascii_case("legacy") {
match_ignore_ascii_case! { a,
"left" => Ok(ALIGN_LEGACY | ALIGN_LEFT),
"right" => Ok(ALIGN_LEGACY | ALIGN_RIGHT),
"center" => Ok(ALIGN_LEGACY | ALIGN_CENTER),
_ => Err(())
}
} else {
Err(())
}
}

View file

@ -21,7 +21,7 @@ use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
use super::computed::Shadow as ComputedShadow;
#[cfg(feature = "gecko")]
pub use self::align::{AlignJustifyContent, AlignJustifySelf};
pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems};
pub use self::grid::GridLine;
pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient};
pub use self::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword};