use crate::parser::{Parse, ParserContext};
use crate::values::generics::background::BackgroundSize as GenericBackgroundSize;
use crate::values::specified::length::{
NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto,
};
use cssparser::Parser;
use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, ToCss};
pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>;
impl Parse for BackgroundSize {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
if let Ok(width) = input.try_parse(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
{
let height = input
.try_parse(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
.unwrap_or(NonNegativeLengthPercentageOrAuto::auto());
return Ok(GenericBackgroundSize::ExplicitSize { width, height });
}
Ok(try_match_ident_ignore_ascii_case! { input,
"cover" => GenericBackgroundSize::Cover,
"contain" => GenericBackgroundSize::Contain,
})
}
}
#[derive(
Clone,
Copy,
Debug,
Eq,
MallocSizeOf,
Parse,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[allow(missing_docs)]
#[value_info(other_values = "repeat-x,repeat-y")]
pub enum BackgroundRepeatKeyword {
Repeat,
Space,
Round,
NoRepeat,
}
#[derive(
Clone,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToComputedValue,
ToResolvedValue,
ToShmem,
)]
pub struct BackgroundRepeat(pub BackgroundRepeatKeyword, pub BackgroundRepeatKeyword);
impl BackgroundRepeat {
pub fn repeat() -> Self {
BackgroundRepeat(
BackgroundRepeatKeyword::Repeat,
BackgroundRepeatKeyword::Repeat,
)
}
}
impl ToCss for BackgroundRepeat {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match (self.0, self.1) {
(BackgroundRepeatKeyword::Repeat, BackgroundRepeatKeyword::NoRepeat) => {
dest.write_str("repeat-x")
},
(BackgroundRepeatKeyword::NoRepeat, BackgroundRepeatKeyword::Repeat) => {
dest.write_str("repeat-y")
},
(horizontal, vertical) => {
horizontal.to_css(dest)?;
if horizontal != vertical {
dest.write_char(' ')?;
vertical.to_css(dest)?;
}
Ok(())
},
}
}
}
impl Parse for BackgroundRepeat {
fn parse<'i, 't>(
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let ident = input.expect_ident_cloned()?;
match_ignore_ascii_case! { &ident,
"repeat-x" => {
return Ok(BackgroundRepeat(BackgroundRepeatKeyword::Repeat, BackgroundRepeatKeyword::NoRepeat));
},
"repeat-y" => {
return Ok(BackgroundRepeat(BackgroundRepeatKeyword::NoRepeat, BackgroundRepeatKeyword::Repeat));
},
_ => {},
}
let horizontal = match BackgroundRepeatKeyword::from_ident(&ident) {
Ok(h) => h,
Err(()) => {
return Err(
input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))
);
},
};
let vertical = input.try_parse(BackgroundRepeatKeyword::parse).ok();
Ok(BackgroundRepeat(horizontal, vertical.unwrap_or(horizontal)))
}
}