style: More cleanups around length parsing and viewport rule parsing.

This commit is contained in:
Emilio Cobos Álvarez 2017-04-06 14:18:41 +02:00
parent 705ecb4557
commit 846c950b6b
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
6 changed files with 72 additions and 101 deletions

View file

@ -483,36 +483,23 @@ ${helpers.single_keyword("background-origin",
} }
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> { pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
let width; if input.try(|input| input.expect_ident_matching("cover")).is_ok() {
if let Ok(value) = input.try(|input| { return Ok(SpecifiedValue::Cover);
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))
} }
let height; if input.try(|input| input.expect_ident_matching("contain")).is_ok() {
if let Ok(value) = input.try(|input| { return Ok(SpecifiedValue::Contain);
match input.next() {
Err(_) => Ok(specified::LengthOrPercentageOrAuto::Auto),
Ok(_) => Err(()),
}
}) {
height = value
} else {
height = try!(specified::LengthOrPercentageOrAuto::parse_non_negative(input));
} }
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 { Ok(SpecifiedValue::Explicit(ExplicitSize {
width: width, width: width,
height: height, height: height,

View file

@ -142,7 +142,8 @@ ${helpers.predefined_type("flex-basis",
"LengthOrPercentageOrAutoOrContent", "LengthOrPercentageOrAutoOrContent",
"computed::LengthOrPercentageOrAuto::Auto" if product == "gecko" else "computed::LengthOrPercentageOrAuto::Auto" if product == "gecko" else
"computed::LengthOrPercentageOrAutoOrContent::Auto", "computed::LengthOrPercentageOrAutoOrContent::Auto",
"parse_non_negative_with_context", "parse_non_negative",
needs_context=False,
spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property", spec="https://drafts.csswg.org/css-flexbox/#flex-basis-property",
extra_prefixes="webkit", extra_prefixes="webkit",
animatable=True if product == "gecko" else False)} animatable=True if product == "gecko" else False)}

View file

@ -48,13 +48,7 @@
<%helpers:shorthand name="flex" sub_properties="flex-grow flex-shrink flex-basis" extra_prefixes="webkit" <%helpers:shorthand name="flex" sub_properties="flex-grow flex-shrink flex-basis" extra_prefixes="webkit"
spec="https://drafts.csswg.org/css-flexbox/#flex-property"> spec="https://drafts.csswg.org/css-flexbox/#flex-property">
use parser::Parse; use values::specified::Number;
use values::specified::{Number, NoCalcLength};
% if product == "gecko":
use values::specified::LengthOrPercentageOrAuto;
% else:
use values::specified::LengthOrPercentageOrAutoOrContent;
% endif
fn parse_flexibility(input: &mut Parser) fn parse_flexibility(input: &mut Parser)
-> Result<(Number, Option<Number>),()> { -> Result<(Number, Option<Number>),()> {
@ -72,12 +66,7 @@
return Ok(Longhands { return Ok(Longhands {
flex_grow: Number::new(0.0), flex_grow: Number::new(0.0),
flex_shrink: Number::new(0.0), flex_shrink: Number::new(0.0),
% if product == "gecko": flex_basis: longhands::flex_basis::SpecifiedValue::auto(),
flex_basis: LengthOrPercentageOrAuto::Auto
% else:
flex_basis: LengthOrPercentageOrAutoOrContent::Auto
% endif
}) })
} }
loop { loop {
@ -89,11 +78,7 @@
} }
} }
if basis.is_none() { if basis.is_none() {
% if product == "gecko": if let Ok(value) = input.try(|input| longhands::flex_basis::parse(context, input)) {
if let Ok(value) = input.try(|i| LengthOrPercentageOrAuto::parse(context, i)) {
% else:
if let Ok(value) = input.try(|i| LengthOrPercentageOrAutoOrContent::parse(context, i)) {
% endif
basis = Some(value); basis = Some(value);
continue continue
} }
@ -107,21 +92,17 @@
Ok(Longhands { Ok(Longhands {
flex_grow: grow.unwrap_or(Number::new(1.0)), flex_grow: grow.unwrap_or(Number::new(1.0)),
flex_shrink: shrink.unwrap_or(Number::new(1.0)), flex_shrink: shrink.unwrap_or(Number::new(1.0)),
% if product == "gecko": flex_basis: basis.unwrap_or(longhands::flex_basis::SpecifiedValue::zero()),
flex_basis: basis.unwrap_or(LengthOrPercentageOrAuto::Length(NoCalcLength::zero()))
% else:
flex_basis: basis.unwrap_or(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero()))
% endif
}) })
} }
impl<'a> ToCss for LonghandsToSerialize<'a> { impl<'a> ToCss for LonghandsToSerialize<'a> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(self.flex_grow.to_css(dest)); try!(self.flex_grow.to_css(dest));
try!(write!(dest, " ")); try!(dest.write_str(" "));
try!(self.flex_shrink.to_css(dest)); try!(self.flex_shrink.to_css(dest));
try!(write!(dest, " ")); try!(dest.write_str(" "));
self.flex_basis.to_css(dest) self.flex_basis.to_css(dest)
} }

View file

