mirror of
https://github.com/servo/servo.git
synced 2025-08-08 23:15:33 +01:00
Run rustfmt on selectors, servo_arc, and style.
This was generated with: ./mach cargo fmt --package selectors && ./mach cargo fmt --package servo_arc && ./mach cargo fmt --package style Using rustfmt 0.4.1-nightly (a4462d1 2018-03-26)
This commit is contained in:
parent
f7ae1a37e3
commit
c99bcdd4b8
181 changed files with 9981 additions and 7933 deletions
|
@ -103,15 +103,17 @@ macro_rules! parse_quoted_or_unquoted_string {
|
|||
($input:ident, $url_matching_function:expr) => {
|
||||
$input.parse_nested_block(|input| {
|
||||
let start = input.position();
|
||||
input.parse_entirely(|input| {
|
||||
let string = input.expect_string()?;
|
||||
Ok($url_matching_function(string.as_ref().to_owned()))
|
||||
}).or_else(|_: ParseError| {
|
||||
while let Ok(_) = input.next() {}
|
||||
Ok($url_matching_function(input.slice_from(start).to_string()))
|
||||
})
|
||||
input
|
||||
.parse_entirely(|input| {
|
||||
let string = input.expect_string()?;
|
||||
Ok($url_matching_function(string.as_ref().to_owned()))
|
||||
})
|
||||
.or_else(|_: ParseError| {
|
||||
while let Ok(_) = input.next() {}
|
||||
Ok($url_matching_function(input.slice_from(start).to_string()))
|
||||
})
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl UrlMatchingFunction {
|
||||
|
@ -120,17 +122,28 @@ impl UrlMatchingFunction {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if input.try(|input| input.expect_function_matching("url-prefix")).is_ok() {
|
||||
return parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::UrlPrefix)
|
||||
if input
|
||||
.try(|input| input.expect_function_matching("url-prefix"))
|
||||
.is_ok()
|
||||
{
|
||||
return parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::UrlPrefix);
|
||||
}
|
||||
|
||||
if input.try(|input| input.expect_function_matching("domain")).is_ok() {
|
||||
return parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain)
|
||||
if input
|
||||
.try(|input| input.expect_function_matching("domain"))
|
||||
.is_ok()
|
||||
{
|
||||
return parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain);
|
||||
}
|
||||
|
||||
if input.try(|input| input.expect_function_matching("regexp")).is_ok() {
|
||||
if input
|
||||
.try(|input| input.expect_function_matching("regexp"))
|
||||
.is_ok()
|
||||
{
|
||||
return input.parse_nested_block(|input| {
|
||||
Ok(UrlMatchingFunction::Regexp(input.expect_string()?.as_ref().to_owned()))
|
||||
Ok(UrlMatchingFunction::Regexp(
|
||||
input.expect_string()?.as_ref().to_owned(),
|
||||
))
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -158,9 +171,7 @@ impl UrlMatchingFunction {
|
|||
UrlMatchingFunction::Domain(ref pat) |
|
||||
UrlMatchingFunction::Regexp(ref pat) => pat,
|
||||
});
|
||||
unsafe {
|
||||
Gecko_DocumentRule_UseForPresentation(device.pres_context(), &*pattern, func)
|
||||
}
|
||||
unsafe { Gecko_DocumentRule_UseForPresentation(device.pres_context(), &*pattern, func) }
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gecko"))]
|
||||
|
@ -187,24 +198,25 @@ impl DocumentCondition {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let conditions = input.parse_comma_separated(|input| {
|
||||
UrlMatchingFunction::parse(context, input)
|
||||
})?;
|
||||
let conditions =
|
||||
input.parse_comma_separated(|input| UrlMatchingFunction::parse(context, input))?;
|
||||
|
||||
let condition = DocumentCondition(conditions);
|
||||
if !condition.allowed_in(context) {
|
||||
return Err(input.new_custom_error(
|
||||
StyleParseErrorKind::UnsupportedAtRule("-moz-document".into())
|
||||
))
|
||||
return Err(
|
||||
input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(
|
||||
"-moz-document".into(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
Ok(condition)
|
||||
}
|
||||
|
||||
/// Evaluate a document condition.
|
||||
pub fn evaluate(&self, device: &Device) -> bool {
|
||||
self.0.iter().any(|url_matching_function| {
|
||||
url_matching_function.evaluate(device)
|
||||
})
|
||||
self.0
|
||||
.iter()
|
||||
.any(|url_matching_function| url_matching_function.evaluate(device))
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
|
@ -225,7 +237,9 @@ impl DocumentCondition {
|
|||
return true;
|
||||
}
|
||||
|
||||
if !unsafe { structs::StaticPrefs_sVarCache_layout_css_moz_document_url_prefix_hack_enabled } {
|
||||
if !unsafe {
|
||||
structs::StaticPrefs_sVarCache_layout_css_moz_document_url_prefix_hack_enabled
|
||||
} {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -239,7 +253,7 @@ impl DocumentCondition {
|
|||
// NOTE(emilio): This technically allows url-prefix("") too, but...
|
||||
match self.0[0] {
|
||||
UrlMatchingFunction::UrlPrefix(ref prefix) => prefix.is_empty(),
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use error_reporting::{ContextualParseError, ParseErrorReporter};
|
|||
use gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry;
|
||||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray};
|
||||
use parser::{ParserContext, ParserErrorContext, Parse};
|
||||
use parser::{Parse, ParserContext, ParserErrorContext};
|
||||
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use std::fmt::{self, Write};
|
||||
use str::CssStringWriter;
|
||||
|
@ -62,11 +62,18 @@ pub trait ToGeckoFontFeatureValues {
|
|||
pub struct SingleValue(pub u32);
|
||||
|
||||
impl Parse for SingleValue {
|
||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<SingleValue, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<SingleValue, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
match *input.next()? {
|
||||
Token::Number { int_value: Some(v), .. } if v >= 0 => Ok(SingleValue(v as u32)),
|
||||
Token::Number {
|
||||
int_value: Some(v), ..
|
||||
} if v >= 0 =>
|
||||
{
|
||||
Ok(SingleValue(v as u32))
|
||||
},
|
||||
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +82,9 @@ impl Parse for SingleValue {
|
|||
#[cfg(feature = "gecko")]
|
||||
impl ToGeckoFontFeatureValues for SingleValue {
|
||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
||||
unsafe { array.set_len_pod(1); }
|
||||
unsafe {
|
||||
array.set_len_pod(1);
|
||||
}
|
||||
array[0] = self.0 as u32;
|
||||
}
|
||||
}
|
||||
|
@ -85,22 +94,32 @@ impl ToGeckoFontFeatureValues for SingleValue {
|
|||
pub struct PairValues(pub u32, pub Option<u32>);
|
||||
|
||||
impl Parse for PairValues {
|
||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<PairValues, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<PairValues, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
let first = match *input.next()? {
|
||||
Token::Number { int_value: Some(a), .. } if a >= 0 => a as u32,
|
||||
Token::Number {
|
||||
int_value: Some(a), ..
|
||||
} if a >= 0 =>
|
||||
{
|
||||
a as u32
|
||||
},
|
||||
ref t => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
};
|
||||
let location = input.current_source_location();
|
||||
match input.next() {
|
||||
Ok(&Token::Number { int_value: Some(b), .. }) if b >= 0 => {
|
||||
Ok(&Token::Number {
|
||||
int_value: Some(b), ..
|
||||
}) if b >= 0 =>
|
||||
{
|
||||
Ok(PairValues(first, Some(b as u32)))
|
||||
}
|
||||
},
|
||||
// It can't be anything other than number.
|
||||
Ok(t) => Err(location.new_unexpected_token_error(t.clone())),
|
||||
// It can be just one value.
|
||||
Err(_) => Ok(PairValues(first, None))
|
||||
Err(_) => Ok(PairValues(first, None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +129,9 @@ impl ToGeckoFontFeatureValues for PairValues {
|
|||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
||||
let len = if self.1.is_some() { 2 } else { 1 };
|
||||
|
||||
unsafe { array.set_len_pod(len); }
|
||||
unsafe {
|
||||
array.set_len_pod(len);
|
||||
}
|
||||
array[0] = self.0 as u32;
|
||||
if let Some(second) = self.1 {
|
||||
array[1] = second as u32;
|
||||
|
@ -123,15 +144,20 @@ impl ToGeckoFontFeatureValues for PairValues {
|
|||
pub struct VectorValues(#[css(iterable)] pub Vec<u32>);
|
||||
|
||||
impl Parse for VectorValues {
|
||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<VectorValues, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
_context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<VectorValues, ParseError<'i>> {
|
||||
let mut vec = vec![];
|
||||
loop {
|
||||
let location = input.current_source_location();
|
||||
match input.next() {
|
||||
Ok(&Token::Number { int_value: Some(a), .. }) if a >= 0 => {
|
||||
Ok(&Token::Number {
|
||||
int_value: Some(a), ..
|
||||
}) if a >= 0 =>
|
||||
{
|
||||
vec.push(a as u32);
|
||||
},
|
||||
}
|
||||
// It can't be anything other than number.
|
||||
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
Err(_) => break,
|
||||
|
@ -149,7 +175,9 @@ impl Parse for VectorValues {
|
|||
#[cfg(feature = "gecko")]
|
||||
impl ToGeckoFontFeatureValues for VectorValues {
|
||||
fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) {
|
||||
unsafe { array.set_len_pod(self.0.len() as u32); }
|
||||
unsafe {
|
||||
array.set_len_pod(self.0.len() as u32);
|
||||
}
|
||||
for (dest, value) in array.iter_mut().zip(self.0.iter()) {
|
||||
*dest = *value;
|
||||
}
|
||||
|
@ -157,9 +185,13 @@ impl ToGeckoFontFeatureValues for VectorValues {
|
|||
}
|
||||
|
||||
/// Parses a list of `FamilyName`s.
|
||||
pub fn parse_family_name_list<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Vec<FamilyName>, ParseError<'i>> {
|
||||
input.parse_comma_separated(|i| FamilyName::parse(context, i)).map_err(|e| e.into())
|
||||
pub fn parse_family_name_list<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Vec<FamilyName>, ParseError<'i>> {
|
||||
input
|
||||
.parse_comma_separated(|i| FamilyName::parse(context, i))
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
/// @font-feature-values inside block parser. Parses a list of `FFVDeclaration`.
|
||||
|
@ -178,13 +210,17 @@ impl<'a, 'b, 'i, T> AtRuleParser<'i> for FFVDeclarationsParser<'a, 'b, T> {
|
|||
}
|
||||
|
||||
impl<'a, 'b, 'i, T> DeclarationParser<'i> for FFVDeclarationsParser<'a, 'b, T>
|
||||
where T: Parse
|
||||
where
|
||||
T: Parse,
|
||||
{
|
||||
type Declaration = ();
|
||||
type Error = StyleParseErrorKind<'i>;
|
||||
|
||||
fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
|
||||
-> Result<(), ParseError<'i>> {
|
||||
fn parse_value<'t>(
|
||||
&mut self,
|
||||
name: CowRcStr<'i>,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<(), ParseError<'i>> {
|
||||
let value = input.parse_entirely(|i| T::parse(self.context, i))?;
|
||||
let new = FFVDeclaration {
|
||||
name: Atom::from(&*name),
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
use cssparser::SourceLocation;
|
||||
use media_queries::MediaList;
|
||||
use shared_lock::{DeepCloneWithLock, DeepCloneParams};
|
||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock};
|
||||
use shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
|
||||
use std::fmt::{self, Write};
|
||||
use str::CssStringWriter;
|
||||
|
@ -32,10 +32,7 @@ impl DeepCloneWithLock for ImportSheet {
|
|||
use gecko::data::GeckoStyleSheet;
|
||||
use gecko_bindings::bindings;
|
||||
let clone = unsafe {
|
||||
bindings::Gecko_StyleSheet_Clone(
|
||||
self.0.raw() as *const _,
|
||||
params.reference_sheet
|
||||
)
|
||||
bindings::Gecko_StyleSheet_Clone(self.0.raw() as *const _, params.reference_sheet)
|
||||
};
|
||||
ImportSheet(unsafe { GeckoStyleSheet::from_addrefed(clone) })
|
||||
}
|
||||
|
@ -117,7 +114,7 @@ impl ToCssWithGuard for ImportRule {
|
|||
Some(media) if !media.is_empty() => {
|
||||
dest.write_str(" ")?;
|
||||
media.to_css(&mut CssWriter::new(dest))?;
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
//! Keyframes: https://drafts.csswg.org/css-animations/#keyframes
|
||||
|
||||
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser, ParserInput, CowRcStr};
|
||||
use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule, SourceLocation, Token};
|
||||
use error_reporting::{NullReporter, ContextualParseError, ParseErrorReporter};
|
||||
use cssparser::{AtRuleParser, CowRcStr, Parser, ParserInput, QualifiedRuleParser, RuleListParser};
|
||||
use cssparser::{parse_one_rule, DeclarationListParser, DeclarationParser, SourceLocation, Token};
|
||||
use error_reporting::{ContextualParseError, NullReporter, ParseErrorReporter};
|
||||
use parser::{ParserContext, ParserErrorContext};
|
||||
use properties::{DeclarationSource, Importance, PropertyDeclaration};
|
||||
use properties::{LonghandId, PropertyDeclarationBlock, PropertyId};
|
||||
|
@ -21,7 +21,7 @@ use str::CssStringWriter;
|
|||
use style_traits::{CssWriter, ParseError, ParsingMode, StyleParseErrorKind, ToCss};
|
||||
use stylesheets::{CssRuleType, StylesheetContents};
|
||||
use stylesheets::rule_parser::VendorPrefix;
|
||||
use values::{KeyframesName, serialize_percentage};
|
||||
use values::{serialize_percentage, KeyframesName};
|
||||
|
||||
/// A [`@keyframes`][keyframes] rule.
|
||||
///
|
||||
|
@ -82,11 +82,14 @@ impl DeepCloneWithLock for KeyframesRule {
|
|||
) -> Self {
|
||||
KeyframesRule {
|
||||
name: self.name.clone(),
|
||||
keyframes: self.keyframes.iter()
|
||||
keyframes: self.keyframes
|
||||
.iter()
|
||||
.map(|x| {
|
||||
Arc::new(lock.wrap(
|
||||
x.read_with(guard).deep_clone_with_lock(lock, guard, params)
|
||||
))
|
||||
Arc::new(lock.wrap(x.read_with(guard).deep_clone_with_lock(
|
||||
lock,
|
||||
guard,
|
||||
params,
|
||||
)))
|
||||
})
|
||||
.collect(),
|
||||
vendor_prefix: self.vendor_prefix.clone(),
|
||||
|
@ -108,7 +111,7 @@ impl ::std::cmp::Ord for KeyframePercentage {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::cmp::Eq for KeyframePercentage { }
|
||||
impl ::std::cmp::Eq for KeyframePercentage {}
|
||||
|
||||
impl ToCss for KeyframePercentage {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
|
@ -136,12 +139,14 @@ impl KeyframePercentage {
|
|||
Token::Ident(ref identifier) if identifier.as_ref().eq_ignore_ascii_case("to") => {
|
||||
Ok(KeyframePercentage::new(1.))
|
||||
},
|
||||
Token::Percentage { unit_value: percentage, .. } if percentage >= 0. && percentage <= 1. => {
|
||||
Token::Percentage {
|
||||
unit_value: percentage,
|
||||
..
|
||||
} if percentage >= 0. && percentage <= 1. =>
|
||||
{
|
||||
Ok(KeyframePercentage::new(percentage))
|
||||
},
|
||||
_ => {
|
||||
Err(input.new_unexpected_token_error(token))
|
||||
},
|
||||
_ => Err(input.new_unexpected_token_error(token)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,8 +171,9 @@ impl KeyframeSelector {
|
|||
|
||||
/// Parse a keyframe selector from CSS input.
|
||||
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||
input.parse_comma_separated(KeyframePercentage::parse)
|
||||
.map(KeyframeSelector)
|
||||
input
|
||||
.parse_comma_separated(KeyframePercentage::parse)
|
||||
.map(KeyframeSelector)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,9 +218,11 @@ impl Keyframe {
|
|||
&url_data,
|
||||
Some(CssRuleType::Keyframe),
|
||||
ParsingMode::DEFAULT,
|
||||
parent_stylesheet_contents.quirks_mode
|
||||
parent_stylesheet_contents.quirks_mode,
|
||||
);
|
||||
let error_context = ParserErrorContext { error_reporter: &error_reporter };
|
||||
let error_context = ParserErrorContext {
|
||||
error_reporter: &error_reporter,
|
||||
};
|
||||
context.namespaces = Some(&*namespaces);
|
||||
let mut input = ParserInput::new(css);
|
||||
let mut input = Parser::new(&mut input);
|
||||
|
@ -259,7 +267,7 @@ pub enum KeyframesStepValue {
|
|||
#[cfg_attr(feature = "gecko",
|
||||
ignore_malloc_size_of = "XXX: Primary ref, measure if DMD says it's worthwhile")]
|
||||
#[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
|
||||
block: Arc<Locked<PropertyDeclarationBlock>>
|
||||
block: Arc<Locked<PropertyDeclarationBlock>>,
|
||||
},
|
||||
/// A synthetic step computed from the current computed values at the time
|
||||
/// of the animation.
|
||||
|
@ -283,18 +291,20 @@ pub struct KeyframesStep {
|
|||
|
||||
impl KeyframesStep {
|
||||
#[inline]
|
||||
fn new(percentage: KeyframePercentage,
|
||||
value: KeyframesStepValue,
|
||||
guard: &SharedRwLockReadGuard) -> Self {
|
||||
fn new(
|
||||
percentage: KeyframePercentage,
|
||||
value: KeyframesStepValue,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
) -> Self {
|
||||
let declared_timing_function = match value {
|
||||
KeyframesStepValue::Declarations { ref block } => {
|
||||
block.read_with(guard).declarations().iter().any(|prop_decl| {
|
||||
match *prop_decl {
|
||||
PropertyDeclaration::AnimationTimingFunction(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
}
|
||||
KeyframesStepValue::Declarations { ref block } => block
|
||||
.read_with(guard)
|
||||
.declarations()
|
||||
.iter()
|
||||
.any(|prop_decl| match *prop_decl {
|
||||
PropertyDeclaration::AnimationTimingFunction(..) => true,
|
||||
_ => false,
|
||||
}),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
@ -306,16 +316,21 @@ impl KeyframesStep {
|
|||
}
|
||||
|
||||
/// Return specified TransitionTimingFunction if this KeyframesSteps has 'animation-timing-function'.
|
||||
pub fn get_animation_timing_function(&self, guard: &SharedRwLockReadGuard)
|
||||
-> Option<SpecifiedTimingFunction> {
|
||||
pub fn get_animation_timing_function(
|
||||
&self,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
) -> Option<SpecifiedTimingFunction> {
|
||||
if !self.declared_timing_function {
|
||||
return None;
|
||||
}
|
||||
match self.value {
|
||||
KeyframesStepValue::Declarations { ref block } => {
|
||||
let guard = block.read_with(guard);
|
||||
let (declaration, _) =
|
||||
guard.get(PropertyDeclarationId::Longhand(LonghandId::AnimationTimingFunction)).unwrap();
|
||||
let (declaration, _) = guard
|
||||
.get(PropertyDeclarationId::Longhand(
|
||||
LonghandId::AnimationTimingFunction,
|
||||
))
|
||||
.unwrap();
|
||||
match *declaration {
|
||||
PropertyDeclaration::AnimationTimingFunction(ref value) => {
|
||||
// Use the first value.
|
||||
|
@ -350,7 +365,7 @@ pub struct KeyframesAnimation {
|
|||
/// Get all the animated properties in a keyframes animation.
|
||||
fn get_animated_properties(
|
||||
keyframes: &[Arc<Locked<Keyframe>>],
|
||||
guard: &SharedRwLockReadGuard
|
||||
guard: &SharedRwLockReadGuard,
|
||||
) -> LonghandIdSet {
|
||||
let mut ret = LonghandIdSet::new();
|
||||
// NB: declarations are already deduplicated, so we don't have to check for
|
||||
|
@ -417,9 +432,13 @@ impl KeyframesAnimation {
|
|||
for keyframe in keyframes {
|
||||
let keyframe = keyframe.read_with(&guard);
|
||||
for percentage in keyframe.selector.0.iter() {
|
||||
result.steps.push(KeyframesStep::new(*percentage, KeyframesStepValue::Declarations {
|
||||
block: keyframe.block.clone(),
|
||||
}, guard));
|
||||
result.steps.push(KeyframesStep::new(
|
||||
*percentage,
|
||||
KeyframesStepValue::Declarations {
|
||||
block: keyframe.block.clone(),
|
||||
},
|
||||
guard,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,15 +447,22 @@ impl KeyframesAnimation {
|
|||
|
||||
// Prepend autogenerated keyframes if appropriate.
|
||||
if result.steps[0].start_percentage.0 != 0. {
|
||||
result.steps.insert(0, KeyframesStep::new(KeyframePercentage::new(0.),
|
||||
KeyframesStepValue::ComputedValues,
|
||||
guard));
|
||||
result.steps.insert(
|
||||
0,
|
||||
KeyframesStep::new(
|
||||
KeyframePercentage::new(0.),
|
||||
KeyframesStepValue::ComputedValues,
|
||||
guard,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if result.steps.last().unwrap().start_percentage.0 != 1. {
|
||||
result.steps.push(KeyframesStep::new(KeyframePercentage::new(1.),
|
||||
KeyframesStepValue::ComputedValues,
|
||||
guard));
|
||||
result.steps.push(KeyframesStep::new(
|
||||
KeyframePercentage::new(1.),
|
||||
KeyframesStepValue::ComputedValues,
|
||||
guard,
|
||||
));
|
||||
}
|
||||
|
||||
result
|
||||
|
@ -463,20 +489,27 @@ pub fn parse_keyframe_list<R>(
|
|||
context: &ParserContext,
|
||||
error_context: &ParserErrorContext<R>,
|
||||
input: &mut Parser,
|
||||
shared_lock: &SharedRwLock
|
||||
shared_lock: &SharedRwLock,
|
||||
) -> Vec<Arc<Locked<Keyframe>>>
|
||||
where R: ParseErrorReporter
|
||||
where
|
||||
R: ParseErrorReporter,
|
||||
{
|
||||
debug_assert!(context.namespaces.is_some(),
|
||||
"Parsing a keyframe list from a context without namespaces?");
|
||||
debug_assert!(
|
||||
context.namespaces.is_some(),
|
||||
"Parsing a keyframe list from a context without namespaces?"
|
||||
);
|
||||
|
||||
let mut declarations = SourcePropertyDeclaration::new();
|
||||
RuleListParser::new_for_nested_rule(input, KeyframeListParser {
|
||||
context: context,
|
||||
error_context: error_context,
|
||||
shared_lock: shared_lock,
|
||||
declarations: &mut declarations,
|
||||
}).filter_map(Result::ok).collect()
|
||||
RuleListParser::new_for_nested_rule(
|
||||
input,
|
||||
KeyframeListParser {
|
||||
context: context,
|
||||
error_context: error_context,
|
||||
shared_lock: shared_lock,
|
||||
declarations: &mut declarations,
|
||||
},
|
||||
).filter_map(Result::ok)
|
||||
.collect()
|
||||
}
|
||||
|
||||
impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> {
|
||||
|
@ -497,33 +530,40 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
|
|||
type QualifiedRule = Arc<Locked<Keyframe>>;
|
||||
type Error = StyleParseErrorKind<'i>;
|
||||
|
||||
fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result<Self::Prelude, ParseError<'i>> {
|
||||
fn parse_prelude<'t>(
|
||||
&mut self,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self::Prelude, ParseError<'i>> {
|
||||
let start_position = input.position();
|
||||
let start_location = input.current_source_location();
|
||||
match KeyframeSelector::parse(input) {
|
||||
Ok(sel) => {
|
||||
Ok(KeyframeSelectorParserPrelude {
|
||||
selector: sel,
|
||||
source_location: start_location,
|
||||
})
|
||||
},
|
||||
Ok(sel) => Ok(KeyframeSelectorParserPrelude {
|
||||
selector: sel,
|
||||
source_location: start_location,
|
||||
}),
|
||||
Err(e) => {
|
||||
let location = e.location;
|
||||
let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone());
|
||||
self.context.log_css_error(self.error_context, location, error);
|
||||
let error = ContextualParseError::InvalidKeyframeRule(
|
||||
input.slice_from(start_position),
|
||||
e.clone(),
|
||||
);
|
||||
self.context
|
||||
.log_css_error(self.error_context, location, error);
|
||||
Err(e)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_block<'t>(&mut self, prelude: Self::Prelude, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self::QualifiedRule, ParseError<'i>> {
|
||||
let context =
|
||||
ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
CssRuleType::Keyframe,
|
||||
self.context.namespaces.unwrap(),
|
||||
);
|
||||
fn parse_block<'t>(
|
||||
&mut self,
|
||||
prelude: Self::Prelude,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self::QualifiedRule, ParseError<'i>> {
|
||||
let context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
CssRuleType::Keyframe,
|
||||
self.context.namespaces.unwrap(),
|
||||
);
|
||||
|
||||
let parser = KeyframeDeclarationParser {
|
||||
context: &context,
|
||||
|
@ -539,13 +579,14 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
|
|||
Importance::Normal,
|
||||
DeclarationSource::Parsing,
|
||||
);
|
||||
}
|
||||
},
|
||||
Err((error, slice)) => {
|
||||
iter.parser.declarations.clear();
|
||||
let location = error.location;
|
||||
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error);
|
||||
let error =
|
||||
ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error);
|
||||
context.log_css_error(self.error_context, location, error);
|
||||
}
|
||||
},
|
||||
}
|
||||
// `parse_important` is not called here, `!important` is not allowed in keyframe blocks.
|
||||
}
|
||||
|
|
|
@ -46,7 +46,9 @@ impl ToCssWithGuard for MediaRule {
|
|||
// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSMediaRule
|
||||
fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
|
||||
dest.write_str("@media ")?;
|
||||
self.media_queries.read_with(guard).to_css(&mut CssWriter::new(dest))?;
|
||||
self.media_queries
|
||||
.read_with(guard)
|
||||
.to_css(&mut CssWriter::new(dest))?;
|
||||
self.rules.read_with(guard).to_css_block(guard, dest)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ pub use self::rule_parser::{State, TopLevelRuleParser};
|
|||
pub use self::rule_list::{CssRules, CssRulesHelpers};
|
||||
pub use self::rules_iterator::{AllRules, EffectiveRules};
|
||||
pub use self::rules_iterator::{NestedRuleIterationCondition, RulesIterator};
|
||||
pub use self::stylesheet::{Namespaces, Stylesheet, DocumentStyleSheet};
|
||||
pub use self::stylesheet::{DocumentStyleSheet, Namespaces, Stylesheet};
|
||||
pub use self::stylesheet::{StylesheetContents, StylesheetInDocument, UserAgentStylesheets};
|
||||
pub use self::style_rule::StyleRule;
|
||||
pub use self::supports_rule::SupportsRule;
|
||||
|
@ -94,7 +94,6 @@ impl Eq for UrlExtraData {}
|
|||
pub enum CssRule {
|
||||
// No Charset here, CSSCharsetRule has been removed from CSSOM
|
||||
// https://drafts.csswg.org/cssom/#changes-from-5-december-2013
|
||||
|
||||
Namespace(Arc<Locked<NamespaceRule>>),
|
||||
Import(Arc<Locked<ImportRule>>),
|
||||
Style(Arc<Locked<StyleRule>>),
|
||||
|
@ -116,18 +115,19 @@ impl CssRule {
|
|||
match *self {
|
||||
// Not all fields are currently fully measured. Extra measurement
|
||||
// may be added later.
|
||||
|
||||
CssRule::Namespace(_) => 0,
|
||||
|
||||
// We don't need to measure ImportRule::stylesheet because we measure
|
||||
// it on the C++ side in the child list of the ServoStyleSheet.
|
||||
CssRule::Import(_) => 0,
|
||||
|
||||
CssRule::Style(ref lock) =>
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),
|
||||
CssRule::Style(ref lock) => {
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
|
||||
},
|
||||
|
||||
CssRule::Media(ref lock) =>
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),
|
||||
CssRule::Media(ref lock) => {
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
|
||||
},
|
||||
|
||||
CssRule::FontFace(_) => 0,
|
||||
CssRule::FontFeatureValues(_) => 0,
|
||||
|
@ -135,14 +135,17 @@ impl CssRule {
|
|||
CssRule::Viewport(_) => 0,
|
||||
CssRule::Keyframes(_) => 0,
|
||||
|
||||
CssRule::Supports(ref lock) =>
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),
|
||||
CssRule::Supports(ref lock) => {
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
|
||||
},
|
||||
|
||||
CssRule::Page(ref lock) =>
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),
|
||||
CssRule::Page(ref lock) => {
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
|
||||
},
|
||||
|
||||
CssRule::Document(ref lock) =>
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops),
|
||||
CssRule::Document(ref lock) => {
|
||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,28 +154,28 @@ impl CssRule {
|
|||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CssRuleType {
|
||||
// https://drafts.csswg.org/cssom/#the-cssrule-interface
|
||||
Style = 1,
|
||||
Charset = 2,
|
||||
Import = 3,
|
||||
Media = 4,
|
||||
FontFace = 5,
|
||||
Page = 6,
|
||||
Style = 1,
|
||||
Charset = 2,
|
||||
Import = 3,
|
||||
Media = 4,
|
||||
FontFace = 5,
|
||||
Page = 6,
|
||||
// https://drafts.csswg.org/css-animations-1/#interface-cssrule-idl
|
||||
Keyframes = 7,
|
||||
Keyframe = 8,
|
||||
Keyframes = 7,
|
||||
Keyframe = 8,
|
||||
// https://drafts.csswg.org/cssom/#the-cssrule-interface
|
||||
Margin = 9,
|
||||
Namespace = 10,
|
||||
Margin = 9,
|
||||
Namespace = 10,
|
||||
// https://drafts.csswg.org/css-counter-styles-3/#extentions-to-cssrule-interface
|
||||
CounterStyle = 11,
|
||||
CounterStyle = 11,
|
||||
// https://drafts.csswg.org/css-conditional-3/#extentions-to-cssrule-interface
|
||||
Supports = 12,
|
||||
Supports = 12,
|
||||
// https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#extentions-to-cssrule-interface
|
||||
Document = 13,
|
||||
Document = 13,
|
||||
// https://drafts.csswg.org/css-fonts-3/#om-fontfeaturevalues
|
||||
FontFeatureValues = 14,
|
||||
FontFeatureValues = 14,
|
||||
// https://drafts.csswg.org/css-device-adapt/#css-rule-interface
|
||||
Viewport = 15,
|
||||
Viewport = 15,
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
|
@ -213,7 +216,7 @@ impl CssRule {
|
|||
CssRule::Viewport(_) => CssRuleType::Viewport,
|
||||
CssRule::Supports(_) => CssRuleType::Supports,
|
||||
CssRule::Page(_) => CssRuleType::Page,
|
||||
CssRule::Document(_) => CssRuleType::Document,
|
||||
CssRule::Document(_) => CssRuleType::Document,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,7 +239,7 @@ impl CssRule {
|
|||
parent_stylesheet_contents: &StylesheetContents,
|
||||
shared_lock: &SharedRwLock,
|
||||
state: Option<State>,
|
||||
loader: Option<&StylesheetLoader>
|
||||
loader: Option<&StylesheetLoader>,
|
||||
) -> Result<(Self, State), SingleRuleParseError> {
|
||||
let url_data = parent_stylesheet_contents.url_data.read();
|
||||
let error_reporter = NullReporter;
|
||||
|
@ -258,7 +261,9 @@ impl CssRule {
|
|||
let mut rule_parser = TopLevelRuleParser {
|
||||
stylesheet_origin: parent_stylesheet_contents.origin,
|
||||
context: context,
|
||||
error_context: ParserErrorContext { error_reporter: &error_reporter },
|
||||
error_context: ParserErrorContext {
|
||||
error_reporter: &error_reporter,
|
||||
},
|
||||
shared_lock: &shared_lock,
|
||||
loader: loader,
|
||||
state: state,
|
||||
|
@ -298,13 +303,19 @@ impl DeepCloneWithLock for CssRule {
|
|||
},
|
||||
CssRule::Style(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
CssRule::Style(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
|
||||
CssRule::Style(Arc::new(lock.wrap(rule.deep_clone_with_lock(
|
||||
lock,
|
||||
guard,
|
||||
params,
|
||||
))))
|
||||
},
|
||||
CssRule::Media(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
CssRule::Media(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
|
||||
CssRule::Media(Arc::new(lock.wrap(rule.deep_clone_with_lock(
|
||||
lock,
|
||||
guard,
|
||||
params,
|
||||
))))
|
||||
},
|
||||
CssRule::FontFace(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
|
@ -324,23 +335,35 @@ impl DeepCloneWithLock for CssRule {
|
|||
},
|
||||
CssRule::Keyframes(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
CssRule::Keyframes(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
|
||||
CssRule::Keyframes(Arc::new(lock.wrap(rule.deep_clone_with_lock(
|
||||
lock,
|
||||
guard,
|
||||
params,
|
||||
))))
|
||||
},
|
||||
CssRule::Supports(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
CssRule::Supports(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
|
||||
CssRule::Supports(Arc::new(lock.wrap(rule.deep_clone_with_lock(
|
||||
lock,
|
||||
guard,
|
||||
params,
|
||||
))))
|
||||
},
|
||||
CssRule::Page(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
CssRule::Page(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
|
||||
CssRule::Page(Arc::new(lock.wrap(rule.deep_clone_with_lock(
|
||||
lock,
|
||||
guard,
|
||||
params,
|
||||
))))
|
||||
},
|
||||
CssRule::Document(ref arc) => {
|
||||
let rule = arc.read_with(guard);
|
||||
CssRule::Document(Arc::new(
|
||||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params))))
|
||||
CssRule::Document(Arc::new(lock.wrap(rule.deep_clone_with_lock(
|
||||
lock,
|
||||
guard,
|
||||
params,
|
||||
))))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,10 +57,7 @@ impl OriginSet {
|
|||
/// See the `OriginSet` documentation for information about the order
|
||||
/// origins are iterated.
|
||||
pub fn iter(&self) -> OriginSetIterator {
|
||||
OriginSetIterator {
|
||||
set: *self,
|
||||
cur: 0,
|
||||
}
|
||||
OriginSetIterator { set: *self, cur: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +91,7 @@ impl Iterator for OriginSetIterator {
|
|||
self.cur += 1;
|
||||
|
||||
if self.set.contains(origin.into()) {
|
||||
return Some(origin)
|
||||
return Some(origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +174,10 @@ pub struct PerOriginIter<'a, T: 'a> {
|
|||
rev: bool,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for PerOriginIter<'a, T> where T: 'a {
|
||||
impl<'a, T> Iterator for PerOriginIter<'a, T>
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
type Item = (&'a T, Origin);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -201,7 +201,10 @@ pub struct PerOriginIterMut<'a, T: 'a> {
|
|||
_marker: PhantomData<&'a mut PerOrigin<T>>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for PerOriginIterMut<'a, T> where T: 'a {
|
||||
impl<'a, T> Iterator for PerOriginIterMut<'a, T>
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
type Item = (&'a mut T, Origin);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -209,6 +212,9 @@ impl<'a, T> Iterator for PerOriginIterMut<'a, T> where T: 'a {
|
|||
|
||||
self.cur += 1;
|
||||
|
||||
Some((unsafe { (*self.data).borrow_mut_for_origin(&origin) }, origin))
|
||||
Some((
|
||||
unsafe { (*self.data).borrow_mut_for_origin(&origin) },
|
||||
origin,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,12 @@ impl DeepCloneWithLock for CssRules {
|
|||
guard: &SharedRwLockReadGuard,
|
||||
params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
CssRules(self.0.iter().map(|x| {
|
||||
x.deep_clone_with_lock(lock, guard, params)
|
||||
}).collect())
|
||||
CssRules(
|
||||
self.0
|
||||
.iter()
|
||||
.map(|x| x.deep_clone_with_lock(lock, guard, params))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,12 +62,9 @@ impl CssRules {
|
|||
/// Returns whether all the rules in this list are namespace or import
|
||||
/// rules.
|
||||
fn only_ns_or_import(&self) -> bool {
|
||||
self.0.iter().all(|r| {
|
||||
match *r {
|
||||
CssRule::Namespace(..) |
|
||||
CssRule::Import(..) => true,
|
||||
_ => false
|
||||
}
|
||||
self.0.iter().all(|r| match *r {
|
||||
CssRule::Namespace(..) | CssRule::Import(..) => true,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,11 @@ impl CssRules {
|
|||
///
|
||||
/// This should be speced into CSSOM spec at some point. See
|
||||
/// <https://github.com/w3c/csswg-drafts/issues/1985>
|
||||
pub fn to_css_block(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
|
||||
pub fn to_css_block(
|
||||
&self,
|
||||
guard: &SharedRwLockReadGuard,
|
||||
dest: &mut CssStringWriter,
|
||||
) -> fmt::Result {
|
||||
dest.write_str(" {")?;
|
||||
for rule in self.0.iter() {
|
||||
dest.write_str("\n ")?;
|
||||
|
@ -116,25 +120,27 @@ pub trait CssRulesHelpers {
|
|||
///
|
||||
/// TODO(emilio): We could also pass the write guard down into the loader
|
||||
/// instead, but that seems overkill.
|
||||
fn insert_rule(&self,
|
||||
lock: &SharedRwLock,
|
||||
rule: &str,
|
||||
parent_stylesheet_contents: &StylesheetContents,
|
||||
index: usize,
|
||||
nested: bool,
|
||||
loader: Option<&StylesheetLoader>)
|
||||
-> Result<CssRule, RulesMutateError>;
|
||||
fn insert_rule(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
rule: &str,
|
||||
parent_stylesheet_contents: &StylesheetContents,
|
||||
index: usize,
|
||||
nested: bool,
|
||||
loader: Option<&StylesheetLoader>,
|
||||
) -> Result<CssRule, RulesMutateError>;
|
||||
}
|
||||
|
||||
impl CssRulesHelpers for RawOffsetArc<Locked<CssRules>> {
|
||||
fn insert_rule(&self,
|
||||
lock: &SharedRwLock,
|
||||
rule: &str,
|
||||
parent_stylesheet_contents: &StylesheetContents,
|
||||
index: usize,
|
||||
nested: bool,
|
||||
loader: Option<&StylesheetLoader>)
|
||||
-> Result<CssRule, RulesMutateError> {
|
||||
fn insert_rule(
|
||||
&self,
|
||||
lock: &SharedRwLock,
|
||||
rule: &str,
|
||||
parent_stylesheet_contents: &StylesheetContents,
|
||||
index: usize,
|
||||
nested: bool,
|
||||
loader: Option<&StylesheetLoader>,
|
||||
) -> Result<CssRule, RulesMutateError> {
|
||||
let state = {
|
||||
let read_guard = lock.read();
|
||||
let rules = self.read_with(&read_guard);
|
||||
|
@ -157,13 +163,7 @@ impl CssRulesHelpers for RawOffsetArc<Locked<CssRules>> {
|
|||
// Step 3, 4
|
||||
// XXXManishearth should we also store the namespace map?
|
||||
let (new_rule, new_state) =
|
||||
CssRule::parse(
|
||||
&rule,
|
||||
parent_stylesheet_contents,
|
||||
lock,
|
||||
state,
|
||||
loader
|
||||
)?;
|
||||
CssRule::parse(&rule, parent_stylesheet_contents, lock, state, loader)?;
|
||||
|
||||
{
|
||||
let mut write_guard = lock.write();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use {Namespace, Prefix};
|
||||
use counter_style::{parse_counter_style_body, parse_counter_style_name_definition};
|
||||
use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser};
|
||||
use cssparser::{CowRcStr, SourceLocation, BasicParseError, BasicParseErrorKind};
|
||||
use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, SourceLocation};
|
||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||
use font_face::parse_font_face_block;
|
||||
use media_queries::{parse_media_query_list, MediaList};
|
||||
|
@ -18,8 +18,8 @@ use selectors::SelectorList;
|
|||
use servo_arc::Arc;
|
||||
use shared_lock::{Locked, SharedRwLock};
|
||||
use str::starts_with_ignore_ascii_case;
|
||||
use style_traits::{StyleParseErrorKind, ParseError};
|
||||
use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader};
|
||||
use style_traits::{ParseError, StyleParseErrorKind};
|
||||
use stylesheets::{CssRule, CssRuleType, CssRules, Origin, StylesheetLoader};
|
||||
use stylesheets::{DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule};
|
||||
use stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule};
|
||||
use stylesheets::document_rule::DocumentCondition;
|
||||
|
@ -146,7 +146,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
|
|||
fn parse_prelude<'t>(
|
||||
&mut self,
|
||||
name: CowRcStr<'i>,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<AtRuleType<AtRuleNonBlockPrelude, AtRuleBlockPrelude>, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
match_ignore_ascii_case! { &*name,
|
||||
|
@ -203,18 +203,20 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
|
|||
fn parse_block<'t>(
|
||||
&mut self,
|
||||
prelude: AtRuleBlockPrelude,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CssRule, ParseError<'i>> {
|
||||
AtRuleParser::parse_block(&mut self.nested(), prelude, input)
|
||||
.map(|rule| { self.state = State::Body; rule })
|
||||
AtRuleParser::parse_block(&mut self.nested(), prelude, input).map(|rule| {
|
||||
self.state = State::Body;
|
||||
rule
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rule_without_block(&mut self, prelude: AtRuleNonBlockPrelude) -> CssRule {
|
||||
match prelude {
|
||||
AtRuleNonBlockPrelude::Import(url, media, location) => {
|
||||
let loader =
|
||||
self.loader.expect("Expected a stylesheet loader for @import");
|
||||
let loader = self.loader
|
||||
.expect("Expected a stylesheet loader for @import");
|
||||
|
||||
let import_rule = loader.request_stylesheet(
|
||||
url,
|
||||
|
@ -226,12 +228,10 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
|
|||
|
||||
self.state = State::Imports;
|
||||
CssRule::Import(import_rule)
|
||||
}
|
||||
},
|
||||
AtRuleNonBlockPrelude::Namespace(prefix, url, location) => {
|
||||
let opt_prefix = if let Some(prefix) = prefix {
|
||||
self.namespaces
|
||||
.prefixes
|
||||
.insert(prefix.clone(), url.clone());
|
||||
self.namespaces.prefixes.insert(prefix.clone(), url.clone());
|
||||
Some(prefix)
|
||||
} else {
|
||||
self.namespaces.default = Some(url.clone());
|
||||
|
@ -239,14 +239,12 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
|
|||
};
|
||||
|
||||
self.state = State::Namespaces;
|
||||
CssRule::Namespace(Arc::new(
|
||||
self.shared_lock.wrap(NamespaceRule {
|
||||
prefix: opt_prefix,
|
||||
url: url,
|
||||
source_location: location,
|
||||
})
|
||||
))
|
||||
}
|
||||
CssRule::Namespace(Arc::new(self.shared_lock.wrap(NamespaceRule {
|
||||
prefix: opt_prefix,
|
||||
url: url,
|
||||
source_location: location,
|
||||
})))
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,14 +271,16 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRulePars
|
|||
fn parse_block<'t>(
|
||||
&mut self,
|
||||
prelude: QualifiedRuleParserPrelude,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CssRule, ParseError<'i>> {
|
||||
QualifiedRuleParser::parse_block(&mut self.nested(), prelude, input)
|
||||
.map(|result| { self.state = State::Body; result })
|
||||
QualifiedRuleParser::parse_block(&mut self.nested(), prelude, input).map(|result| {
|
||||
self.state = State::Body;
|
||||
result
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)] // shallow, relatively cheap .clone
|
||||
#[derive(Clone)] // shallow, relatively cheap .clone
|
||||
struct NestedRuleParser<'a, 'b: 'a, R: 'b> {
|
||||
stylesheet_origin: Origin,
|
||||
shared_lock: &'a SharedRwLock,
|
||||
|
@ -293,13 +293,9 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
|
|||
fn parse_nested_rules(
|
||||
&mut self,
|
||||
input: &mut Parser,
|
||||
rule_type: CssRuleType
|
||||
rule_type: CssRuleType,
|
||||
) -> Arc<Locked<CssRules>> {
|
||||
let context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
rule_type,
|
||||
self.namespaces,
|
||||
);
|
||||
let context = ParserContext::new_with_rule_type(self.context, rule_type, self.namespaces);
|
||||
|
||||
let nested_parser = NestedRuleParser {
|
||||
stylesheet_origin: self.stylesheet_origin,
|
||||
|
@ -317,8 +313,9 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
|
|||
Err((error, slice)) => {
|
||||
let location = error.location;
|
||||
let error = ContextualParseError::InvalidRule(slice, error);
|
||||
self.context.log_css_error(self.error_context, location, error);
|
||||
}
|
||||
self.context
|
||||
.log_css_error(self.error_context, location, error);
|
||||
},
|
||||
}
|
||||
}
|
||||
CssRules::new(rules, self.shared_lock)
|
||||
|
@ -334,7 +331,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
fn parse_prelude<'t>(
|
||||
&mut self,
|
||||
name: CowRcStr<'i>,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<AtRuleType<AtRuleNonBlockPrelude, AtRuleBlockPrelude>, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
|
||||
|
@ -416,7 +413,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
fn parse_block<'t>(
|
||||
&mut self,
|
||||
prelude: AtRuleBlockPrelude,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CssRule, ParseError<'i>> {
|
||||
match prelude {
|
||||
AtRuleBlockPrelude::FontFace(location) => {
|
||||
|
@ -427,8 +424,9 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
);
|
||||
|
||||
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap(
|
||||
parse_font_face_block(&context, self.error_context, input, location).into()))))
|
||||
}
|
||||
parse_font_face_block(&context, self.error_context, input, location).into(),
|
||||
))))
|
||||
},
|
||||
AtRuleBlockPrelude::FontFeatureValues(family_names, location) => {
|
||||
let context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
|
@ -437,8 +435,15 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
);
|
||||
|
||||
Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap(
|
||||
FontFeatureValuesRule::parse(&context, self.error_context, input, family_names, location)))))
|
||||
}
|
||||
FontFeatureValuesRule::parse(
|
||||
&context,
|
||||
self.error_context,
|
||||
input,
|
||||
family_names,
|
||||
location,
|
||||
),
|
||||
))))
|
||||
},
|
||||
AtRuleBlockPrelude::CounterStyle(name, location) => {
|
||||
let context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
|
@ -446,23 +451,25 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
self.namespaces,
|
||||
);
|
||||
|
||||
Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap(
|
||||
parse_counter_style_body(
|
||||
name,
|
||||
&context,
|
||||
self.error_context,
|
||||
input,
|
||||
location
|
||||
)?.into()
|
||||
))))
|
||||
}
|
||||
Ok(CssRule::CounterStyle(Arc::new(
|
||||
self.shared_lock.wrap(
|
||||
parse_counter_style_body(
|
||||
name,
|
||||
&context,
|
||||
self.error_context,
|
||||
input,
|
||||
location,
|
||||
)?.into(),
|
||||
),
|
||||
)))
|
||||
},
|
||||
AtRuleBlockPrelude::Media(media_queries, location) => {
|
||||
Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule {
|
||||
media_queries: media_queries,
|
||||
rules: self.parse_nested_rules(input, CssRuleType::Media),
|
||||
source_location: location,
|
||||
}))))
|
||||
}
|
||||
},
|
||||
AtRuleBlockPrelude::Supports(cond, location) => {
|
||||
let eval_context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
|
@ -471,13 +478,15 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
);
|
||||
|
||||
let enabled = cond.eval(&eval_context);
|
||||
Ok(CssRule::Supports(Arc::new(self.shared_lock.wrap(SupportsRule {
|
||||
condition: cond,
|
||||
rules: self.parse_nested_rules(input, CssRuleType::Supports),
|
||||
enabled: enabled,
|
||||
source_location: location,
|
||||
}))))
|
||||
}
|
||||
Ok(CssRule::Supports(Arc::new(self.shared_lock.wrap(
|
||||
SupportsRule {
|
||||
condition: cond,
|
||||
rules: self.parse_nested_rules(input, CssRuleType::Supports),
|
||||
enabled: enabled,
|
||||
source_location: location,
|
||||
},
|
||||
))))
|
||||
},
|
||||
AtRuleBlockPrelude::Viewport => {
|
||||
let context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
|
@ -486,8 +495,9 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
);
|
||||
|
||||
Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap(
|
||||
ViewportRule::parse(&context, self.error_context, input)?))))
|
||||
}
|
||||
ViewportRule::parse(&context, self.error_context, input)?,
|
||||
))))
|
||||
},
|
||||
AtRuleBlockPrelude::Keyframes(name, prefix, location) => {
|
||||
let context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
|
@ -495,13 +505,20 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
self.namespaces,
|
||||
);
|
||||
|
||||
Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule {
|
||||
name: name,
|
||||
keyframes: parse_keyframe_list(&context, self.error_context, input, self.shared_lock),
|
||||
vendor_prefix: prefix,
|
||||
source_location: location,
|
||||
}))))
|
||||
}
|
||||
Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(
|
||||
KeyframesRule {
|
||||
name: name,
|
||||
keyframes: parse_keyframe_list(
|
||||
&context,
|
||||
self.error_context,
|
||||
input,
|
||||
self.shared_lock,
|
||||
),
|
||||
vendor_prefix: prefix,
|
||||
source_location: location,
|
||||
},
|
||||
))))
|
||||
},
|
||||
AtRuleBlockPrelude::Page(location) => {
|
||||
let context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
|
@ -509,23 +526,26 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
|||
self.namespaces,
|
||||
);
|
||||
|
||||
let declarations = parse_property_declaration_list(&context, self.error_context, input);
|
||||
let declarations =
|
||||
parse_property_declaration_list(&context, self.error_context, input);
|
||||
Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule {
|
||||
block: Arc::new(self.shared_lock.wrap(declarations)),
|
||||
source_location: location,
|
||||
}))))
|
||||
}
|
||||
},
|
||||
AtRuleBlockPrelude::Document(cond, location) => {
|
||||
if cfg!(feature = "gecko") {
|
||||
Ok(CssRule::Document(Arc::new(self.shared_lock.wrap(DocumentRule {
|
||||
condition: cond,
|
||||
rules: self.parse_nested_rules(input, CssRuleType::Document),
|
||||
source_location: location,
|
||||
}))))
|
||||
Ok(CssRule::Document(Arc::new(self.shared_lock.wrap(
|
||||
DocumentRule {
|
||||
condition: cond,
|
||||
rules: self.parse_nested_rules(input, CssRuleType::Document),
|
||||
source_location: location,
|
||||
},
|
||||
))))
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -537,7 +557,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRulePa
|
|||
|
||||
fn parse_prelude<'t>(
|
||||
&mut self,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<QualifiedRuleParserPrelude, ParseError<'i>> {
|
||||
let selector_parser = SelectorParser {
|
||||
stylesheet_origin: self.stylesheet_origin,
|
||||
|
@ -557,13 +577,10 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRulePa
|
|||
fn parse_block<'t>(
|
||||
&mut self,
|
||||
prelude: QualifiedRuleParserPrelude,
|
||||
input: &mut Parser<'i, 't>
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CssRule, ParseError<'i>> {
|
||||
let context = ParserContext::new_with_rule_type(
|
||||
self.context,
|
||||
CssRuleType::Style,
|
||||
self.namespaces,
|
||||
);
|
||||
let context =
|
||||
ParserContext::new_with_rule_type(self.context, CssRuleType::Style, self.namespaces);
|
||||
|
||||
let declarations = parse_property_declaration_list(&context, self.error_context, input);
|
||||
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
|
||||
|
|
|
@ -14,8 +14,9 @@ use stylesheets::StylesheetInDocument;
|
|||
|
||||
/// An iterator over a list of rules.
|
||||
pub struct RulesIterator<'a, 'b, C>
|
||||
where 'b: 'a,
|
||||
C: NestedRuleIterationCondition + 'static,
|
||||
where
|
||||
'b: 'a,
|
||||
C: NestedRuleIterationCondition + 'static,
|
||||
{
|
||||
device: &'a Device,
|
||||
quirks_mode: QuirksMode,
|
||||
|
@ -25,17 +26,17 @@ pub struct RulesIterator<'a, 'b, C>
|
|||
}
|
||||
|
||||
impl<'a, 'b, C> RulesIterator<'a, 'b, C>
|
||||
where 'b: 'a,
|
||||
C: NestedRuleIterationCondition + 'static,
|
||||
where
|
||||
'b: 'a,
|
||||
C: NestedRuleIterationCondition + 'static,
|
||||
{
|
||||
/// Creates a new `RulesIterator` to iterate over `rules`.
|
||||
pub fn new(
|
||||
device: &'a Device,
|
||||
quirks_mode: QuirksMode,
|
||||
guard: &'a SharedRwLockReadGuard<'b>,
|
||||
rules: &'a CssRules)
|
||||
-> Self
|
||||
{
|
||||
rules: &'a CssRules,
|
||||
) -> Self {
|
||||
let mut stack = SmallVec::new();
|
||||
stack.push(rules.0.iter());
|
||||
Self {
|
||||
|
@ -54,8 +55,9 @@ impl<'a, 'b, C> RulesIterator<'a, 'b, C>
|
|||
}
|
||||
|
||||
impl<'a, 'b, C> Iterator for RulesIterator<'a, 'b, C>
|
||||
where 'b: 'a,
|
||||
C: NestedRuleIterationCondition + 'static,
|
||||
where
|
||||
'b: 'a,
|
||||
C: NestedRuleIterationCondition + 'static,
|
||||
{
|
||||
type Item = &'a CssRule;
|
||||
|
||||
|
@ -75,8 +77,8 @@ impl<'a, 'b, C> Iterator for RulesIterator<'a, 'b, C>
|
|||
Some(r) => r,
|
||||
None => {
|
||||
nested_iter_finished = true;
|
||||
continue
|
||||
}
|
||||
continue;
|
||||
},
|
||||
};
|
||||
|
||||
match *rule {
|
||||
|
@ -87,51 +89,53 @@ impl<'a, 'b, C> Iterator for RulesIterator<'a, 'b, C>
|
|||
CssRule::Viewport(_) |
|
||||
CssRule::Keyframes(_) |
|
||||
CssRule::Page(_) |
|
||||
CssRule::FontFeatureValues(_) => {
|
||||
return Some(rule)
|
||||
},
|
||||
CssRule::FontFeatureValues(_) => return Some(rule),
|
||||
CssRule::Import(ref import_rule) => {
|
||||
let import_rule = import_rule.read_with(self.guard);
|
||||
if !C::process_import(self.guard,
|
||||
self.device,
|
||||
self.quirks_mode,
|
||||
import_rule) {
|
||||
if !C::process_import(
|
||||
self.guard,
|
||||
self.device,
|
||||
self.quirks_mode,
|
||||
import_rule,
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
import_rule
|
||||
.stylesheet.contents(self.guard).rules
|
||||
.read_with(self.guard).0.iter()
|
||||
}
|
||||
.stylesheet
|
||||
.contents(self.guard)
|
||||
.rules
|
||||
.read_with(self.guard)
|
||||
.0
|
||||
.iter()
|
||||
},
|
||||
CssRule::Document(ref doc_rule) => {
|
||||
let doc_rule = doc_rule.read_with(self.guard);
|
||||
if !C::process_document(self.guard,
|
||||
self.device,
|
||||
self.quirks_mode,
|
||||
doc_rule) {
|
||||
if !C::process_document(self.guard, self.device, self.quirks_mode, doc_rule)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
doc_rule.rules.read_with(self.guard).0.iter()
|
||||
}
|
||||
},
|
||||
CssRule::Media(ref lock) => {
|
||||
let media_rule = lock.read_with(self.guard);
|
||||
if !C::process_media(self.guard,
|
||||
self.device,
|
||||
self.quirks_mode,
|
||||
media_rule) {
|
||||
if !C::process_media(self.guard, self.device, self.quirks_mode, media_rule)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
media_rule.rules.read_with(self.guard).0.iter()
|
||||
}
|
||||
},
|
||||
CssRule::Supports(ref lock) => {
|
||||
let supports_rule = lock.read_with(self.guard);
|
||||
if !C::process_supports(self.guard,
|
||||
self.device,
|
||||
self.quirks_mode,
|
||||
supports_rule) {
|
||||
if !C::process_supports(
|
||||
self.guard,
|
||||
self.device,
|
||||
self.quirks_mode,
|
||||
supports_rule,
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
supports_rule.rules.read_with(self.guard).0.iter()
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -150,16 +154,16 @@ pub trait NestedRuleIterationCondition {
|
|||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
rule: &ImportRule)
|
||||
-> bool;
|
||||
rule: &ImportRule,
|
||||
) -> bool;
|
||||
|
||||
/// Whether we should process the nested rules in a given `@media` rule.
|
||||
fn process_media(
|
||||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
rule: &MediaRule)
|
||||
-> bool;
|
||||
rule: &MediaRule,
|
||||
) -> bool;
|
||||
|
||||
/// Whether we should process the nested rules in a given `@-moz-document`
|
||||
/// rule.
|
||||
|
@ -167,16 +171,16 @@ pub trait NestedRuleIterationCondition {
|
|||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
rule: &DocumentRule)
|
||||
-> bool;
|
||||
rule: &DocumentRule,
|
||||
) -> bool;
|
||||
|
||||
/// Whether we should process the nested rules in a given `@supports` rule.
|
||||
fn process_supports(
|
||||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
rule: &SupportsRule)
|
||||
-> bool;
|
||||
rule: &SupportsRule,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
/// A struct that represents the condition that a rule applies to the document.
|
||||
|
@ -187,9 +191,8 @@ impl NestedRuleIterationCondition for EffectiveRules {
|
|||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
_quirks_mode: QuirksMode,
|
||||
rule: &ImportRule)
|
||||
-> bool
|
||||
{
|
||||
rule: &ImportRule,
|
||||
) -> bool {
|
||||
rule.stylesheet.is_effective_for_device(device, guard)
|
||||
}
|
||||
|
||||
|
@ -197,19 +200,19 @@ impl NestedRuleIterationCondition for EffectiveRules {
|
|||
guard: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
quirks_mode: QuirksMode,
|
||||
rule: &MediaRule)
|
||||
-> bool
|
||||
{
|
||||
rule.media_queries.read_with(guard).evaluate(device, quirks_mode)
|
||||
rule: &MediaRule,
|
||||
) -> bool {
|
||||
rule.media_queries
|
||||
.read_with(guard)
|
||||
.evaluate(device, quirks_mode)
|
||||
}
|
||||
|
||||
fn process_document(
|
||||
_: &SharedRwLockReadGuard,
|
||||
device: &Device,
|
||||
_: QuirksMode,
|
||||
rule: &DocumentRule)
|
||||
-> bool
|
||||
{
|
||||
rule: &DocumentRule,
|
||||
) -> bool {
|
||||
rule.condition.evaluate(device)
|
||||
}
|
||||
|
||||
|
@ -217,9 +220,8 @@ impl NestedRuleIterationCondition for EffectiveRules {
|
|||
_: &SharedRwLockReadGuard,
|
||||
_: &Device,
|
||||
_: QuirksMode,
|
||||
rule: &SupportsRule)
|
||||
-> bool
|
||||
{
|
||||
rule: &SupportsRule,
|
||||
) -> bool {
|
||||
rule.enabled
|
||||
}
|
||||
}
|
||||
|
@ -232,19 +234,12 @@ impl NestedRuleIterationCondition for AllRules {
|
|||
_: &SharedRwLockReadGuard,
|
||||
_: &Device,
|
||||
_: QuirksMode,
|
||||
_: &ImportRule)
|
||||
-> bool
|
||||
{
|
||||
_: &ImportRule,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn process_media(
|
||||
_: &SharedRwLockReadGuard,
|
||||
_: &Device,
|
||||
_: QuirksMode,
|
||||
_: &MediaRule)
|
||||
-> bool
|
||||
{
|
||||
fn process_media(_: &SharedRwLockReadGuard, _: &Device, _: QuirksMode, _: &MediaRule) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -252,9 +247,8 @@ impl NestedRuleIterationCondition for AllRules {
|
|||
_: &SharedRwLockReadGuard,
|
||||
_: &Device,
|
||||
_: QuirksMode,
|
||||
_: &DocumentRule)
|
||||
-> bool
|
||||
{
|
||||
_: &DocumentRule,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -262,9 +256,8 @@ impl NestedRuleIterationCondition for AllRules {
|
|||
_: &SharedRwLockReadGuard,
|
||||
_: &Device,
|
||||
_: QuirksMode,
|
||||
_: &SupportsRule)
|
||||
-> bool
|
||||
{
|
||||
_: &SupportsRule,
|
||||
) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ impl StyleRule {
|
|||
}
|
||||
|
||||
n += self.block.unconditional_shallow_size_of(ops) +
|
||||
self.block.read_with(guard).size_of(ops);
|
||||
self.block.read_with(guard).size_of(ops);
|
||||
|
||||
n
|
||||
}
|
||||
|
@ -88,4 +88,3 @@ impl ToCssWithGuard for StyleRule {
|
|||
dest.write_str("}")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
* 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/. */
|
||||
|
||||
use {Prefix, Namespace};
|
||||
use {Namespace, Prefix};
|
||||
use context::QuirksMode;
|
||||
use cssparser::{Parser, RuleListParser, ParserInput};
|
||||
use error_reporting::{ParseErrorReporter, ContextualParseError};
|
||||
use cssparser::{Parser, ParserInput, RuleListParser};
|
||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||
use fallible::FallibleVec;
|
||||
use fnv::FnvHashMap;
|
||||
use invalidation::media_queries::{MediaListKey, ToMediaListKey};
|
||||
#[cfg(feature = "gecko")]
|
||||
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||
use media_queries::{MediaList, Device};
|
||||
use media_queries::{Device, MediaList};
|
||||
use parking_lot::RwLock;
|
||||
use parser::{ParserContext, ParserErrorContext};
|
||||
use servo_arc::Arc;
|
||||
|
@ -77,7 +77,7 @@ impl StylesheetContents {
|
|||
stylesheet_loader: Option<&StylesheetLoader>,
|
||||
error_reporter: &R,
|
||||
quirks_mode: QuirksMode,
|
||||
line_number_offset: u32
|
||||
line_number_offset: u32,
|
||||
) -> Self {
|
||||
let namespaces = RwLock::new(Namespaces::default());
|
||||
let (rules, source_map_url, source_url) = Stylesheet::parse_rules(
|
||||
|
@ -108,7 +108,7 @@ impl StylesheetContents {
|
|||
pub fn iter_rules<'a, 'b, C>(
|
||||
&'a self,
|
||||
device: &'a Device,
|
||||
guard: &'a SharedRwLockReadGuard<'b>
|
||||
guard: &'a SharedRwLockReadGuard<'b>,
|
||||
) -> RulesIterator<'a, 'b, C>
|
||||
where
|
||||
C: NestedRuleIterationCondition,
|
||||
|
@ -117,7 +117,7 @@ impl StylesheetContents {
|
|||
device,
|
||||
self.quirks_mode,
|
||||
guard,
|
||||
&self.rules.read_with(guard)
|
||||
&self.rules.read_with(guard),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -138,9 +138,9 @@ impl DeepCloneWithLock for StylesheetContents {
|
|||
params: &DeepCloneParams,
|
||||
) -> Self {
|
||||
// Make a deep clone of the rules, using the new lock.
|
||||
let rules =
|
||||
self.rules.read_with(guard)
|
||||
.deep_clone_with_lock(lock, guard, params);
|
||||
let rules = self.rules
|
||||
.read_with(guard)
|
||||
.deep_clone_with_lock(lock, guard, params);
|
||||
|
||||
Self {
|
||||
rules: Arc::new(lock.wrap(rules)),
|
||||
|
@ -206,11 +206,7 @@ pub trait StylesheetInDocument {
|
|||
fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList>;
|
||||
|
||||
/// Returns whether the style-sheet applies for the current device.
|
||||
fn is_effective_for_device(
|
||||
&self,
|
||||
device: &Device,
|
||||
guard: &SharedRwLockReadGuard
|
||||
) -> bool {
|
||||
fn is_effective_for_device(&self, device: &Device, guard: &SharedRwLockReadGuard) -> bool {
|
||||
match self.media(guard) {
|
||||
Some(medialist) => medialist.evaluate(device, self.quirks_mode(guard)),
|
||||
None => true,
|
||||
|
@ -225,7 +221,7 @@ pub trait StylesheetInDocument {
|
|||
fn iter_rules<'a, 'b, C>(
|
||||
&'a self,
|
||||
device: &'a Device,
|
||||
guard: &'a SharedRwLockReadGuard<'b>
|
||||
guard: &'a SharedRwLockReadGuard<'b>,
|
||||
) -> RulesIterator<'a, 'b, C>
|
||||
where
|
||||
C: NestedRuleIterationCondition,
|
||||
|
@ -239,7 +235,7 @@ pub trait StylesheetInDocument {
|
|||
fn effective_rules<'a, 'b>(
|
||||
&'a self,
|
||||
device: &'a Device,
|
||||
guard: &'a SharedRwLockReadGuard<'b>
|
||||
guard: &'a SharedRwLockReadGuard<'b>,
|
||||
) -> EffectiveRulesIterator<'a, 'b> {
|
||||
self.iter_rules::<EffectiveRules>(device, guard)
|
||||
}
|
||||
|
@ -277,8 +273,7 @@ impl StylesheetInDocument for Stylesheet {
|
|||
#[derive(Clone)]
|
||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
||||
pub struct DocumentStyleSheet(
|
||||
#[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")]
|
||||
pub Arc<Stylesheet>
|
||||
#[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] pub Arc<Stylesheet>,
|
||||
);
|
||||
|
||||
impl PartialEq for DocumentStyleSheet {
|
||||
|
@ -316,28 +311,26 @@ impl Stylesheet {
|
|||
stylesheet_loader: Option<&StylesheetLoader>,
|
||||
error_reporter: &R,
|
||||
line_number_offset: u32,
|
||||
)
|
||||
where
|
||||
) where
|
||||
R: ParseErrorReporter,
|
||||
{
|
||||
let namespaces = RwLock::new(Namespaces::default());
|
||||
let (rules, source_map_url, source_url) =
|
||||
Stylesheet::parse_rules(
|
||||
css,
|
||||
&url_data,
|
||||
existing.contents.origin,
|
||||
&mut *namespaces.write(),
|
||||
&existing.shared_lock,
|
||||
stylesheet_loader,
|
||||
error_reporter,
|
||||
existing.contents.quirks_mode,
|
||||
line_number_offset
|
||||
);
|
||||
let (rules, source_map_url, source_url) = Stylesheet::parse_rules(
|
||||
css,
|
||||
&url_data,
|
||||
existing.contents.origin,
|
||||
&mut *namespaces.write(),
|
||||
&existing.shared_lock,
|
||||
stylesheet_loader,
|
||||
error_reporter,
|
||||
existing.contents.quirks_mode,
|
||||
line_number_offset,
|
||||
);
|
||||
|
||||
*existing.contents.url_data.write() = url_data;
|
||||
mem::swap(
|
||||
&mut *existing.contents.namespaces.write(),
|
||||
&mut *namespaces.write()
|
||||
&mut *namespaces.write(),
|
||||
);
|
||||
|
||||
// Acquire the lock *after* parsing, to minimize the exclusive section.
|
||||
|
@ -356,19 +349,13 @@ impl Stylesheet {
|
|||
stylesheet_loader: Option<&StylesheetLoader>,
|
||||
error_reporter: &R,
|
||||
quirks_mode: QuirksMode,
|
||||
line_number_offset: u32
|
||||
line_number_offset: u32,
|
||||
) -> (Vec<CssRule>, Option<String>, Option<String>) {
|
||||
let mut rules = Vec::new();
|
||||
let mut input = ParserInput::new_with_line_number_offset(css, line_number_offset);
|
||||
let mut input = Parser::new(&mut input);
|
||||
|
||||
let context = ParserContext::new(
|
||||
origin,
|
||||
url_data,
|
||||
None,
|
||||
ParsingMode::DEFAULT,
|
||||
quirks_mode
|
||||
);
|
||||
let context = ParserContext::new(origin, url_data, None, ParsingMode::DEFAULT, quirks_mode);
|
||||
|
||||
let error_context = ParserErrorContext { error_reporter };
|
||||
|
||||
|
@ -384,8 +371,7 @@ impl Stylesheet {
|
|||
};
|
||||
|
||||
{
|
||||
let mut iter =
|
||||
RuleListParser::new_for_stylesheet(&mut input, rule_parser);
|
||||
let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
|
||||
|
||||
while let Some(result) = iter.next() {
|
||||
match result {
|
||||
|
@ -400,9 +386,12 @@ impl Stylesheet {
|
|||
Err((error, slice)) => {
|
||||
let location = error.location;
|
||||
let error = ContextualParseError::InvalidRule(slice, error);
|
||||
iter.parser.context.log_css_error(&iter.parser.error_context,
|
||||
location, error);
|
||||
}
|
||||
iter.parser.context.log_css_error(
|
||||
&iter.parser.error_context,
|
||||
location,
|
||||
error,
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -426,9 +415,8 @@ impl Stylesheet {
|
|||
stylesheet_loader: Option<&StylesheetLoader>,
|
||||
error_reporter: &R,
|
||||
quirks_mode: QuirksMode,
|
||||
line_number_offset: u32)
|
||||
-> Stylesheet
|
||||
{
|
||||
line_number_offset: u32,
|
||||
) -> Stylesheet {
|
||||
let contents = StylesheetContents::from_str(
|
||||
css,
|
||||
url_data,
|
||||
|
@ -437,7 +425,7 @@ impl Stylesheet {
|
|||
stylesheet_loader,
|
||||
error_reporter,
|
||||
quirks_mode,
|
||||
line_number_offset
|
||||
line_number_offset,
|
||||
);
|
||||
|
||||
Stylesheet {
|
||||
|
@ -476,11 +464,8 @@ impl Clone for Stylesheet {
|
|||
// Make a deep clone of the media, using the new lock.
|
||||
let media = self.media.read_with(&guard).clone();
|
||||
let media = Arc::new(lock.wrap(media));
|
||||
let contents = self.contents.deep_clone_with_lock(
|
||||
&lock,
|
||||
&guard,
|
||||
&DeepCloneParams
|
||||
);
|
||||
let contents = self.contents
|
||||
.deep_clone_with_lock(&lock, &guard, &DeepCloneParams);
|
||||
|
||||
Stylesheet {
|
||||
contents,
|
||||
|
@ -490,4 +475,3 @@ impl Clone for Stylesheet {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ use cssparser::parse_important;
|
|||
#[cfg(feature = "gecko")]
|
||||
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||
use parser::ParserContext;
|
||||
use properties::{PropertyId, PropertyDeclaration, SourcePropertyDeclaration};
|
||||
use properties::{PropertyDeclaration, PropertyId, SourcePropertyDeclaration};
|
||||
use selectors::parser::SelectorParseErrorKind;
|
||||
use servo_arc::Arc;
|
||||
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
|
||||
|
@ -111,33 +111,38 @@ impl SupportsCondition {
|
|||
let (keyword, wrapper) = match input.next() {
|
||||
Err(_) => {
|
||||
// End of input
|
||||
return Ok(in_parens)
|
||||
}
|
||||
return Ok(in_parens);
|
||||
},
|
||||
Ok(&Token::Ident(ref ident)) => {
|
||||
match_ignore_ascii_case! { &ident,
|
||||
"and" => ("and", SupportsCondition::And as fn(_) -> _),
|
||||
"or" => ("or", SupportsCondition::Or as fn(_) -> _),
|
||||
_ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
|
||||
}
|
||||
}
|
||||
Ok(t) => return Err(location.new_unexpected_token_error(t.clone()))
|
||||
},
|
||||
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||
};
|
||||
|
||||
let mut conditions = Vec::with_capacity(2);
|
||||
conditions.push(in_parens);
|
||||
loop {
|
||||
conditions.push(SupportsCondition::parse_in_parens(input)?);
|
||||
if input.try(|input| input.expect_ident_matching(keyword)).is_err() {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching(keyword))
|
||||
.is_err()
|
||||
{
|
||||
// Did not find the expected keyword.
|
||||
// If we found some other token,
|
||||
// it will be rejected by `Parser::parse_entirely` somewhere up the stack.
|
||||
return Ok(wrapper(conditions))
|
||||
return Ok(wrapper(conditions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-conditional-3/#supports_condition_in_parens>
|
||||
fn parse_in_parens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<SupportsCondition, ParseError<'i>> {
|
||||
fn parse_in_parens<'i, 't>(
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<SupportsCondition, ParseError<'i>> {
|
||||
// Whitespace is normally taken care of in `Parser::next`,
|
||||
// but we want to not include it in `pos` for the SupportsCondition::FutureSyntax cases.
|
||||
while input.try(Parser::expect_whitespace).is_ok() {}
|
||||
|
@ -146,13 +151,12 @@ impl SupportsCondition {
|
|||
// FIXME: remove clone() when lifetimes are non-lexical
|
||||
match input.next()?.clone() {
|
||||
Token::ParenthesisBlock => {
|
||||
let nested = input.try(|input| {
|
||||
input.parse_nested_block(|i| parse_condition_or_declaration(i))
|
||||
});
|
||||
let nested = input
|
||||
.try(|input| input.parse_nested_block(|i| parse_condition_or_declaration(i)));
|
||||
if nested.is_ok() {
|
||||
return nested;
|
||||
}
|
||||
}
|
||||
},
|
||||
Token::Function(ident) => {
|
||||
// Although this is an internal syntax, it is not necessary to check
|
||||
// parsing context as far as we accept any unexpected token as future
|
||||
|
@ -165,18 +169,19 @@ impl SupportsCondition {
|
|||
.map(|s| s.to_string())
|
||||
.map_err(CssParseError::<()>::from)
|
||||
}).and_then(|s| {
|
||||
CString::new(s)
|
||||
.map_err(|_| location.new_custom_error(()))
|
||||
})
|
||||
CString::new(s).map_err(|_| location.new_custom_error(()))
|
||||
})
|
||||
}) {
|
||||
return Ok(SupportsCondition::MozBoolPref(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
t => return Err(location.new_unexpected_token_error(t)),
|
||||
}
|
||||
input.parse_nested_block(|i| consume_any_value(i))?;
|
||||
Ok(SupportsCondition::FutureSyntax(input.slice_from(pos).to_owned()))
|
||||
Ok(SupportsCondition::FutureSyntax(
|
||||
input.slice_from(pos).to_owned(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Evaluate a supports condition
|
||||
|
@ -188,7 +193,7 @@ impl SupportsCondition {
|
|||
SupportsCondition::Or(ref vec) => vec.iter().any(|c| c.eval(cx)),
|
||||
SupportsCondition::Declaration(ref decl) => decl.eval(cx),
|
||||
SupportsCondition::MozBoolPref(ref name) => eval_moz_bool_pref(name, cx),
|
||||
SupportsCondition::FutureSyntax(_) => false
|
||||
SupportsCondition::FutureSyntax(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,8 +215,9 @@ fn eval_moz_bool_pref(_: &CStr, _: &ParserContext) -> bool {
|
|||
|
||||
/// supports_condition | declaration
|
||||
/// <https://drafts.csswg.org/css-conditional/#dom-css-supports-conditiontext-conditiontext>
|
||||
pub fn parse_condition_or_declaration<'i, 't>(input: &mut Parser<'i, 't>)
|
||||
-> Result<SupportsCondition, ParseError<'i>> {
|
||||
pub fn parse_condition_or_declaration<'i, 't>(
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<SupportsCondition, ParseError<'i>> {
|
||||
if let Ok(condition) = input.try(SupportsCondition::parse) {
|
||||
Ok(SupportsCondition::Parenthesized(Box::new(condition)))
|
||||
} else {
|
||||
|
@ -228,12 +234,12 @@ impl ToCss for SupportsCondition {
|
|||
SupportsCondition::Not(ref cond) => {
|
||||
dest.write_str("not ")?;
|
||||
cond.to_css(dest)
|
||||
}
|
||||
},
|
||||
SupportsCondition::Parenthesized(ref cond) => {
|
||||
dest.write_str("(")?;
|
||||
cond.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
}
|
||||
},
|
||||
SupportsCondition::And(ref vec) => {
|
||||
let mut first = true;
|
||||
for cond in vec {
|
||||
|
@ -244,7 +250,7 @@ impl ToCss for SupportsCondition {
|
|||
cond.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
SupportsCondition::Or(ref vec) => {
|
||||
let mut first = true;
|
||||
for cond in vec {
|
||||
|
@ -255,19 +261,19 @@ impl ToCss for SupportsCondition {
|
|||
cond.to_css(dest)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
SupportsCondition::Declaration(ref decl) => {
|
||||
dest.write_str("(")?;
|
||||
decl.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
}
|
||||
},
|
||||
SupportsCondition::MozBoolPref(ref name) => {
|
||||
dest.write_str("-moz-bool-pref(")?;
|
||||
let name = str::from_utf8(name.as_bytes())
|
||||
.expect("Should be parsed from valid UTF-8");
|
||||
let name =
|
||||
str::from_utf8(name.as_bytes()).expect("Should be parsed from valid UTF-8");
|
||||
name.to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
}
|
||||
},
|
||||
SupportsCondition::FutureSyntax(ref s) => dest.write_str(&s),
|
||||
}
|
||||
}
|
||||
|
@ -309,20 +315,21 @@ impl Declaration {
|
|||
|
||||
let mut input = ParserInput::new(&self.0);
|
||||
let mut input = Parser::new(&mut input);
|
||||
input.parse_entirely(|input| -> Result<(), CssParseError<()>> {
|
||||
let prop = input.expect_ident_cloned().unwrap();
|
||||
input.expect_colon().unwrap();
|
||||
input
|
||||
.parse_entirely(|input| -> Result<(), CssParseError<()>> {
|
||||
let prop = input.expect_ident_cloned().unwrap();
|
||||
input.expect_colon().unwrap();
|
||||
|
||||
let id = PropertyId::parse(&prop)
|
||||
.map_err(|_| input.new_custom_error(()))?;
|
||||
let id = PropertyId::parse(&prop).map_err(|_| input.new_custom_error(()))?;
|
||||
|
||||
let mut declarations = SourcePropertyDeclaration::new();
|
||||
input.parse_until_before(Delimiter::Bang, |input| {
|
||||
PropertyDeclaration::parse_into(&mut declarations, id, prop, &context, input)
|
||||
.map_err(|_| input.new_custom_error(()))
|
||||
})?;
|
||||
let _ = input.try(parse_important);
|
||||
Ok(())
|
||||
}).is_ok()
|
||||
let mut declarations = SourcePropertyDeclaration::new();
|
||||
input.parse_until_before(Delimiter::Bang, |input| {
|
||||
PropertyDeclaration::parse_into(&mut declarations, id, prop, &context, input)
|
||||
.map_err(|_| input.new_custom_error(()))
|
||||
})?;
|
||||
let _ = input.try(parse_important);
|
||||
Ok(())
|
||||
})
|
||||
.is_ok()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
use app_units::Au;
|
||||
use context::QuirksMode;
|
||||
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important};
|
||||
use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
|
||||
use cssparser::CowRcStr;
|
||||
use error_reporting::{ContextualParseError, ParseErrorReporter};
|
||||
use euclid::TypedSize2D;
|
||||
|
@ -28,15 +28,18 @@ use std::str::Chars;
|
|||
use str::CssStringWriter;
|
||||
use style_traits::{CssWriter, ParseError, PinchZoomFactor, StyleParseErrorKind, ToCss};
|
||||
use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom};
|
||||
use stylesheets::{StylesheetInDocument, Origin};
|
||||
use stylesheets::{Origin, StylesheetInDocument};
|
||||
use values::computed::{Context, ToComputedValue};
|
||||
use values::specified::{NoCalcLength, LengthOrPercentageOrAuto, ViewportPercentageLength};
|
||||
use values::specified::{LengthOrPercentageOrAuto, NoCalcLength, ViewportPercentageLength};
|
||||
|
||||
/// Whether parsing and processing of `@viewport` rules is enabled.
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn enabled() -> bool {
|
||||
use servo_config::prefs::PREFS;
|
||||
PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false)
|
||||
PREFS
|
||||
.get("layout.viewport.enabled")
|
||||
.as_boolean()
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Whether parsing and processing of `@viewport` rules is enabled.
|
||||
|
@ -147,7 +150,7 @@ trait FromMeta: Sized {
|
|||
#[derive(Clone, Debug, PartialEq, ToCss)]
|
||||
pub enum ViewportLength {
|
||||
Specified(LengthOrPercentageOrAuto),
|
||||
ExtendToZoom
|
||||
ExtendToZoom,
|
||||
}
|
||||
|
||||
impl FromMeta for ViewportLength {
|
||||
|
@ -155,28 +158,30 @@ impl FromMeta for ViewportLength {
|
|||
macro_rules! specified {
|
||||
($value:expr) => {
|
||||
ViewportLength::Specified(LengthOrPercentageOrAuto::Length($value))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Some(match value {
|
||||
v if v.eq_ignore_ascii_case("device-width") =>
|
||||
specified!(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(100.))),
|
||||
v if v.eq_ignore_ascii_case("device-height") =>
|
||||
specified!(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vh(100.))),
|
||||
_ => {
|
||||
match value.parse::<f32>() {
|
||||
Ok(n) if n >= 0. => specified!(NoCalcLength::from_px(n.max(1.).min(10000.))),
|
||||
Ok(_) => return None,
|
||||
Err(_) => specified!(NoCalcLength::from_px(1.))
|
||||
}
|
||||
}
|
||||
v if v.eq_ignore_ascii_case("device-width") => specified!(
|
||||
NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(100.))
|
||||
),
|
||||
v if v.eq_ignore_ascii_case("device-height") => specified!(
|
||||
NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vh(100.))
|
||||
),
|
||||
_ => match value.parse::<f32>() {
|
||||
Ok(n) if n >= 0. => specified!(NoCalcLength::from_px(n.max(1.).min(10000.))),
|
||||
Ok(_) => return None,
|
||||
Err(_) => specified!(NoCalcLength::from_px(1.)),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ViewportLength {
|
||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>> {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
// we explicitly do not accept 'extend-to-zoom', since it is a UA
|
||||
// internal value for <META> viewport translation
|
||||
LengthOrPercentageOrAuto::parse_non_negative(context, input).map(ViewportLength::Specified)
|
||||
|
@ -190,13 +195,11 @@ impl FromMeta for Zoom {
|
|||
v if v.eq_ignore_ascii_case("no") => Zoom::Number(0.1),
|
||||
v if v.eq_ignore_ascii_case("device-width") => Zoom::Number(10.),
|
||||
v if v.eq_ignore_ascii_case("device-height") => Zoom::Number(10.),
|
||||
_ => {
|
||||
match value.parse::<f32>() {
|
||||
Ok(n) if n >= 0. => Zoom::Number(n.max(0.1).min(10.)),
|
||||
Ok(_) => return None,
|
||||
Err(_) => Zoom::Number(0.1),
|
||||
}
|
||||
}
|
||||
_ => match value.parse::<f32>() {
|
||||
Ok(n) if n >= 0. => Zoom::Number(n.max(0.1).min(10.)),
|
||||
Ok(_) => return None,
|
||||
Err(_) => Zoom::Number(0.1),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -208,18 +211,16 @@ impl FromMeta for UserZoom {
|
|||
v if v.eq_ignore_ascii_case("no") => UserZoom::Fixed,
|
||||
v if v.eq_ignore_ascii_case("device-width") => UserZoom::Zoom,
|
||||
v if v.eq_ignore_ascii_case("device-height") => UserZoom::Zoom,
|
||||
_ => {
|
||||
match value.parse::<f32>() {
|
||||
Ok(n) if n >= 1. || n <= -1. => UserZoom::Zoom,
|
||||
_ => UserZoom::Fixed
|
||||
}
|
||||
}
|
||||
_ => match value.parse::<f32>() {
|
||||
Ok(n) if n >= 1. || n <= -1. => UserZoom::Zoom,
|
||||
_ => UserZoom::Fixed,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct ViewportRuleParser<'a, 'b: 'a> {
|
||||
context: &'a ParserContext<'b>
|
||||
context: &'a ParserContext<'b>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
|
@ -228,19 +229,20 @@ struct ViewportRuleParser<'a, 'b: 'a> {
|
|||
pub struct ViewportDescriptorDeclaration {
|
||||
pub origin: Origin,
|
||||
pub descriptor: ViewportDescriptor,
|
||||
pub important: bool
|
||||
pub important: bool,
|
||||
}
|
||||
|
||||
impl ViewportDescriptorDeclaration {
|
||||
#[allow(missing_docs)]
|
||||
pub fn new(origin: Origin,
|
||||
descriptor: ViewportDescriptor,
|
||||
important: bool) -> ViewportDescriptorDeclaration
|
||||
{
|
||||
pub fn new(
|
||||
origin: Origin,
|
||||
descriptor: ViewportDescriptor,
|
||||
important: bool,
|
||||
) -> ViewportDescriptorDeclaration {
|
||||
ViewportDescriptorDeclaration {
|
||||
origin: origin,
|
||||
descriptor: descriptor,
|
||||
important: important
|
||||
important: important,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,12 +260,14 @@ impl ToCss for ViewportDescriptorDeclaration {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_shorthand<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||
-> Result<(ViewportLength, ViewportLength), ParseError<'i>> {
|
||||
fn parse_shorthand<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<(ViewportLength, ViewportLength), ParseError<'i>> {
|
||||
let min = ViewportLength::parse(context, input)?;
|
||||
match input.try(|i| ViewportLength::parse(context, i)) {
|
||||
Err(_) => Ok((min.clone(), min)),
|
||||
Ok(max) => Ok((min, max))
|
||||
Ok(max) => Ok((min, max)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,8 +282,11 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
|
|||
type Declaration = Vec<ViewportDescriptorDeclaration>;
|
||||
type Error = StyleParseErrorKind<'i>;
|
||||
|
||||
fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>)
|
||||
-> Result<Vec<ViewportDescriptorDeclaration>, ParseError<'i>> {
|
||||
fn parse_value<'t>(
|
||||
&mut self,
|
||||
name: CowRcStr<'i>,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Vec<ViewportDescriptorDeclaration>, ParseError<'i>> {
|
||||
macro_rules! declaration {
|
||||
($declaration:ident($parse:expr)) => {
|
||||
declaration!($declaration(value: try!($parse(input)),
|
||||
|
@ -301,9 +308,11 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
|
|||
let shorthand = parse_shorthand(self.context, input)?;
|
||||
let important = input.try(parse_important).is_ok();
|
||||
|
||||
Ok(vec![declaration!($min(value: shorthand.0, important: important)),
|
||||
declaration!($max(value: shorthand.1, important: important))])
|
||||
}}
|
||||
Ok(vec![
|
||||
declaration!($min(value: shorthand.0, important: important)),
|
||||
declaration!($max(value: shorthand.1, important: important)),
|
||||
])
|
||||
}};
|
||||
}
|
||||
|
||||
match_ignore_ascii_case! { &*name,
|
||||
|
@ -328,7 +337,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
|
|||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
||||
pub struct ViewportRule {
|
||||
/// The declarations contained in this @viewport rule.
|
||||
pub declarations: Vec<ViewportDescriptorDeclaration>
|
||||
pub declarations: Vec<ViewportDescriptorDeclaration>,
|
||||
}
|
||||
|
||||
/// Whitespace as defined by DEVICE-ADAPT § 9.2
|
||||
|
@ -346,11 +355,13 @@ fn is_whitespace_separator_or_equals(c: &char) -> bool {
|
|||
|
||||
impl ViewportRule {
|
||||
/// Parse a single @viewport rule.
|
||||
pub fn parse<'i, 't, R>(context: &ParserContext,
|
||||
error_context: &ParserErrorContext<R>,
|
||||
input: &mut Parser<'i, 't>)
|
||||
-> Result<Self, ParseError<'i>>
|
||||
where R: ParseErrorReporter
|
||||
pub fn parse<'i, 't, R>(
|
||||
context: &ParserContext,
|
||||
error_context: &ParserErrorContext<R>,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>>
|
||||
where
|
||||
R: ParseErrorReporter,
|
||||
{
|
||||
let parser = ViewportRuleParser { context: context };
|
||||
|
||||
|
@ -362,15 +373,20 @@ impl ViewportRule {
|
|||
for declarations in declarations {
|
||||
cascade.add(Cow::Owned(declarations))
|
||||
}
|
||||
}
|
||||
},
|
||||
Err((error, slice)) => {
|
||||
let location = error.location;
|
||||
let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(slice, error);
|
||||
let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(
|
||||
slice,
|
||||
error,
|
||||
);
|
||||
context.log_css_error(error_context, location, error);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(ViewportRule { declarations: cascade.finish() })
|
||||
Ok(ViewportRule {
|
||||
declarations: cascade.finish(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,9 +401,10 @@ impl ViewportRule {
|
|||
declarations[discriminant] = Some(ViewportDescriptorDeclaration::new(
|
||||
Origin::Author,
|
||||
descriptor,
|
||||
false));
|
||||
}
|
||||
}}
|
||||
false,
|
||||
));
|
||||
}};
|
||||
}
|
||||
|
||||
let mut has_width = false;
|
||||
let mut has_height = false;
|
||||
|
@ -397,16 +414,15 @@ impl ViewportRule {
|
|||
|
||||
macro_rules! start_of_name {
|
||||
($iter:ident) => {
|
||||
$iter.by_ref()
|
||||
$iter
|
||||
.by_ref()
|
||||
.skip_while(|&(_, c)| is_whitespace_separator_or_equals(&c))
|
||||
.next()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
while let Some((start, _)) = start_of_name!(iter) {
|
||||
let property = ViewportRule::parse_meta_property(content,
|
||||
&mut iter,
|
||||
start);
|
||||
let property = ViewportRule::parse_meta_property(content, &mut iter, start);
|
||||
|
||||
if let Some((name, value)) = property {
|
||||
macro_rules! push {
|
||||
|
@ -414,7 +430,7 @@ impl ViewportRule {
|
|||
if let Some(value) = $translate(value) {
|
||||
push_descriptor!($descriptor(value));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
match name {
|
||||
|
@ -424,27 +440,26 @@ impl ViewportRule {
|
|||
push_descriptor!(MaxWidth(value));
|
||||
has_width = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
n if n.eq_ignore_ascii_case("height") => {
|
||||
if let Some(value) = ViewportLength::from_meta(value) {
|
||||
push_descriptor!(MinHeight(ViewportLength::ExtendToZoom));
|
||||
push_descriptor!(MaxHeight(value));
|
||||
has_height = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
n if n.eq_ignore_ascii_case("initial-scale") => {
|
||||
if let Some(value) = Zoom::from_meta(value) {
|
||||
push_descriptor!(Zoom(value));
|
||||
has_zoom = true;
|
||||
}
|
||||
}
|
||||
n if n.eq_ignore_ascii_case("minimum-scale") =>
|
||||
push!(MinZoom(Zoom::from_meta)),
|
||||
n if n.eq_ignore_ascii_case("maximum-scale") =>
|
||||
push!(MaxZoom(Zoom::from_meta)),
|
||||
n if n.eq_ignore_ascii_case("user-scalable") =>
|
||||
push!(UserZoom(UserZoom::from_meta)),
|
||||
_ => {}
|
||||
},
|
||||
n if n.eq_ignore_ascii_case("minimum-scale") => push!(MinZoom(Zoom::from_meta)),
|
||||
n if n.eq_ignore_ascii_case("maximum-scale") => push!(MaxZoom(Zoom::from_meta)),
|
||||
n if n.eq_ignore_ascii_case("user-scalable") => {
|
||||
push!(UserZoom(UserZoom::from_meta))
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -453,8 +468,12 @@ impl ViewportRule {
|
|||
// http://dev.w3.org/csswg/css-device-adapt/#width-and-height-properties
|
||||
if !has_width && has_zoom {
|
||||
if has_height {
|
||||
push_descriptor!(MinWidth(ViewportLength::Specified(LengthOrPercentageOrAuto::Auto)));
|
||||
push_descriptor!(MaxWidth(ViewportLength::Specified(LengthOrPercentageOrAuto::Auto)));
|
||||
push_descriptor!(MinWidth(ViewportLength::Specified(
|
||||
LengthOrPercentageOrAuto::Auto
|
||||
)));
|
||||
push_descriptor!(MaxWidth(ViewportLength::Specified(
|
||||
LengthOrPercentageOrAuto::Auto
|
||||
)));
|
||||
} else {
|
||||
push_descriptor!(MinWidth(ViewportLength::ExtendToZoom));
|
||||
push_descriptor!(MaxWidth(ViewportLength::ExtendToZoom));
|
||||
|
@ -463,17 +482,19 @@ impl ViewportRule {
|
|||
|
||||
let declarations: Vec<_> = declarations.into_iter().filter_map(|entry| entry).collect();
|
||||
if !declarations.is_empty() {
|
||||
Some(ViewportRule { declarations: declarations })
|
||||
Some(ViewportRule {
|
||||
declarations: declarations,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_meta_property<'a>(content: &'a str,
|
||||
iter: &mut Enumerate<Chars<'a>>,
|
||||
start: usize)
|
||||
-> Option<(&'a str, &'a str)>
|
||||
{
|
||||
fn parse_meta_property<'a>(
|
||||
content: &'a str,
|
||||
iter: &mut Enumerate<Chars<'a>>,
|
||||
start: usize,
|
||||
) -> Option<(&'a str, &'a str)> {
|
||||
fn end_of_token(iter: &mut Enumerate<Chars>) -> Option<(usize, char)> {
|
||||
iter.by_ref()
|
||||
.skip_while(|&(_, c)| !is_whitespace_separator_or_equals(&c))
|
||||
|
@ -488,25 +509,23 @@ impl ViewportRule {
|
|||
|
||||
// <name> <whitespace>* '='
|
||||
let end = match end_of_token(iter) {
|
||||
Some((end, c)) if WHITESPACE.contains(&c) => {
|
||||
match skip_whitespace(iter) {
|
||||
Some((_, c)) if c == '=' => end,
|
||||
_ => return None
|
||||
}
|
||||
}
|
||||
Some((end, c)) if WHITESPACE.contains(&c) => match skip_whitespace(iter) {
|
||||
Some((_, c)) if c == '=' => end,
|
||||
_ => return None,
|
||||
},
|
||||
Some((end, c)) if c == '=' => end,
|
||||
_ => return None
|
||||
_ => return None,
|
||||
};
|
||||
let name = &content[start..end];
|
||||
|
||||
// <whitespace>* <value>
|
||||
let start = match skip_whitespace(iter) {
|
||||
Some((start, c)) if !SEPARATOR.contains(&c) => start,
|
||||
_ => return None
|
||||
_ => return None,
|
||||
};
|
||||
let value = match end_of_token(iter) {
|
||||
Some((end, _)) => &content[start..end],
|
||||
_ => &content[start..]
|
||||
_ => &content[start..],
|
||||
};
|
||||
|
||||
Some((name, value))
|
||||
|
@ -567,7 +586,7 @@ impl Cascade {
|
|||
pub fn from_stylesheets<'a, I, S>(
|
||||
stylesheets: I,
|
||||
guards: &StylesheetGuards,
|
||||
device: &Device
|
||||
device: &Device,
|
||||
) -> Self
|
||||
where
|
||||
I: Iterator<Item = (&'a S, Origin)>,
|
||||
|
@ -584,7 +603,7 @@ impl Cascade {
|
|||
cascade
|
||||
}
|
||||
|
||||
pub fn add(&mut self, declaration: Cow<ViewportDescriptorDeclaration>) {
|
||||
pub fn add(&mut self, declaration: Cow<ViewportDescriptorDeclaration>) {
|
||||
let descriptor = declaration.descriptor.discriminant_value();
|
||||
|
||||
match self.declarations[descriptor] {
|
||||
|
@ -593,18 +612,22 @@ impl Cascade {
|
|||
*entry_declaration = declaration.into_owned();
|
||||
*order_of_appearance = self.count_so_far;
|
||||
}
|
||||
}
|
||||
},
|
||||
ref mut entry @ None => {
|
||||
*entry = Some((self.count_so_far, declaration.into_owned()));
|
||||
}
|
||||
},
|
||||
}
|
||||
self.count_so_far += 1;
|
||||
}
|
||||
|
||||
pub fn finish(mut self) -> Vec<ViewportDescriptorDeclaration> {
|
||||
// sort the descriptors by order of appearance
|
||||
self.declarations.sort_by_key(|entry| entry.as_ref().map(|&(index, _)| index));
|
||||
self.declarations.into_iter().filter_map(|entry| entry.map(|(_, decl)| decl)).collect()
|
||||
self.declarations
|
||||
.sort_by_key(|entry| entry.as_ref().map(|&(index, _)| index));
|
||||
self.declarations
|
||||
.into_iter()
|
||||
.filter_map(|entry| entry.map(|(_, decl)| decl))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,22 +635,23 @@ impl Cascade {
|
|||
pub trait MaybeNew {
|
||||
/// Create a ViewportConstraints from a viewport size and a `@viewport`
|
||||
/// rule.
|
||||
fn maybe_new(device: &Device,
|
||||
rule: &ViewportRule,
|
||||
quirks_mode: QuirksMode)
|
||||
-> Option<ViewportConstraints>;
|
||||
fn maybe_new(
|
||||
device: &Device,
|
||||
rule: &ViewportRule,
|
||||
quirks_mode: QuirksMode,
|
||||
) -> Option<ViewportConstraints>;
|
||||
}
|
||||
|
||||
impl MaybeNew for ViewportConstraints {
|
||||
fn maybe_new(device: &Device,
|
||||
rule: &ViewportRule,
|
||||
quirks_mode: QuirksMode)
|
||||
-> Option<ViewportConstraints>
|
||||
{
|
||||
fn maybe_new(
|
||||
device: &Device,
|
||||
rule: &ViewportRule,
|
||||
quirks_mode: QuirksMode,
|
||||
) -> Option<ViewportConstraints> {
|
||||
use std::cmp;
|
||||
|
||||
if rule.declarations.is_empty() {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut min_width = None;
|
||||
|
@ -657,7 +681,7 @@ impl MaybeNew for ViewportConstraints {
|
|||
ViewportDescriptor::MaxZoom(value) => max_zoom = value.to_f32(),
|
||||
|
||||
ViewportDescriptor::UserZoom(value) => user_zoom = value,
|
||||
ViewportDescriptor::Orientation(value) => orientation = value
|
||||
ViewportDescriptor::Orientation(value) => orientation = value,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -671,17 +695,17 @@ impl MaybeNew for ViewportConstraints {
|
|||
(None, b) => b,
|
||||
(Some(a), Some(b)) => Some(a.$op(b)),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! min {
|
||||
($opta:expr, $optb:expr) => {
|
||||
choose!(min, $opta, $optb)
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! max {
|
||||
($opta:expr, $optb:expr) => {
|
||||
choose!(max, $opta, $optb)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// DEVICE-ADAPT § 6.2.1 Resolve min-zoom and max-zoom values
|
||||
|
@ -731,14 +755,16 @@ impl MaybeNew for ViewportConstraints {
|
|||
if let Some($value) = $value {
|
||||
match *$value {
|
||||
ViewportLength::Specified(ref length) => match *length {
|
||||
LengthOrPercentageOrAuto::Length(ref value) =>
|
||||
Some(Au::from(value.to_computed_value(&context))),
|
||||
LengthOrPercentageOrAuto::Percentage(value) =>
|
||||
Some(initial_viewport.$dimension.scale_by(value.0)),
|
||||
LengthOrPercentageOrAuto::Length(ref value) => {
|
||||
Some(Au::from(value.to_computed_value(&context)))
|
||||
},
|
||||
LengthOrPercentageOrAuto::Percentage(value) => {
|
||||
Some(initial_viewport.$dimension.scale_by(value.0))
|
||||
},
|
||||
LengthOrPercentageOrAuto::Auto => None,
|
||||
LengthOrPercentageOrAuto::Calc(ref calc) => {
|
||||
calc.to_computed_value(&context).to_used_value(Some(initial_viewport.$dimension))
|
||||
}
|
||||
LengthOrPercentageOrAuto::Calc(ref calc) => calc.to_computed_value(
|
||||
&context,
|
||||
).to_used_value(Some(initial_viewport.$dimension)),
|
||||
},
|
||||
ViewportLength::ExtendToZoom => {
|
||||
// $extend_to will be 'None' if 'extend-to-zoom' is 'auto'
|
||||
|
@ -746,14 +772,14 @@ impl MaybeNew for ViewportConstraints {
|
|||
(None, None) => None,
|
||||
(a, None) => a,
|
||||
(None, b) => b,
|
||||
(a, b) => cmp::max(a, b)
|
||||
(a, b) => cmp::max(a, b),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// DEVICE-ADAPT § 9.3 states that max-descriptors need to be resolved
|
||||
|
@ -771,17 +797,17 @@ impl MaybeNew for ViewportConstraints {
|
|||
if $min.is_some() || $max.is_some() {
|
||||
let max = match $max {
|
||||
Some(max) => cmp::min(max, $initial),
|
||||
None => $initial
|
||||
None => $initial,
|
||||
};
|
||||
|
||||
Some(match $min {
|
||||
Some(min) => cmp::max(min, max),
|
||||
None => max
|
||||
None => max,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let width = resolve!(min_width, max_width, initial_viewport.width);
|
||||
|
@ -789,7 +815,7 @@ impl MaybeNew for ViewportConstraints {
|
|||
|
||||
// DEVICE-ADAPT § 6.2.5 Resolve width value
|
||||
let width = if width.is_none() && height.is_none() {
|
||||
Some(initial_viewport.width)
|
||||
Some(initial_viewport.width)
|
||||
} else {
|
||||
width
|
||||
};
|
||||
|
@ -799,7 +825,7 @@ impl MaybeNew for ViewportConstraints {
|
|||
initial_height => {
|
||||
let ratio = initial_viewport.width.to_f32_px() / initial_height.to_f32_px();
|
||||
Au::from_f32_px(height.unwrap().to_f32_px() * ratio)
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// DEVICE-ADAPT § 6.2.6 Resolve height value
|
||||
|
@ -808,7 +834,7 @@ impl MaybeNew for ViewportConstraints {
|
|||
initial_width => {
|
||||
let ratio = initial_viewport.height.to_f32_px() / initial_width.to_f32_px();
|
||||
Au::from_f32_px(width.to_f32_px() * ratio)
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Some(ViewportConstraints {
|
||||
|
@ -820,7 +846,7 @@ impl MaybeNew for ViewportConstraints {
|
|||
max_zoom: max_zoom.map(PinchZoomFactor::new),
|
||||
|
||||
user_zoom: user_zoom,
|
||||
orientation: orientation
|
||||
orientation: orientation,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue