diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /servo/components/style_traits/viewport.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | servo/components/style_traits/viewport.rs | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/servo/components/style_traits/viewport.rs b/servo/components/style_traits/viewport.rs new file mode 100644 index 0000000000..eff1dfca7a --- /dev/null +++ b/servo/components/style_traits/viewport.rs @@ -0,0 +1,148 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Helper types for the `@viewport` rule. + +use crate::{CSSPixel, CssWriter, ParseError, PinchZoomFactor, ToCss}; +use cssparser::Parser; +use euclid::Size2D; +use std::fmt::{self, Write}; + +define_css_keyword_enum! { + pub enum UserZoom { + Zoom = "zoom", + Fixed = "fixed", + } +} + +define_css_keyword_enum! { + pub enum Orientation { + Auto = "auto", + Portrait = "portrait", + Landscape = "landscape", + } +} + +/// A set of viewport descriptors: +/// +/// <https://drafts.csswg.org/css-device-adapt/#viewport-desc> +#[derive(Clone, Debug, PartialEq)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))] +pub struct ViewportConstraints { + /// Width and height: + /// * https://drafts.csswg.org/css-device-adapt/#width-desc + /// * https://drafts.csswg.org/css-device-adapt/#height-desc + pub size: Size2D<f32, CSSPixel>, + /// <https://drafts.csswg.org/css-device-adapt/#zoom-desc> + pub initial_zoom: PinchZoomFactor, + /// <https://drafts.csswg.org/css-device-adapt/#min-max-width-desc> + pub min_zoom: Option<PinchZoomFactor>, + /// <https://drafts.csswg.org/css-device-adapt/#min-max-width-desc> + pub max_zoom: Option<PinchZoomFactor>, + /// <https://drafts.csswg.org/css-device-adapt/#user-zoom-desc> + pub user_zoom: UserZoom, + /// <https://drafts.csswg.org/css-device-adapt/#orientation-desc> + pub orientation: Orientation, +} + +impl ToCss for ViewportConstraints { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result + where + W: Write, + { + dest.write_str("@viewport { width: ")?; + self.size.width.to_css(dest)?; + + dest.write_str("px; height: ")?; + self.size.height.to_css(dest)?; + + dest.write_str("px; zoom: ")?; + self.initial_zoom.get().to_css(dest)?; + + if let Some(min_zoom) = self.min_zoom { + dest.write_str("; min-zoom: ")?; + min_zoom.get().to_css(dest)?; + } + + if let Some(max_zoom) = self.max_zoom { + dest.write_str("; max-zoom: ")?; + max_zoom.get().to_css(dest)?; + } + + dest.write_str("; user-zoom: ")?; + self.user_zoom.to_css(dest)?; + + dest.write_str("; orientation: ")?; + self.orientation.to_css(dest)?; + dest.write_str("; }") + } +} + +/// <https://drafts.csswg.org/css-device-adapt/#descdef-viewport-zoom> +#[derive(Clone, Copy, Debug, PartialEq, ToShmem)] +#[cfg_attr(feature = "servo", derive(MallocSizeOf))] +pub enum Zoom { + /// A number value. + Number(f32), + /// A percentage value. + Percentage(f32), + /// The `auto` keyword. + Auto, +} + +impl ToCss for Zoom { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result + where + W: fmt::Write, + { + match *self { + Zoom::Number(number) => number.to_css(dest), + Zoom::Auto => dest.write_str("auto"), + Zoom::Percentage(percentage) => { + (percentage * 100.).to_css(dest)?; + dest.write_char('%') + }, + } + } +} + +impl Zoom { + /// Parse a zoom value per: + /// + /// <https://drafts.csswg.org/css-device-adapt/#descdef-viewport-zoom> + pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Zoom, ParseError<'i>> { + use crate::values::specified::AllowedNumericType::NonNegative; + use crate::ParsingMode; + use cssparser::Token; + + let location = input.current_source_location(); + match *input.next()? { + // TODO: This parse() method should take ParserContext as an + // argument, and pass ParsingMode owned by the ParserContext to + // is_ok() instead of using ParsingMode::DEFAULT directly. + // In order to do so, we might want to move these stuff into style::stylesheets::viewport_rule. + Token::Percentage { unit_value, .. } + if NonNegative.is_ok(ParsingMode::DEFAULT, unit_value) => + { + Ok(Zoom::Percentage(unit_value)) + }, + Token::Number { value, .. } if NonNegative.is_ok(ParsingMode::DEFAULT, value) => { + Ok(Zoom::Number(value)) + }, + Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => Ok(Zoom::Auto), + ref t => Err(location.new_unexpected_token_error(t.clone())), + } + } + + /// Get this zoom value as a float value. Returns `None` if the value is the + /// `auto` keyword. + #[inline] + pub fn to_f32(&self) -> Option<f32> { + match *self { + Zoom::Number(number) => Some(number as f32), + Zoom::Percentage(percentage) => Some(percentage as f32), + Zoom::Auto => None, + } + } +} |