Make text-shadow and box-shadow use SimpleShadow

This commit is contained in:
Anthony Ramine 2017-06-28 11:36:27 +02:00
parent 65ff4a399c
commit 201d7e79e7
14 changed files with 414 additions and 434 deletions

View file

@ -6,11 +6,13 @@
use cssparser::{BasicParseError, Parser, Token};
use parser::{Parse, ParserContext};
use style_traits::ParseError;
use style_traits::{ParseError, StyleParseError};
#[cfg(not(feature = "gecko"))]
use values::Impossible;
use values::computed::{Context, Number as ComputedNumber, ToComputedValue};
use values::computed::effects::BoxShadow as ComputedBoxShadow;
use values::computed::effects::SimpleShadow as ComputedSimpleShadow;
use values::generics::effects::BoxShadow as GenericBoxShadow;
use values::generics::effects::Filter as GenericFilter;
use values::generics::effects::SimpleShadow as GenericSimpleShadow;
use values::specified::{Angle, Percentage};
@ -19,6 +21,9 @@ use values::specified::length::Length;
#[cfg(feature = "gecko")]
use values::specified::url::SpecifiedUrl;
/// A specified value for a single shadow of the `box-shadow` property.
pub type BoxShadow = GenericBoxShadow<Option<Color>, Length, Option<Length>>;
/// A specified value for a single `filter`.
#[cfg(feature = "gecko")]
pub type Filter = GenericFilter<Angle, Factor, Length, SimpleShadow>;
@ -42,6 +47,85 @@ pub enum Factor {
/// A specified value for the `drop-shadow()` filter.
pub type SimpleShadow = GenericSimpleShadow<Option<Color>, Length, Option<Length>>;
impl Parse for BoxShadow {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let mut lengths = None;
let mut color = None;
let mut inset = false;
loop {
if !inset {
if input.try(|input| input.expect_ident_matching("inset")).is_ok() {
inset = true;
continue;
}
}
if lengths.is_none() {
let value = input.try::<_, _, ParseError>(|i| {
let horizontal = Length::parse(context, i)?;
let vertical = Length::parse(context, i)?;
let (blur, spread) = match i.try::<_, _, ParseError>(|i| Length::parse_non_negative(context, i)) {
Ok(blur) => {
let spread = i.try(|i| Length::parse(context, i)).ok();
(Some(blur), spread)
},
Err(_) => (None, None),
};
Ok((horizontal, vertical, blur, spread))
});
if let Ok(value) = value {
lengths = Some(value);
continue;
}
}
if color.is_none() {
if let Ok(value) = input.try(|i| Color::parse(context, i)) {
color = Some(value);
continue;
}
}
break;
}
let lengths = lengths.ok_or(StyleParseError::UnspecifiedError)?;
Ok(BoxShadow {
base: SimpleShadow {
color: color,
horizontal: lengths.0,
vertical: lengths.1,
blur: lengths.2,
},
spread: lengths.3,
inset: inset,
})
}
}
impl ToComputedValue for BoxShadow {
type ComputedValue = ComputedBoxShadow;
#[inline]
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
ComputedBoxShadow {
base: self.base.to_computed_value(context),
spread: self.spread.as_ref().unwrap_or(&Length::zero()).to_computed_value(context),
inset: self.inset,
}
}
#[inline]
fn from_computed_value(computed: &ComputedBoxShadow) -> Self {
BoxShadow {
base: ToComputedValue::from_computed_value(&computed.base),
spread: Some(ToComputedValue::from_computed_value(&computed.spread)),
inset: computed.inset,
}
}
}
impl Parse for Filter {
#[inline]
fn parse<'i, 't>(