tor-browser

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

intersection_observer.rs (3092B)


      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 intersection observer that utilizes style parser.
      6 //!
      7 //! <https://w3c.github.io/IntersectionObserver/#intersection-observer-api>
      8 
      9 use crate::parser::{Parse, ParserContext};
     10 use crate::values::computed::{self, Length, LengthPercentage};
     11 use crate::values::generics::rect::Rect;
     12 use cssparser::{match_ignore_ascii_case, Parser, Token};
     13 use std::fmt;
     14 use style_traits::values::SequenceWriter;
     15 use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
     16 
     17 fn parse_pixel_or_percent<'i, 't>(
     18    _context: &ParserContext,
     19    input: &mut Parser<'i, 't>,
     20 ) -> Result<LengthPercentage, ParseError<'i>> {
     21    let location = input.current_source_location();
     22    let token = input.next()?;
     23    let value = match *token {
     24        Token::Dimension {
     25            value, ref unit, ..
     26        } => {
     27            match_ignore_ascii_case! { unit,
     28                "px" => Ok(LengthPercentage::new_length(Length::new(value))),
     29                _ => Err(()),
     30            }
     31        },
     32        Token::Percentage { unit_value, .. } => Ok(LengthPercentage::new_percent(
     33            computed::Percentage(unit_value),
     34        )),
     35        _ => Err(()),
     36    };
     37    value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError))
     38 }
     39 
     40 /// The value of an IntersectionObserver's (root or scroll) margin property.
     41 ///
     42 /// Only bare px or percentage values are allowed. Other length units and
     43 /// calc() values are not allowed.
     44 ///
     45 /// <https://w3c.github.io/IntersectionObserver/#parse-a-margin>
     46 #[repr(transparent)]
     47 pub struct IntersectionObserverMargin(pub Rect<LengthPercentage>);
     48 
     49 impl Parse for IntersectionObserverMargin {
     50    fn parse<'i, 't>(
     51        context: &ParserContext,
     52        input: &mut Parser<'i, 't>,
     53    ) -> Result<Self, ParseError<'i>> {
     54        use crate::Zero;
     55        if input.is_exhausted() {
     56            // If there are zero elements in tokens, set tokens to ["0px"].
     57            return Ok(IntersectionObserverMargin(Rect::all(
     58                LengthPercentage::zero(),
     59            )));
     60        }
     61        let rect = Rect::parse_with(context, input, parse_pixel_or_percent)?;
     62        Ok(IntersectionObserverMargin(rect))
     63    }
     64 }
     65 
     66 // Strictly speaking this is not ToCss. It's serializing for DOM. But
     67 // we can just reuse the infrastructure of this.
     68 //
     69 // <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-rootmargin>
     70 impl ToCss for IntersectionObserverMargin {
     71    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     72    where
     73        W: fmt::Write,
     74    {
     75        // We cannot use the ToCss impl of Rect, because that would
     76        // merge items when they are equal. We want to list them all.
     77        let mut writer = SequenceWriter::new(dest, " ");
     78        let rect = &self.0;
     79        writer.item(&rect.0)?;
     80        writer.item(&rect.1)?;
     81        writer.item(&rect.2)?;
     82        writer.item(&rect.3)
     83    }
     84 }