style: Introduce SourceSizeList.

MozReview-Commit-ID: 9QMF45VcBFB
This commit is contained in:
Emilio Cobos Álvarez 2017-11-06 13:47:46 +01:00
parent 001c50bcca
commit 3fa75bbdf6
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
5 changed files with 131 additions and 54 deletions

View file

@ -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

View file

@ -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;

View file

@ -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 })
}
}