style/values/specified/
page.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 @page at-rule properties and named-page style properties
6
7use crate::derives::*;
8use crate::parser::{Parse, ParserContext};
9use crate::values::generics::size::Size2D;
10use crate::values::specified::length::NonNegativeLength;
11use crate::values::{generics, CustomIdent};
12use cssparser::{match_ignore_ascii_case, Parser};
13use style_traits::ParseError;
14
15pub use generics::page::PageOrientation;
16pub use generics::page::PageSizeOrientation;
17pub use generics::page::PaperSize;
18/// Specified value of the @page size descriptor
19pub type PageSize = generics::page::PageSize<Size2D<NonNegativeLength>>;
20
21impl Parse for PageSize {
22    fn parse<'i, 't>(
23        context: &ParserContext,
24        input: &mut Parser<'i, 't>,
25    ) -> Result<Self, ParseError<'i>> {
26        // Try to parse as <page-size> [ <orientation> ]
27        if let Ok(paper_size) = input.try_parse(PaperSize::parse) {
28            let orientation = input
29                .try_parse(PageSizeOrientation::parse)
30                .unwrap_or(PageSizeOrientation::Portrait);
31            return Ok(PageSize::PaperSize(paper_size, orientation));
32        }
33        // Try to parse as <orientation> [ <page-size> ]
34        if let Ok(orientation) = input.try_parse(PageSizeOrientation::parse) {
35            if let Ok(paper_size) = input.try_parse(PaperSize::parse) {
36                return Ok(PageSize::PaperSize(paper_size, orientation));
37            }
38            return Ok(PageSize::Orientation(orientation));
39        }
40        // Try to parse dimensions
41        if let Ok(size) =
42            input.try_parse(|i| Size2D::parse_with(context, i, NonNegativeLength::parse))
43        {
44            return Ok(PageSize::Size(size));
45        }
46        // auto value
47        input.expect_ident_matching("auto")?;
48        Ok(PageSize::Auto)
49    }
50}
51
52/// Page name value.
53///
54/// https://drafts.csswg.org/css-page-3/#using-named-pages
55#[derive(
56    Clone,
57    Debug,
58    MallocSizeOf,
59    PartialEq,
60    SpecifiedValueInfo,
61    ToCss,
62    ToComputedValue,
63    ToResolvedValue,
64    ToShmem,
65    ToTyped,
66)]
67#[repr(C, u8)]
68pub enum PageName {
69    /// `auto` value.
70    Auto,
71    /// Page name value
72    PageName(CustomIdent),
73}
74
75impl Parse for PageName {
76    fn parse<'i, 't>(
77        _context: &ParserContext,
78        input: &mut Parser<'i, 't>,
79    ) -> Result<Self, ParseError<'i>> {
80        let location = input.current_source_location();
81        let ident = input.expect_ident()?;
82        Ok(match_ignore_ascii_case! { ident,
83            "auto" => PageName::auto(),
84            _ => PageName::PageName(CustomIdent::from_ident(location, ident, &[])?),
85        })
86    }
87}
88
89impl PageName {
90    /// `auto` value.
91    #[inline]
92    pub fn auto() -> Self {
93        PageName::Auto
94    }
95
96    /// Whether this is the `auto` value.
97    #[inline]
98    pub fn is_auto(&self) -> bool {
99        matches!(*self, PageName::Auto)
100    }
101}