tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

background.rs (4479B)


      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 CSS values related to backgrounds.
      6 
      7 use crate::derives::*;
      8 use crate::parser::{Parse, ParserContext};
      9 use crate::values::generics::background::BackgroundSize as GenericBackgroundSize;
     10 use crate::values::specified::length::{
     11    NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto,
     12 };
     13 use cssparser::{match_ignore_ascii_case, Parser};
     14 use selectors::parser::SelectorParseErrorKind;
     15 use std::fmt::{self, Write};
     16 use style_traits::{CssWriter, ParseError, ToCss};
     17 
     18 /// A specified value for the `background-size` property.
     19 pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthPercentage>;
     20 
     21 impl Parse for BackgroundSize {
     22    fn parse<'i, 't>(
     23        context: &ParserContext,
     24        input: &mut Parser<'i, 't>,
     25    ) -> Result<Self, ParseError<'i>> {
     26        if let Ok(width) = input.try_parse(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
     27        {
     28            let height = input
     29                .try_parse(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
     30                .unwrap_or(NonNegativeLengthPercentageOrAuto::auto());
     31            return Ok(GenericBackgroundSize::ExplicitSize { width, height });
     32        }
     33        Ok(try_match_ident_ignore_ascii_case! { input,
     34            "cover" => GenericBackgroundSize::Cover,
     35            "contain" => GenericBackgroundSize::Contain,
     36        })
     37    }
     38 }
     39 
     40 /// One of the keywords for `background-repeat`.
     41 #[derive(
     42    Clone,
     43    Copy,
     44    Debug,
     45    Eq,
     46    MallocSizeOf,
     47    Parse,
     48    PartialEq,
     49    SpecifiedValueInfo,
     50    ToComputedValue,
     51    ToCss,
     52    ToResolvedValue,
     53    ToShmem,
     54 )]
     55 #[allow(missing_docs)]
     56 #[value_info(other_values = "repeat-x,repeat-y")]
     57 pub enum BackgroundRepeatKeyword {
     58    Repeat,
     59    Space,
     60    Round,
     61    NoRepeat,
     62 }
     63 
     64 /// The value of the `background-repeat` property, with `repeat-x` / `repeat-y`
     65 /// represented as the combination of `no-repeat` and `repeat` in the opposite
     66 /// axes.
     67 ///
     68 /// https://drafts.csswg.org/css-backgrounds/#the-background-repeat
     69 #[derive(
     70    Clone,
     71    Debug,
     72    MallocSizeOf,
     73    PartialEq,
     74    SpecifiedValueInfo,
     75    ToComputedValue,
     76    ToResolvedValue,
     77    ToShmem,
     78 )]
     79 pub struct BackgroundRepeat(pub BackgroundRepeatKeyword, pub BackgroundRepeatKeyword);
     80 
     81 impl BackgroundRepeat {
     82    /// Returns the `repeat repeat` value.
     83    pub fn repeat() -> Self {
     84        BackgroundRepeat(
     85            BackgroundRepeatKeyword::Repeat,
     86            BackgroundRepeatKeyword::Repeat,
     87        )
     88    }
     89 }
     90 
     91 impl ToCss for BackgroundRepeat {
     92    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     93    where
     94        W: Write,
     95    {
     96        match (self.0, self.1) {
     97            (BackgroundRepeatKeyword::Repeat, BackgroundRepeatKeyword::NoRepeat) => {
     98                dest.write_str("repeat-x")
     99            },
    100            (BackgroundRepeatKeyword::NoRepeat, BackgroundRepeatKeyword::Repeat) => {
    101                dest.write_str("repeat-y")
    102            },
    103            (horizontal, vertical) => {
    104                horizontal.to_css(dest)?;
    105                if horizontal != vertical {
    106                    dest.write_char(' ')?;
    107                    vertical.to_css(dest)?;
    108                }
    109                Ok(())
    110            },
    111        }
    112    }
    113 }
    114 
    115 impl Parse for BackgroundRepeat {
    116    fn parse<'i, 't>(
    117        _context: &ParserContext,
    118        input: &mut Parser<'i, 't>,
    119    ) -> Result<Self, ParseError<'i>> {
    120        let ident = input.expect_ident_cloned()?;
    121 
    122        match_ignore_ascii_case! { &ident,
    123            "repeat-x" => {
    124                return Ok(BackgroundRepeat(BackgroundRepeatKeyword::Repeat, BackgroundRepeatKeyword::NoRepeat));
    125            },
    126            "repeat-y" => {
    127                return Ok(BackgroundRepeat(BackgroundRepeatKeyword::NoRepeat, BackgroundRepeatKeyword::Repeat));
    128            },
    129            _ => {},
    130        }
    131 
    132        let horizontal = match BackgroundRepeatKeyword::from_ident(&ident) {
    133            Ok(h) => h,
    134            Err(()) => {
    135                return Err(
    136                    input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))
    137                );
    138            },
    139        };
    140 
    141        let vertical = input.try_parse(BackgroundRepeatKeyword::parse).ok();
    142        Ok(BackgroundRepeat(horizontal, vertical.unwrap_or(horizontal)))
    143    }
    144 }