page.rs (3082B)
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 7 use crate::derives::*; 8 use crate::parser::{Parse, ParserContext}; 9 use crate::values::generics::size::Size2D; 10 use crate::values::specified::length::NonNegativeLength; 11 use crate::values::{generics, CustomIdent}; 12 use cssparser::{match_ignore_ascii_case, Parser}; 13 use style_traits::ParseError; 14 15 pub use generics::page::PageOrientation; 16 pub use generics::page::PageSizeOrientation; 17 pub use generics::page::PaperSize; 18 /// Specified value of the @page size descriptor 19 pub type PageSize = generics::page::PageSize<Size2D<NonNegativeLength>>; 20 21 impl 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)] 68 pub enum PageName { 69 /// `auto` value. 70 Auto, 71 /// Page name value 72 PageName(CustomIdent), 73 } 74 75 impl 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 89 impl 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 }