From b24614f894bf5da7ee09f534e04352b27983ea95 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 28 Feb 2017 11:50:12 +1100 Subject: [PATCH 1/5] Resolve color:currentcolor during computing The keyword value "currentcolor" should be preserved rather than being replaced by the CSS-wide keyword "inherit" during parsing. --- components/script/dom/element.rs | 15 +++--- .../style/properties/longhand/color.mako.rs | 47 +++++++++++-------- ports/geckolib/glue.rs | 5 +- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 47177172895..ca4ec57773f 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -103,7 +103,7 @@ use style::matching::{common_style_affecting_attributes, rare_style_affecting_at use style::parser::ParserContextExtraData; use style::properties::{DeclaredValue, Importance}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; -use style::properties::longhands::{background_image, border_spacing, font_family, font_size, overflow_x}; +use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size, overflow_x}; use style::restyle_hints::RESTYLE_SELF; use style::rule_tree::CascadeLevel; use style::selector_parser::{NonTSPseudoClass, RestyleDamage, SelectorImpl, SelectorParser}; @@ -111,7 +111,7 @@ use style::sink::Push; use style::stylist::ApplicableDeclarationBlock; use style::thread_state; use style::values::CSSFloat; -use style::values::specified::{self, CSSColor, CSSRGBA}; +use style::values::specified::{self, CSSColor}; use stylesheet_loader::StylesheetOwner; // TODO: Update focus state when the top-level browsing context gains or loses system focus, @@ -441,10 +441,13 @@ impl LayoutElementHelpers for LayoutJS { if let Some(color) = color { hints.push(from_declaration( - PropertyDeclaration::Color(DeclaredValue::Value(CSSRGBA { - parsed: color, - authored: None, - })))); + PropertyDeclaration::Color(DeclaredValue::Value( + longhands::color::SpecifiedValue(CSSColor { + parsed: Color::RGBA(color), + authored: None, + }) + )) + )); } let font_family = if let Some(this) = self.downcast::() { diff --git a/components/style/properties/longhand/color.mako.rs b/components/style/properties/longhand/color.mako.rs index 6062db455be..136546e2e70 100644 --- a/components/style/properties/longhand/color.mako.rs +++ b/components/style/properties/longhand/color.mako.rs @@ -6,30 +6,46 @@ <% data.new_style_struct("Color", inherited=True) %> -<%helpers:raw_longhand name="color" need_clone="True" animatable="True" - spec="https://drafts.csswg.org/css-color/#color"> +<%helpers:longhand name="color" need_clone="True" animatable="True" + spec="https://drafts.csswg.org/css-color/#color"> use cssparser::Color as CSSParserColor; use cssparser::RGBA; + use std::fmt; + use style_traits::ToCss; + use values::HasViewportPercentage; use values::specified::{CSSColor, CSSRGBA}; impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; #[inline] - fn to_computed_value(&self, _context: &Context) -> computed_value::T { - self.parsed + fn to_computed_value(&self, context: &Context) -> computed_value::T { + match self.0.parsed { + CSSParserColor::RGBA(rgba) => rgba, + CSSParserColor::CurrentColor => context.inherited_style.get_color().clone_color(), + } } #[inline] fn from_computed_value(computed: &computed_value::T) -> Self { - CSSRGBA { - parsed: *computed, + SpecifiedValue(CSSColor { + parsed: CSSParserColor::RGBA(*computed), authored: None, - } + }) + } + } + + #[derive(Clone, PartialEq, Debug)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub struct SpecifiedValue(pub CSSColor); + no_viewport_percentage!(SpecifiedValue); + + impl ToCss for SpecifiedValue { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + self.0.to_css(dest) } } - pub type SpecifiedValue = CSSRGBA; pub mod computed_value { use cssparser; pub type T = cssparser::RGBA; @@ -38,16 +54,7 @@ pub fn get_initial_value() -> computed_value::T { RGBA::new(0, 0, 0, 255) // black } - pub fn parse_specified(context: &ParserContext, input: &mut Parser) - -> Result, ()> { - let value = try!(CSSColor::parse(context, input)); - let rgba = match value.parsed { - CSSParserColor::RGBA(rgba) => rgba, - CSSParserColor::CurrentColor => return Ok(DeclaredValue::Inherit) - }; - Ok(DeclaredValue::Value(CSSRGBA { - parsed: rgba, - authored: value.authored, - })) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + CSSColor::parse(context, input).map(SpecifiedValue) } - + diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 4026696825f..915b5e1a77b 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -1102,7 +1102,8 @@ pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations: use cssparser::Color; use style::gecko::values::convert_nscolor_to_rgba; use style::properties::{DeclaredValue, PropertyDeclaration, LonghandId}; - use style::values::specified::{CSSColor, CSSRGBA}; + use style::properties::longhands; + use style::values::specified::CSSColor; let declarations = RwLock::::as_arc(&declarations); let long = get_longhand_from_id!(property); @@ -1114,7 +1115,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations: BorderRightColor => color, BorderBottomColor => color, BorderLeftColor => color, - Color => CSSRGBA { parsed: rgba, authored: None }, + Color => longhands::color::SpecifiedValue(color), BackgroundColor => color, }; declarations.write().declarations.push((prop, Default::default())); From ce46e6d034fe215413c4ffdb6be5412f2c88dc84 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 28 Feb 2017 13:45:12 +1100 Subject: [PATCH 2/5] Remove raw_longhand helper function --- components/style/properties/helpers.mako.rs | 28 ++++++++------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index ca5806fc2de..41f3eff772f 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -4,23 +4,6 @@ <%! from data import Keyword, to_rust_ident, to_camel_case, LOGICAL_SIDES, PHYSICAL_SIDES, LOGICAL_SIZES %> -<%def name="longhand(name, **kwargs)"> - <%call expr="raw_longhand(name, **kwargs)"> - ${caller.body()} - % if not data.longhands_by_name[name].derived_from: - pub fn parse_specified(context: &ParserContext, input: &mut Parser) - % if data.longhands_by_name[name].boxed: - -> Result>, ()> { - parse(context, input).map(|result| DeclaredValue::Value(Box::new(result))) - % else: - -> Result, ()> { - parse(context, input).map(DeclaredValue::Value) - % endif - } - % endif - - - <%def name="predefined_type(name, type, initial_value, parse_method='parse', needs_context=True, vector=False, **kwargs)"> <%def name="predefined_type_inner(name, type, initial_value, parse_method)"> @@ -212,7 +195,7 @@ -<%def name="raw_longhand(*args, **kwargs)"> +<%def name="longhand(*args, **kwargs)"> <% property = data.declare_longhand(*args, **kwargs) if property is None: @@ -322,6 +305,15 @@ % endif } % if not property.derived_from: + pub fn parse_specified(context: &ParserContext, input: &mut Parser) + % if property.boxed: + -> Result>, ()> { + parse(context, input).map(|result| DeclaredValue::Value(Box::new(result))) + % else: + -> Result, ()> { + parse(context, input).map(DeclaredValue::Value) + % endif + } pub fn parse_declared(context: &ParserContext, input: &mut Parser) % if property.boxed: -> Result>, ()> { From 2e07ce7e84636a7b3db379c00e7ed7165a6a2791 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 28 Feb 2017 15:20:34 +1100 Subject: [PATCH 3/5] Add get_initial_specified_value to many longhands --- components/style/properties/helpers.mako.rs | 5 ++++- .../properties/longhand/background.mako.rs | 1 + .../style/properties/longhand/column.mako.rs | 7 +++++++ .../style/properties/longhand/font.mako.rs | 20 ++++++++++++++++++ .../longhand/inherited_text.mako.rs | 13 +++++++++++- .../style/properties/longhand/list.mako.rs | 2 +- .../style/properties/longhand/outline.mako.rs | 12 +++++++++++ .../style/properties/longhand/text.mako.rs | 7 ++++++- components/style/values/specified/length.rs | 6 ++++++ components/style/values/specified/mod.rs | 21 +++++++++++++++++++ 10 files changed, 90 insertions(+), 4 deletions(-) diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 41f3eff772f..aa5381d3fb7 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -5,7 +5,7 @@ <%! from data import Keyword, to_rust_ident, to_camel_case, LOGICAL_SIDES, PHYSICAL_SIDES, LOGICAL_SIZES %> <%def name="predefined_type(name, type, initial_value, parse_method='parse', - needs_context=True, vector=False, **kwargs)"> + needs_context=True, vector=False, initial_specified_value=None, **kwargs)"> <%def name="predefined_type_inner(name, type, initial_value, parse_method)"> #[allow(unused_imports)] use app_units::Au; @@ -15,6 +15,9 @@ pub use values::computed::${type} as T; } #[inline] pub fn get_initial_value() -> computed_value::T { ${initial_value} } + % if initial_specified_value: + #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { ${initial_specified_value} } + % endif #[allow(unused_variables)] #[inline] pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 6aa537b269a..429731b8158 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -8,6 +8,7 @@ ${helpers.predefined_type("background-color", "CSSColor", "::cssparser::Color::RGBA(::cssparser::RGBA::transparent())", + initial_specified_value="SpecifiedValue::transparent()", spec="https://drafts.csswg.org/css-backgrounds/#background-color", animatable=True, complex_color=True)} diff --git a/components/style/properties/longhand/column.mako.rs b/components/style/properties/longhand/column.mako.rs index f55524f5201..b3c782e5c2e 100644 --- a/components/style/properties/longhand/column.mako.rs +++ b/components/style/properties/longhand/column.mako.rs @@ -10,6 +10,7 @@ ${helpers.predefined_type("column-width", "length::LengthOrAuto", "Either::Second(Auto)", + initial_specified_value="Either::Second(Auto)", parse_method="parse_non_negative_length", extra_prefixes="moz", animatable=False, @@ -62,6 +63,11 @@ ${helpers.predefined_type("column-width", computed_value::T(None) } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue::Auto + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -146,6 +152,7 @@ ${helpers.single_keyword("column-fill", "auto balance", extra_prefixes="moz", // https://drafts.csswg.org/css-multicol-1/#crc ${helpers.predefined_type("column-rule-color", "CSSColor", "::cssparser::Color::CurrentColor", + initial_specified_value="specified::CSSColor::currentcolor()", products="gecko", animatable=True, extra_prefixes="moz", complex_color=True, need_clone=True, spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule-color")} diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 4b05c50b970..37c467b242f 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -326,6 +326,11 @@ ${helpers.single_keyword("font-variant-caps", computed_value::T::Weight400 // normal } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue::Normal + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -407,6 +412,11 @@ ${helpers.single_keyword("font-variant-caps", Au::from_px(FONT_MEDIUM_PX) } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue(specified::LengthOrPercentage::Length(NoCalcLength::medium())) + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -502,6 +512,11 @@ ${helpers.single_keyword("font-variant-caps", computed_value::T::None } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue::None + } + /// none | pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { use values::specified::Number; @@ -750,6 +765,11 @@ ${helpers.single_keyword("font-variant-position", computed_value::T::Normal } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue::Normal + } + pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { if input.try(|input| input.expect_ident_matching("normal")).is_ok() { Ok(SpecifiedValue::Normal) diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 60ca0ee5194..637c2776aa3 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -101,6 +101,11 @@ #[inline] pub fn get_initial_value() -> computed_value::T { computed_value::T::Normal } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue::Normal + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -1031,6 +1036,7 @@ ${helpers.single_keyword("text-align-last", ${helpers.predefined_type("text-emphasis-color", "CSSColor", "::cssparser::Color::CurrentColor", + initial_specified_value="specified::CSSColor::currentcolor()", products="gecko", animatable=True, complex_color=True, need_clone=True, spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-color")} @@ -1056,6 +1062,7 @@ ${helpers.predefined_type( ${helpers.predefined_type( "-webkit-text-stroke-color", "CSSColor", "CSSParserColor::CurrentColor", + initial_specified_value="specified::CSSColor::currentcolor()", products="gecko", animatable=True, complex_color=True, need_clone=True, spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke-color")} @@ -1066,7 +1073,7 @@ ${helpers.predefined_type( use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::specified::BorderWidth; + use values::specified::{BorderWidth, Length}; pub type SpecifiedValue = BorderWidth; @@ -1082,6 +1089,10 @@ ${helpers.predefined_type( #[inline] pub fn get_initial_value() -> computed_value::T { Au::from_px(0) } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + BorderWidth::from_length(Length::zero()) + } diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index 5f1bf103d7f..81ce62a32e1 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -38,7 +38,7 @@ ${helpers.single_keyword("list-style-type", """ spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type")} ${helpers.predefined_type("list-style-image", "UrlOrNone", "Either::Second(None_)", - animatable=False, + initial_specified_value="Either::Second(None_)", animatable=False, spec="https://drafts.csswg.org/css-lists/#propdef-list-style-image")} <%helpers:longhand name="quotes" animatable="False" diff --git a/components/style/properties/longhand/outline.mako.rs b/components/style/properties/longhand/outline.mako.rs index 8b2f51ef2ed..65be748c187 100644 --- a/components/style/properties/longhand/outline.mako.rs +++ b/components/style/properties/longhand/outline.mako.rs @@ -11,6 +11,7 @@ // TODO(pcwalton): `invert` ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::CurrentColor", + initial_specified_value="specified::CSSColor::currentcolor()", animatable=True, complex_color=True, need_clone=True, spec="https://drafts.csswg.org/css-ui/#propdef-outline-color")} @@ -39,6 +40,11 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr Either::Second(BorderStyle::none) } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + Either::Second(BorderStyle::none) + } + pub mod computed_value { pub type T = super::SpecifiedValue; } @@ -88,7 +94,13 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr use app_units::Au; pub type T = Au; } + pub use super::border_top_width::get_initial_value; + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue(specified::Length::NoCalc(specified::NoCalcLength::medium())) + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index 9b2a851bc6f..654eac072ae 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -169,6 +169,10 @@ ${helpers.single_keyword("unicode-bidi", #[inline] pub fn get_initial_value() -> computed_value::T { computed_value::none } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue::empty() + } /// none | [ underline || overline || line-through || blink ] pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { let mut result = SpecifiedValue::empty(); @@ -219,7 +223,8 @@ ${helpers.single_keyword("text-decoration-style", ${helpers.predefined_type( "text-decoration-color", "CSSColor", - "CSSParserColor::RGBA(RGBA::new(0, 0, 0, 255))", + "::cssparser::Color::CurrentColor", + initial_specified_value="specified::CSSColor::currentcolor()", complex_color=True, products="gecko", animatable=True, diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 8293622cbe5..97ef54845ab 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -344,6 +344,12 @@ impl NoCalcLength { *self == NoCalcLength::Absolute(Au(0)) } + #[inline] + /// Returns a `medium` length. + pub fn medium() -> NoCalcLength { + NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX)) + } + /// Get an absolute length from a px value. #[inline] pub fn from_px(px_value: CSSFloat) -> NoCalcLength { diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 4dc93972554..7584ec7bee8 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -78,6 +78,27 @@ impl ToCss for CSSColor { } } +impl CSSColor { + #[inline] + /// Returns currentcolor value. + pub fn currentcolor() -> CSSColor { + CSSColor { + parsed: cssparser::Color::CurrentColor, + authored: None, + } + } + + #[inline] + /// Returns transparent value. + pub fn transparent() -> CSSColor { + CSSColor { + parsed: cssparser::Color::RGBA(cssparser::RGBA::transparent()), + // This should probably be "transparent", but maybe it doesn't matter. + authored: None, + } + } +} + #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] From f33b0b4ea3e9295493fd543adbb2d9ef5cd0d380 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 28 Feb 2017 15:21:17 +1100 Subject: [PATCH 4/5] Have shorthand parsing functions return values Shorthands are responsible to set all its longhands to a proper value, rather than returning None. Fixes #15380. --- components/style/properties/helpers.mako.rs | 18 ++-- .../style/properties/properties.mako.rs | 13 ++- .../properties/shorthand/background.mako.rs | 22 ++--- .../style/properties/shorthand/border.mako.rs | 34 ++++--- .../style/properties/shorthand/box.mako.rs | 92 ++++++++----------- .../style/properties/shorthand/column.mako.rs | 12 +-- .../style/properties/shorthand/font.mako.rs | 35 +++---- .../shorthand/inherited_svg.mako.rs | 6 +- .../shorthand/inherited_text.mako.rs | 17 +--- .../style/properties/shorthand/list.mako.rs | 22 +++-- .../style/properties/shorthand/mask.mako.rs | 6 +- .../properties/shorthand/outline.mako.rs | 8 +- .../properties/shorthand/position.mako.rs | 16 ++-- .../style/properties/shorthand/text.mako.rs | 8 +- tests/unit/style/parsing/background.rs | 76 +++++++-------- tests/unit/style/parsing/border.rs | 50 +++++----- tests/unit/style/parsing/inherited_text.rs | 8 +- tests/unit/style/parsing/mask.rs | 56 +++++------ 18 files changed, 240 insertions(+), 259 deletions(-) diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index aa5381d3fb7..8b674a6c96e 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -492,8 +492,7 @@ pub struct Longhands { % for sub_property in shorthand.sub_properties: - pub ${sub_property.ident}: - Option, + pub ${sub_property.ident}: longhands::${sub_property.ident}::SpecifiedValue, % endfor } @@ -606,14 +605,11 @@ if let Ok(value) = value { % for sub_property in shorthand.sub_properties: declarations.push((PropertyDeclaration::${sub_property.camel_case}( - match value.${sub_property.ident} { - % if sub_property.boxed: - Some(value) => DeclaredValue::Value(Box::new(value)), - % else: - Some(value) => DeclaredValue::Value(value), - % endif - None => DeclaredValue::Initial, - } + % if sub_property.boxed: + DeclaredValue::Value(Box::new(value.${sub_property.ident})) + % else: + DeclaredValue::Value(value.${sub_property.ident}) + % endif ), Importance::Normal)); % endfor Ok(()) @@ -660,7 +656,7 @@ % endif Ok(Longhands { % for side in ["top", "right", "bottom", "left"]: - ${to_rust_ident(sub_property_pattern % side)}: Some(${side}), + ${to_rust_ident(sub_property_pattern % side)}: ${side}, % endfor }) } diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 924412cc91b..bec5065a3d5 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -88,6 +88,12 @@ pub mod longhands { <%include file="/longhand/xul.mako.rs" /> } +macro_rules! unwrap_or_initial { + ($prop: ident) => (unwrap_or_initial!($prop, $prop)); + ($prop: ident, $expr: expr) => + ($expr.unwrap_or_else(|| $prop::get_initial_specified_value())); +} + /// A module with code for all the shorthand css properties, and a few /// serialization helpers. #[allow(missing_docs)] @@ -343,13 +349,12 @@ impl PropertyDeclarationIdSet { % if property in shorthand.sub_properties: Some(ShorthandId::${shorthand.camel_case}) => { shorthands::${shorthand.ident}::parse_value(&context, input) - .map(|result| match result.${property.ident} { + .map(|result| { % if property.boxed: - Some(value) => DeclaredValue::Value(Box::new(value)), + DeclaredValue::Value(Box::new(result.${property.ident})) % else: - Some(value) => DeclaredValue::Value(value), + DeclaredValue::Value(result.${property.ident}) % endif - None => DeclaredValue::Initial, }) } % endif diff --git a/components/style/properties/shorthand/background.mako.rs b/components/style/properties/shorthand/background.mako.rs index 30c60e977ab..3404f6c9b26 100644 --- a/components/style/properties/shorthand/background.mako.rs +++ b/components/style/properties/shorthand/background.mako.rs @@ -115,15 +115,15 @@ })); Ok(Longhands { - background_color: background_color, - background_image: Some(background_image), - background_position_x: Some(background_position_x), - background_position_y: Some(background_position_y), - background_repeat: Some(background_repeat), - background_attachment: Some(background_attachment), - background_size: Some(background_size), - background_origin: Some(background_origin), - background_clip: Some(background_clip), + background_color: unwrap_or_initial!(background_color), + background_image: background_image, + background_position_x: background_position_x, + background_position_y: background_position_y, + background_repeat: background_repeat, + background_attachment: background_attachment, + background_size: background_size, + background_origin: background_origin, + background_clip: background_clip, }) } @@ -246,8 +246,8 @@ } Ok(Longhands { - background_position_x: Some(position_x), - background_position_y: Some(position_y), + background_position_x: position_x, + background_position_y: position_y, }) } diff --git a/components/style/properties/shorthand/border.mako.rs b/components/style/properties/shorthand/border.mako.rs index 93f6222f852..f6ae7df638e 100644 --- a/components/style/properties/shorthand/border.mako.rs +++ b/components/style/properties/shorthand/border.mako.rs @@ -24,7 +24,7 @@ ${helpers.four_sides_shorthand("border-style", "border-%s-style", 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}), + ${to_rust_ident('border-%s-width' % side)}: ${side}, % endfor }) } @@ -42,10 +42,10 @@ ${helpers.four_sides_shorthand("border-style", "border-%s-style", pub fn parse_border(context: &ParserContext, input: &mut Parser) - -> Result<(Option, - Option, - Option), ()> { - use values::specified; + -> Result<(specified::CSSColor, + specified::BorderStyle, + specified::BorderWidth), ()> { + use values::specified::{CSSColor, BorderStyle, BorderWidth}; let _unused = context; let mut color = None; let mut style = None; @@ -53,21 +53,21 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) let mut any = false; loop { if color.is_none() { - if let Ok(value) = input.try(|i| specified::CSSColor::parse(context, i)) { + if let Ok(value) = input.try(|i| CSSColor::parse(context, i)) { color = Some(value); any = true; continue } } if style.is_none() { - if let Ok(value) = input.try(|i| specified::BorderStyle::parse(context, i)) { + if let Ok(value) = input.try(|i| BorderStyle::parse(context, i)) { style = Some(value); any = true; continue } } if width.is_none() { - if let Ok(value) = input.try(|i| specified::BorderWidth::parse(context, i)) { + if let Ok(value) = input.try(|i| BorderWidth::parse(context, i)) { width = Some(value); any = true; continue @@ -75,7 +75,13 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) } break } - if any { Ok((color, style, width)) } else { Err(()) } + if any { + Ok((color.unwrap_or_else(|| CSSColor::currentcolor()), + style.unwrap_or(BorderStyle::none), + width.unwrap_or(BorderWidth::Medium))) + } else { + Err(()) + } } % for side, logical in ALL_SIDES: @@ -158,10 +164,10 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { 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), - border_bottom_right_radius: Some(radii.bottom_right), - border_bottom_left_radius: Some(radii.bottom_left), + border_top_left_radius: radii.top_left, + border_top_right_radius: radii.top_right, + border_bottom_right_radius: radii.bottom_right, + border_bottom_left_radius: radii.bottom_left, }) } @@ -254,7 +260,7 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) Ok(Longhands { % for name in "outset repeat slice source width".split(): - border_image_${name}: Some(border_image_${name}), + border_image_${name}: border_image_${name}, % endfor }) } diff --git a/components/style/properties/shorthand/box.mako.rs b/components/style/properties/shorthand/box.mako.rs index b91ecd5b506..d1b7ccb62f5 100644 --- a/components/style/properties/shorthand/box.mako.rs +++ b/components/style/properties/shorthand/box.mako.rs @@ -11,8 +11,8 @@ pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { let overflow = try!(overflow_x::parse(context, input)); Ok(Longhands { - overflow_x: Some(overflow), - overflow_y: Some(overflow_y::SpecifiedValue(overflow)), + overflow_x: overflow, + overflow_y: overflow_y::SpecifiedValue(overflow), }) } @@ -103,31 +103,25 @@ macro_rules! try_parse_one { } } - if input.try(|input| input.expect_ident_matching("none")).is_ok() { - return Ok(Longhands { - transition_property: None, - transition_duration: None, - transition_timing_function: None, - transition_delay: None, - }) - } - - 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 { - properties.push(result.transition_property); - durations.push(result.transition_duration); - timing_functions.push(result.transition_timing_function); - delays.push(result.transition_delay); + + if input.try(|input| input.expect_ident_matching("none")).is_err() { + let results = try!(input.parse_comma_separated(|i| parse_one_transition(context, i))); + for result in results { + properties.push(result.transition_property); + durations.push(result.transition_duration); + timing_functions.push(result.transition_timing_function); + delays.push(result.transition_delay); + } } Ok(Longhands { - transition_property: Some(transition_property::SpecifiedValue(properties)), - transition_duration: Some(transition_duration::SpecifiedValue(durations)), + transition_property: transition_property::SpecifiedValue(properties), + transition_duration: transition_duration::SpecifiedValue(durations), transition_timing_function: - Some(transition_timing_function::SpecifiedValue(timing_functions)), - transition_delay: Some(transition_delay::SpecifiedValue(delays)), + transition_timing_function::SpecifiedValue(timing_functions), + transition_delay: transition_delay::SpecifiedValue(delays), }) } @@ -258,21 +252,6 @@ macro_rules! try_parse_one { } } - if input.try(|input| input.expect_ident_matching("none")).is_ok() { - return Ok(Longhands { - animation_name: None, - animation_duration: None, - animation_timing_function: None, - animation_delay: None, - animation_iteration_count: None, - animation_direction: None, - animation_fill_mode: None, - animation_play_state: None, - }) - } - - let results = try!(input.parse_comma_separated(|i| parse_one_animation(context, i))); - let mut names = vec![]; let mut durations = vec![]; let mut timing_functions = vec![]; @@ -282,26 +261,29 @@ macro_rules! try_parse_one { let mut fill_modes = vec![]; let mut play_states = vec![]; - for result in results.into_iter() { - names.push(result.animation_name); - durations.push(result.animation_duration); - timing_functions.push(result.animation_timing_function); - delays.push(result.animation_delay); - iteration_counts.push(result.animation_iteration_count); - directions.push(result.animation_direction); - fill_modes.push(result.animation_fill_mode); - play_states.push(result.animation_play_state); + if input.try(|input| input.expect_ident_matching("none")).is_err() { + let results = try!(input.parse_comma_separated(|i| parse_one_animation(context, i))); + for result in results.into_iter() { + names.push(result.animation_name); + durations.push(result.animation_duration); + timing_functions.push(result.animation_timing_function); + delays.push(result.animation_delay); + iteration_counts.push(result.animation_iteration_count); + directions.push(result.animation_direction); + fill_modes.push(result.animation_fill_mode); + play_states.push(result.animation_play_state); + } } Ok(Longhands { - animation_name: Some(animation_name::SpecifiedValue(names)), - animation_duration: Some(animation_duration::SpecifiedValue(durations)), - animation_timing_function: Some(animation_timing_function::SpecifiedValue(timing_functions)), - animation_delay: Some(animation_delay::SpecifiedValue(delays)), - animation_iteration_count: Some(animation_iteration_count::SpecifiedValue(iteration_counts)), - animation_direction: Some(animation_direction::SpecifiedValue(directions)), - animation_fill_mode: Some(animation_fill_mode::SpecifiedValue(fill_modes)), - animation_play_state: Some(animation_play_state::SpecifiedValue(play_states)), + animation_name: animation_name::SpecifiedValue(names), + animation_duration: animation_duration::SpecifiedValue(durations), + animation_timing_function: animation_timing_function::SpecifiedValue(timing_functions), + animation_delay: animation_delay::SpecifiedValue(delays), + animation_iteration_count: animation_iteration_count::SpecifiedValue(iteration_counts), + animation_direction: animation_direction::SpecifiedValue(directions), + animation_fill_mode: animation_fill_mode::SpecifiedValue(fill_modes), + animation_play_state: animation_play_state::SpecifiedValue(play_states), }) } @@ -364,8 +346,8 @@ macro_rules! try_parse_one { pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { let result = try!(scroll_snap_type_x::parse(context, input)); Ok(Longhands { - scroll_snap_type_x: Some(result), - scroll_snap_type_y: Some(result), + scroll_snap_type_x: result, + scroll_snap_type_y: result, }) } diff --git a/components/style/properties/shorthand/column.mako.rs b/components/style/properties/shorthand/column.mako.rs index eac7020da78..0fe39cbb2d1 100644 --- a/components/style/properties/shorthand/column.mako.rs +++ b/components/style/properties/shorthand/column.mako.rs @@ -43,8 +43,8 @@ Err(()) } else { Ok(Longhands { - column_count: column_count, - column_width: column_width, + column_count: unwrap_or_initial!(column_count), + column_width: unwrap_or_initial!(column_width), }) } } @@ -87,11 +87,9 @@ } if any { Ok(Longhands { - % for name in "width style".split(): - column_rule_${name}: column_rule_${name} - .or(Some(column_rule_${name}::get_initial_specified_value())), - % endfor - column_rule_color: column_rule_color, + column_rule_width: unwrap_or_initial!(column_rule_width), + column_rule_style: unwrap_or_initial!(column_rule_style), + column_rule_color: unwrap_or_initial!(column_rule_color), }) } else { Err(()) diff --git a/components/style/properties/shorthand/font.mako.rs b/components/style/properties/shorthand/font.mako.rs index 2a89e461ad0..22d3001d656 100644 --- a/components/style/properties/shorthand/font.mako.rs +++ b/components/style/properties/shorthand/font.mako.rs @@ -14,6 +14,12 @@ spec="https://drafts.csswg.org/css-fonts-3/#propdef-font"> use properties::longhands::{font_style, font_variant, font_weight, font_stretch}; use properties::longhands::{font_size, line_height}; + % if product == "gecko": + use properties::longhands::{font_size_adjust, font_kerning, font_variant_caps, font_variant_position}; + % endif + % if product == "none": + use properties::longhands::font_language_override; + % endif use properties::longhands::font_family::SpecifiedValue as FontFamily; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { @@ -72,22 +78,19 @@ }; let family = FontFamily::parse(input)?; Ok(Longhands { - font_style: style, - font_variant: variant, - font_weight: weight, - font_stretch: stretch, - font_size: size, - line_height: line_height, - font_family: Some(family), - % if product == "gecko": - font_size_adjust: None, - font_kerning: None, - font_variant_caps: None, - font_variant_position: None, - % endif - % if product == "none": - font_language_override: None, - % endif + % for name in "style variant weight stretch size".split(): + font_${name}: unwrap_or_initial!(font_${name}, ${name}), + % endfor + line_height: unwrap_or_initial!(line_height), + font_family: family, + % if product == "gecko": + % for name in "size_adjust kerning variant_caps variant_position".split(): + font_${name}: font_${name}::get_initial_specified_value(), + % endfor + % endif + % if product == "none": + font_language_override: font_language_override::get_initial_specified_value(), + % endif }) } diff --git a/components/style/properties/shorthand/inherited_svg.mako.rs b/components/style/properties/shorthand/inherited_svg.mako.rs index 81be3b777a4..14a5de0cfdf 100644 --- a/components/style/properties/shorthand/inherited_svg.mako.rs +++ b/components/style/properties/shorthand/inherited_svg.mako.rs @@ -14,9 +14,9 @@ let url = UrlOrNone::parse(context, input)?; Ok(Longhands { - marker_start: Some(url.clone()), - marker_mid: Some(url.clone()), - marker_end: Some(url), + marker_start: url.clone(), + marker_mid: url.clone(), + marker_end: url, }) } diff --git a/components/style/properties/shorthand/inherited_text.mako.rs b/components/style/properties/shorthand/inherited_text.mako.rs index f97c129590d..3012f21b7e3 100644 --- a/components/style/properties/shorthand/inherited_text.mako.rs +++ b/components/style/properties/shorthand/inherited_text.mako.rs @@ -29,13 +29,9 @@ break } if color.is_some() || style.is_some() { - if style.is_none() { - style = Some(text_emphasis_style::get_initial_specified_value()); - } - Ok(Longhands { - text_emphasis_color: color, - text_emphasis_style: style, + text_emphasis_color: unwrap_or_initial!(text_emphasis_color, color), + text_emphasis_style: unwrap_or_initial!(text_emphasis_style, style), }) } else { Err(()) @@ -68,13 +64,9 @@ -webkit-text-stroke-width" products="gecko" spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke"> - use cssparser::Color as CSSParserColor; use properties::longhands::{_webkit_text_stroke_color, _webkit_text_stroke_width}; - use values::specified::CSSColor; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { - use values::specified::{BorderWidth, Length}; - let mut color = None; let mut width = None; loop { @@ -96,9 +88,8 @@ if color.is_some() || width.is_some() { Ok(Longhands { - _webkit_text_stroke_color: color.or(Some(CSSColor { parsed: CSSParserColor::CurrentColor, - authored: None })), - _webkit_text_stroke_width: width.or(Some(BorderWidth::from_length(Length::zero()))), + _webkit_text_stroke_color: unwrap_or_initial!(_webkit_text_stroke_color, color), + _webkit_text_stroke_width: unwrap_or_initial!(_webkit_text_stroke_width, width), }) } else { Err(()) diff --git a/components/style/properties/shorthand/list.mako.rs b/components/style/properties/shorthand/list.mako.rs index 95b27da2a81..6f1c8707fe0 100644 --- a/components/style/properties/shorthand/list.mako.rs +++ b/components/style/properties/shorthand/list.mako.rs @@ -51,6 +51,8 @@ break } + let position = unwrap_or_initial!(list_style_position, position); + // If there are two `none`s, then we can't have a type or image; if there is one `none`, // then we can't have both a type *and* an image; if there is no `none` then we're fine as // long as we parsed something. @@ -58,36 +60,36 @@ (true, 2, None, None) => { Ok(Longhands { list_style_position: position, - list_style_image: Some(Either::Second(None_)), - list_style_type: Some(list_style_type::SpecifiedValue::none), + list_style_image: Either::Second(None_), + list_style_type: list_style_type::SpecifiedValue::none, }) } (true, 1, None, Some(image)) => { Ok(Longhands { list_style_position: position, - list_style_image: Some(image), - list_style_type: Some(list_style_type::SpecifiedValue::none), + list_style_image: image, + list_style_type: list_style_type::SpecifiedValue::none, }) } (true, 1, Some(list_style_type), None) => { Ok(Longhands { list_style_position: position, - list_style_image: Some(Either::Second(None_)), - list_style_type: Some(list_style_type), + list_style_image: Either::Second(None_), + list_style_type: list_style_type, }) } (true, 1, None, None) => { Ok(Longhands { list_style_position: position, - list_style_image: Some(Either::Second(None_)), - list_style_type: Some(list_style_type::SpecifiedValue::none), + list_style_image: Either::Second(None_), + list_style_type: list_style_type::SpecifiedValue::none, }) } (true, 0, list_style_type, image) => { Ok(Longhands { list_style_position: position, - list_style_image: image, - list_style_type: list_style_type, + list_style_image: unwrap_or_initial!(list_style_image, image), + list_style_type: unwrap_or_initial!(list_style_type), }) } _ => Err(()), diff --git a/components/style/properties/shorthand/mask.mako.rs b/components/style/properties/shorthand/mask.mako.rs index 0d07e108d31..34b4f5308a4 100644 --- a/components/style/properties/shorthand/mask.mako.rs +++ b/components/style/properties/shorthand/mask.mako.rs @@ -115,7 +115,7 @@ Ok(Longhands { % for name in "image mode position_x position_y size repeat origin clip composite".split(): - mask_${name}: Some(mask_${name}), + mask_${name}: mask_${name}, % endfor }) } @@ -263,8 +263,8 @@ } Ok(Longhands { - mask_position_x: Some(position_x), - mask_position_y: Some(position_y), + mask_position_x: position_x, + mask_position_y: position_y, }) } diff --git a/components/style/properties/shorthand/outline.mako.rs b/components/style/properties/shorthand/outline.mako.rs index 70fee7f9536..803a80afff9 100644 --- a/components/style/properties/shorthand/outline.mako.rs +++ b/components/style/properties/shorthand/outline.mako.rs @@ -6,7 +6,7 @@ <%helpers:shorthand name="outline" sub_properties="outline-color outline-style outline-width" spec="https://drafts.csswg.org/css-ui/#propdef-outline"> - use properties::longhands::{outline_width, outline_style}; + use properties::longhands::{outline_color, outline_width, outline_style}; use values::specified; use parser::Parse; @@ -42,9 +42,9 @@ } if any { Ok(Longhands { - outline_color: color, - outline_style: style, - outline_width: width, + outline_color: unwrap_or_initial!(outline_color, color), + outline_style: unwrap_or_initial!(outline_style, style), + outline_width: unwrap_or_initial!(outline_width, width), }) } else { Err(()) diff --git a/components/style/properties/shorthand/position.mako.rs b/components/style/properties/shorthand/position.mako.rs index b5673925996..78286951dae 100644 --- a/components/style/properties/shorthand/position.mako.rs +++ b/components/style/properties/shorthand/position.mako.rs @@ -31,8 +31,8 @@ return Err(()) } Ok(Longhands { - flex_direction: direction, - flex_wrap: wrap, + flex_direction: unwrap_or_initial!(flex_direction, direction), + flex_wrap: unwrap_or_initial!(flex_wrap, wrap), }) } @@ -73,9 +73,9 @@ if input.try(|input| input.expect_ident_matching("none")).is_ok() { return Ok(Longhands { - flex_grow: Some(Number(0.0)), - flex_shrink: Some(Number(0.0)), - flex_basis: Some(LengthOrPercentageOrAutoOrContent::Auto) + flex_grow: Number(0.0), + flex_shrink: Number(0.0), + flex_basis: LengthOrPercentageOrAutoOrContent::Auto }) } loop { @@ -99,9 +99,9 @@ return Err(()) } Ok(Longhands { - flex_grow: grow.or(Some(Number(1.0))), - flex_shrink: shrink.or(Some(Number(1.0))), - flex_basis: basis.or(Some(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero()))) + flex_grow: grow.unwrap_or(Number(1.0)), + flex_shrink: shrink.unwrap_or(Number(1.0)), + flex_basis: basis.unwrap_or(LengthOrPercentageOrAutoOrContent::Length(NoCalcLength::zero())) }) } diff --git a/components/style/properties/shorthand/text.mako.rs b/components/style/properties/shorthand/text.mako.rs index 2be6bd80867..278459a339c 100644 --- a/components/style/properties/shorthand/text.mako.rs +++ b/components/style/properties/shorthand/text.mako.rs @@ -13,7 +13,6 @@ spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration"> use cssparser::Color as CSSParserColor; use properties::longhands::{text_decoration_color, text_decoration_line, text_decoration_style}; - use values::specified::CSSColor; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { let (mut color, mut line, mut style, mut any) = (None, None, None, false); @@ -41,10 +40,9 @@ } Ok(Longhands { - text_decoration_color: color.or(Some(CSSColor { parsed: CSSParserColor::CurrentColor, - authored: None })), - text_decoration_line: line.or(Some(text_decoration_line::computed_value::none)), - text_decoration_style: style.or(Some(text_decoration_style::computed_value::T::solid)), + text_decoration_color: unwrap_or_initial!(text_decoration_color, color), + text_decoration_line: unwrap_or_initial!(text_decoration_line, line), + text_decoration_style: unwrap_or_initial!(text_decoration_style, style), }) } diff --git a/tests/unit/style/parsing/background.rs b/tests/unit/style/parsing/background.rs index f5a6ceda850..6d1c1f0e954 100644 --- a/tests/unit/style/parsing/background.rs +++ b/tests/unit/style/parsing/background.rs @@ -20,15 +20,15 @@ fn background_shorthand_should_parse_all_available_properties_when_specified() { content-box red"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_image.unwrap(), parse_longhand!(background_image, "url(\"http://servo/test.png\")")); - assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "center")); - assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "top")); - assert_eq!(result.background_size.unwrap(), parse_longhand!(background_size, "200px 200px")); - assert_eq!(result.background_repeat.unwrap(), parse_longhand!(background_repeat, "repeat-x")); - assert_eq!(result.background_attachment.unwrap(), parse_longhand!(background_attachment, "fixed")); - assert_eq!(result.background_origin.unwrap(), parse_longhand!(background_origin, "padding-box")); - assert_eq!(result.background_clip.unwrap(), parse_longhand!(background_clip, "content-box")); - assert_eq!(result.background_color.unwrap(), parse_longhand!(background_color, "red")); + assert_eq!(result.background_image, parse_longhand!(background_image, "url(\"http://servo/test.png\")")); + assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "center")); + assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "top")); + assert_eq!(result.background_size, parse_longhand!(background_size, "200px 200px")); + assert_eq!(result.background_repeat, parse_longhand!(background_repeat, "repeat-x")); + assert_eq!(result.background_attachment, parse_longhand!(background_attachment, "fixed")); + assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box")); + assert_eq!(result.background_clip, parse_longhand!(background_clip, "content-box")); + assert_eq!(result.background_color, parse_longhand!(background_color, "red")); } #[test] @@ -38,27 +38,27 @@ fn background_shorthand_should_parse_when_some_fields_set() { let mut parser = Parser::new("14px 40px repeat-y"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "14px")); - assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "40px")); - assert_eq!(result.background_repeat.unwrap(), parse_longhand!(background_repeat, "repeat-y")); + assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "14px")); + assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "40px")); + assert_eq!(result.background_repeat, parse_longhand!(background_repeat, "repeat-y")); let mut parser = Parser::new("url(\"http://servo/test.png\") repeat blue"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_image.unwrap(), parse_longhand!(background_image, "url(\"http://servo/test.png\")")); - assert_eq!(result.background_repeat.unwrap(), parse_longhand!(background_repeat, "repeat")); - assert_eq!(result.background_color.unwrap(), parse_longhand!(background_color, "blue")); + assert_eq!(result.background_image, parse_longhand!(background_image, "url(\"http://servo/test.png\")")); + assert_eq!(result.background_repeat, parse_longhand!(background_repeat, "repeat")); + assert_eq!(result.background_color, parse_longhand!(background_color, "blue")); let mut parser = Parser::new("padding-box"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_origin.unwrap(), parse_longhand!(background_origin, "padding-box")); - assert_eq!(result.background_clip.unwrap(), parse_longhand!(background_clip, "padding-box")); + assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box")); + assert_eq!(result.background_clip, parse_longhand!(background_clip, "padding-box")); let mut parser = Parser::new("url(\"http://servo/test.png\")"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_image.unwrap(), parse_longhand!(background_image, "url(\"http://servo/test.png\")")); + assert_eq!(result.background_image, parse_longhand!(background_image, "url(\"http://servo/test.png\")")); } #[test] @@ -69,17 +69,17 @@ fn background_shorthand_should_parse_comma_separated_declarations() { center / 100% 100% no-repeat, white"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_image.unwrap(), parse_longhand!(background_image, "url(\"http://servo/test.png\"), \ + assert_eq!(result.background_image, parse_longhand!(background_image, "url(\"http://servo/test.png\"), \ url(\"http://servo/test.png\"), none")); - assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "left, center, 0%")); - assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "top, center, 0%")); - assert_eq!(result.background_repeat.unwrap(), parse_longhand!(background_repeat, "no-repeat, no-repeat, repeat")); - assert_eq!(result.background_clip.unwrap(), parse_longhand!(background_clip, "border-box, border-box, border-box")); - assert_eq!(result.background_origin.unwrap(), parse_longhand!(background_origin, "padding-box, padding-box, \ + assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "left, center, 0%")); + assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "top, center, 0%")); + assert_eq!(result.background_repeat, parse_longhand!(background_repeat, "no-repeat, no-repeat, repeat")); + assert_eq!(result.background_clip, parse_longhand!(background_clip, "border-box, border-box, border-box")); + assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box, padding-box, \ padding-box")); - assert_eq!(result.background_size.unwrap(), parse_longhand!(background_size, "auto auto, 100% 100%, auto auto")); - assert_eq!(result.background_attachment.unwrap(), parse_longhand!(background_attachment, "scroll, scroll, scroll")); - assert_eq!(result.background_color.unwrap(), parse_longhand!(background_color, "white")); + assert_eq!(result.background_size, parse_longhand!(background_size, "auto auto, 100% 100%, auto auto")); + assert_eq!(result.background_attachment, parse_longhand!(background_attachment, "scroll, scroll, scroll")); + assert_eq!(result.background_color, parse_longhand!(background_color, "white")); } #[test] @@ -89,15 +89,15 @@ fn background_shorthand_should_parse_position_and_size_correctly() { let mut parser = Parser::new("7px 4px"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "7px")); - assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "4px")); + assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "7px")); + assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "4px")); let mut parser = Parser::new("7px 4px / 30px 20px"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_position_x.unwrap(), parse_longhand!(background_position_x, "7px")); - assert_eq!(result.background_position_y.unwrap(), parse_longhand!(background_position_y, "4px")); - assert_eq!(result.background_size.unwrap(), parse_longhand!(background_size, "30px 20px")); + assert_eq!(result.background_position_x, parse_longhand!(background_position_x, "7px")); + assert_eq!(result.background_position_y, parse_longhand!(background_position_y, "4px")); + assert_eq!(result.background_size, parse_longhand!(background_size, "30px 20px")); let mut parser = Parser::new("/ 30px 20px"); assert!(background::parse_value(&context, &mut parser).is_err()); @@ -113,18 +113,18 @@ fn background_shorthand_should_parse_origin_and_clip_correctly() { let mut parser = Parser::new("padding-box content-box"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_origin.unwrap(), parse_longhand!(background_origin, "padding-box")); - assert_eq!(result.background_clip.unwrap(), parse_longhand!(background_clip, "content-box")); + assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box")); + assert_eq!(result.background_clip, parse_longhand!(background_clip, "content-box")); let mut parser = Parser::new("padding-box padding-box"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_origin.unwrap(), parse_longhand!(background_origin, "padding-box")); - assert_eq!(result.background_clip.unwrap(), parse_longhand!(background_clip, "padding-box")); + assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box")); + assert_eq!(result.background_clip, parse_longhand!(background_clip, "padding-box")); let mut parser = Parser::new("padding-box"); let result = background::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.background_origin.unwrap(), parse_longhand!(background_origin, "padding-box")); - assert_eq!(result.background_clip.unwrap(), parse_longhand!(background_clip, "padding-box")); + assert_eq!(result.background_origin, parse_longhand!(background_origin, "padding-box")); + assert_eq!(result.background_clip, parse_longhand!(background_clip, "padding-box")); } diff --git a/tests/unit/style/parsing/border.rs b/tests/unit/style/parsing/border.rs index fe6ef2ef087..ced526dea95 100644 --- a/tests/unit/style/parsing/border.rs +++ b/tests/unit/style/parsing/border.rs @@ -20,12 +20,12 @@ fn border_image_shorthand_should_parse_when_all_properties_specified() { round stretch"); let result = border_image::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.border_image_source.unwrap(), + assert_eq!(result.border_image_source, parse_longhand!(border_image_source, "linear-gradient(red, blue)")); - assert_eq!(result.border_image_slice.unwrap(), parse_longhand!(border_image_slice, "30 30% 45 fill")); - assert_eq!(result.border_image_width.unwrap(), parse_longhand!(border_image_width, "20px 40px")); - assert_eq!(result.border_image_outset.unwrap(), parse_longhand!(border_image_outset, "10px")); - assert_eq!(result.border_image_repeat.unwrap(), parse_longhand!(border_image_repeat, "round stretch")); + assert_eq!(result.border_image_slice, parse_longhand!(border_image_slice, "30 30% 45 fill")); + assert_eq!(result.border_image_width, parse_longhand!(border_image_width, "20px 40px")); + assert_eq!(result.border_image_outset, parse_longhand!(border_image_outset, "10px")); + assert_eq!(result.border_image_repeat, parse_longhand!(border_image_repeat, "round stretch")); } #[test] @@ -35,12 +35,12 @@ fn border_image_shorthand_should_parse_without_width() { let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill / / 10px round stretch"); let result = border_image::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.border_image_source.unwrap(), + assert_eq!(result.border_image_source, parse_longhand!(border_image_source, "linear-gradient(red, blue)")); - assert_eq!(result.border_image_slice.unwrap(), parse_longhand!(border_image_slice, "30 30% 45 fill")); - assert_eq!(result.border_image_outset.unwrap(), parse_longhand!(border_image_outset, "10px")); - assert_eq!(result.border_image_repeat.unwrap(), parse_longhand!(border_image_repeat, "round stretch")); - assert_eq!(result.border_image_width.unwrap(), border_image_width::get_initial_specified_value()); + assert_eq!(result.border_image_slice, parse_longhand!(border_image_slice, "30 30% 45 fill")); + assert_eq!(result.border_image_outset, parse_longhand!(border_image_outset, "10px")); + assert_eq!(result.border_image_repeat, parse_longhand!(border_image_repeat, "round stretch")); + assert_eq!(result.border_image_width, border_image_width::get_initial_specified_value()); } #[test] @@ -50,12 +50,12 @@ fn border_image_shorthand_should_parse_without_outset() { let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill / 20px 40px round"); let result = border_image::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.border_image_source.unwrap(), + assert_eq!(result.border_image_source, parse_longhand!(border_image_source, "linear-gradient(red, blue)")); - assert_eq!(result.border_image_slice.unwrap(), parse_longhand!(border_image_slice, "30 30% 45 fill")); - assert_eq!(result.border_image_width.unwrap(), parse_longhand!(border_image_width, "20px 40px")); - assert_eq!(result.border_image_repeat.unwrap(), parse_longhand!(border_image_repeat, "round")); - assert_eq!(result.border_image_outset.unwrap(), border_image_outset::get_initial_specified_value()); + assert_eq!(result.border_image_slice, parse_longhand!(border_image_slice, "30 30% 45 fill")); + assert_eq!(result.border_image_width, parse_longhand!(border_image_width, "20px 40px")); + assert_eq!(result.border_image_repeat, parse_longhand!(border_image_repeat, "round")); + assert_eq!(result.border_image_outset, border_image_outset::get_initial_specified_value()); } #[test] @@ -65,12 +65,12 @@ fn border_image_shorthand_should_parse_without_width_or_outset() { let mut parser = Parser::new("linear-gradient(red, blue) 30 30% 45 fill round"); let result = border_image::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.border_image_source.unwrap(), + assert_eq!(result.border_image_source, parse_longhand!(border_image_source, "linear-gradient(red, blue)")); - assert_eq!(result.border_image_slice.unwrap(), parse_longhand!(border_image_slice, "30 30% 45 fill")); - assert_eq!(result.border_image_repeat.unwrap(), parse_longhand!(border_image_repeat, "round")); - assert_eq!(result.border_image_width.unwrap(), border_image_width::get_initial_specified_value()); - assert_eq!(result.border_image_outset.unwrap(), border_image_outset::get_initial_specified_value()); + assert_eq!(result.border_image_slice, parse_longhand!(border_image_slice, "30 30% 45 fill")); + assert_eq!(result.border_image_repeat, parse_longhand!(border_image_repeat, "round")); + assert_eq!(result.border_image_width, border_image_width::get_initial_specified_value()); + assert_eq!(result.border_image_outset, border_image_outset::get_initial_specified_value()); } #[test] @@ -80,12 +80,12 @@ fn border_image_shorthand_should_parse_with_just_source() { let mut parser = Parser::new("linear-gradient(red, blue)"); let result = border_image::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.border_image_source.unwrap(), + assert_eq!(result.border_image_source, parse_longhand!(border_image_source, "linear-gradient(red, blue)")); - assert_eq!(result.border_image_slice.unwrap(), border_image_slice::get_initial_specified_value()); - assert_eq!(result.border_image_width.unwrap(), border_image_width::get_initial_specified_value()); - assert_eq!(result.border_image_outset.unwrap(), border_image_outset::get_initial_specified_value()); - assert_eq!(result.border_image_repeat.unwrap(), border_image_repeat::get_initial_specified_value()); + assert_eq!(result.border_image_slice, border_image_slice::get_initial_specified_value()); + assert_eq!(result.border_image_width, border_image_width::get_initial_specified_value()); + assert_eq!(result.border_image_outset, border_image_outset::get_initial_specified_value()); + assert_eq!(result.border_image_repeat, border_image_repeat::get_initial_specified_value()); } #[test] diff --git a/tests/unit/style/parsing/inherited_text.rs b/tests/unit/style/parsing/inherited_text.rs index 366497cf969..a9604f8dc09 100644 --- a/tests/unit/style/parsing/inherited_text.rs +++ b/tests/unit/style/parsing/inherited_text.rs @@ -115,14 +115,14 @@ fn webkit_text_stroke_shorthand_should_parse_properly() { let mut parser = Parser::new("thin red"); let result = _webkit_text_stroke::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result._webkit_text_stroke_color.unwrap(), parse_longhand!(_webkit_text_stroke_color, "red")); - assert_eq!(result._webkit_text_stroke_width.unwrap(), parse_longhand!(_webkit_text_stroke_width, "thin")); + assert_eq!(result._webkit_text_stroke_color, parse_longhand!(_webkit_text_stroke_color, "red")); + assert_eq!(result._webkit_text_stroke_width, parse_longhand!(_webkit_text_stroke_width, "thin")); // ensure its no longer sensitive to order let mut parser = Parser::new("red thin"); let result = _webkit_text_stroke::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result._webkit_text_stroke_color.unwrap(), parse_longhand!(_webkit_text_stroke_color, "red")); - assert_eq!(result._webkit_text_stroke_width.unwrap(), parse_longhand!(_webkit_text_stroke_width, "thin")); + assert_eq!(result._webkit_text_stroke_color, parse_longhand!(_webkit_text_stroke_color, "red")); + assert_eq!(result._webkit_text_stroke_width, parse_longhand!(_webkit_text_stroke_width, "thin")); } #[test] diff --git a/tests/unit/style/parsing/mask.rs b/tests/unit/style/parsing/mask.rs index ed655bc844d..b57f8a2b4b4 100644 --- a/tests/unit/style/parsing/mask.rs +++ b/tests/unit/style/parsing/mask.rs @@ -19,15 +19,15 @@ fn mask_shorthand_should_parse_all_available_properties_when_specified() { repeat-x padding-box border-box subtract"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_image.unwrap(), parse_longhand!(mask_image, "url(\"http://servo/test.png\")")); - assert_eq!(result.mask_mode.unwrap(), parse_longhand!(mask_mode, "luminance")); - assert_eq!(result.mask_position_x.unwrap(), parse_longhand!(mask_position_x, "7px")); - assert_eq!(result.mask_position_y.unwrap(), parse_longhand!(mask_position_y, "4px")); - assert_eq!(result.mask_size.unwrap(), parse_longhand!(mask_size, "70px 50px")); - assert_eq!(result.mask_repeat.unwrap(), parse_longhand!(mask_repeat, "repeat-x")); - assert_eq!(result.mask_origin.unwrap(), parse_longhand!(mask_origin, "padding-box")); - assert_eq!(result.mask_clip.unwrap(), parse_longhand!(mask_clip, "border-box")); - assert_eq!(result.mask_composite.unwrap(), parse_longhand!(mask_composite, "subtract")); + assert_eq!(result.mask_image, parse_longhand!(mask_image, "url(\"http://servo/test.png\")")); + assert_eq!(result.mask_mode, parse_longhand!(mask_mode, "luminance")); + assert_eq!(result.mask_position_x, parse_longhand!(mask_position_x, "7px")); + assert_eq!(result.mask_position_y, parse_longhand!(mask_position_y, "4px")); + assert_eq!(result.mask_size, parse_longhand!(mask_size, "70px 50px")); + assert_eq!(result.mask_repeat, parse_longhand!(mask_repeat, "repeat-x")); + assert_eq!(result.mask_origin, parse_longhand!(mask_origin, "padding-box")); + assert_eq!(result.mask_clip, parse_longhand!(mask_clip, "border-box")); + assert_eq!(result.mask_composite, parse_longhand!(mask_composite, "subtract")); } #[test] @@ -37,26 +37,26 @@ fn mask_shorthand_should_parse_when_some_fields_set() { let mut parser = Parser::new("14px 40px repeat-y"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_position_x.unwrap(), parse_longhand!(mask_position_x, "14px")); - assert_eq!(result.mask_position_y.unwrap(), parse_longhand!(mask_position_y, "40px")); - assert_eq!(result.mask_repeat.unwrap(), parse_longhand!(mask_repeat, "repeat-y")); + assert_eq!(result.mask_position_x, parse_longhand!(mask_position_x, "14px")); + assert_eq!(result.mask_position_y, parse_longhand!(mask_position_y, "40px")); + assert_eq!(result.mask_repeat, parse_longhand!(mask_repeat, "repeat-y")); let mut parser = Parser::new("url(\"http://servo/test.png\") repeat add"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_image.unwrap(), parse_longhand!(mask_image, "url(\"http://servo/test.png\")")); - assert_eq!(result.mask_repeat.unwrap(), parse_longhand!(mask_repeat, "repeat")); - assert_eq!(result.mask_composite.unwrap(), parse_longhand!(mask_composite, "add")); + assert_eq!(result.mask_image, parse_longhand!(mask_image, "url(\"http://servo/test.png\")")); + assert_eq!(result.mask_repeat, parse_longhand!(mask_repeat, "repeat")); + assert_eq!(result.mask_composite, parse_longhand!(mask_composite, "add")); let mut parser = Parser::new("intersect"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_composite.unwrap(), parse_longhand!(mask_composite, "intersect")); + assert_eq!(result.mask_composite, parse_longhand!(mask_composite, "intersect")); let mut parser = Parser::new("url(\"http://servo/test.png\")"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_image.unwrap(), parse_longhand!(mask_image, "url(\"http://servo/test.png\")")); + assert_eq!(result.mask_image, parse_longhand!(mask_image, "url(\"http://servo/test.png\")")); } #[test] @@ -66,15 +66,15 @@ fn mask_shorthand_should_parse_position_and_size_correctly() { let mut parser = Parser::new("7px 4px"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_position_x.unwrap(), parse_longhand!(mask_position_x, "7px")); - assert_eq!(result.mask_position_y.unwrap(), parse_longhand!(mask_position_y, "4px")); + assert_eq!(result.mask_position_x, parse_longhand!(mask_position_x, "7px")); + assert_eq!(result.mask_position_y, parse_longhand!(mask_position_y, "4px")); let mut parser = Parser::new("7px 4px / 30px 20px"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_position_x.unwrap(), parse_longhand!(mask_position_x, "7px")); - assert_eq!(result.mask_position_y.unwrap(), parse_longhand!(mask_position_y, "4px")); - assert_eq!(result.mask_size.unwrap(), parse_longhand!(mask_size, "30px 20px")); + assert_eq!(result.mask_position_x, parse_longhand!(mask_position_x, "7px")); + assert_eq!(result.mask_position_y, parse_longhand!(mask_position_y, "4px")); + assert_eq!(result.mask_size, parse_longhand!(mask_size, "30px 20px")); let mut parser = Parser::new("/ 30px 20px"); assert!(mask::parse_value(&context, &mut parser).is_err()); @@ -90,20 +90,20 @@ fn mask_shorthand_should_parse_origin_and_clip_correctly() { let mut parser = Parser::new("padding-box content-box"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_origin.unwrap(), parse_longhand!(mask_origin, "padding-box")); - assert_eq!(result.mask_clip.unwrap(), parse_longhand!(mask_clip, "content-box")); + assert_eq!(result.mask_origin, parse_longhand!(mask_origin, "padding-box")); + assert_eq!(result.mask_clip, parse_longhand!(mask_clip, "content-box")); let mut parser = Parser::new("padding-box padding-box"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_origin.unwrap(), parse_longhand!(mask_origin, "padding-box")); - assert_eq!(result.mask_clip.unwrap(), parse_longhand!(mask_clip, "padding-box")); + assert_eq!(result.mask_origin, parse_longhand!(mask_origin, "padding-box")); + assert_eq!(result.mask_clip, parse_longhand!(mask_clip, "padding-box")); let mut parser = Parser::new("padding-box"); let result = mask::parse_value(&context, &mut parser).unwrap(); - assert_eq!(result.mask_origin.unwrap(), parse_longhand!(mask_origin, "padding-box")); - assert_eq!(result.mask_clip.unwrap(), parse_longhand!(mask_clip, "padding-box")); + assert_eq!(result.mask_origin, parse_longhand!(mask_origin, "padding-box")); + assert_eq!(result.mask_clip, parse_longhand!(mask_clip, "padding-box")); } #[test] From e850d9572a023b07b3b72b6014f28ca7e5f66610 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 28 Feb 2017 17:17:54 +1100 Subject: [PATCH 5/5] Don't serialize currentcolor for border shorthand --- components/style/properties/shorthand/serialize.mako.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/style/properties/shorthand/serialize.mako.rs b/components/style/properties/shorthand/serialize.mako.rs index 017e77586eb..660c455f027 100644 --- a/components/style/properties/shorthand/serialize.mako.rs +++ b/components/style/properties/shorthand/serialize.mako.rs @@ -2,6 +2,7 @@ * 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::Color; use properties::DeclaredValue; use style_traits::ToCss; use values::specified::{BorderStyle, CSSColor}; @@ -84,7 +85,7 @@ fn serialize_directional_border(dest: &mut W, }; match *color { - DeclaredValue::Value(ref color) => { + DeclaredValue::Value(ref color) if color.parsed != Color::CurrentColor => { try!(write!(dest, " ")); color.to_css(dest) },