From e9c14bb9fcd2a2f634eb234806865a214b0a75a3 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Wed, 8 Jan 2020 11:56:25 +0000 Subject: [PATCH] style: Don't use hardcoded value for safearea. To implement safe area support on Gecko, we should get safe area from Device. Differential Revision: https://phabricator.services.mozilla.com/D52504 --- components/style/custom_properties.rs | 84 +++++++++++++++++-------- components/style/gecko/media_queries.rs | 7 ++- components/style/servo/media_queries.rs | 7 ++- 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/components/style/custom_properties.rs b/components/style/custom_properties.rs index a8ccd96effb..06d0e71cb8b 100644 --- a/components/style/custom_properties.rs +++ b/components/style/custom_properties.rs @@ -12,7 +12,7 @@ use crate::properties::{CSSWideKeyword, CustomDeclaration, CustomDeclarationValu use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet, PrecomputedHasher}; use crate::stylesheets::{Origin, PerOrigin}; use crate::Atom; -use cssparser::{Delimiter, Parser, ParserInput, SourcePosition, Token, TokenSerializationType}; +use cssparser::{CowRcStr, Delimiter, Parser, ParserInput, SourcePosition, Token, TokenSerializationType}; use indexmap::IndexMap; use selectors::parser::SelectorParseErrorKind; use servo_arc::Arc; @@ -30,50 +30,52 @@ use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; #[derive(Debug, MallocSizeOf)] pub struct CssEnvironment; +type EnvironmentEvaluator = fn(device: &Device) -> VariableValue; + struct EnvironmentVariable { name: Atom, - value: VariableValue, + evaluator: EnvironmentEvaluator, } macro_rules! make_variable { - ($name:expr, $value:expr) => {{ + ($name:expr, $evaluator:expr) => {{ EnvironmentVariable { name: $name, - value: { - // TODO(emilio): We could make this be more efficient (though a - // bit less convenient). - let mut input = ParserInput::new($value); - let mut input = Parser::new(&mut input); - - let (first_token_type, css, last_token_type) = - parse_self_contained_declaration_value(&mut input, None).unwrap(); - - VariableValue { - css: css.into_owned(), - first_token_type, - last_token_type, - references: Default::default(), - references_environment: false, - } - }, + evaluator: $evaluator, } }}; } +fn get_safearea_inset_top(device: &Device) -> VariableValue { + VariableValue::pixel(device.safe_area_insets().top) +} + +fn get_safearea_inset_bottom(device: &Device) -> VariableValue { + VariableValue::pixel(device.safe_area_insets().bottom) +} + +fn get_safearea_inset_left(device: &Device) -> VariableValue { + VariableValue::pixel(device.safe_area_insets().left) +} + +fn get_safearea_inset_right(device: &Device) -> VariableValue { + VariableValue::pixel(device.safe_area_insets().right) +} + lazy_static! { static ref ENVIRONMENT_VARIABLES: [EnvironmentVariable; 4] = [ - make_variable!(atom!("safe-area-inset-top"), "0px"), - make_variable!(atom!("safe-area-inset-bottom"), "0px"), - make_variable!(atom!("safe-area-inset-left"), "0px"), - make_variable!(atom!("safe-area-inset-right"), "0px"), + make_variable!(atom!("safe-area-inset-top"), get_safearea_inset_top), + make_variable!(atom!("safe-area-inset-bottom"), get_safearea_inset_bottom), + make_variable!(atom!("safe-area-inset-left"), get_safearea_inset_left), + make_variable!(atom!("safe-area-inset-right"), get_safearea_inset_right), ]; } impl CssEnvironment { #[inline] - fn get(&self, name: &Atom) -> Option<&VariableValue> { + fn get(&self, name: &Atom, device: &Device) -> Option { let var = ENVIRONMENT_VARIABLES.iter().find(|var| var.name == *name)?; - Some(&var.value) + Some((var.evaluator)(device)) } } @@ -253,6 +255,28 @@ impl VariableValue { references_environment: references.references_environment, })) } + + /// Create VariableValue from css pixel value + pub fn pixel(number: f32) -> Self { + // FIXME (https://github.com/servo/rust-cssparser/issues/266): + // No way to get TokenSerializationType::Dimension without creating + // Token object. + let token = Token::Dimension { + has_sign: false, + value: number, + int_value: None, + unit: CowRcStr::from("px"), + }; + let token_type = token.serialization_type(); + + VariableValue { + css: token.to_css_string(), + first_token_type: token_type, + last_token_type: token_type, + references: Default::default(), + references_environment: false, + } + } } /// Parse the value of a non-custom property that contains `var()` references. @@ -929,8 +953,14 @@ fn substitute_block<'i>( } }; + let env_value; let value = if is_env { - device.environment().get(&name) + if let Some(v) = device.environment().get(&name, device) { + env_value = v; + Some(&env_value) + } else { + None + } } else { custom_properties.get(&name).map(|v| &**v) }; diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 390c1d4fe58..39b99a4fefe 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -16,7 +16,7 @@ use crate::values::{CustomIdent, KeyframesName}; use app_units::{Au, AU_PER_PX}; use cssparser::RGBA; use euclid::default::Size2D; -use euclid::Scale; +use euclid::{Scale, SideOffsets2D}; use servo_arc::Arc; use std::fmt; use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering}; @@ -301,4 +301,9 @@ impl Device { pub fn unzoom_text(&self, size: Au) -> Au { size.scale_by(1. / self.effective_text_zoom()) } + + /// Returns safe area insets + pub fn safe_area_insets(&self) -> SideOffsets2D { + SideOffsets2D::zero() + } } diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs index 4cdfc80eef7..b1e752234e5 100644 --- a/components/style/servo/media_queries.rs +++ b/components/style/servo/media_queries.rs @@ -16,7 +16,7 @@ use crate::values::KeyframesName; use app_units::Au; use cssparser::RGBA; use euclid::default::Size2D as UntypedSize2D; -use euclid::{Scale, Size2D}; +use euclid::{Scale, Size2D, SideOffsets2D}; use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; use style_traits::viewport::ViewportConstraints; use style_traits::{CSSPixel, DevicePixel}; @@ -164,6 +164,11 @@ impl Device { pub fn default_background_color(&self) -> RGBA { RGBA::new(255, 255, 255, 255) } + + /// Returns safe area insets + pub fn safe_area_insets(&self) -> SideOffsets2D { + SideOffsets2D::zero() + } } /// https://drafts.csswg.org/mediaqueries-4/#width