Skip to main content

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(context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
23        // Try to parse as <page-size> [ <orientation> ]
24        if let Ok(paper_size) = input.try_parse(PaperSize::parse) {
25            let orientation = input
26                .try_parse(PageSizeOrientation::parse)
27                .unwrap_or(PageSizeOrientation::Portrait);
28            return Ok(PageSize::PaperSize(paper_size, orientation));
29        }
30        // Try to parse as <orientation> [ <page-size> ]
31        if let Ok(orientation) = input.try_parse(PageSizeOrientation::parse) {
32            if let Ok(paper_size) = input.try_parse(PaperSize::parse) {
33                return Ok(PageSize::PaperSize(paper_size, orientation));
34            }
35            return Ok(PageSize::Orientation(orientation));
36        }
37        // Try to parse dimensions
38        if let Ok(size) =
39            input.try_parse(|i| Size2D::parse_with(context, i, NonNegativeLength::parse))
40        {
41            return Ok(PageSize::Size(size));
42        }
43        // auto value
44        input.expect_ident_matching("auto")?;
45        Ok(PageSize::Auto)
46    }
47}
48
49/// Page name value.
50///
51/// https://drafts.csswg.org/css-page-3/#using-named-pages
52#[derive(
53    Clone,
54    Debug,
55    MallocSizeOf,
56    PartialEq,
57    SpecifiedValueInfo,
58    ToCss,
59    ToComputedValue,
60    ToResolvedValue,
61    ToShmem,
62    ToTyped,
63)]
64#[repr(C, u8)]
65pub enum PageName {
66    /// `auto` value.
67    Auto,
68    /// Page name value
69    PageName(CustomIdent),
70}
71
72impl Parse for PageName {
73    fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
74        let ident = input.expect_ident()?;
75        Ok(match_ignore_ascii_case! { ident,
76            "auto" => PageName::auto(),
77            _ => PageName::PageName(CustomIdent::from_ident(ident, &[])?),
78        })
79    }
80}
81
82impl PageName {
83    /// `auto` value.
84    #[inline]
85    pub fn auto() -> Self {
86        PageName::Auto
87    }
88
89    /// Whether this is the `auto` value.
90    #[inline]
91    pub fn is_auto(&self) -> bool {
92        matches!(*self, PageName::Auto)
93    }
94}