Skip to main content

style/values/specified/
list.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! `list` specified values.
6
7use crate::counter_style::{CounterStyle, CounterStyleParsingFlags};
8use crate::derives::*;
9use crate::parser::{Parse, ParserContext};
10use cssparser::{Parser, Token};
11use style_traits::{ParseError, StyleParseErrorKind};
12
13/// Specified and computed `list-style-type` property.
14#[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    /// Initial specified value for `list-style-type`.
33    #[inline]
34    pub fn disc() -> Self {
35        Self(CounterStyle::disc())
36    }
37
38    /// none value.
39    #[inline]
40    pub fn none() -> Self {
41        Self(CounterStyle::None)
42    }
43
44    /// Returns whether `self` is a particular identifier.
45    #[inline]
46    pub fn is_name(&self, n: &crate::Atom) -> bool {
47        self.0.is_name(n)
48    }
49
50    /// Convert from gecko keyword to list-style-type.
51    ///
52    /// This should only be used for mapping type attribute to list-style-type, and thus only
53    /// values possible in that attribute is considered here.
54    #[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    /// Is this a bullet? (i.e. `list-style-type: disc|circle|square|disclosure-closed|disclosure-open`)
77    #[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/// A quote pair.
91#[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    /// The opening quote.
105    pub opening: crate::OwnedStr,
106
107    /// The closing quote.
108    pub closing: crate::OwnedStr,
109}
110
111/// List of quote pairs for the specified/computed value of `quotes` property.
112#[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/// Specified and computed `quotes` property: `auto`, `none`, or a list
132/// of characters.
133#[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    /// list of quote pairs
149    QuoteList(QuoteList),
150    /// auto (use lang-dependent quote marks)
151    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/// https://drafts.csswg.org/css-lists/#propdef-list-style-position
193#[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}