1use crate::counter_style::CounterStyle;
8use crate::derives::*;
9use crate::values::specified::Attr;
10use crate::values::CustomIdent;
11use std::fmt::{self, Write};
12use std::ops::Deref;
13use style_traits::{CssWriter, ToCss};
14
15#[derive(
17 Clone,
18 Debug,
19 MallocSizeOf,
20 PartialEq,
21 SpecifiedValueInfo,
22 ToComputedValue,
23 ToResolvedValue,
24 ToShmem,
25)]
26#[repr(C)]
27pub struct GenericCounterPair<Integer> {
28 pub name: CustomIdent,
30 pub value: Integer,
32 pub is_reversed: bool,
35}
36pub use self::GenericCounterPair as CounterPair;
37
38impl<Integer> ToCss for CounterPair<Integer>
39where
40 Integer: ToCss + PartialEq<i32>,
41{
42 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
43 where
44 W: Write,
45 {
46 if self.is_reversed {
47 dest.write_str("reversed(")?;
48 }
49 self.name.to_css(dest)?;
50 if self.is_reversed {
51 dest.write_char(')')?;
52 if self.value == i32::min_value() {
53 return Ok(());
54 }
55 }
56 dest.write_char(' ')?;
57 self.value.to_css(dest)
58 }
59}
60
61#[derive(
63 Clone,
64 Debug,
65 Default,
66 MallocSizeOf,
67 PartialEq,
68 SpecifiedValueInfo,
69 ToComputedValue,
70 ToCss,
71 ToResolvedValue,
72 ToShmem,
73 ToTyped,
74)]
75#[repr(transparent)]
76pub struct GenericCounterIncrement<I>(#[css(field_bound)] pub GenericCounters<I>);
77pub use self::GenericCounterIncrement as CounterIncrement;
78
79impl<I> CounterIncrement<I> {
80 #[inline]
82 pub fn new(counters: Vec<CounterPair<I>>) -> Self {
83 CounterIncrement(Counters(counters.into()))
84 }
85}
86
87impl<I> Deref for CounterIncrement<I> {
88 type Target = [CounterPair<I>];
89
90 #[inline]
91 fn deref(&self) -> &Self::Target {
92 &(self.0).0
93 }
94}
95
96#[derive(
98 Clone,
99 Debug,
100 Default,
101 MallocSizeOf,
102 PartialEq,
103 SpecifiedValueInfo,
104 ToComputedValue,
105 ToCss,
106 ToResolvedValue,
107 ToShmem,
108 ToTyped,
109)]
110#[repr(transparent)]
111pub struct GenericCounterSet<I>(#[css(field_bound)] pub GenericCounters<I>);
112pub use self::GenericCounterSet as CounterSet;
113
114impl<I> CounterSet<I> {
115 #[inline]
117 pub fn new(counters: Vec<CounterPair<I>>) -> Self {
118 CounterSet(Counters(counters.into()))
119 }
120}
121
122impl<I> Deref for CounterSet<I> {
123 type Target = [CounterPair<I>];
124
125 #[inline]
126 fn deref(&self) -> &Self::Target {
127 &(self.0).0
128 }
129}
130
131#[derive(
133 Clone,
134 Debug,
135 Default,
136 MallocSizeOf,
137 PartialEq,
138 SpecifiedValueInfo,
139 ToComputedValue,
140 ToCss,
141 ToResolvedValue,
142 ToShmem,
143 ToTyped,
144)]
145#[repr(transparent)]
146pub struct GenericCounterReset<I>(#[css(field_bound)] pub GenericCounters<I>);
147pub use self::GenericCounterReset as CounterReset;
148
149impl<I> CounterReset<I> {
150 #[inline]
152 pub fn new(counters: Vec<CounterPair<I>>) -> Self {
153 CounterReset(Counters(counters.into()))
154 }
155}
156
157impl<I> Deref for CounterReset<I> {
158 type Target = [CounterPair<I>];
159
160 #[inline]
161 fn deref(&self) -> &Self::Target {
162 &(self.0).0
163 }
164}
165
166#[derive(
170 Clone,
171 Debug,
172 Default,
173 MallocSizeOf,
174 PartialEq,
175 SpecifiedValueInfo,
176 ToComputedValue,
177 ToCss,
178 ToResolvedValue,
179 ToShmem,
180)]
181#[repr(transparent)]
182pub struct GenericCounters<I>(
183 #[css(field_bound)]
184 #[css(iterable, if_empty = "none")]
185 crate::OwnedSlice<GenericCounterPair<I>>,
186);
187pub use self::GenericCounters as Counters;
188
189
190#[inline]
191fn is_decimal(counter_type: &CounterStyle) -> bool {
192 *counter_type == CounterStyle::decimal()
193}
194
195#[derive(
197 Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
198)]
199#[repr(C)]
200pub struct GenericContentItems<Image> {
201 pub items: thin_vec::ThinVec<GenericContentItem<Image>>,
204 pub alt_start: usize,
207}
208
209impl<Image> ToCss for GenericContentItems<Image>
210where
211 Image: ToCss,
212{
213 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
214 where
215 W: Write,
216 {
217 for (i, item) in self.items.iter().enumerate() {
218 if i == self.alt_start {
219 dest.write_str(" /")?;
220 }
221 if i != 0 {
222 dest.write_str(" ")?;
223 }
224 item.to_css(dest)?;
225 }
226 Ok(())
227 }
228}
229
230#[derive(
234 Clone,
235 Debug,
236 Eq,
237 MallocSizeOf,
238 PartialEq,
239 SpecifiedValueInfo,
240 ToComputedValue,
241 ToCss,
242 ToShmem,
243 ToTyped,
244)]
245#[repr(u8)]
246pub enum GenericContent<Image> {
247 Normal,
249 None,
251 Items(GenericContentItems<Image>),
253}
254
255pub use self::GenericContent as Content;
256
257impl<Image> Content<Image> {
258 #[inline]
260 pub fn is_items(&self) -> bool {
261 matches!(*self, Self::Items(..))
262 }
263
264 #[inline]
266 pub fn normal() -> Self {
267 Content::Normal
268 }
269}
270
271#[derive(
273 Clone,
274 Debug,
275 Eq,
276 MallocSizeOf,
277 PartialEq,
278 ToComputedValue,
279 SpecifiedValueInfo,
280 ToCss,
281 ToResolvedValue,
282 ToShmem,
283)]
284#[repr(u8)]
285pub enum GenericContentItem<I> {
286 String(crate::OwnedStr),
288 #[css(comma, function)]
290 Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyle),
291 #[css(comma, function)]
293 Counters(
294 CustomIdent,
295 crate::OwnedStr,
296 #[css(skip_if = "is_decimal")] CounterStyle,
297 ),
298 OpenQuote,
300 CloseQuote,
302 NoOpenQuote,
304 NoCloseQuote,
306 #[cfg(feature = "gecko")]
308 MozAltContent,
309 #[cfg(feature = "gecko")]
313 MozLabelContent,
314 Attr(Attr),
316 Image(I),
318}
319
320pub use self::GenericContentItem as ContentItem;