1use crate::counter_style::{CounterStyle, CounterStyleParsingFlags};
8use crate::derives::*;
9use crate::parser::{Parse, ParserContext};
10use cssparser::{Parser, Token};
11use style_traits::{ParseError, StyleParseErrorKind};
12
13#[derive(
15 Clone,
16 Debug,
17 Eq,
18 MallocSizeOf,
19 PartialEq,
20 SpecifiedValueInfo,
21 ToComputedValue,
22 ToCss,
23 ToResolvedValue,
24 ToShmem,
25 ToTyped,
26)]
27#[repr(transparent)]
28#[typed(todo_derive_fields)]
29pub struct ListStyleType(pub CounterStyle);
30
31impl ListStyleType {
32 #[inline]
34 pub fn disc() -> Self {
35 Self(CounterStyle::disc())
36 }
37
38 #[inline]
40 pub fn none() -> Self {
41 Self(CounterStyle::None)
42 }
43
44 #[inline]
46 pub fn is_name(&self, n: &crate::Atom) -> bool {
47 self.0.is_name(n)
48 }
49
50 #[cfg(feature = "gecko")]
55 pub fn from_gecko_keyword(value: u32) -> Self {
56 use crate::gecko_bindings::structs;
57 use crate::values::CustomIdent;
58 let v8 = value as u8;
59 if v8 == structs::ListStyle_None {
60 return Self::none();
61 }
62
63 Self(CounterStyle::Name(CustomIdent(match v8 {
64 structs::ListStyle_Disc => atom!("disc"),
65 structs::ListStyle_Circle => atom!("circle"),
66 structs::ListStyle_Square => atom!("square"),
67 structs::ListStyle_Decimal => atom!("decimal"),
68 structs::ListStyle_LowerRoman => atom!("lower-roman"),
69 structs::ListStyle_UpperRoman => atom!("upper-roman"),
70 structs::ListStyle_LowerAlpha => atom!("lower-alpha"),
71 structs::ListStyle_UpperAlpha => atom!("upper-alpha"),
72 _ => unreachable!("Unknown counter style keyword value"),
73 })))
74 }
75
76 #[inline]
78 pub fn is_bullet(&self) -> bool {
79 self.0.is_bullet()
80 }
81}
82
83impl Parse for ListStyleType {
84 fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
85 let flags = CounterStyleParsingFlags::ALLOW_NONE | CounterStyleParsingFlags::ALLOW_STRING;
86 Ok(Self(CounterStyle::parse(context, input, flags)?))
87 }
88}
89
90#[derive(
92 Clone,
93 Debug,
94 MallocSizeOf,
95 PartialEq,
96 SpecifiedValueInfo,
97 ToComputedValue,
98 ToCss,
99 ToResolvedValue,
100 ToShmem,
101)]
102#[repr(C)]
103pub struct QuotePair {
104 pub opening: crate::OwnedStr,
106
107 pub closing: crate::OwnedStr,
109}
110
111#[derive(
113 Clone,
114 Debug,
115 Default,
116 MallocSizeOf,
117 PartialEq,
118 SpecifiedValueInfo,
119 ToComputedValue,
120 ToCss,
121 ToResolvedValue,
122 ToShmem,
123)]
124#[repr(transparent)]
125pub struct QuoteList(
126 #[css(iterable, if_empty = "none")]
127 #[ignore_malloc_size_of = "Arc"]
128 pub crate::ArcSlice<QuotePair>,
129);
130
131#[derive(
134 Clone,
135 Debug,
136 MallocSizeOf,
137 PartialEq,
138 SpecifiedValueInfo,
139 ToComputedValue,
140 ToCss,
141 ToResolvedValue,
142 ToShmem,
143 ToTyped,
144)]
145#[repr(C)]
146#[typed(todo_derive_fields)]
147pub enum Quotes {
148 QuoteList(QuoteList),
150 Auto,
152}
153
154impl Parse for Quotes {
155 fn parse(_: &ParserContext, input: &mut Parser) -> Result<Quotes, ParseError> {
156 if input
157 .try_parse(|input| input.expect_ident_matching("auto"))
158 .is_ok()
159 {
160 return Ok(Quotes::Auto);
161 }
162
163 if input
164 .try_parse(|input| input.expect_ident_matching("none"))
165 .is_ok()
166 {
167 return Ok(Quotes::QuoteList(QuoteList::default()));
168 }
169
170 let mut quotes = Vec::new();
171 loop {
172 let opening = match input.next() {
173 Ok(Token::QuotedString(value)) => value.as_ref().to_owned().into(),
174 Ok(_) => return Err(ParseError::unexpected_token()),
175 Err(_) => break,
176 };
177
178 let closing = input.expect_string()?.as_ref().to_owned().into();
179 quotes.push(QuotePair { opening, closing });
180 }
181
182 if !quotes.is_empty() {
183 Ok(Quotes::QuoteList(QuoteList(crate::ArcSlice::from_iter(
184 quotes.into_iter(),
185 ))))
186 } else {
187 Err(ParseError::custom(StyleParseErrorKind::UnspecifiedError))
188 }
189 }
190}
191
192#[allow(missing_docs)]
194#[derive(
195 Clone,
196 Copy,
197 Debug,
198 Deserialize,
199 Eq,
200 FromPrimitive,
201 Hash,
202 MallocSizeOf,
203 Parse,
204 PartialEq,
205 Serialize,
206 SpecifiedValueInfo,
207 ToComputedValue,
208 ToCss,
209 ToResolvedValue,
210 ToShmem,
211 ToTyped,
212)]
213#[repr(u8)]
214pub enum ListStylePosition {
215 Outside,
216 Inside,
217}