@ -23,7 +23,7 @@ use gecko_bindings::sugar::refptr::RefPtr;
use keyframes::{Keyframe, parse_keyframe_list}; use keyframes::{Keyframe, parse_keyframe_list};
use media_queries::{Device, MediaList, parse_media_query_list}; use media_queries::{Device, MediaList, parse_media_query_list};
use parking_lot::RwLock; 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 properties::{PropertyDeclarationBlock, parse_property_declaration_list};
use selector_parser::{SelectorImpl, SelectorParser}; use selector_parser::{SelectorImpl, SelectorParser};
use selectors::parser::SelectorList; use selectors::parser::SelectorList;
@ -1059,7 +1059,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
} }
AtRulePrelude::Viewport => { AtRulePrelude::Viewport => {
Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap( Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap(
try!(ViewportRule::parse(input, self.context)))))) try!(ViewportRule::parse(self.context, input))))))
} }
AtRulePrelude::Keyframes(name) => { AtRulePrelude::Keyframes(name) => {
Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule { Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap(KeyframesRule {

View file

@ -1150,15 +1150,14 @@ impl ToCss for LengthOrPercentageOrAuto {
impl LengthOrPercentageOrAuto { impl LengthOrPercentageOrAuto {
fn parse_internal(input: &mut Parser, context: AllowedNumericType) fn parse_internal(input: &mut Parser, context: AllowedNumericType)
-> Result<LengthOrPercentageOrAuto, ()> -> Result<Self, ()> {
{
match try!(input.next()) { match try!(input.next()) {
Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAuto::Length), NoCalcLength::parse_dimension(value.value, unit).map(LengthOrPercentageOrAuto::Length),
Token::Percentage(ref value) if context.is_ok(value.unit_value) => Token::Percentage(ref value) if context.is_ok(value.unit_value) =>
Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))), Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))),
Token::Number(ref value) if value.value == 0. => 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") => Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") =>
Ok(LengthOrPercentageOrAuto::Auto), Ok(LengthOrPercentageOrAuto::Auto),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
@ -1175,12 +1174,14 @@ impl LengthOrPercentageOrAuto {
Self::parse_internal(input, AllowedNumericType::NonNegative) Self::parse_internal(input, AllowedNumericType::NonNegative)
} }
/// Parse a non-negative length, percentage, or auto. /// Returns the `auto` value.
#[inline] pub fn auto() -> Self {
pub fn parse_non_negative_with_context(_context: &ParserContext, LengthOrPercentageOrAuto::Auto
input: &mut Parser) }
-> Result<LengthOrPercentageOrAuto, ()> {
LengthOrPercentageOrAuto::parse_non_negative(input) /// Returns a value representing a `0` length.
pub fn zero() -> Self {
LengthOrPercentageOrAuto::Length(NoCalcLength::zero())
} }
} }
@ -1286,12 +1287,36 @@ pub enum LengthOrPercentageOrAutoOrContent {
} }
impl LengthOrPercentageOrAutoOrContent { impl LengthOrPercentageOrAutoOrContent {
/// Alias to `parse` so that Gecko and Servo can use the same method name for /// Parse a non-negative LengthOrPercentageOrAutoOrContent.
/// both `LengthOrPercentageOrAuto` and `LengthOrPercentageOrAutoOrContent`. pub fn parse_non_negative(input: &mut Parser) -> Result<Self, ()> {
/// let context = AllowedNumericType::NonNegative;
/// NOTE: `parse` already only accepts non-negative values. match try!(input.next()) {
pub fn parse_non_negative_with_context(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { Token::Dimension(ref value, ref unit) if context.is_ok(value.value) =>
Self::parse(context, input) 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<Self, ()> {
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 `<length>` or a `<number>`. /// Either a `<length>` or a `<number>`.
pub type LengthOrNumber = Either<Length, Number>; pub type LengthOrNumber = Either<Length, Number>;

View file

@ -14,7 +14,7 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser,
use cssparser::ToCss as ParserToCss; use cssparser::ToCss as ParserToCss;
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
use media_queries::Device; use media_queries::Device;
use parser::{ParserContext, log_css_error}; use parser::{Parse, ParserContext, log_css_error};
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::Cow; use std::borrow::Cow;
@ -165,9 +165,9 @@ impl FromMeta for ViewportLength {
} }
impl ViewportLength { impl ViewportLength {
fn parse(input: &mut Parser) -> Result<ViewportLength, ()> { fn parse(input: &mut Parser) -> Result<Self, ()> {
// we explicitly do not accept 'extend-to-zoom', since it is a UA internal value // we explicitly do not accept 'extend-to-zoom', since it is a UA
// for <META> viewport translation // internal value for <META> viewport translation
LengthOrPercentageOrAuto::parse_non_negative(input).map(ViewportLength::Specified) 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), ()> { fn parse_shorthand(input: &mut Parser) -> Result<(ViewportLength, ViewportLength), ()> {
let min = try!(ViewportLength::parse(input)); let min = try!(ViewportLength::parse(input));
match input.try(|input| ViewportLength::parse(input)) { match input.try(ViewportLength::parse) {
Err(()) => Ok((min.clone(), min)), Err(()) => Ok((min.clone(), min)),
Ok(max) => Ok((min, max)) 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 == '=' WHITESPACE.contains(c) || SEPARATOR.contains(c) || *c == '='
} }
impl ViewportRule { impl Parse for ViewportRule {
#[allow(missing_docs)] #[allow(missing_docs)]
pub fn parse(input: &mut Parser, context: &ParserContext) fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
-> Result<ViewportRule, ()>
{
let parser = ViewportRuleParser { context: context }; let parser = ViewportRuleParser { context: context };
let mut cascade = Cascade::new(); let mut cascade = Cascade::new();
@ -351,7 +349,9 @@ impl ViewportRule {
} }
Ok(ViewportRule { declarations: cascade.finish() }) Ok(ViewportRule { declarations: cascade.finish() })
} }
}
impl ViewportRule {
#[allow(missing_docs)] #[allow(missing_docs)]
pub fn from_meta(content: &str) -> Option<ViewportRule> { pub fn from_meta(content: &str) -> Option<ViewportRule> {
let mut declarations = vec![None; VIEWPORT_DESCRIPTOR_VARIANTS]; let mut declarations = vec![None; VIEWPORT_DESCRIPTOR_VARIANTS];