1use crate::counter_style::CounterStyle;
8use crate::derives::*;
9use crate::values::CustomIdent;
10use std::fmt::{self, Write};
11use std::ops::Deref;
12use style_traits::{CssWriter, ToCss};
13
14#[derive(
16 Clone,
17 Debug,
18 MallocSizeOf,
19 PartialEq,
20 SpecifiedValueInfo,
21 ToComputedValue,
22 ToResolvedValue,
23 ToShmem,
24)]
25#[repr(C)]
26pub struct GenericCounterPair<Integer> {
27 pub name: CustomIdent,
29 pub value: Integer,
31 pub is_reversed: bool,
34}
35pub use self::GenericCounterPair as CounterPair;
36
37impl<Integer> ToCss for CounterPair<Integer>
38where
39 Integer: ToCss + PartialEq<i32>,
40{
41 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
42 where
43 W: Write,
44 {
45 if self.is_reversed {
46 dest.write_str("reversed(")?;
47 }
48 self.name.to_css(dest)?;
49 if self.is_reversed {
50 dest.write_char(')')?;
51 if self.value == i32::MIN {
52 return Ok(());
53 }
54 }
55 dest.write_char(' ')?;
56 self.value.to_css(dest)
57 }
58}
59
60#[derive(
62 Clone,
63 Debug,
64 Default,
65 MallocSizeOf,
66 PartialEq,
67 SpecifiedValueInfo,
68 ToComputedValue,
69 ToCss,
70 ToResolvedValue,
71 ToShmem,
72 ToTyped,
73)]
74#[repr(transparent)]
75#[typed(todo_derive_fields)]
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)]
111#[typed(todo_derive_fields)]
112pub struct GenericCounterSet<I>(#[css(field_bound)] pub GenericCounters<I>);
113pub use self::GenericCounterSet as CounterSet;
114
115impl<I> CounterSet<I> {
116 #[inline]
118 pub fn new(counters: Vec<CounterPair<I>>) -> Self {
119 CounterSet(Counters(counters.into()))
120 }
121}
122
123impl<I> Deref for CounterSet<I> {
124 type Target = [CounterPair<I>];
125
126 #[inline]
127 fn deref(&self) -> &Self::Target {
128 &(self.0).0
129 }
130}
131
132#[derive(
134 Clone,
135 Debug,
136 Default,
137 MallocSizeOf,
138 PartialEq,
139 SpecifiedValueInfo,
140 ToComputedValue,
141 ToCss,
142 ToResolvedValue,
143 ToShmem,
144 ToTyped,
145)]
146#[repr(transparent)]
147#[typed(todo_derive_fields)]
148pub struct GenericCounterReset<I>(#[css(field_bound)] pub GenericCounters<I>);
149pub use self::GenericCounterReset as CounterReset;
150
151impl<I> CounterReset<I> {
152 #[inline]
154 pub fn new(counters: Vec<CounterPair<I>>) -> Self {
155 CounterReset(Counters(counters.into()))
156 }
157}
158
159impl<I> Deref for CounterReset<I> {
160 type Target = [CounterPair<I>];
161
162 #[inline]
163 fn deref(&self) -> &Self::Target {
164 &(self.0).0
165 }
166}
167
168#[derive(
172 Clone,
173 Debug,
174 Default,
175 MallocSizeOf,
176 PartialEq,
177 SpecifiedValueInfo,
178 ToComputedValue,
179 ToCss,
180 ToResolvedValue,
181 ToShmem,
182)]
183#[repr(transparent)]
184pub struct GenericCounters<I>(
185 #[css(field_bound)]
186 #[css(iterable, if_empty = "none")]
187 crate::OwnedSlice<GenericCounterPair<I>>,
188);
189pub use self::GenericCounters as Counters;
190
191#[inline]
192fn is_decimal(counter_type: &CounterStyle) -> bool {
193 *counter_type == CounterStyle::decimal()
194}
195
196#[derive(
198 Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
199)]
200#[repr(C)]
201pub struct GenericContentItems<Image> {
202 pub items: thin_vec::ThinVec<GenericContentItem<Image>>,
205 pub alt_start: usize,
208}
209
210impl<Image> ToCss for GenericContentItems<Image>
211where
212 Image: ToCss,
213{
214 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
215 where
216 W: Write,
217 {
218 for (i, item) in self.items.iter().enumerate() {
219 if i == self.alt_start {
220 dest.write_str(" /")?;
221 }
222 if i != 0 {
223 dest.write_str(" ")?;
224 }
225 item.to_css(dest)?;
226 }
227 Ok(())
228 }
229}
230
231#[derive(
235 Clone,
236 Debug,
237 Eq,
238 MallocSizeOf,
239 PartialEq,
240 SpecifiedValueInfo,
241 ToComputedValue,
242 ToCss,
243 ToShmem,
244 ToTyped,
245)]
246#[repr(u8)]
247#[typed(todo_derive_fields)]
248pub enum GenericContent<Image> {
249 Normal,
251 None,
253 Items(GenericContentItems<Image>),
255}
256
257pub use self::GenericContent as Content;
258
259impl<Image> Content<Image> {
260 #[inline]
262 pub fn is_items(&self) -> bool {
263 matches!(*self, Self::Items(..))
264 }
265
266 #[inline]
268 pub fn normal() -> Self {
269 Content::Normal
270 }
271}
272
273#[derive(
275 Clone,
276 Debug,
277 Eq,
278 MallocSizeOf,
279 PartialEq,
280 ToComputedValue,
281 SpecifiedValueInfo,
282 ToCss,
283 ToResolvedValue,
284 ToShmem,
285)]
286#[repr(u8)]
287pub enum GenericContentItem<I> {
288 String(crate::OwnedStr),
290 #[css(comma, function)]
292 Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyle),
293 #[css(comma, function)]
295 Counters(
296 CustomIdent,
297 crate::OwnedStr,
298 #[css(skip_if = "is_decimal")] CounterStyle,
299 ),
300 OpenQuote,
302 CloseQuote,
304 NoOpenQuote,
306 NoCloseQuote,
308 #[cfg(feature = "gecko")]
310 MozAltContent,
311 #[cfg(feature = "gecko")]
315 MozLabelContent,
316 Image(I),
318}
319
320pub use self::GenericContentItem as ContentItem;