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)]
76#[typed(todo_derive_fields)]
77pub struct GenericCounterIncrement<I>(#[css(field_bound)] pub GenericCounters<I>);
78pub use self::GenericCounterIncrement as CounterIncrement;
79
80impl<I> CounterIncrement<I> {
81 #[inline]
83 pub fn new(counters: Vec<CounterPair<I>>) -> Self {
84 CounterIncrement(Counters(counters.into()))
85 }
86}
87
88impl<I> Deref for CounterIncrement<I> {
89 type Target = [CounterPair<I>];
90
91 #[inline]
92 fn deref(&self) -> &Self::Target {
93 &(self.0).0
94 }
95}
96
97#[derive(
99 Clone,
100 Debug,
101 Default,
102 MallocSizeOf,
103 PartialEq,
104 SpecifiedValueInfo,
105 ToComputedValue,
106 ToCss,
107 ToResolvedValue,
108 ToShmem,
109 ToTyped,
110)]
111#[repr(transparent)]
112#[typed(todo_derive_fields)]
113pub struct GenericCounterSet<I>(#[css(field_bound)] pub GenericCounters<I>);
114pub use self::GenericCounterSet as CounterSet;
115
116impl<I> CounterSet<I> {
117 #[inline]
119 pub fn new(counters: Vec<CounterPair<I>>) -> Self {
120 CounterSet(Counters(counters.into()))
121 }
122}
123
124impl<I> Deref for CounterSet<I> {
125 type Target = [CounterPair<I>];
126
127 #[inline]
128 fn deref(&self) -> &Self::Target {
129 &(self.0).0
130 }
131}
132
133#[derive(
135 Clone,
136 Debug,
137 Default,
138 MallocSizeOf,
139 PartialEq,
140 SpecifiedValueInfo,
141 ToComputedValue,
142 ToCss,
143 ToResolvedValue,
144 ToShmem,
145 ToTyped,
146)]
147#[repr(transparent)]
148#[typed(todo_derive_fields)]
149pub struct GenericCounterReset<I>(#[css(field_bound)] pub GenericCounters<I>);
150pub use self::GenericCounterReset as CounterReset;
151
152impl<I> CounterReset<I> {
153 #[inline]
155 pub fn new(counters: Vec<CounterPair<I>>) -> Self {
156 CounterReset(Counters(counters.into()))
157 }
158}
159
160impl<I> Deref for CounterReset<I> {
161 type Target = [CounterPair<I>];
162
163 #[inline]
164 fn deref(&self) -> &Self::Target {
165 &(self.0).0
166 }
167}
168
169#[derive(
173 Clone,
174 Debug,
175 Default,
176 MallocSizeOf,
177 PartialEq,
178 SpecifiedValueInfo,
179 ToComputedValue,
180 ToCss,
181 ToResolvedValue,
182 ToShmem,
183)]
184#[repr(transparent)]
185pub struct GenericCounters<I>(
186 #[css(field_bound)]
187 #[css(iterable, if_empty = "none")]
188 crate::OwnedSlice<GenericCounterPair<I>>,
189);
190pub use self::GenericCounters as Counters;
191
192
193#[inline]
194fn is_decimal(counter_type: &CounterStyle) -> bool {
195 *counter_type == CounterStyle::decimal()
196}
197
198#[derive(
200 Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
201)]
202#[repr(C)]
203pub struct GenericContentItems<Image> {
204 pub items: thin_vec::ThinVec<GenericContentItem<Image>>,
207 pub alt_start: usize,
210}
211
212impl<Image> ToCss for GenericContentItems<Image>
213where
214 Image: ToCss,
215{
216 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
217 where
218 W: Write,
219 {
220 for (i, item) in self.items.iter().enumerate() {
221 if i == self.alt_start {
222 dest.write_str(" /")?;
223 }
224 if i != 0 {
225 dest.write_str(" ")?;
226 }
227 item.to_css(dest)?;
228 }
229 Ok(())
230 }
231}
232
233#[derive(
237 Clone,
238 Debug,
239 Eq,
240 MallocSizeOf,
241 PartialEq,
242 SpecifiedValueInfo,
243 ToComputedValue,
244 ToCss,
245 ToShmem,
246 ToTyped,
247)]
248#[repr(u8)]
249#[typed(todo_derive_fields)]
250pub enum GenericContent<Image> {
251 Normal,
253 None,
255 Items(GenericContentItems<Image>),
257}
258
259pub use self::GenericContent as Content;
260
261impl<Image> Content<Image> {
262 #[inline]
264 pub fn is_items(&self) -> bool {
265 matches!(*self, Self::Items(..))
266 }
267
268 #[inline]
270 pub fn normal() -> Self {
271 Content::Normal
272 }
273}
274
275#[derive(
277 Clone,
278 Debug,
279 Eq,
280 MallocSizeOf,
281 PartialEq,
282 ToComputedValue,
283 SpecifiedValueInfo,
284 ToCss,
285 ToResolvedValue,
286 ToShmem,
287)]
288#[repr(u8)]
289pub enum GenericContentItem<I> {
290 String(crate::OwnedStr),
292 #[css(comma, function)]
294 Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyle),
295 #[css(comma, function)]
297 Counters(
298 CustomIdent,
299 crate::OwnedStr,
300 #[css(skip_if = "is_decimal")] CounterStyle,
301 ),
302 OpenQuote,
304 CloseQuote,
306 NoOpenQuote,
308 NoCloseQuote,
310 #[cfg(feature = "gecko")]
312 MozAltContent,
313 #[cfg(feature = "gecko")]
317 MozLabelContent,
318 Attr(Attr),
320 Image(I),
322}
323
324pub use self::GenericContentItem as ContentItem;