Refactor content property parsing.

It wasn’t wrong, but it could be a lot shorter.

* Use try! and match_ignore_ascii_case! macros whenever possible
* Use expect_comma() instead of parse_comma_separated() when comma-separated values don’t have the same syntax
* Prefer Parser::expect_* methods over doing the same with Parser::next
* Take advantage of parse_nested_block returnin the return value of the closure
* Use try! more.
This commit is contained in:
Simon Sapin 2015-02-25 15:51:23 +01:00
parent 30fd28d107
commit 50800940dc

View file

@ -691,7 +691,6 @@ pub mod longhands {
<%self:longhand name="content"> <%self:longhand name="content">
use cssparser::{ToCss, Token}; use cssparser::{ToCss, Token};
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
use super::list_style_type; use super::list_style_type;
@ -801,116 +800,35 @@ pub mod longhands {
content.push(ContentItem::String(value.into_owned())) content.push(ContentItem::String(value.into_owned()))
} }
Ok(Token::Function(name)) => { Ok(Token::Function(name)) => {
if name.eq_ignore_ascii_case("counter") { content.push(try!(match_ignore_ascii_case! { name,
let (mut counter_name, mut counter_style) = (None, None); "counter" => input.parse_nested_block(|input| {
match input.parse_nested_block(|input| { let name = try!(input.expect_ident()).into_owned();
input.parse_comma_separated(|input| { let style = input.try(|input| {
if counter_name.is_none() { try!(input.expect_comma());
match input.next() {
Ok(Token::Ident(value)) => {
counter_name = Some((*value).to_owned());
Ok(())
}
_ => Err(())
}
} else if counter_style.is_none() {
match list_style_type::parse(context, input) {
Ok(style) => {
counter_style = Some(style);
Ok(())
}
_ => Err(())
}
} else {
Err(())
}
})
}) {
Ok(_) => {
match (counter_name, counter_style) {
(Some(name), Some(style)) => {
content.push(ContentItem::Counter(name, style))
}
(Some(name), None) => {
content.push(ContentItem::Counter(
name,
list_style_type::computed_value::T::decimal))
}
_ => return Err(()),
}
}
Err(_) => return Err(()),
}
} else if name.eq_ignore_ascii_case("counters") {
let mut counter_name = None;
let mut counter_separator = None;
let mut counter_style = None;
match input.parse_nested_block(|input| {
input.parse_comma_separated(|input| {
if counter_name.is_none() {
match input.next() {
Ok(Token::Ident(value)) => {
counter_name = Some((*value).to_owned());
Ok(())
}
_ => Err(())
}
} else if counter_separator.is_none() {
match input.next() {
Ok(Token::QuotedString(value)) => {
counter_separator = Some((*value).to_owned());
Ok(())
}
_ => Err(())
}
} else if counter_style.is_none() {
match input.try(|input| {
list_style_type::parse(context, input) list_style_type::parse(context, input)
}) { }).unwrap_or(list_style_type::computed_value::T::decimal);
Ok(style) => { Ok(ContentItem::Counter(name, style))
counter_style = Some(style); }),
Ok(()) "counters" => input.parse_nested_block(|input| {
} let name = try!(input.expect_ident()).into_owned();
_ => Err(()), try!(input.expect_comma());
} let separator = try!(input.expect_string()).into_owned();
} else { let style = input.try(|input| {
Err(()) try!(input.expect_comma());
} list_style_type::parse(context, input)
}).unwrap_or(list_style_type::computed_value::T::decimal);
Ok(ContentItem::Counters(name, separator, style))
}) })
}) { _ => return Err(())
Ok(_) => { }));
match (counter_name, counter_separator, counter_style) {
(Some(name), Some(separator), Some(style)) => {
content.push(ContentItem::Counters(name,
separator,
style))
}
(Some(name), Some(separator), None) => {
content.push(ContentItem::Counters(
name,
separator,
list_style_type::computed_value::T::decimal))
}
_ => return Err(()),
}
}
Err(_) => return Err(()),
}
} else {
return Err(())
}
} }
Ok(Token::Ident(ident)) => { Ok(Token::Ident(ident)) => {
if ident.eq_ignore_ascii_case("open-quote") { match_ignore_ascii_case! { ident,
content.push(ContentItem::OpenQuote) "open-quote" => content.push(ContentItem::OpenQuote),
} else if ident.eq_ignore_ascii_case("close-quote") { "close-quote" => content.push(ContentItem::CloseQuote),
content.push(ContentItem::CloseQuote) "no-open-quote" => content.push(ContentItem::NoOpenQuote),
} else if ident.eq_ignore_ascii_case("no-open-quote") { "no-close-quote" => content.push(ContentItem::NoCloseQuote)
content.push(ContentItem::NoOpenQuote) _ => return Err(())
} else if ident.eq_ignore_ascii_case("no-close-quote") {
content.push(ContentItem::NoCloseQuote)
} else {
return Err(())
} }
} }
Err(()) if !content.is_empty() => { Err(()) if !content.is_empty() => {