style/values/specified/
background.rs1use crate::parser::{Parse, ParserContext};
8use crate::values::generics::background::BackgroundSize as GenericBackgroundSize;
9use crate::values::specified::length::{
10 NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto,
11};
12use cssparser::Parser;
13use selectors::parser::SelectorParseErrorKind;
14use std::fmt::{self, Write};
15use style_traits::{CssWriter, ParseError, ToCss};
16
17pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>;
19
20impl Parse for BackgroundSize {
21 fn parse<'i, 't>(
22 context: &ParserContext,
23 input: &mut Parser<'i, 't>,
24 ) -> Result<Self, ParseError<'i>> {
25 if let Ok(width) = input.try_parse(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
26 {
27 let height = input
28 .try_parse(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
29 .unwrap_or(NonNegativeLengthPercentageOrAuto::auto());
30 return Ok(GenericBackgroundSize::ExplicitSize { width, height });
31 }
32 Ok(try_match_ident_ignore_ascii_case! { input,
33 "cover" => GenericBackgroundSize::Cover,
34 "contain" => GenericBackgroundSize::Contain,
35 })
36 }
37}
38
39#[derive(
41 Clone,
42 Copy,
43 Debug,
44 Eq,
45 MallocSizeOf,
46 Parse,
47 PartialEq,
48 SpecifiedValueInfo,
49 ToComputedValue,
50 ToCss,
51 ToResolvedValue,
52 ToShmem,
53)]
54#[allow(missing_docs)]
55#[value_info(other_values = "repeat-x,repeat-y")]
56pub enum BackgroundRepeatKeyword {
57 Repeat,
58 Space,
59 Round,
60 NoRepeat,
61}
62
63#[derive(
69 Clone,
70 Debug,
71 MallocSizeOf,
72 PartialEq,
73 SpecifiedValueInfo,
74 ToComputedValue,
75 ToResolvedValue,
76 ToShmem,
77)]
78pub struct BackgroundRepeat(pub BackgroundRepeatKeyword, pub BackgroundRepeatKeyword);
79
80impl BackgroundRepeat {
81 pub fn repeat() -> Self {
83 BackgroundRepeat(
84 BackgroundRepeatKeyword::Repeat,
85 BackgroundRepeatKeyword::Repeat,
86 )
87 }
88}
89
90impl ToCss for BackgroundRepeat {
91 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
92 where
93 W: Write,
94 {
95 match (self.0, self.1) {
96 (BackgroundRepeatKeyword::Repeat, BackgroundRepeatKeyword::NoRepeat) => {
97 dest.write_str("repeat-x")
98 },
99 (BackgroundRepeatKeyword::NoRepeat, BackgroundRepeatKeyword::Repeat) => {
100 dest.write_str("repeat-y")
101 },
102 (horizontal, vertical) => {
103 horizontal.to_css(dest)?;
104 if horizontal != vertical {
105 dest.write_char(' ')?;
106 vertical.to_css(dest)?;
107 }
108 Ok(())
109 },
110 }
111 }
112}
113
114impl Parse for BackgroundRepeat {
115 fn parse<'i, 't>(
116 _context: &ParserContext,
117 input: &mut Parser<'i, 't>,
118 ) -> Result<Self, ParseError<'i>> {
119 let ident = input.expect_ident_cloned()?;
120
121 match_ignore_ascii_case! { &ident,
122 "repeat-x" => {
123 return Ok(BackgroundRepeat(BackgroundRepeatKeyword::Repeat, BackgroundRepeatKeyword::NoRepeat));
124 },
125 "repeat-y" => {
126 return Ok(BackgroundRepeat(BackgroundRepeatKeyword::NoRepeat, BackgroundRepeatKeyword::Repeat));
127 },
128 _ => {},
129 }
130
131 let horizontal = match BackgroundRepeatKeyword::from_ident(&ident) {
132 Ok(h) => h,
133 Err(()) => {
134 return Err(
135 input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))
136 );
137 },
138 };
139
140 let vertical = input.try_parse(BackgroundRepeatKeyword::parse).ok();
141 Ok(BackgroundRepeat(horizontal, vertical.unwrap_or(horizontal)))
142 }
143}