diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 66db18d6447..b053be48fbd 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -483,36 +483,23 @@ ${helpers.single_keyword("background-origin", } pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - let width; - if let Ok(value) = input.try(|input| { - match input.next() { - Err(_) => Err(()), - Ok(Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("cover") => { - Ok(SpecifiedValue::Cover) - } - Ok(Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("contain") => { - Ok(SpecifiedValue::Contain) - } - Ok(_) => Err(()), - } - }) { - return Ok(value) - } else { - width = try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input)) + if input.try(|input| input.expect_ident_matching("cover")).is_ok() { + return Ok(SpecifiedValue::Cover); } - let height; - if let Ok(value) = input.try(|input| { - match input.next() { - Err(_) => Ok(specified::LengthOrPercentageOrAuto::Auto), - Ok(_) => Err(()), - } - }) { - height = value - } else { - height = try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input)); + if input.try(|input| input.expect_ident_matching("contain")).is_ok() { + return Ok(SpecifiedValue::Contain); } + let width = + try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input)); + + let height = if input.is_exhausted() { + specified::LengthOrPercentageOrAuto::Auto + } else { + try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input)) + }; + Ok(SpecifiedValue::Explicit(ExplicitSize { width: width, height: height, diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index c4a03e15deb..a5df58b28af 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -142,7 +142,8 @@ ${helpers.predefined_type("flex-basis", "LengthOrPercentageOrAutoOrContent", "computed::LengthOrPercentageOrAuto::Auto" if product == "gecko" else "computed::LengthOrPercentageOrAutoOrContent::Auto", - "parse_non_negative_with_context", + "parse_non_negative", + needs_context=False, spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property", extra_prefixes="webkit", animatable=True if product == "gecko" else False)} diff --git a/components/style/properties/shorthand/position.mako.rs b/components/style/properties/shorthand/position.mako.rs index 3a777365687..3d4009d750f 100644 --- a/components/style/properties/shorthand/position.mako.rs +++ b/components/style/properties/shorthand/position.mako.rs @@ -48,13 +48,7 @@ <%helpers:shorthand name="flex" sub_properties="flex-grow flex-shrink flex-basis" extra_prefixes="webkit" spec="https://drafts.csswg.org/css-flexbox/#flex-property"> - use parser::Parse; - use values::specified::{Number, NoCalcLength}; - % if product == "gecko": - use values::specified::LengthOrPercentageOrAuto; - % else: - use values::specified::LengthOrPercentageOrAutoOrContent; - % endif + use values::specified::Number; fn parse_flexibility(input: &mut Parser) -> Result<(Number, Option),()> { @@ -72,12 +66,7 @@ return Ok(Longhands { flex_grow: Number::new(0.0), flex_shrink: Number::new(0.0), - % if product == "gecko": - flex_basis: LengthOrPercentageOrAuto::Auto - % else: - flex_basis: LengthOrPercentageOrAutoOrContent::Auto - % endif - + flex_basis: longhands::flex_basis::SpecifiedValue::auto(), }) } loop { @@ -89,11 +78,7 @@ } } if basis.is_none() { - % if product == "gecko": - if let Ok(value) = input.try(|i| LengthOrPercentageOrAuto::parse(context, i)) { - % else: - if let Ok(value) = input.try(|i| LengthOrPercentageOrAutoOrContent::parse(context, i)) { - % endif + if let Ok(value) = input.try(|input| longhands::flex_basis::parse(context, input)) { basis = Some(value); continue } @@ -107,21 +92,17 @@ Ok(Longhands { flex_grow: grow.unwrap_or(Number::new(1.0)), flex_shrink: shrink.unwrap_or(Number::new(1.0)), - % if product == "gecko": - flex_basis: basis.unwrap_or(LengthOrPercentageOrAuto::Length(NoCalcLength::zero())) - % else: - flex_basis: basis.unwrap_or(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero())) - % endif + flex_basis: basis.unwrap_or(longhands::flex_basis::SpecifiedValue::zero()), }) } impl<'a> ToCss for LonghandsToSerialize<'a> { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { try!(self.flex_grow.to_css(dest)); - try!(write!(dest, " ")); + try!(dest.write_str(" ")); try!(self.flex_shrink.to_css(dest)); - try!(write!(dest, " ")); + try!(dest.write_str(" ")); self.flex_basis.to_css(dest) } diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index f59aceb9e61..865b2fb4b75 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -23,7 +23,7 @@ use gecko_bindings::sugar::refptr::RefPtr; use keyframes::{Keyframe, parse_keyframe_list}; use media_queries::{Device, MediaList, parse_media_query_list}; use parking_lot::RwLock; -use parser::{ParserContext, log_css_error}; +use parser::{Parse, ParserContext, log_css_error}; use properties::{PropertyDeclarationBlock, parse_property_declaration_list}; use selector_parser::{SelectorImpl, SelectorParser}; use selectors::parser::SelectorList; @@ -1059,7 +1059,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> { } AtRulePrelude::Viewport => { Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap( - try!(ViewportRule::parse(input, self.context)))))) + try!(ViewportRule::parse(self.context, input)))))) } AtRulePrelude::Keyframes(name) => { Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule { diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index f647eafef9c..5e96e0e40f6 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -1150,15 +1150,14 @@ impl ToCss for LengthOrPercentageOrAuto { impl LengthOrPercentageOrAuto { fn parse_internal(input: &mut Parser, context: AllowedNumericType) - -> Result - { + -> Result { match try!(input.next()) { Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAuto::Length), Token::Percentage(ref value) if context.is_ok(value.unit_value) => Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))), Token::Number(ref value) if value.value == 0. => - Ok(LengthOrPercentageOrAuto::Length(NoCalcLength::zero())), + Ok(Self::zero()), Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => Ok(LengthOrPercentageOrAuto::Auto), Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { @@ -1175,12 +1174,14 @@ impl LengthOrPercentageOrAuto { Self::parse_internal(input, AllowedNumericType::NonNegative) } - /// Parse a non-negative length, percentage, or auto. - #[inline] - pub fn parse_non_negative_with_context(_context: &ParserContext, - input: &mut Parser) - -> Result { - LengthOrPercentageOrAuto::parse_non_negative(input) + /// Returns the `auto` value. + pub fn auto() -> Self { + LengthOrPercentageOrAuto::Auto + } + + /// Returns a value representing a `0` length. + pub fn zero() -> Self { + LengthOrPercentageOrAuto::Length(NoCalcLength::zero()) } } @@ -1286,12 +1287,36 @@ pub enum LengthOrPercentageOrAutoOrContent { } impl LengthOrPercentageOrAutoOrContent { - /// Alias to `parse` so that Gecko and Servo can use the same method name for - /// both `LengthOrPercentageOrAuto` and `LengthOrPercentageOrAutoOrContent`. - /// - /// NOTE: `parse` already only accepts non-negative values. - pub fn parse_non_negative_with_context(context: &ParserContext, input: &mut Parser) -> Result { - Self::parse(context, input) + /// Parse a non-negative LengthOrPercentageOrAutoOrContent. + pub fn parse_non_negative(input: &mut Parser) -> Result { + let context = AllowedNumericType::NonNegative; + match try!(input.next()) { + Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => + NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAutoOrContent::Length), + Token::Percentage(ref value) if context.is_ok(value.unit_value) => + Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))), + Token::Number(ref value) if value.value == 0. => + Ok(Self::zero()), + Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => + Ok(LengthOrPercentageOrAutoOrContent::Auto), + Token::Ident(ref value) if value.eq_ignore_ascii_case("content") => + Ok(LengthOrPercentageOrAutoOrContent::Content), + Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { + let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage)); + Ok(LengthOrPercentageOrAutoOrContent::Calc(Box::new(calc))) + }, + _ => Err(()) + } + } + + /// Returns the `auto` value. + pub fn auto() -> Self { + LengthOrPercentageOrAutoOrContent::Auto + } + + /// Returns a value representing a `0` length. + pub fn zero() -> Self { + LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero()) } } @@ -1317,29 +1342,6 @@ impl ToCss for LengthOrPercentageOrAutoOrContent { } } -impl Parse for LengthOrPercentageOrAutoOrContent { - fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - let context = AllowedNumericType::NonNegative; - match try!(input.next()) { - Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => - NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAutoOrContent::Length), - Token::Percentage(ref value) if context.is_ok(value.unit_value) => - Ok(LengthOrPercentageOrAutoOrContent::Percentage(Percentage(value.unit_value))), - Token::Number(ref value) if value.value == 0. => - Ok(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero())), - Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => - Ok(LengthOrPercentageOrAutoOrContent::Auto), - Token::Ident(ref value) if value.eq_ignore_ascii_case("content") => - Ok(LengthOrPercentageOrAutoOrContent::Content), - Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { - let calc = try!(input.parse_nested_block(CalcLengthOrPercentage::parse_length_or_percentage)); - Ok(LengthOrPercentageOrAutoOrContent::Calc(Box::new(calc))) - }, - _ => Err(()) - } - } -} - /// Either a `` or a ``. pub type LengthOrNumber = Either; diff --git a/components/style/viewport.rs b/components/style/viewport.rs index 2ddced848bb..d2d2af77480 100644 --- a/components/style/viewport.rs +++ b/components/style/viewport.rs @@ -14,7 +14,7 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, use cssparser::ToCss as ParserToCss; use euclid::size::TypedSize2D; use media_queries::Device; -use parser::{ParserContext, log_css_error}; +use parser::{Parse, ParserContext, log_css_error}; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::ascii::AsciiExt; use std::borrow::Cow; @@ -165,9 +165,9 @@ impl FromMeta for ViewportLength { } impl ViewportLength { - fn parse(input: &mut Parser) -> Result { - // we explicitly do not accept 'extend-to-zoom', since it is a UA internal value - // for viewport translation + fn parse(input: &mut Parser) -> Result { + // we explicitly do not accept 'extend-to-zoom', since it is a UA + // internal value for viewport translation LengthOrPercentageOrAuto::parse_non_negative(input).map(ViewportLength::Specified) } } @@ -246,7 +246,7 @@ impl ToCss for ViewportDescriptorDeclaration { fn parse_shorthand(input: &mut Parser) -> Result<(ViewportLength, ViewportLength), ()> { let min = try!(ViewportLength::parse(input)); - match input.try(|input| ViewportLength::parse(input)) { + match input.try(ViewportLength::parse) { Err(()) => Ok((min.clone(), min)), Ok(max) => Ok((min, max)) } @@ -325,11 +325,9 @@ fn is_whitespace_separator_or_equals(c: &char) -> bool { WHITESPACE.contains(c) || SEPARATOR.contains(c) || *c == '=' } -impl ViewportRule { +impl Parse for ViewportRule { #[allow(missing_docs)] - pub fn parse(input: &mut Parser, context: &ParserContext) - -> Result - { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { let parser = ViewportRuleParser { context: context }; let mut cascade = Cascade::new(); @@ -351,7 +349,9 @@ impl ViewportRule { } Ok(ViewportRule { declarations: cascade.finish() }) } +} +impl ViewportRule { #[allow(missing_docs)] pub fn from_meta(content: &str) -> Option { let mut declarations = vec![None; VIEWPORT_DESCRIPTOR_VARIANTS];