Skip to main content

style/values/specified/
ui.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//! Specified types for UI properties.
6
7use crate::derives::*;
8use crate::parser::{Parse, ParserContext};
9use crate::values::generics::ui as generics;
10use crate::values::specified::color::Color;
11use crate::values::specified::image::Image;
12use crate::values::specified::Number;
13use cssparser::Parser;
14use std::fmt::{self, Write};
15use style_traits::{
16    CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss,
17};
18
19/// A specified value for the `cursor` property.
20pub type Cursor = generics::GenericCursor<CursorImage>;
21
22/// A specified value for item of `image cursors`.
23pub type CursorImage = generics::GenericCursorImage<Image, Number>;
24
25impl Parse for Cursor {
26    /// cursor: [<url> [<number> <number>]?]# [auto | default | ...]
27    fn parse<'i, 't>(
28        context: &ParserContext,
29        input: &mut Parser<'i, 't>,
30    ) -> Result<Self, ParseError<'i>> {
31        let mut images = vec![];
32        loop {
33            match input.try_parse(|input| CursorImage::parse(context, input)) {
34                Ok(image) => images.push(image),
35                Err(_) => break,
36            }
37            input.expect_comma()?;
38        }
39        Ok(Self {
40            images: images.into(),
41            keyword: CursorKind::parse(input)?,
42        })
43    }
44}
45
46impl Parse for CursorImage {
47    fn parse<'i, 't>(
48        context: &ParserContext,
49        input: &mut Parser<'i, 't>,
50    ) -> Result<Self, ParseError<'i>> {
51        use crate::Zero;
52
53        let image = Image::parse_only_url(context, input)?;
54        let mut has_hotspot = false;
55        let mut hotspot_x = Number::zero();
56        let mut hotspot_y = Number::zero();
57
58        if let Ok(x) = input.try_parse(|input| Number::parse(context, input)) {
59            has_hotspot = true;
60            hotspot_x = x;
61            hotspot_y = Number::parse(context, input)?;
62        }
63
64        Ok(Self {
65            image,
66            has_hotspot,
67            hotspot_x,
68            hotspot_y,
69        })
70    }
71}
72
73// This trait is manually implemented because we don't support the whole <image>
74// syntax for cursors
75impl SpecifiedValueInfo for CursorImage {
76    fn collect_completion_keywords(f: KeywordsCollectFn) {
77        f(&["url", "image-set"]);
78    }
79}
80/// Specified value of `-moz-force-broken-image-icon`
81#[derive(
82    Clone,
83    Copy,
84    Debug,
85    MallocSizeOf,
86    PartialEq,
87    SpecifiedValueInfo,
88    ToComputedValue,
89    ToResolvedValue,
90    ToShmem,
91    ToTyped,
92)]
93#[repr(transparent)]
94#[typed(todo_derive_fields)]
95pub struct BoolInteger(pub bool);
96
97impl BoolInteger {
98    /// Returns 0
99    #[inline]
100    pub fn zero() -> Self {
101        Self(false)
102    }
103}
104
105impl Parse for BoolInteger {
106    fn parse<'i, 't>(
107        _context: &ParserContext,
108        input: &mut Parser<'i, 't>,
109    ) -> Result<Self, ParseError<'i>> {
110        // We intentionally don't support calc values here.
111        match input.expect_integer()? {
112            0 => Ok(Self(false)),
113            1 => Ok(Self(true)),
114            _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
115        }
116    }
117}
118
119impl ToCss for BoolInteger {
120    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
121    where
122        W: Write,
123    {
124        dest.write_str(if self.0 { "1" } else { "0" })
125    }
126}
127
128/// A specified value for `scrollbar-color` property
129pub type ScrollbarColor = generics::ScrollbarColor<Color>;
130
131impl Parse for ScrollbarColor {
132    fn parse<'i, 't>(
133        context: &ParserContext,
134        input: &mut Parser<'i, 't>,
135    ) -> Result<Self, ParseError<'i>> {
136        if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
137            return Ok(generics::ScrollbarColor::Auto);
138        }
139        Ok(generics::ScrollbarColor::Colors {
140            thumb: Color::parse(context, input)?,
141            track: Color::parse(context, input)?,
142        })
143    }
144}
145
146/// The specified value for the `user-select` property.
147///
148/// https://drafts.csswg.org/css-ui-4/#propdef-user-select
149#[allow(missing_docs)]
150#[derive(
151    Clone,
152    Copy,
153    Debug,
154    Eq,
155    MallocSizeOf,
156    Parse,
157    PartialEq,
158    SpecifiedValueInfo,
159    ToComputedValue,
160    ToCss,
161    ToResolvedValue,
162    ToShmem,
163    ToTyped,
164)]
165#[repr(u8)]
166pub enum UserSelect {
167    Auto,
168    Text,
169    #[parse(aliases = "-moz-none")]
170    None,
171    /// Force selection of all children.
172    All,
173}
174
175/// The keywords allowed in the Cursor property.
176///
177/// https://drafts.csswg.org/css-ui-4/#propdef-cursor
178#[allow(missing_docs)]
179#[derive(
180    Clone,
181    Copy,
182    Debug,
183    Eq,
184    FromPrimitive,
185    MallocSizeOf,
186    Parse,
187    PartialEq,
188    SpecifiedValueInfo,
189    ToComputedValue,
190    ToCss,
191    ToResolvedValue,
192    ToShmem,
193)]
194#[repr(u8)]
195pub enum CursorKind {
196    None,
197    Default,
198    Pointer,
199    ContextMenu,
200    Help,
201    Progress,
202    Wait,
203    Cell,
204    Crosshair,
205    Text,
206    VerticalText,
207    Alias,
208    Copy,
209    Move,
210    NoDrop,
211    NotAllowed,
212    #[parse(aliases = "-moz-grab")]
213    Grab,
214    #[parse(aliases = "-moz-grabbing")]
215    Grabbing,
216    EResize,
217    NResize,
218    NeResize,
219    NwResize,
220    SResize,
221    SeResize,
222    SwResize,
223    WResize,
224    EwResize,
225    NsResize,
226    NeswResize,
227    NwseResize,
228    ColResize,
229    RowResize,
230    AllScroll,
231    #[parse(aliases = "-moz-zoom-in")]
232    ZoomIn,
233    #[parse(aliases = "-moz-zoom-out")]
234    ZoomOut,
235    Auto,
236}
237
238/// The keywords allowed in the -moz-theme property.
239#[derive(
240    Clone,
241    Copy,
242    Debug,
243    Eq,
244    FromPrimitive,
245    MallocSizeOf,
246    Parse,
247    PartialEq,
248    SpecifiedValueInfo,
249    ToComputedValue,
250    ToCss,
251    ToResolvedValue,
252    ToShmem,
253    ToTyped,
254)]
255#[repr(u8)]
256pub enum MozTheme {
257    /// Choose the default (maybe native) rendering.
258    Auto,
259    /// Choose the non-native rendering.
260    NonNative,
261}
262
263/// The pointer-events property
264/// https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty
265#[allow(missing_docs)]
266#[derive(
267    Clone,
268    Copy,
269    Debug,
270    Eq,
271    FromPrimitive,
272    MallocSizeOf,
273    Parse,
274    PartialEq,
275    SpecifiedValueInfo,
276    ToComputedValue,
277    ToCss,
278    ToResolvedValue,
279    ToShmem,
280    ToTyped,
281)]
282#[repr(u8)]
283pub enum PointerEvents {
284    Auto,
285    None,
286    #[cfg(feature = "gecko")]
287    Visiblepainted,
288    #[cfg(feature = "gecko")]
289    Visiblefill,
290    #[cfg(feature = "gecko")]
291    Visiblestroke,
292    #[cfg(feature = "gecko")]
293    Visible,
294    #[cfg(feature = "gecko")]
295    Painted,
296    #[cfg(feature = "gecko")]
297    Fill,
298    #[cfg(feature = "gecko")]
299    Stroke,
300    #[cfg(feature = "gecko")]
301    All,
302}
303
304/// Internal property to represent the inert attribute state:
305/// https://html.spec.whatwg.org/multipage/#inert-subtrees
306#[allow(missing_docs)]
307#[derive(
308    Clone,
309    Copy,
310    Debug,
311    Eq,
312    FromPrimitive,
313    MallocSizeOf,
314    Parse,
315    PartialEq,
316    SpecifiedValueInfo,
317    ToComputedValue,
318    ToCss,
319    ToResolvedValue,
320    ToShmem,
321    ToTyped,
322)]
323#[repr(u8)]
324pub enum Inert {
325    None,
326    Inert,
327}
328
329/// Internal -moz-user-focus property.
330/// https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-user-focus
331#[allow(missing_docs)]
332#[derive(
333    Clone,
334    Copy,
335    Debug,
336    Eq,
337    FromPrimitive,
338    MallocSizeOf,
339    Parse,
340    PartialEq,
341    SpecifiedValueInfo,
342    ToComputedValue,
343    ToCss,
344    ToResolvedValue,
345    ToShmem,
346    ToTyped,
347)]
348#[repr(u8)]
349pub enum UserFocus {
350    Normal,
351    None,
352    Ignore,
353}