aboutsummaryrefslogtreecommitdiffstats
path: root/components/style/values
diff options
context:
space:
mode:
Diffstat (limited to 'components/style/values')
-rw-r--r--components/style/values/computed/mod.rs32
-rw-r--r--components/style/values/specified/mod.rs1
-rw-r--r--components/style/values/specified/source_size_list.rs79
3 files changed, 111 insertions, 1 deletions
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
index e74386bfc42..c6b33d58748 100644
--- a/components/style/values/computed/mod.rs
+++ b/components/style/values/computed/mod.rs
@@ -7,7 +7,7 @@
use {Atom, Namespace};
use context::QuirksMode;
use euclid::Size2D;
-use font_metrics::FontMetricsProvider;
+use font_metrics::{FontMetricsProvider, get_metrics_provider_for_product};
use media_queries::Device;
#[cfg(feature = "gecko")]
use properties;
@@ -136,6 +136,36 @@ pub struct Context<'a> {
}
impl<'a> Context<'a> {
+ /// Creates a suitable context for media query evaluation, in which
+ /// font-relative units compute against the system_font, and executes `f`
+ /// with it.
+ pub fn for_media_query_evaluation<F, R>(
+ device: &Device,
+ quirks_mode: QuirksMode,
+ f: F,
+ ) -> R
+ where
+ F: FnOnce(&Context) -> R
+ {
+ let mut conditions = RuleCacheConditions::default();
+ let default_values = device.default_computed_values();
+ let provider = get_metrics_provider_for_product();
+
+ let context = Context {
+ is_root_element: false,
+ builder: StyleBuilder::for_derived_style(device, default_values, None, None),
+ font_metrics_provider: &provider,
+ cached_system_font: None,
+ in_media_query: true,
+ quirks_mode,
+ for_smil_animation: false,
+ for_non_inherited_property: None,
+ rule_cache_conditions: RefCell::new(&mut conditions),
+ };
+
+ f(&context)
+ }
+
/// Whether the current element is the root element.
pub fn is_root_element(&self) -> bool {
self.is_root_element
diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs
index 004910ae6b1..ffe4d7ba59b 100644
--- a/components/style/values/specified/mod.rs
+++ b/components/style/values/specified/mod.rs
@@ -76,6 +76,7 @@ pub mod length;
pub mod percentage;
pub mod position;
pub mod rect;
+pub mod source_size_list;
pub mod svg;
pub mod table;
pub mod text;
diff --git a/components/style/values/specified/source_size_list.rs b/components/style/values/specified/source_size_list.rs
new file mode 100644
index 00000000000..4a0c068ce78
--- /dev/null
+++ b/components/style/values/specified/source_size_list.rs
@@ -0,0 +1,79 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+
+//! https://html.spec.whatwg.org/multipage/#source-size-list
+
+use app_units::Au;
+use cssparser::Parser;
+use media_queries::{Device, Expression as MediaExpression};
+use parser::{Parse, ParserContext};
+use selectors::context::QuirksMode;
+use style_traits::ParseError;
+use values::computed::{self, ToComputedValue};
+use values::specified::Length;
+
+/// A value for a `<source-size>`:
+///
+/// https://html.spec.whatwg.org/multipage/#source-size
+pub struct SourceSize {
+ condition: MediaExpression,
+ value: Length,
+}
+
+impl Parse for SourceSize {
+ fn parse<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<Self, ParseError<'i>> {
+ let condition = MediaExpression::parse(context, input)?;
+ let value = Length::parse_non_negative(context, input)?;
+
+ Ok(Self { condition, value })
+ }
+}
+
+/// A value for a `<source-size-list>`:
+///
+/// https://html.spec.whatwg.org/multipage/#source-size-list
+pub struct SourceSizeList {
+ source_sizes: Vec<SourceSize>,
+ value: Length,
+}
+
+impl SourceSizeList {
+ /// Evaluate this <source-size-list> to get the final viewport length.
+ pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> Au {
+ let matching_source_size = self.source_sizes.iter().find(|source_size| {
+ source_size.condition.matches(device, quirks_mode)
+ });
+
+ computed::Context::for_media_query_evaluation(device, quirks_mode, |context| {
+ match matching_source_size {
+ Some(source_size) => {
+ source_size.value.to_computed_value(context)
+ }
+ None => {
+ self.value.to_computed_value(context)
+ }
+ }
+ }).into()
+ }
+}
+
+impl Parse for SourceSizeList {
+ fn parse<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<Self, ParseError<'i>> {
+ let source_sizes = input.try(|input| {
+ input.parse_comma_separated(|input| {
+ SourceSize::parse(context, input)
+ })
+ }).unwrap_or(vec![]);
+
+ let value = Length::parse_non_negative(context, input)?;
+
+ Ok(Self { source_sizes, value })
+ }
+}