From f0120bad7b744d8408e6b361c6ee371cf7c2d649 Mon Sep 17 00:00:00 2001 From: Ravi Shankar Date: Sat, 26 Nov 2016 19:20:10 -0800 Subject: [PATCH] servo: Merge #14373 - Use the ParserContext along with the Parser (from Wafflespeanut:parse); r=emilio This changes the `parse` function's signature to include `ParserContext`, so that we don't introduce another trait just for the sake of the context. Instead, we can safely ignore the context whenever we don't need it. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes do not require tests because it's a refactor r? @SimonSapin or @emilio or @Manishearth Source-Repo: https://github.com/servo/servo Source-Revision: 4755cb7586ab4a89f35bbccf8b57c85ed2f428e7 --- servo/components/style/custom_properties.rs | 4 +- servo/components/style/parser.rs | 4 +- .../style/properties/helpers.mako.rs | 16 ++- .../properties/longhand/background.mako.rs | 10 +- .../style/properties/longhand/border.mako.rs | 23 ++-- .../style/properties/longhand/box.mako.rs | 86 ++++++------- .../style/properties/longhand/color.mako.rs | 4 +- .../style/properties/longhand/column.mako.rs | 4 +- .../style/properties/longhand/effects.mako.rs | 49 ++++---- .../style/properties/longhand/font.mako.rs | 8 +- .../properties/longhand/inherited_svg.mako.rs | 1 + .../longhand/inherited_text.mako.rs | 20 ++- .../style/properties/longhand/list.mako.rs | 1 - .../style/properties/longhand/outline.mako.rs | 2 +- .../style/properties/longhand/padding.mako.rs | 1 + .../properties/longhand/pointing.mako.rs | 8 +- .../properties/longhand/position.mako.rs | 5 + .../style/properties/longhand/text.mako.rs | 8 +- .../style/properties/longhand/xul.mako.rs | 1 + .../style/properties/properties.mako.rs | 17 +-- .../style/properties/shorthand/border.mako.rs | 17 +-- .../style/properties/shorthand/box.mako.rs | 40 +++--- .../properties/shorthand/outline.mako.rs | 2 +- .../properties/shorthand/position.mako.rs | 4 +- servo/components/style/values/mod.rs | 10 +- .../style/values/specified/basic_shape.rs | 114 +++++++++--------- .../style/values/specified/image.rs | 82 +++++++------ .../style/values/specified/length.rs | 16 +-- .../components/style/values/specified/mod.rs | 30 ++--- .../style/values/specified/position.rs | 16 +-- servo/tests/unit/style/parsing/basic_shape.rs | 9 +- servo/tests/unit/style/parsing/mod.rs | 30 ++--- servo/tests/unit/style/parsing/position.rs | 57 ++++----- servo/tests/unit/style/parsing/selectors.rs | 12 +- 34 files changed, 369 insertions(+), 342 deletions(-) diff --git a/servo/components/style/custom_properties.rs b/servo/components/style/custom_properties.rs index 0e8877814043..f9d3c77b1c40 100644 --- a/servo/components/style/custom_properties.rs +++ b/servo/components/style/custom_properties.rs @@ -8,7 +8,7 @@ use Atom; use cssparser::{Delimiter, Parser, SourcePosition, Token, TokenSerializationType}; -use parser::Parse; +use parser::{Parse, ParserContext}; use properties::DeclaredValue; use std::ascii::AsciiExt; use std::borrow::Cow; @@ -113,7 +113,7 @@ impl ComputedValue { } impl Parse for SpecifiedValue { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { let mut references = Some(HashSet::new()); let (first, css, last) = try!(parse_self_contained_declaration_value(input, &mut references)); Ok(SpecifiedValue { diff --git a/servo/components/style/parser.rs b/servo/components/style/parser.rs index c847e082acef..0295607805a0 100644 --- a/servo/components/style/parser.rs +++ b/servo/components/style/parser.rs @@ -69,8 +69,6 @@ pub fn log_css_error(input: &mut Parser, position: SourcePosition, message: &str // XXXManishearth Replace all specified value parse impls with impls of this // trait. This will make it easy to write more generic values in the future. -// There may need to be two traits -- one for parsing with context, and one -// for parsing without pub trait Parse { - fn parse(input: &mut Parser) -> Result where Self: Sized; + fn parse(context: &ParserContext, input: &mut Parser) -> Result where Self: Sized; } diff --git a/servo/components/style/properties/helpers.mako.rs b/servo/components/style/properties/helpers.mako.rs index 88c53eb9c2f5..274dc35c9982 100644 --- a/servo/components/style/properties/helpers.mako.rs +++ b/servo/components/style/properties/helpers.mako.rs @@ -16,7 +16,7 @@ -<%def name="predefined_type(name, type, initial_value, parse_method='parse', needs_context=False, **kwargs)"> +<%def name="predefined_type(name, type, initial_value, parse_method='parse', needs_context=True, **kwargs)"> <%call expr="longhand(name, predefined_type=type, **kwargs)"> #[allow(unused_imports)] use app_units::Au; @@ -283,7 +283,7 @@ % if not property.derived_from: pub fn parse_declared(context: &ParserContext, input: &mut Parser) -> Result, ()> { - match input.try(CSSWideKeyword::parse) { + match input.try(|i| CSSWideKeyword::parse(context, i)) { Ok(CSSWideKeyword::InheritKeyword) => Ok(DeclaredValue::Inherit), Ok(CSSWideKeyword::InitialKeyword) => Ok(DeclaredValue::Initial), Ok(CSSWideKeyword::UnsetKeyword) => Ok(DeclaredValue::${ @@ -515,7 +515,7 @@ % endif -<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function)"> +<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function, needs_context=True)"> <%self:shorthand name="${name}" sub_properties="${ ' '.join(sub_property_pattern % side for side in ['top', 'right', 'bottom', 'left'])}"> @@ -524,8 +524,14 @@ use super::parse_four_sides; use values::specified; - pub fn parse_value(_: &ParserContext, input: &mut Parser) -> Result { - let (top, right, bottom, left) = try!(parse_four_sides(input, ${parser_function})); + pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { + let (top, right, bottom, left) = + % if needs_context: + try!(parse_four_sides(input, |i| ${parser_function}(context, i))); + % else: + try!(parse_four_sides(input, ${parser_function})); + let _unused = context; + % endif Ok(Longhands { % for side in ["top", "right", "bottom", "left"]: ${to_rust_ident(sub_property_pattern % side)}: Some(${side}), diff --git a/servo/components/style/properties/longhand/background.mako.rs b/servo/components/style/properties/longhand/background.mako.rs index cb814a0adea5..4b2c073fb6c9 100644 --- a/servo/components/style/properties/longhand/background.mako.rs +++ b/servo/components/style/properties/longhand/background.mako.rs @@ -120,9 +120,9 @@ ${helpers.predefined_type("background-color", "CSSColor", } } - pub fn parse(_context: &ParserContext, input: &mut Parser) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { - Ok(try!(Position::parse(input))) + Ok(try!(Position::parse(context, input))) } @@ -302,7 +302,7 @@ ${helpers.single_keyword("background-origin", }) } - pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { let width; if let Ok(value) = input.try(|input| { match input.next() { @@ -318,7 +318,7 @@ ${helpers.single_keyword("background-origin", }) { return Ok(value) } else { - width = try!(specified::LengthOrPercentageOrAuto::parse(input)) + width = try!(specified::LengthOrPercentageOrAuto::parse(context, input)) } let height; @@ -330,7 +330,7 @@ ${helpers.single_keyword("background-origin", }) { height = value } else { - height = try!(specified::LengthOrPercentageOrAuto::parse(input)); + height = try!(specified::LengthOrPercentageOrAuto::parse(context, input)); } Ok(SpecifiedValue::Explicit(ExplicitSize { diff --git a/servo/components/style/properties/longhand/border.mako.rs b/servo/components/style/properties/longhand/border.mako.rs index 07fe93b9e756..c4ccfeb032fb 100644 --- a/servo/components/style/properties/longhand/border.mako.rs +++ b/servo/components/style/properties/longhand/border.mako.rs @@ -18,7 +18,8 @@ % for side in ALL_SIDES: ${helpers.predefined_type("border-%s-style" % side[0], "BorderStyle", "specified::BorderStyle::none", - need_clone=True, animatable=False, logical = side[1])} + needs_context=False, need_clone=True, + animatable=False, logical = side[1])} % endfor % for side in ALL_SIDES: @@ -32,9 +33,9 @@ pub type SpecifiedValue = BorderWidth; #[inline] - pub fn parse(_context: &ParserContext, input: &mut Parser) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { - BorderWidth::parse(input) + BorderWidth::parse(context, input) } pub mod computed_value { @@ -503,12 +504,12 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } impl Parse for SingleSpecifiedValue { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { if input.try(|input| input.expect_ident_matching("auto")).is_ok() { return Ok(SingleSpecifiedValue::Auto); } - if let Ok(len) = input.try(|input| LengthOrPercentage::parse(input)) { + if let Ok(len) = input.try(|input| LengthOrPercentage::parse(context, input)) { return Ok(SingleSpecifiedValue::LengthOrPercentage(len)); } @@ -517,10 +518,10 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { let mut values = vec![]; for _ in 0..4 { - let value = input.try(|input| SingleSpecifiedValue::parse(input)); + let value = input.try(|input| SingleSpecifiedValue::parse(context, input)); match value { Ok(val) => values.push(val), Err(_) => break, @@ -709,8 +710,8 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } impl Parse for PercentageOrNumber { - fn parse(input: &mut Parser) -> Result { - if let Ok(per) = input.try(|input| Percentage::parse(input)) { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + if let Ok(per) = input.try(|input| Percentage::parse(context, input)) { return Ok(PercentageOrNumber::Percentage(per)); } @@ -719,12 +720,12 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { let mut fill = input.try(|input| input.expect_ident_matching("fill")).is_ok(); let mut values = vec![]; for _ in 0..4 { - let value = input.try(|input| PercentageOrNumber::parse(input)); + let value = input.try(|input| PercentageOrNumber::parse(context, input)); match value { Ok(val) => values.push(val), Err(_) => break, diff --git a/servo/components/style/properties/longhand/box.mako.rs b/servo/components/style/properties/longhand/box.mako.rs index bce137f70eaa..39f859f2e65a 100644 --- a/servo/components/style/properties/longhand/box.mako.rs +++ b/servo/components/style/properties/longhand/box.mako.rs @@ -183,8 +183,8 @@ ${helpers.single_keyword("clear", "none left right both", } /// baseline | sub | super | top | text-top | middle | bottom | text-bottom /// | | - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - input.try(specified::LengthOrPercentage::parse) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + input.try(|i| specified::LengthOrPercentage::parse(context, i)) .map(SpecifiedValue::LengthOrPercentage) .or_else(|()| { match_ignore_ascii_case! { try!(input.expect_ident()), @@ -359,8 +359,8 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", computed_value::T(vec![get_initial_single_value()]) } - pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { - Ok(SpecifiedValue(try!(input.parse_comma_separated(Time::parse)))) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + Ok(SpecifiedValue(try!(input.parse_comma_separated(|i| Time::parse(context, i))))) } @@ -416,7 +416,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", pub mod computed_value { use euclid::point::Point2D; - use parser::Parse; + use parser::{Parse, ParserContext}; use std::fmt; use style_traits::ToCss; use values::specified; @@ -432,7 +432,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", } impl Parse for TransitionTimingFunction { - fn parse(input: &mut ::cssparser::Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result { if let Ok(function_name) = input.try(|input| input.expect_function()) { return match_ignore_ascii_case! { function_name, "cubic-bezier" => { @@ -559,8 +559,10 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", computed_value::T(vec![get_initial_single_value()]) } - pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { - Ok(SpecifiedValue(try!(input.parse_comma_separated(TransitionTimingFunction::parse)))) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + Ok(SpecifiedValue(try!(input.parse_comma_separated(|i| { + TransitionTimingFunction::parse(context, i) + })))) } @@ -606,7 +608,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", computed_value::T(Vec::new()) } - pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { Ok(SpecifiedValue(try!(input.parse_comma_separated(SingleSpecifiedValue::parse)))) } @@ -633,7 +635,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", pub mod computed_value { use Atom; - use parser::Parse; + use parser::{Parse, ParserContext}; use std::fmt; use std::ops::Deref; use style_traits::ToCss; @@ -651,7 +653,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", pub use self::AnimationName as SingleComputedValue; impl Parse for AnimationName { - fn parse(input: &mut ::cssparser::Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result { use cssparser::Token; Ok(match input.next() { Ok(Token::Ident(ref value)) if value != "none" => AnimationName(Atom::from(&**value)), @@ -692,9 +694,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", computed_value::T(vec![]) } - pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { use std::borrow::Cow; - Ok(SpecifiedValue(try!(input.parse_comma_separated(SingleSpecifiedValue::parse)))) + Ok(SpecifiedValue(try!(input.parse_comma_separated(|i| SingleSpecifiedValue::parse(context, i))))) } impl ComputedValueAsSpecified for SpecifiedValue {} @@ -728,7 +730,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", use values::NoViewportPercentage; pub mod computed_value { - use parser::Parse; + use parser::{Parse, ParserContext}; use std::fmt; use style_traits::ToCss; @@ -742,7 +744,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", } impl Parse for AnimationIterationCount { - fn parse(input: &mut ::cssparser::Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result { if input.try(|input| input.expect_ident_matching("infinite")).is_ok() { return Ok(AnimationIterationCount::Infinite) } @@ -796,8 +798,10 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", } #[inline] - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - Ok(SpecifiedValue(try!(input.parse_comma_separated(AnimationIterationCount::parse)))) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + Ok(SpecifiedValue(try!(input.parse_comma_separated(|i| { + AnimationIterationCount::parse(context, i) + })))) } #[inline] @@ -997,13 +1001,13 @@ ${helpers.single_keyword("animation-fill-mode", pub use self::computed_value::ComputedMatrix as SpecifiedMatrix; - fn parse_two_lengths_or_percentages(input: &mut Parser) + fn parse_two_lengths_or_percentages(context: &ParserContext, input: &mut Parser) -> Result<(specified::LengthOrPercentage, specified::LengthOrPercentage),()> { - let first = try!(specified::LengthOrPercentage::parse(input)); + let first = try!(specified::LengthOrPercentage::parse(context, input)); let second = input.try(|input| { try!(input.expect_comma()); - specified::LengthOrPercentage::parse(input) + specified::LengthOrPercentage::parse(context, input) }).unwrap_or(specified::LengthOrPercentage::zero()); Ok((first, second)) } @@ -1017,11 +1021,12 @@ ${helpers.single_keyword("animation-fill-mode", Ok((first, second)) } - fn parse_two_angles(input: &mut Parser) -> Result<(specified::Angle, specified::Angle),()> { - let first = try!(specified::Angle::parse(input)); + fn parse_two_angles(context: &ParserContext, input: &mut Parser) + -> Result<(specified::Angle, specified::Angle),()> { + let first = try!(specified::Angle::parse(context, input)); let second = input.try(|input| { try!(input.expect_comma()); - specified::Angle::parse(input) + specified::Angle::parse(context, input) }).unwrap_or(specified::Angle(0.0)); Ok((first, second)) } @@ -1160,7 +1165,7 @@ ${helpers.single_keyword("animation-fill-mode", computed_value::T(None) } - pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { if input.try(|input| input.expect_ident_matching("none")).is_ok() { return Ok(SpecifiedValue(Vec::new())) } @@ -1211,7 +1216,7 @@ ${helpers.single_keyword("animation-fill-mode", }, "translate" => { try!(input.parse_nested_block(|input| { - let (tx, ty) = try!(parse_two_lengths_or_percentages(input)); + let (tx, ty) = try!(parse_two_lengths_or_percentages(context, input)); result.push(SpecifiedOperation::Translate(TranslateKind::Translate, tx, ty, @@ -1221,7 +1226,7 @@ ${helpers.single_keyword("animation-fill-mode", }, "translatex" => { try!(input.parse_nested_block(|input| { - let tx = try!(specified::LengthOrPercentage::parse(input)); + let tx = try!(specified::LengthOrPercentage::parse(context, input)); result.push(SpecifiedOperation::Translate( TranslateKind::TranslateX, tx, @@ -1232,7 +1237,7 @@ ${helpers.single_keyword("animation-fill-mode", }, "translatey" => { try!(input.parse_nested_block(|input| { - let ty = try!(specified::LengthOrPercentage::parse(input)); + let ty = try!(specified::LengthOrPercentage::parse(context, input)); result.push(SpecifiedOperation::Translate( TranslateKind::TranslateY, specified::LengthOrPercentage::zero(), @@ -1243,7 +1248,7 @@ ${helpers.single_keyword("animation-fill-mode", }, "translatez" => { try!(input.parse_nested_block(|input| { - let tz = try!(specified::Length::parse(input)); + let tz = try!(specified::Length::parse(context, input)); result.push(SpecifiedOperation::Translate( TranslateKind::TranslateZ, specified::LengthOrPercentage::zero(), @@ -1254,11 +1259,11 @@ ${helpers.single_keyword("animation-fill-mode", }, "translate3d" => { try!(input.parse_nested_block(|input| { - let tx = try!(specified::LengthOrPercentage::parse(input)); + let tx = try!(specified::LengthOrPercentage::parse(context, input)); try!(input.expect_comma()); - let ty = try!(specified::LengthOrPercentage::parse(input)); + let ty = try!(specified::LengthOrPercentage::parse(context, input)); try!(input.expect_comma()); - let tz = try!(specified::Length::parse(input)); + let tz = try!(specified::Length::parse(context, input)); result.push(SpecifiedOperation::Translate( TranslateKind::Translate3D, tx, @@ -1309,28 +1314,28 @@ ${helpers.single_keyword("animation-fill-mode", }, "rotate" => { try!(input.parse_nested_block(|input| { - let theta = try!(specified::Angle::parse(input)); + let theta = try!(specified::Angle::parse(context,input)); result.push(SpecifiedOperation::Rotate(0.0, 0.0, 1.0, theta)); Ok(()) })) }, "rotatex" => { try!(input.parse_nested_block(|input| { - let theta = try!(specified::Angle::parse(input)); + let theta = try!(specified::Angle::parse(context,input)); result.push(SpecifiedOperation::Rotate(1.0, 0.0, 0.0, theta)); Ok(()) })) }, "rotatey" => { try!(input.parse_nested_block(|input| { - let theta = try!(specified::Angle::parse(input)); + let theta = try!(specified::Angle::parse(context,input)); result.push(SpecifiedOperation::Rotate(0.0, 1.0, 0.0, theta)); Ok(()) })) }, "rotatez" => { try!(input.parse_nested_block(|input| { - let theta = try!(specified::Angle::parse(input)); + let theta = try!(specified::Angle::parse(context,input)); result.push(SpecifiedOperation::Rotate(0.0, 0.0, 1.0, theta)); Ok(()) })) @@ -1343,7 +1348,7 @@ ${helpers.single_keyword("animation-fill-mode", try!(input.expect_comma()); let az = try!(specified::parse_number(input)); try!(input.expect_comma()); - let theta = try!(specified::Angle::parse(input)); + let theta = try!(specified::Angle::parse(context,input)); // TODO(gw): Check the axis can be normalized!! result.push(SpecifiedOperation::Rotate(ax, ay, az, theta)); Ok(()) @@ -1351,28 +1356,28 @@ ${helpers.single_keyword("animation-fill-mode", }, "skew" => { try!(input.parse_nested_block(|input| { - let (theta_x, theta_y) = try!(parse_two_angles(input)); + let (theta_x, theta_y) = try!(parse_two_angles(context, input)); result.push(SpecifiedOperation::Skew(theta_x, theta_y)); Ok(()) })) }, "skewx" => { try!(input.parse_nested_block(|input| { - let theta_x = try!(specified::Angle::parse(input)); + let theta_x = try!(specified::Angle::parse(context,input)); result.push(SpecifiedOperation::Skew(theta_x, specified::Angle(0.0))); Ok(()) })) }, "skewy" => { try!(input.parse_nested_block(|input| { - let theta_y = try!(specified::Angle::parse(input)); + let theta_y = try!(specified::Angle::parse(context,input)); result.push(SpecifiedOperation::Skew(specified::Angle(0.0), theta_y)); Ok(()) })) }, "perspective" => { try!(input.parse_nested_block(|input| { - let d = try!(specified::Length::parse(input)); + let d = try!(specified::Length::parse(context, input)); result.push(SpecifiedOperation::Perspective(d)); Ok(()) })) @@ -1547,7 +1552,6 @@ ${helpers.single_keyword("-moz-appearance", // Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding ${helpers.predefined_type("-moz-binding", "UrlOrNone", "computed_value::T::None", - needs_context=True, products="gecko", animatable="False", disable_when_testing="True")} diff --git a/servo/components/style/properties/longhand/color.mako.rs b/servo/components/style/properties/longhand/color.mako.rs index a3bde89e1882..38c8e79f5ab4 100644 --- a/servo/components/style/properties/longhand/color.mako.rs +++ b/servo/components/style/properties/longhand/color.mako.rs @@ -37,9 +37,9 @@ pub fn get_initial_value() -> computed_value::T { RGBA { red: 0., green: 0., blue: 0., alpha: 1. } /* black */ } - pub fn parse_specified(_context: &ParserContext, input: &mut Parser) + pub fn parse_specified(context: &ParserContext, input: &mut Parser) -> Result, ()> { - let value = try!(CSSColor::parse(input)); + let value = try!(CSSColor::parse(context, input)); let rgba = match value.parsed { CSSParserColor::RGBA(rgba) => rgba, CSSParserColor::CurrentColor => return Ok(DeclaredValue::Inherit) diff --git a/servo/components/style/properties/longhand/column.mako.rs b/servo/components/style/properties/longhand/column.mako.rs index 3df4d8e25269..4db1b5126baf 100644 --- a/servo/components/style/properties/longhand/column.mako.rs +++ b/servo/components/style/properties/longhand/column.mako.rs @@ -273,8 +273,8 @@ ${helpers.single_keyword("column-fill", "auto balance", Au::from_px(3) // medium } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - BorderWidth::parse(input) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + BorderWidth::parse(context, input) } diff --git a/servo/components/style/properties/longhand/effects.mako.rs b/servo/components/style/properties/longhand/effects.mako.rs index 7e79546f8519..2ce79bea20c4 100644 --- a/servo/components/style/properties/longhand/effects.mako.rs +++ b/servo/components/style/properties/longhand/effects.mako.rs @@ -125,7 +125,7 @@ ${helpers.predefined_type("opacity", } } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { use app_units::Au; let mut lengths = [specified::Length::Absolute(Au(0)); 4]; let mut lengths_parsed = false; @@ -140,11 +140,11 @@ ${helpers.predefined_type("opacity", } } if !lengths_parsed { - if let Ok(value) = input.try(specified::Length::parse) { + if let Ok(value) = input.try(|i| specified::Length::parse(context, i)) { lengths[0] = value; let mut length_parsed_count = 1; while length_parsed_count < 4 { - if let Ok(value) = input.try(specified::Length::parse) { + if let Ok(value) = input.try(|i| specified::Length::parse(context, i)) { lengths[length_parsed_count] = value } else { break @@ -162,7 +162,7 @@ ${helpers.predefined_type("opacity", } } if color.is_none() { - if let Ok(value) = input.try(specified::CSSColor::parse) { + if let Ok(value) = input.try(|i| specified::CSSColor::parse(context, i)) { color = Some(value); continue } @@ -352,16 +352,16 @@ ${helpers.predefined_type("opacity", } } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { use app_units::Au; use std::ascii::AsciiExt; use values::specified::Length; - fn parse_argument(input: &mut Parser) -> Result, ()> { + fn parse_argument(context: &ParserContext, input: &mut Parser) -> Result, ()> { if input.try(|input| input.expect_ident_matching("auto")).is_ok() { Ok(None) } else { - Length::parse(input).map(Some) + Length::parse(context, input).map(Some) } } @@ -373,21 +373,21 @@ ${helpers.predefined_type("opacity", } input.parse_nested_block(|input| { - let top = try!(parse_argument(input)); + let top = try!(parse_argument(context, input)); let right; let bottom; let left; if input.try(|input| input.expect_comma()).is_ok() { - right = try!(parse_argument(input)); + right = try!(parse_argument(context, input)); try!(input.expect_comma()); - bottom = try!(parse_argument(input)); + bottom = try!(parse_argument(context, input)); try!(input.expect_comma()); - left = try!(parse_argument(input)); + left = try!(parse_argument(context, input)); } else { - right = try!(parse_argument(input)); - bottom = try!(parse_argument(input)); - left = try!(parse_argument(input)); + right = try!(parse_argument(context, input)); + bottom = try!(parse_argument(context, input)); + left = try!(parse_argument(context, input)); } Ok(SpecifiedValue(Some(SpecifiedClipRect { top: top.unwrap_or(Length::Absolute(Au(0))), @@ -627,7 +627,7 @@ ${helpers.predefined_type("opacity", computed_value::T::new(Vec::new()) } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { let mut filters = Vec::new(); if input.try(|input| input.expect_ident_matching("none")).is_ok() { return Ok(SpecifiedValue(filters)) @@ -640,13 +640,13 @@ ${helpers.predefined_type("opacity", "brightness" => parse_factor(input).map(SpecifiedFilter::Brightness), "contrast" => parse_factor(input).map(SpecifiedFilter::Contrast), "grayscale" => parse_factor(input).map(SpecifiedFilter::Grayscale), - "hue-rotate" => Angle::parse(input).map(SpecifiedFilter::HueRotate), + "hue-rotate" => Angle::parse(context, input).map(SpecifiedFilter::HueRotate), "invert" => parse_factor(input).map(SpecifiedFilter::Invert), "opacity" => parse_factor(input).map(SpecifiedFilter::Opacity), "saturate" => parse_factor(input).map(SpecifiedFilter::Saturate), "sepia" => parse_factor(input).map(SpecifiedFilter::Sepia), % if product == "gecko": - "drop-shadow" => parse_drop_shadow(input), + "drop-shadow" => parse_drop_shadow(context, input), % endif _ => Err(()) } @@ -669,11 +669,12 @@ ${helpers.predefined_type("opacity", } % if product == "gecko": - fn parse_drop_shadow(input: &mut Parser) -> Result { - let offset_x = try!(specified::Length::parse(input)); - let offset_y = try!(specified::Length::parse(input)); - let blur_radius = input.try(specified::Length::parse).unwrap_or(specified::Length::from_px(0.0)); - let color = input.try(specified::CSSColor::parse).ok(); + fn parse_drop_shadow(context: &ParserContext, input: &mut Parser) -> Result { + let offset_x = try!(specified::Length::parse(context, input)); + let offset_y = try!(specified::Length::parse(context, input)); + let blur_radius = input.try(|i| specified::Length::parse(context, i)) + .unwrap_or(specified::Length::from_px(0.0)); + let color = input.try(|i| specified::CSSColor::parse(context, i)).ok(); Ok(SpecifiedFilter::DropShadow(offset_x, offset_y, blur_radius, color)) } % endif @@ -745,7 +746,7 @@ pub struct OriginParseResult { pub depth: Option } -pub fn parse_origin(_: &ParserContext, input: &mut Parser) -> Result { +pub fn parse_origin(context: &ParserContext, input: &mut Parser) -> Result { use values::specified::{LengthOrPercentage, Percentage}; let (mut horizontal, mut vertical, mut depth) = (None, None, None); loop { @@ -794,7 +795,7 @@ pub fn parse_origin(_: &ParserContext, input: &mut Parser) -> Result { if horizontal.is_none() { horizontal = Some(value); diff --git a/servo/components/style/properties/longhand/font.mako.rs b/servo/components/style/properties/longhand/font.mako.rs index eee69ecaf040..17cd56a31636 100644 --- a/servo/components/style/properties/longhand/font.mako.rs +++ b/servo/components/style/properties/longhand/font.mako.rs @@ -510,7 +510,7 @@ ${helpers.single_keyword("font-variant-position", pub mod computed_value { use cssparser::Parser; - use parser::Parse; + use parser::{Parse, ParserContext}; use std::fmt; use style_traits::ToCss; @@ -560,7 +560,7 @@ ${helpers.single_keyword("font-variant-position", impl Parse for FeatureTagValue { /// https://www.w3.org/TR/css-fonts-3/#propdef-font-feature-settings /// [ on | off | ] - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { let tag = try!(input.expect_string()); // allowed strings of length 4 containing chars: @@ -597,11 +597,11 @@ ${helpers.single_keyword("font-variant-position", } /// normal | # - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { if input.try(|input| input.expect_ident_matching("normal")).is_ok() { Ok(computed_value::T::Normal) } else { - input.parse_comma_separated(computed_value::FeatureTagValue::parse) + input.parse_comma_separated(|i| computed_value::FeatureTagValue::parse(context, i)) .map(computed_value::T::Tag) } } diff --git a/servo/components/style/properties/longhand/inherited_svg.mako.rs b/servo/components/style/properties/longhand/inherited_svg.mako.rs index ce233ecb3664..8bff77f9c373 100644 --- a/servo/components/style/properties/longhand/inherited_svg.mako.rs +++ b/servo/components/style/properties/longhand/inherited_svg.mako.rs @@ -50,6 +50,7 @@ ${helpers.single_keyword("stroke-linejoin", "miter round bevel", ${helpers.predefined_type("stroke-miterlimit", "Number", "4.0", "parse_at_least_one", products="gecko", + needs_context=False, animatable=False)} ${helpers.predefined_type("stroke-opacity", "Opacity", "1.0", diff --git a/servo/components/style/properties/longhand/inherited_text.mako.rs b/servo/components/style/properties/longhand/inherited_text.mako.rs index f08764ab2307..e6d474aca23d 100644 --- a/servo/components/style/properties/longhand/inherited_text.mako.rs +++ b/servo/components/style/properties/longhand/inherited_text.mako.rs @@ -200,8 +200,7 @@ #[inline] pub fn get_initial_value() -> computed_value::T { computed_value::T::start } - pub fn parse(_context: &ParserContext, input: &mut Parser) - -> Result { + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { computed_value::T::parse(input) } @@ -645,15 +644,15 @@ ${helpers.single_keyword("text-align-last", computed_value::T(Vec::new()) } - pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { if input.try(|input| input.expect_ident_matching("none")).is_ok() { Ok(SpecifiedValue(Vec::new())) } else { - input.parse_comma_separated(parse_one_text_shadow).map(SpecifiedValue) + input.parse_comma_separated(|i| parse_one_text_shadow(context, i)).map(SpecifiedValue) } } - fn parse_one_text_shadow(input: &mut Parser) -> Result { + fn parse_one_text_shadow(context: &ParserContext, input: &mut Parser) -> Result { use app_units::Au; let mut lengths = [specified::Length::Absolute(Au(0)); 3]; let mut lengths_parsed = false; @@ -661,11 +660,11 @@ ${helpers.single_keyword("text-align-last", loop { if !lengths_parsed { - if let Ok(value) = input.try(specified::Length::parse) { + if let Ok(value) = input.try(|i| specified::Length::parse(context, i)) { lengths[0] = value; let mut length_parsed_count = 1; while length_parsed_count < 3 { - if let Ok(value) = input.try(specified::Length::parse) { + if let Ok(value) = input.try(|i| specified::Length::parse(context, i)) { lengths[length_parsed_count] = value } else { break @@ -683,7 +682,7 @@ ${helpers.single_keyword("text-align-last", } } if color.is_none() { - if let Ok(value) = input.try(specified::CSSColor::parse) { + if let Ok(value) = input.try(|i| specified::CSSColor::parse(context, i)) { color = Some(value); continue } @@ -1024,9 +1023,8 @@ ${helpers.predefined_type( pub type SpecifiedValue = BorderWidth; #[inline] - pub fn parse(_context: &ParserContext, input: &mut Parser) - -> Result { - BorderWidth::parse(input) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + BorderWidth::parse(context, input) } pub mod computed_value { diff --git a/servo/components/style/properties/longhand/list.mako.rs b/servo/components/style/properties/longhand/list.mako.rs index f237e4b0e034..5419ca12935e 100644 --- a/servo/components/style/properties/longhand/list.mako.rs +++ b/servo/components/style/properties/longhand/list.mako.rs @@ -27,7 +27,6 @@ ${helpers.single_keyword("list-style-type", """ animatable=False)} ${helpers.predefined_type("list-style-image", "UrlOrNone", "computed_value::T::None", - needs_context=True, animatable="False")} <%helpers:longhand name="quotes" animatable="False"> diff --git a/servo/components/style/properties/longhand/outline.mako.rs b/servo/components/style/properties/longhand/outline.mako.rs index 5f4c12a0772d..73057ab7c330 100644 --- a/servo/components/style/properties/longhand/outline.mako.rs +++ b/servo/components/style/properties/longhand/outline.mako.rs @@ -19,7 +19,7 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr pub mod computed_value { pub use values::specified::BorderStyle as T; } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { match SpecifiedValue::parse(input) { Ok(SpecifiedValue::hidden) => Err(()), result => result diff --git a/servo/components/style/properties/longhand/padding.mako.rs b/servo/components/style/properties/longhand/padding.mako.rs index 72626e69f902..b0778bde34bd 100644 --- a/servo/components/style/properties/longhand/padding.mako.rs +++ b/servo/components/style/properties/longhand/padding.mako.rs @@ -10,6 +10,7 @@ ${helpers.predefined_type("padding-%s" % side[0], "LengthOrPercentage", "computed::LengthOrPercentage::Length(Au(0))", "parse_non_negative", + needs_context=False, animatable=True, logical = side[1])} % endfor diff --git a/servo/components/style/properties/longhand/pointing.mako.rs b/servo/components/style/properties/longhand/pointing.mako.rs index c46e4fdb8417..d5306f376a92 100644 --- a/servo/components/style/properties/longhand/pointing.mako.rs +++ b/servo/components/style/properties/longhand/pointing.mako.rs @@ -96,7 +96,7 @@ } impl Parse for computed_value::Keyword { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { use std::ascii::AsciiExt; use style_traits::cursor::Cursor; let ident = try!(input.expect_ident()); @@ -120,8 +120,8 @@ } #[cfg(not(feature = "gecko"))] - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - computed_value::Keyword::parse(input) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + computed_value::Keyword::parse(context, input) } /// cursor: [ [ ]?]# [auto | default | ...] @@ -138,7 +138,7 @@ Ok(computed_value::T { images: images, - keyword: try!(computed_value::Keyword::parse(input)), + keyword: try!(computed_value::Keyword::parse(context, input)), }) } diff --git a/servo/components/style/properties/longhand/position.mako.rs b/servo/components/style/properties/longhand/position.mako.rs index a02790931165..0d05c2253d88 100644 --- a/servo/components/style/properties/longhand/position.mako.rs +++ b/servo/components/style/properties/longhand/position.mako.rs @@ -95,10 +95,12 @@ ${helpers.single_keyword("align-content", "stretch flex-start flex-end center sp // Flex item properties ${helpers.predefined_type("flex-grow", "Number", "0.0", "parse_non_negative", + needs_context=False, animatable=True)} ${helpers.predefined_type("flex-shrink", "Number", "1.0", "parse_non_negative", + needs_context=False, animatable=True)} ${helpers.single_keyword("align-self", "auto stretch flex-start flex-end center baseline", @@ -140,6 +142,7 @@ ${helpers.predefined_type("flex-basis", "LengthOrPercentageOrAuto", "computed::LengthOrPercentageOrAuto::Auto", "parse_non_negative", + needs_context=False, animatable=True, logical = logical)} // min-width, min-height, min-block-size, min-inline-size @@ -147,6 +150,7 @@ ${helpers.predefined_type("flex-basis", "LengthOrPercentage", "computed::LengthOrPercentage::Length(Au(0))", "parse_non_negative", + needs_context=False, animatable=True, logical = logical)} // max-width, max-height, max-block-size, max-inline-size @@ -154,6 +158,7 @@ ${helpers.predefined_type("flex-basis", "LengthOrPercentageOrNone", "computed::LengthOrPercentageOrNone::None", "parse_non_negative", + needs_context=False, animatable=True, logical = logical)} % endfor diff --git a/servo/components/style/properties/longhand/text.mako.rs b/servo/components/style/properties/longhand/text.mako.rs index 2923948ed1c7..541c8e13e040 100644 --- a/servo/components/style/properties/longhand/text.mako.rs +++ b/servo/components/style/properties/longhand/text.mako.rs @@ -47,16 +47,16 @@ second: None } } - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - let first = try!(Side::parse(input)); - let second = Side::parse(input).ok(); + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + let first = try!(Side::parse(context, input)); + let second = Side::parse(context, input).ok(); Ok(SpecifiedValue { first: first, second: second, }) } impl Parse for Side { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { if let Ok(ident) = input.try(|input| input.expect_ident()) { match_ignore_ascii_case! { ident, "clip" => Ok(Side::Clip), diff --git a/servo/components/style/properties/longhand/xul.mako.rs b/servo/components/style/properties/longhand/xul.mako.rs index 221ff8a397d2..23c1da1246bb 100644 --- a/servo/components/style/properties/longhand/xul.mako.rs +++ b/servo/components/style/properties/longhand/xul.mako.rs @@ -15,4 +15,5 @@ ${helpers.single_keyword("-moz-box-align", "stretch start center baseline end", ${helpers.predefined_type("-moz-box-flex", "Number", "0.0", "parse_non_negative", products="gecko", gecko_ffi_name="mBoxFlex", + needs_context=False, animatable=False)} diff --git a/servo/components/style/properties/properties.mako.rs b/servo/components/style/properties/properties.mako.rs index 85d5ecd04848..508936e873dd 100644 --- a/servo/components/style/properties/properties.mako.rs +++ b/servo/components/style/properties/properties.mako.rs @@ -84,7 +84,8 @@ pub mod shorthands { use values::specified; pub fn parse_four_sides(input: &mut Parser, parse_one: F) -> Result<(T, T, T, T), ()> - where F: Fn(&mut Parser) -> Result, F: Copy, T: Clone { + where F: Fn(&mut Parser) -> Result, T: Clone + { // zero or more than four values is invalid. // one value sets them all // two values set (top, bottom) and (left, right) @@ -94,7 +95,7 @@ pub mod shorthands { let right; let bottom; let left; - match input.try(parse_one) { + match input.try(|i| parse_one(i)) { Err(()) => { right = top.clone(); bottom = top.clone(); @@ -102,14 +103,14 @@ pub mod shorthands { } Ok(value) => { right = value; - match input.try(parse_one) { + match input.try(|i| parse_one(i)) { Err(()) => { bottom = top.clone(); left = right.clone(); } Ok(value) => { bottom = value; - match input.try(parse_one) { + match input.try(|i| parse_one(i)) { Err(()) => { left = right.clone(); } @@ -365,7 +366,7 @@ pub enum CSSWideKeyword { } impl Parse for CSSWideKeyword { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_ident()), "initial" => Ok(CSSWideKeyword::InitialKeyword), "inherit" => Ok(CSSWideKeyword::InheritKeyword), @@ -753,11 +754,11 @@ impl PropertyDeclaration { in_keyframe_block: bool) -> PropertyDeclarationParseResult { if let Ok(name) = ::custom_properties::parse_name(name) { - let value = match input.try(CSSWideKeyword::parse) { + let value = match input.try(|i| CSSWideKeyword::parse(context, i)) { Ok(CSSWideKeyword::UnsetKeyword) | // Custom properties are alawys inherited Ok(CSSWideKeyword::InheritKeyword) => DeclaredValue::Inherit, Ok(CSSWideKeyword::InitialKeyword) => DeclaredValue::Initial, - Err(()) => match ::custom_properties::SpecifiedValue::parse(input) { + Err(()) => match ::custom_properties::SpecifiedValue::parse(context, input) { Ok(value) => DeclaredValue::Value(value), Err(()) => return PropertyDeclarationParseResult::InvalidValue, } @@ -815,7 +816,7 @@ impl PropertyDeclaration { return PropertyDeclarationParseResult::ExperimentalProperty } % endif - match input.try(CSSWideKeyword::parse) { + match input.try(|i| CSSWideKeyword::parse(context, i)) { Ok(CSSWideKeyword::InheritKeyword) => { % for sub_property in shorthand.sub_properties: result_list.push( diff --git a/servo/components/style/properties/shorthand/border.mako.rs b/servo/components/style/properties/shorthand/border.mako.rs index f9f81af34e10..05efc2c53033 100644 --- a/servo/components/style/properties/shorthand/border.mako.rs +++ b/servo/components/style/properties/shorthand/border.mako.rs @@ -6,17 +6,20 @@ <% from data import to_rust_ident, ALL_SIDES %> ${helpers.four_sides_shorthand("border-color", "border-%s-color", "specified::CSSColor::parse")} + ${helpers.four_sides_shorthand("border-style", "border-%s-style", - "specified::BorderStyle::parse")} + "specified::BorderStyle::parse", + needs_context=False)} + <%helpers:shorthand name="border-width" sub_properties="${ ' '.join('border-%s-width' % side for side in ['top', 'right', 'bottom', 'left'])}"> use super::parse_four_sides; + use parser::Parse; use values::specified; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { - let _unused = context; - let (top, right, bottom, left) = try!(parse_four_sides(input, specified::BorderWidth::parse)); + let (top, right, bottom, left) = try!(parse_four_sides(input, |i| specified::BorderWidth::parse(context, i))); Ok(Longhands { % for side in ["top", "right", "bottom", "left"]: ${to_rust_ident('border-%s-width' % side)}: Some(${side}), @@ -58,7 +61,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) let mut any = false; loop { if color.is_none() { - if let Ok(value) = input.try(specified::CSSColor::parse) { + if let Ok(value) = input.try(|i| specified::CSSColor::parse(context, i)) { color = Some(value); any = true; continue @@ -72,7 +75,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) } } if width.is_none() { - if let Ok(value) = input.try(specified::BorderWidth::parse) { + if let Ok(value) = input.try(|i| specified::BorderWidth::parse(context, i)) { width = Some(value); any = true; continue @@ -152,9 +155,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) use parser::Parse; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { - let _ignored = context; - - let radii = try!(BorderRadius::parse(input)); + let radii = try!(BorderRadius::parse(context, input)); Ok(Longhands { border_top_left_radius: Some(radii.top_left), border_top_right_radius: Some(radii.top_right), diff --git a/servo/components/style/properties/shorthand/box.mako.rs b/servo/components/style/properties/shorthand/box.mako.rs index 91e9cb3d604b..e991d5787c0d 100644 --- a/servo/components/style/properties/shorthand/box.mako.rs +++ b/servo/components/style/properties/shorthand/box.mako.rs @@ -58,7 +58,17 @@ macro_rules! try_parse_one { continue; } } - } + }; + ($context: expr, $input: expr, $var: ident, $prop_module: ident) => { + if $var.is_none() { + if let Ok(value) = $input.try(|i| { + $prop_module::computed_value::SingleComputedValue::parse($context, i) + }) { + $var = Some(value); + continue; + } + } + }; } <%helpers:shorthand name="transition" @@ -69,7 +79,7 @@ macro_rules! try_parse_one { use properties::longhands::{transition_delay, transition_duration, transition_property}; use properties::longhands::{transition_timing_function}; - pub fn parse_value(_: &ParserContext, input: &mut Parser) -> Result { + pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { struct SingleTransition { transition_property: transition_property::SingleSpecifiedValue, transition_duration: transition_duration::SingleSpecifiedValue, @@ -77,14 +87,14 @@ macro_rules! try_parse_one { transition_delay: transition_delay::SingleSpecifiedValue, } - fn parse_one_transition(input: &mut Parser) -> Result { + fn parse_one_transition(context: &ParserContext, input: &mut Parser) -> Result { let (mut property, mut duration) = (None, None); let (mut timing_function, mut delay) = (None, None); loop { try_parse_one!(input, property, transition_property); - try_parse_one!(input, duration, transition_duration); - try_parse_one!(input, timing_function, transition_timing_function); - try_parse_one!(input, delay, transition_delay); + try_parse_one!(context, input, duration, transition_duration); + try_parse_one!(context, input, timing_function, transition_timing_function); + try_parse_one!(context, input, delay, transition_delay); break } @@ -113,7 +123,7 @@ macro_rules! try_parse_one { }) } - let results = try!(input.parse_comma_separated(parse_one_transition)); + let results = try!(input.parse_comma_separated(|i| parse_one_transition(context, i))); let (mut properties, mut durations) = (Vec::new(), Vec::new()); let (mut timing_functions, mut delays) = (Vec::new(), Vec::new()); for result in results { @@ -159,7 +169,7 @@ macro_rules! try_parse_one { use properties::longhands::{animation_delay, animation_iteration_count, animation_direction}; use properties::longhands::{animation_fill_mode, animation_play_state}; - pub fn parse_value(_: &ParserContext, input: &mut Parser) -> Result { + pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { struct SingleAnimation { animation_name: animation_name::SingleSpecifiedValue, animation_duration: animation_duration::SingleSpecifiedValue, @@ -171,7 +181,7 @@ macro_rules! try_parse_one { animation_play_state: animation_play_state::SingleSpecifiedValue, } - fn parse_one_animation(input: &mut Parser) -> Result { + fn parse_one_animation(context: &ParserContext, input: &mut Parser) -> Result { let mut duration = None; let mut timing_function = None; let mut delay = None; @@ -187,14 +197,14 @@ macro_rules! try_parse_one { // Also, duration must be before delay, see // https://drafts.csswg.org/css-animations/#typedef-single-animation loop { - try_parse_one!(input, duration, animation_duration); - try_parse_one!(input, timing_function, animation_timing_function); - try_parse_one!(input, delay, animation_delay); - try_parse_one!(input, iteration_count, animation_iteration_count); + try_parse_one!(context, input, duration, animation_duration); + try_parse_one!(context, input, timing_function, animation_timing_function); + try_parse_one!(context, input, delay, animation_delay); + try_parse_one!(context, input, iteration_count, animation_iteration_count); try_parse_one!(input, direction, animation_direction); try_parse_one!(input, fill_mode, animation_fill_mode); try_parse_one!(input, play_state, animation_play_state); - try_parse_one!(input, name, animation_name); + try_parse_one!(context, input, name, animation_name); break } @@ -235,7 +245,7 @@ macro_rules! try_parse_one { }) } - let results = try!(input.parse_comma_separated(parse_one_animation)); + let results = try!(input.parse_comma_separated(|i| parse_one_animation(context, i))); let mut names = vec![]; let mut durations = vec![]; diff --git a/servo/components/style/properties/shorthand/outline.mako.rs b/servo/components/style/properties/shorthand/outline.mako.rs index cb175b9c9c82..51d740181247 100644 --- a/servo/components/style/properties/shorthand/outline.mako.rs +++ b/servo/components/style/properties/shorthand/outline.mako.rs @@ -17,7 +17,7 @@ let mut any = false; loop { if color.is_none() { - if let Ok(value) = input.try(specified::CSSColor::parse) { + if let Ok(value) = input.try(|i| specified::CSSColor::parse(context, i)) { color = Some(value); any = true; continue diff --git a/servo/components/style/properties/shorthand/position.mako.rs b/servo/components/style/properties/shorthand/position.mako.rs index 1b2d511642fc..3865ac8042d8 100644 --- a/servo/components/style/properties/shorthand/position.mako.rs +++ b/servo/components/style/properties/shorthand/position.mako.rs @@ -67,7 +67,7 @@ Ok((grow, shrink)) } - pub fn parse_value(_: &ParserContext, input: &mut Parser) -> Result { + pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { let mut grow = None; let mut shrink = None; let mut basis = None; @@ -88,7 +88,7 @@ } } if basis.is_none() { - if let Ok(value) = input.try(LengthOrPercentageOrAutoOrContent::parse) { + if let Ok(value) = input.try(|i| LengthOrPercentageOrAutoOrContent::parse(context, i)) { basis = Some(value); continue } diff --git a/servo/components/style/values/mod.rs b/servo/components/style/values/mod.rs index 84c581170079..3be4d742eff9 100644 --- a/servo/components/style/values/mod.rs +++ b/servo/components/style/values/mod.rs @@ -7,7 +7,7 @@ //! [values]: https://drafts.csswg.org/css-values/ pub use cssparser::{RGBA, Parser}; -use parser::Parse; +use parser::{Parse, ParserContext}; use std::fmt::{self, Debug}; use style_traits::ToCss; @@ -83,7 +83,7 @@ macro_rules! define_keyword_type { } impl Parse for $name { - fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> { + fn parse(_context: &ParserContext, input: &mut ::cssparser::Parser) -> Result<$name, ()> { input.expect_ident_matching($css).map(|_| $name) } } @@ -132,11 +132,11 @@ impl HasViewportPercentage f } impl Parse for Either { - fn parse(input: &mut Parser) -> Result, ()> { - if let Ok(v) = input.try(|i| A::parse(i)) { + fn parse(context: &ParserContext, input: &mut Parser) -> Result, ()> { + if let Ok(v) = input.try(|i| A::parse(context, i)) { Ok(Either::First(v)) } else { - B::parse(input).map(Either::Second) + B::parse(context, input).map(Either::Second) } } } diff --git a/servo/components/style/values/specified/basic_shape.rs b/servo/components/style/values/specified/basic_shape.rs index 15b630c67610..b754eefde691 100644 --- a/servo/components/style/values/specified/basic_shape.rs +++ b/servo/components/style/values/specified/basic_shape.rs @@ -61,19 +61,20 @@ impl ShapeSource { } else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) { Ok(ShapeSource::Url(url)) } else { - fn parse_component(input: &mut Parser, component: &mut Option) -> bool { + fn parse_component(context: &ParserContext, input: &mut Parser, + component: &mut Option) -> bool { if component.is_some() { return false; // already parsed this component } - *component = input.try(U::parse).ok(); + *component = input.try(|i| U::parse(context, i)).ok(); component.is_some() } let mut shape = None; let mut reference = None; loop { - if !parse_component(input, &mut shape) && - !parse_component(input, &mut reference) { + if !parse_component(context, input, &mut shape) && + !parse_component(context, input, &mut reference) { break; } } @@ -136,23 +137,23 @@ pub enum BasicShape { } impl Parse for BasicShape { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_function()), "inset" => { Ok(BasicShape::Inset( - try!(input.parse_nested_block(InsetRect::parse_function_arguments)))) + try!(input.parse_nested_block(|i| InsetRect::parse_function_arguments(context, i))))) }, "circle" => { Ok(BasicShape::Circle( - try!(input.parse_nested_block(Circle::parse_function_arguments)))) + try!(input.parse_nested_block(|i| Circle::parse_function_arguments(context, i))))) }, "ellipse" => { Ok(BasicShape::Ellipse( - try!(input.parse_nested_block(Ellipse::parse_function_arguments)))) + try!(input.parse_nested_block(|i| Ellipse::parse_function_arguments(context, i))))) }, "polygon" => { Ok(BasicShape::Polygon( - try!(input.parse_nested_block(Polygon::parse_function_arguments)))) + try!(input.parse_nested_block(|i| Polygon::parse_function_arguments(context, i))))) }, _ => Err(()) } @@ -213,8 +214,8 @@ pub struct InsetRect { } impl InsetRect { - pub fn parse_function_arguments(input: &mut Parser) -> Result { - let (t, r, b, l) = try!(parse_four_sides(input, LengthOrPercentage::parse)); + pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result { + let (t, r, b, l) = try!(parse_four_sides(input, |i| LengthOrPercentage::parse(context, i))); let mut rect = InsetRect { top: t, right: r, @@ -223,19 +224,19 @@ impl InsetRect { round: None, }; if let Ok(_) = input.try(|input| input.expect_ident_matching("round")) { - rect.round = Some(try!(BorderRadius::parse(input))); + rect.round = Some(try!(BorderRadius::parse(context, input))); } Ok(rect) } } impl Parse for InsetRect { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_function()), - "inset" => { - Ok(try!(input.parse_nested_block(InsetRect::parse_function_arguments))) - }, - _ => Err(()) + "inset" => { + Ok(try!(input.parse_nested_block(|i| InsetRect::parse_function_arguments(context, i)))) + }, + _ => Err(()) } } } @@ -377,10 +378,10 @@ pub struct Circle { } impl Circle { - pub fn parse_function_arguments(input: &mut Parser) -> Result { - let radius = input.try(ShapeRadius::parse).ok().unwrap_or_else(Default::default); + pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result { + let radius = input.try(|i| ShapeRadius::parse(context, i)).ok().unwrap_or_else(Default::default); let position = if let Ok(_) = input.try(|input| input.expect_ident_matching("at")) { - try!(Position::parse(input)) + try!(Position::parse(context, input)) } else { // Defaults to origin Position { @@ -398,12 +399,12 @@ impl Circle { } impl Parse for Circle { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_function()), - "circle" => { - Ok(try!(input.parse_nested_block(Circle::parse_function_arguments))) - }, - _ => Err(()) + "circle" => { + Ok(try!(input.parse_nested_block(|i| Circle::parse_function_arguments(context, i)))) + }, + _ => Err(()) } } } @@ -452,12 +453,12 @@ pub struct Ellipse { impl Ellipse { - pub fn parse_function_arguments(input: &mut Parser) -> Result { + pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result { let (a, b) = input.try(|input| -> Result<_, ()> { - Ok((try!(ShapeRadius::parse(input)), try!(ShapeRadius::parse(input)))) + Ok((try!(ShapeRadius::parse(context, input)), try!(ShapeRadius::parse(context, input)))) }).ok().unwrap_or_default(); let position = if let Ok(_) = input.try(|input| input.expect_ident_matching("at")) { - try!(Position::parse(input)) + try!(Position::parse(context, input)) } else { // Defaults to origin Position { @@ -476,12 +477,12 @@ impl Ellipse { } impl Parse for Ellipse { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_function()), - "ellipse" => { - Ok(try!(input.parse_nested_block(Ellipse::parse_function_arguments))) - }, - _ => Err(()) + "ellipse" => { + Ok(try!(input.parse_nested_block(|i| Ellipse::parse_function_arguments(context, i)))) + }, + _ => Err(()) } } } @@ -533,16 +534,16 @@ pub struct Polygon { } impl Polygon { - pub fn parse_function_arguments(input: &mut Parser) -> Result { + pub fn parse_function_arguments(context: &ParserContext, input: &mut Parser) -> Result { let fill = input.try(|input| { - let fill = FillRule::parse(input); + let fill = FillRule::parse(context, input); // only eat the comma if there is something before it try!(input.expect_comma()); fill }).ok().unwrap_or_else(Default::default); let buf = try!(input.parse_comma_separated(|input| { - Ok((try!(LengthOrPercentage::parse(input)), - try!(LengthOrPercentage::parse(input)))) + Ok((try!(LengthOrPercentage::parse(context, input)), + try!(LengthOrPercentage::parse(context, input)))) })); Ok(Polygon { fill: fill, @@ -552,12 +553,12 @@ impl Polygon { } impl Parse for Polygon { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_function()), - "polygon" => { - Ok(try!(input.parse_nested_block(Polygon::parse_function_arguments))) - }, - _ => Err(()) + "polygon" => { + Ok(try!(input.parse_nested_block(|i| Polygon::parse_function_arguments(context, i)))) + }, + _ => Err(()) } } } @@ -629,9 +630,8 @@ impl Default for ShapeRadius { } impl Parse for ShapeRadius { - fn parse(input: &mut Parser) -> Result { - input.try(LengthOrPercentage::parse).map(ShapeRadius::Length) - .or_else(|_| { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + input.try(|i| LengthOrPercentage::parse(context, i)).map(ShapeRadius::Length).or_else(|_| { match_ignore_ascii_case! { try!(input.expect_ident()), "closest-side" => Ok(ShapeRadius::ClosestSide), "farthest-side" => Ok(ShapeRadius::FarthestSide), @@ -716,10 +716,10 @@ impl ToCss for BorderRadius { } impl Parse for BorderRadius { - fn parse(input: &mut Parser) -> Result { - let widths = try!(parse_one_set_of_border_values(input)); + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + let widths = try!(parse_one_set_of_border_values(context, input)); let heights = if input.try(|input| input.expect_delim('/')).is_ok() { - try!(parse_one_set_of_border_values(input)) + try!(parse_one_set_of_border_values(context, input)) } else { widths.clone() }; @@ -732,23 +732,23 @@ impl Parse for BorderRadius { } } -fn parse_one_set_of_border_values(mut input: &mut Parser) +fn parse_one_set_of_border_values(context: &ParserContext, mut input: &mut Parser) -> Result<[LengthOrPercentage; 4], ()> { - let a = try!(LengthOrPercentage::parse(input)); + let a = try!(LengthOrPercentage::parse(context, input)); - let b = if let Ok(b) = input.try(LengthOrPercentage::parse) { + let b = if let Ok(b) = input.try(|i| LengthOrPercentage::parse(context, i)) { b } else { return Ok([a, a, a, a]) }; - let c = if let Ok(c) = input.try(LengthOrPercentage::parse) { + let c = if let Ok(c) = input.try(|i| LengthOrPercentage::parse(context, i)) { c } else { return Ok([a, b, a, b]) }; - if let Ok(d) = input.try(LengthOrPercentage::parse) { + if let Ok(d) = input.try(|i| LengthOrPercentage::parse(context, i)) { Ok([a, b, c, d]) } else { Ok([a, b, c, b]) @@ -794,7 +794,7 @@ pub enum FillRule { impl ComputedValueAsSpecified for FillRule {} impl Parse for FillRule { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_ident()), "nonzero" => Ok(FillRule::NonZero), "evenodd" => Ok(FillRule::EvenOdd), @@ -829,8 +829,8 @@ pub enum GeometryBox { } impl Parse for GeometryBox { - fn parse(input: &mut Parser) -> Result { - if let Ok(shape_box) = input.try(ShapeBox::parse) { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + if let Ok(shape_box) = input.try(|i| ShapeBox::parse(context, i)) { Ok(GeometryBox::ShapeBox(shape_box)) } else { match_ignore_ascii_case! { try!(input.expect_ident()), @@ -868,7 +868,7 @@ pub enum ShapeBox { } impl Parse for ShapeBox { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { match_ignore_ascii_case! { try!(input.expect_ident()), "margin-box" => Ok(ShapeBox::Margin), "border-box" => Ok(ShapeBox::Border), diff --git a/servo/components/style/values/specified/image.rs b/servo/components/style/values/specified/image.rs index ba751704465b..94a56d735414 100644 --- a/servo/components/style/values/specified/image.rs +++ b/servo/components/style/values/specified/image.rs @@ -42,7 +42,7 @@ impl Image { return Ok(Image::Url(url)); } - Ok(Image::Gradient(try!(Gradient::parse_function(input)))) + Ok(Image::Gradient(try!(Gradient::parse_function(context, input)))) } /// Creates an already specified image value from an already resolved URL @@ -92,13 +92,13 @@ impl ToCss for Gradient { impl Gradient { /// Parses a gradient from the given arguments. - pub fn parse_function(input: &mut Parser) -> Result { + pub fn parse_function(context: &ParserContext, input: &mut Parser) -> Result { let mut repeating = false; let (gradient_kind, stops) = match_ignore_ascii_case! { try!(input.expect_function()), "linear-gradient" => { try!(input.parse_nested_block(|input| { - let kind = try!(GradientKind::parse_linear(input)); - let stops = try!(input.parse_comma_separated(ColorStop::parse)); + let kind = try!(GradientKind::parse_linear(context, input)); + let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i))); Ok((kind, stops)) }) ) @@ -106,16 +106,16 @@ impl Gradient { "repeating-linear-gradient" => { repeating = true; try!(input.parse_nested_block(|input| { - let kind = try!(GradientKind::parse_linear(input)); - let stops = try!(input.parse_comma_separated(ColorStop::parse)); + let kind = try!(GradientKind::parse_linear(context, input)); + let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i))); Ok((kind, stops)) }) ) }, "radial-gradient" => { try!(input.parse_nested_block(|input| { - let kind = try!(GradientKind::parse_radial(input)); - let stops = try!(input.parse_comma_separated(ColorStop::parse)); + let kind = try!(GradientKind::parse_radial(context, input)); + let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i))); Ok((kind, stops)) }) ) @@ -123,8 +123,8 @@ impl Gradient { "repeating-radial-gradient" => { repeating = true; try!(input.parse_nested_block(|input| { - let kind = try!(GradientKind::parse_radial(input)); - let stops = try!(input.parse_comma_separated(ColorStop::parse)); + let kind = try!(GradientKind::parse_radial(context, input)); + let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i))); Ok((kind, stops)) }) ) @@ -151,29 +151,29 @@ pub enum GradientKind { impl GradientKind { /// Parses a linear gradient kind from the given arguments. - pub fn parse_linear(input: &mut Parser) -> Result { - let angle_or_corner = try!(AngleOrCorner::parse(input)); + pub fn parse_linear(context: &ParserContext, input: &mut Parser) -> Result { + let angle_or_corner = try!(AngleOrCorner::parse(context, input)); Ok(GradientKind::Linear(angle_or_corner)) } /// Parses a radial gradient from the given arguments. - pub fn parse_radial(input: &mut Parser) -> Result { + pub fn parse_radial(context: &ParserContext, input: &mut Parser) -> Result { let mut needs_comma = true; // Ending shape and position can be in various order. Checks all probabilities. - let (shape, position) = if let Ok(position) = input.try(parse_position) { + let (shape, position) = if let Ok(position) = input.try(|i| parse_position(context, i)) { // Handle just (EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner)), position) - } else if let Ok((first, second)) = input.try(parse_two_length) { + } else if let Ok((first, second)) = input.try(|i| parse_two_length(context, i)) { // Handle ? ? let _ = input.try(|input| input.expect_ident_matching("ellipse")); (EndingShape::Ellipse(LengthOrPercentageOrKeyword::LengthOrPercentage(first, second)), - input.try(parse_position).unwrap_or(Position::center())) - } else if let Ok(length) = input.try(Length::parse) { + input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) + } else if let Ok(length) = input.try(|i| Length::parse(context, i)) { // Handle ? ? let _ = input.try(|input| input.expect_ident_matching("circle")); (EndingShape::Circle(LengthOrKeyword::Length(length)), - input.try(parse_position).unwrap_or(Position::center())) + input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) } else if let Ok(keyword) = input.try(SizeKeyword::parse) { // Handle ? ? let shape = if input.try(|input| input.expect_ident_matching("circle")).is_ok() { @@ -182,24 +182,26 @@ impl GradientKind { let _ = input.try(|input| input.expect_ident_matching("ellipse")); EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(keyword)) }; - (shape, input.try(parse_position).unwrap_or(Position::center())) + (shape, input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) } else { // Handle ? ? if input.try(|input| input.expect_ident_matching("ellipse")).is_ok() { // Handle ? ? - let length = input.try(LengthOrPercentageOrKeyword::parse) + let length = input.try(|i| LengthOrPercentageOrKeyword::parse(context, i)) .unwrap_or(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner)); - (EndingShape::Ellipse(length), input.try(parse_position).unwrap_or(Position::center())) + (EndingShape::Ellipse(length), + input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) } else if input.try(|input| input.expect_ident_matching("circle")).is_ok() { // Handle ? ? - let length = input.try(LengthOrKeyword::parse) + let length = input.try(|i| LengthOrKeyword::parse(context, i)) .unwrap_or(LengthOrKeyword::Keyword(SizeKeyword::FarthestCorner)); - (EndingShape::Circle(length), input.try(parse_position).unwrap_or(Position::center())) + (EndingShape::Circle(length), input.try(|i| parse_position(context, i)) + .unwrap_or(Position::center())) } else { // If there is no shape keyword, it should set to default. needs_comma = false; (EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner)), - input.try(parse_position).unwrap_or(Position::center())) + input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) } }; @@ -211,15 +213,16 @@ impl GradientKind { } } -fn parse_two_length(input: &mut Parser) -> Result<(LengthOrPercentage, LengthOrPercentage), ()> { - let first = try!(LengthOrPercentage::parse(input)); - let second = try!(LengthOrPercentage::parse(input)); +fn parse_two_length(context: &ParserContext, input: &mut Parser) + -> Result<(LengthOrPercentage, LengthOrPercentage), ()> { + let first = try!(LengthOrPercentage::parse(context, input)); + let second = try!(LengthOrPercentage::parse(context, input)); Ok((first, second)) } -fn parse_position(input: &mut Parser) -> Result { +fn parse_position(context: &ParserContext, input: &mut Parser) -> Result { try!(input.expect_ident_matching("at")); - input.try(Position::parse) + input.try(|i| Position::parse(context, i)) } /// Specified values for an angle or a corner in a linear gradient. @@ -246,7 +249,7 @@ impl ToCss for AngleOrCorner { } impl Parse for AngleOrCorner { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { if input.try(|input| input.expect_ident_matching("to")).is_ok() { let (horizontal, vertical) = if let Ok(value) = input.try(HorizontalDirection::parse) { @@ -274,7 +277,7 @@ impl Parse for AngleOrCorner { } (None, None) => unreachable!(), } - } else if let Ok(angle) = input.try(Angle::parse) { + } else if let Ok(angle) = input.try(|i| Angle::parse(context, i)) { try!(input.expect_comma()); Ok(AngleOrCorner::Angle(angle)) } else { @@ -313,10 +316,10 @@ define_css_keyword_enum!(HorizontalDirection: "left" => Left, "right" => Right); define_css_keyword_enum!(VerticalDirection: "top" => Top, "bottom" => Bottom); impl Parse for ColorStop { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { Ok(ColorStop { - color: try!(CSSColor::parse(input)), - position: input.try(LengthOrPercentage::parse).ok(), + color: try!(CSSColor::parse(context, input)), + position: input.try(|i| LengthOrPercentage::parse(context, i)).ok(), }) } } @@ -357,11 +360,11 @@ pub enum LengthOrKeyword { } impl Parse for LengthOrKeyword { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { if let Ok(keyword) = input.try(SizeKeyword::parse) { Ok(LengthOrKeyword::Keyword(keyword)) } else { - Ok(LengthOrKeyword::Length(try!(Length::parse(input)))) + Ok(LengthOrKeyword::Length(try!(Length::parse(context, input)))) } } } @@ -385,12 +388,13 @@ pub enum LengthOrPercentageOrKeyword { impl Parse for LengthOrPercentageOrKeyword { - fn parse(input: &mut Parser) -> Result { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { if let Ok(keyword) = input.try(SizeKeyword::parse) { Ok(LengthOrPercentageOrKeyword::Keyword(keyword)) } else { - Ok(LengthOrPercentageOrKeyword::LengthOrPercentage(try!(LengthOrPercentage::parse(input)), - try!(LengthOrPercentage::parse(input)))) + Ok(LengthOrPercentageOrKeyword::LengthOrPercentage( + try!(LengthOrPercentage::parse(context, input)), + try!(LengthOrPercentage::parse(context, input)))) } } } diff --git a/servo/components/style/values/specified/length.rs b/servo/components/style/values/specified/length.rs index 4cdb8308c435..a70c516a0e80 100644 --- a/servo/components/style/values/specified/length.rs +++ b/servo/components/style/values/specified/length.rs @@ -6,7 +6,7 @@ use app_units::Au; use cssparser::{Parser, Token}; use euclid::size::Size2D; use font_metrics::FontMetrics; -use parser::Parse; +use parser::{Parse, ParserContext}; use std::ascii::AsciiExt; use std::cmp; use std::fmt; @@ -338,7 +338,7 @@ impl Length { } impl Parse for Length { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { Length::parse_internal(input, AllowedNumericType::All) } } @@ -753,7 +753,7 @@ impl ToCss for Percentage { impl Parse for Percentage { #[inline] - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { let context = AllowedNumericType::All; match try!(input.next()) { Token::Percentage(ref value) if context.is_ok(value.unit_value) => @@ -821,7 +821,7 @@ impl LengthOrPercentage { impl Parse for LengthOrPercentage { #[inline] - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { LengthOrPercentage::parse_internal(input, AllowedNumericType::All) } } @@ -884,7 +884,7 @@ impl LengthOrPercentageOrAuto { impl Parse for LengthOrPercentageOrAuto { #[inline] - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { LengthOrPercentageOrAuto::parse_internal(input, AllowedNumericType::All) } } @@ -946,7 +946,7 @@ impl LengthOrPercentageOrNone { impl Parse for LengthOrPercentageOrNone { #[inline] - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { LengthOrPercentageOrNone::parse_internal(input, AllowedNumericType::All) } } @@ -986,7 +986,7 @@ impl ToCss for LengthOrPercentageOrAutoOrContent { } impl Parse for LengthOrPercentageOrAutoOrContent { - fn parse(input: &mut Parser) -> Result { + 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) => @@ -1012,7 +1012,7 @@ pub type LengthOrNumber = Either; impl LengthOrNumber { pub fn parse_non_negative(input: &mut Parser) -> Result { - if let Ok(v) = input.try(|i| Length::parse_non_negative(i)) { + if let Ok(v) = input.try(Length::parse_non_negative) { Ok(Either::First(v)) } else { Number::parse_non_negative(input).map(Either::Second) diff --git a/servo/components/style/values/specified/mod.rs b/servo/components/style/values/specified/mod.rs index ca96150a2a32..ddfb44e03be3 100644 --- a/servo/components/style/values/specified/mod.rs +++ b/servo/components/style/values/specified/mod.rs @@ -38,7 +38,7 @@ pub struct CSSColor { } impl Parse for CSSColor { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { let start_position = input.position(); let authored = match input.next() { Ok(Token::Ident(s)) => Some(s.into_owned()), @@ -197,7 +197,7 @@ impl BorderRadiusSize { impl Parse for BorderRadiusSize { #[inline] - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { let first = try!(LengthOrPercentage::parse_non_negative(input)); let second = input.try(LengthOrPercentage::parse_non_negative).unwrap_or(first); Ok(BorderRadiusSize(Size2D::new(first, second))) @@ -241,7 +241,7 @@ const RAD_PER_TURN: CSSFloat = PI * 2.0; impl Parse for Angle { /// Parses an angle according to CSS-VALUES ยง 6.1. - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { match try!(input.next()) { Token::Dimension(ref value, ref unit) => Angle::parse_dimension(value.value, unit), Token::Number(ref value) if value.value == 0. => Ok(Angle(0.)), @@ -265,8 +265,8 @@ impl Angle { } } -pub fn parse_border_radius(input: &mut Parser) -> Result { - input.try(BorderRadiusSize::parse).or_else(|()| { +pub fn parse_border_radius(context: &ParserContext, input: &mut Parser) -> Result { + input.try(|i| BorderRadiusSize::parse(context, i)).or_else(|()| { match_ignore_ascii_case! { try!(input.expect_ident()), "thin" => Ok(BorderRadiusSize::circle( LengthOrPercentage::Length(Length::from_px(1.)))), @@ -299,12 +299,8 @@ pub enum BorderWidth { Width(Length), } -impl BorderWidth { - pub fn from_length(length: Length) -> Self { - BorderWidth::Width(length) - } - - pub fn parse(input: &mut Parser) -> Result { +impl Parse for BorderWidth { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { match input.try(Length::parse_non_negative) { Ok(length) => Ok(BorderWidth::Width(length)), Err(_) => match_ignore_ascii_case! { try!(input.expect_ident()), @@ -317,6 +313,12 @@ impl BorderWidth { } } +impl BorderWidth { + pub fn from_length(length: Length) -> Self { + BorderWidth::Width(length) + } +} + impl ToCss for BorderWidth { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -409,7 +411,7 @@ impl Time { impl ComputedValueAsSpecified for Time {} impl Parse for Time { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { match input.next() { Ok(Token::Dimension(ref value, ref unit)) => { Time::parse_dimension(value.value, &unit) @@ -435,7 +437,7 @@ pub struct Number(pub CSSFloat); impl NoViewportPercentage for Number {} impl Parse for Number { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { parse_number(input).map(Number) } } @@ -482,7 +484,7 @@ pub struct Opacity(pub CSSFloat); impl NoViewportPercentage for Opacity {} impl Parse for Opacity { - fn parse(input: &mut Parser) -> Result { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { parse_number(input).map(Opacity) } } diff --git a/servo/components/style/values/specified/position.rs b/servo/components/style/values/specified/position.rs index 122237f8e6eb..ed9813cf02cb 100644 --- a/servo/components/style/values/specified/position.rs +++ b/servo/components/style/values/specified/position.rs @@ -9,7 +9,7 @@ use app_units::Au; use cssparser::{Parser, Token}; -use parser::Parse; +use parser::{Parse, ParserContext}; use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; @@ -181,14 +181,14 @@ impl Position { } impl Parse for Position { - fn parse(input: &mut Parser) -> Result { - let first = try!(PositionComponent::parse(input)); - let second = input.try(PositionComponent::parse) + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + let first = try!(PositionComponent::parse(context, input)); + let second = input.try(|i| PositionComponent::parse(context, i)) .unwrap_or(PositionComponent::Keyword(Keyword::Center)); // Try to parse third and fourth values - if let Ok(third) = input.try(PositionComponent::parse) { - if let Ok(fourth) = input.try(PositionComponent::parse) { + if let Ok(third) = input.try(|i| PositionComponent::parse(context, i)) { + if let Ok(fourth) = input.try(|i| PositionComponent::parse(context, i)) { // Handle 4 value background position Position::new(Some(second), Some(fourth), Some(first), Some(third)) } else { @@ -375,8 +375,8 @@ impl PositionComponent { } impl Parse for PositionComponent { - fn parse(input: &mut Parser) -> Result { - input.try(LengthOrPercentage::parse) + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + input.try(|i| LengthOrPercentage::parse(context, i)) .map(PositionComponent::Length) .or_else(|()| { match try!(input.next()) { diff --git a/servo/tests/unit/style/parsing/basic_shape.rs b/servo/tests/unit/style/parsing/basic_shape.rs index 6363e7772cac..342d732b5c21 100644 --- a/servo/tests/unit/style/parsing/basic_shape.rs +++ b/servo/tests/unit/style/parsing/basic_shape.rs @@ -2,8 +2,11 @@ * 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 cssparser::Parser; +use media_queries::CSSErrorReporterTest; use parsing::parse; -use style::parser::Parse; +use style::parser::{Parse, ParserContext}; +use style::stylesheets::Origin; use style::values::specified::basic_shape::*; use style_traits::ToCss; @@ -11,8 +14,8 @@ use style_traits::ToCss; // and their individual components macro_rules! assert_roundtrip_basicshape { ($fun:expr, $input:expr, $output:expr) => { - assert_roundtrip!($fun, $input, $output); - assert_roundtrip!(BasicShape::parse, $input, $output); + assert_roundtrip_with_context!($fun, $input, $output); + assert_roundtrip_with_context!(BasicShape::parse, $input, $output); } } diff --git a/servo/tests/unit/style/parsing/mod.rs b/servo/tests/unit/style/parsing/mod.rs index 8e12018a7a31..369e0b66bf06 100644 --- a/servo/tests/unit/style/parsing/mod.rs +++ b/servo/tests/unit/style/parsing/mod.rs @@ -5,32 +5,19 @@ //! Tests for parsing and serialization of values/properties use cssparser::Parser; +use media_queries::CSSErrorReporterTest; +use style::parser::ParserContext; +use style::stylesheets::Origin; -fn parse Result>(f: F, s: &str) -> Result { +fn parse Result>(f: F, s: &str) -> Result { + let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); + let context = ParserContext::new(Origin::Author, &url, Box::new(CSSErrorReporterTest)); let mut parser = Parser::new(s); - f(&mut parser) + f(&context, &mut parser) } - // This is a macro so that the file/line information // is preserved in the panic -macro_rules! assert_roundtrip { - ($fun:expr, $string:expr) => { - assert_roundtrip!($fun, $string, $string); - }; - ($fun:expr, $input:expr, $output:expr) => { - let parsed = $crate::parsing::parse($fun, $input) - .expect(&format!("Failed to parse {}", $input)); - let serialized = ToCss::to_css_string(&parsed); - assert_eq!(serialized, $output); - - let re_parsed = $crate::parsing::parse($fun, &serialized) - .expect(&format!("Failed to parse serialization {}", $input)); - let re_serialized = ToCss::to_css_string(&re_parsed); - assert_eq!(serialized, re_serialized); - } -} - macro_rules! assert_roundtrip_with_context { ($fun:expr, $string:expr) => { assert_roundtrip_with_context!($fun, $string, $string); @@ -46,13 +33,12 @@ macro_rules! assert_roundtrip_with_context { let mut parser = Parser::new(&serialized); let re_parsed = $fun(&context, &mut parser) - .expect(&format!("Failed to parse {}", $input)); + .expect(&format!("Failed to parse serialization {}", $input)); let re_serialized = ToCss::to_css_string(&re_parsed); assert_eq!(serialized, re_serialized); } } - macro_rules! parse_longhand { ($name:ident, $s:expr) => {{ let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); diff --git a/servo/tests/unit/style/parsing/position.rs b/servo/tests/unit/style/parsing/position.rs index e610e9cee2e7..5bb0d4145109 100644 --- a/servo/tests/unit/style/parsing/position.rs +++ b/servo/tests/unit/style/parsing/position.rs @@ -2,8 +2,11 @@ * 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 cssparser::Parser; +use media_queries::CSSErrorReporterTest; use parsing::parse; -use style::parser::Parse; +use style::parser::{Parse, ParserContext}; +use style::stylesheets::Origin; use style::values::specified::position::*; use style_traits::ToCss; @@ -12,38 +15,38 @@ fn test_position() { // Serialization is not actually specced // though these are the values expected by basic-shape // https://github.com/w3c/csswg-drafts/issues/368 - assert_roundtrip!(Position::parse, "center", "center center"); - assert_roundtrip!(Position::parse, "top left", "left top"); - assert_roundtrip!(Position::parse, "left top", "left top"); - assert_roundtrip!(Position::parse, "top right", "right top"); - assert_roundtrip!(Position::parse, "right top", "right top"); - assert_roundtrip!(Position::parse, "bottom left", "left bottom"); - assert_roundtrip!(Position::parse, "left bottom", "left bottom"); - assert_roundtrip!(Position::parse, "left center", "left center"); - assert_roundtrip!(Position::parse, "right center", "right center"); - assert_roundtrip!(Position::parse, "center top", "center top"); - assert_roundtrip!(Position::parse, "center bottom", "center bottom"); - assert_roundtrip!(Position::parse, "center 10px", "center 10px"); - assert_roundtrip!(Position::parse, "center 10%", "center 10%"); - assert_roundtrip!(Position::parse, "right 10%", "right 10%"); + assert_roundtrip_with_context!(Position::parse, "center", "center center"); + assert_roundtrip_with_context!(Position::parse, "top left", "left top"); + assert_roundtrip_with_context!(Position::parse, "left top", "left top"); + assert_roundtrip_with_context!(Position::parse, "top right", "right top"); + assert_roundtrip_with_context!(Position::parse, "right top", "right top"); + assert_roundtrip_with_context!(Position::parse, "bottom left", "left bottom"); + assert_roundtrip_with_context!(Position::parse, "left bottom", "left bottom"); + assert_roundtrip_with_context!(Position::parse, "left center", "left center"); + assert_roundtrip_with_context!(Position::parse, "right center", "right center"); + assert_roundtrip_with_context!(Position::parse, "center top", "center top"); + assert_roundtrip_with_context!(Position::parse, "center bottom", "center bottom"); + assert_roundtrip_with_context!(Position::parse, "center 10px", "center 10px"); + assert_roundtrip_with_context!(Position::parse, "center 10%", "center 10%"); + assert_roundtrip_with_context!(Position::parse, "right 10%", "right 10%"); // Only keywords can be reordered assert!(parse(Position::parse, "top 40%").is_err()); assert!(parse(Position::parse, "40% left").is_err()); // 3 and 4 value serialization - assert_roundtrip!(Position::parse, "left 10px top 15px", "left 10px top 15px"); - assert_roundtrip!(Position::parse, "top 15px left 10px", "left 10px top 15px"); - assert_roundtrip!(Position::parse, "left 10% top 15px", "left 10% top 15px"); - assert_roundtrip!(Position::parse, "top 15px left 10%", "left 10% top 15px"); - assert_roundtrip!(Position::parse, "left top 15px", "left top 15px"); - assert_roundtrip!(Position::parse, "top 15px left", "left top 15px"); - assert_roundtrip!(Position::parse, "left 10px top", "left 10px top"); - assert_roundtrip!(Position::parse, "top left 10px", "left 10px top"); - assert_roundtrip!(Position::parse, "right 10px bottom", "right 10px bottom"); - assert_roundtrip!(Position::parse, "bottom right 10px", "right 10px bottom"); - assert_roundtrip!(Position::parse, "center right 10px", "right 10px center"); - assert_roundtrip!(Position::parse, "center bottom 10px", "center bottom 10px"); + assert_roundtrip_with_context!(Position::parse, "left 10px top 15px", "left 10px top 15px"); + assert_roundtrip_with_context!(Position::parse, "top 15px left 10px", "left 10px top 15px"); + assert_roundtrip_with_context!(Position::parse, "left 10% top 15px", "left 10% top 15px"); + assert_roundtrip_with_context!(Position::parse, "top 15px left 10%", "left 10% top 15px"); + assert_roundtrip_with_context!(Position::parse, "left top 15px", "left top 15px"); + assert_roundtrip_with_context!(Position::parse, "top 15px left", "left top 15px"); + assert_roundtrip_with_context!(Position::parse, "left 10px top", "left 10px top"); + assert_roundtrip_with_context!(Position::parse, "top left 10px", "left 10px top"); + assert_roundtrip_with_context!(Position::parse, "right 10px bottom", "right 10px bottom"); + assert_roundtrip_with_context!(Position::parse, "bottom right 10px", "right 10px bottom"); + assert_roundtrip_with_context!(Position::parse, "center right 10px", "right 10px center"); + assert_roundtrip_with_context!(Position::parse, "center bottom 10px", "center bottom 10px"); // Only horizontal and vertical keywords can have positions assert!(parse(Position::parse, "center 10px left 15px").is_err()); diff --git a/servo/tests/unit/style/parsing/selectors.rs b/servo/tests/unit/style/parsing/selectors.rs index dbbda99381e1..3654360b07cf 100644 --- a/servo/tests/unit/style/parsing/selectors.rs +++ b/servo/tests/unit/style/parsing/selectors.rs @@ -3,11 +3,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use cssparser::{Parser, ToCss}; +use media_queries::CSSErrorReporterTest; use selectors::parser::SelectorList; +use style::parser::ParserContext; use style::selector_parser::{SelectorImpl, SelectorParser}; use style::stylesheets::{Origin, Namespaces}; -fn parse(input: &mut Parser) -> Result, ()> { +fn parse(_context: &ParserContext, input: &mut Parser) -> Result, ()> { let mut ns = Namespaces::default(); ns.prefixes.insert("svg".into(), ns!(svg)); let parser = SelectorParser { @@ -19,8 +21,8 @@ fn parse(input: &mut Parser) -> Result, ()> { #[test] fn test_selectors() { - assert_roundtrip!(parse, "div"); - assert_roundtrip!(parse, "svg|circle"); - assert_roundtrip!(parse, "p:before", "p::before"); - assert_roundtrip!(parse, "[border = \"0\"]:-servo-nonzero-border ~ ::-servo-details-summary"); + assert_roundtrip_with_context!(parse, "div"); + assert_roundtrip_with_context!(parse, "svg|circle"); + assert_roundtrip_with_context!(parse, "p:before", "p::before"); + assert_roundtrip_with_context!(parse, "[border = \"0\"]:-servo-nonzero-border ~ ::-servo-details-summary"); }