diff --git a/servo/components/style/properties/declaration_block.rs b/servo/components/style/properties/declaration_block.rs index 5ba7f52db14e..b65fc6698d68 100644 --- a/servo/components/style/properties/declaration_block.rs +++ b/servo/components/style/properties/declaration_block.rs @@ -214,16 +214,13 @@ impl PropertyDeclarationBlock { if !self.declarations.iter().all(|decl| decl.0.shorthands().contains(&shorthand)) { return Err(fmt::Error) } - let success = try!(shorthand.serialize_shorthand_to_buffer( - dest, - self.declarations.iter() - .map(get_declaration as fn(_) -> _), - &mut true) - ); - if success { - Ok(()) - } else { - Err(fmt::Error) + let iter = self.declarations.iter().map(get_declaration as fn(_) -> _); + match shorthand.get_shorthand_appendable_value(iter) { + Some(AppendableValue::Css(css)) => dest.write_str(css), + Some(AppendableValue::DeclarationsForShorthand(_, decls)) => { + shorthand.longhands_to_css(decls, dest) + } + _ => Ok(()) } } } diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index 3da2bed9546b..396f38c66a4c 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -978,7 +978,8 @@ fn static_assert() { <% skip_box_longhands= """display overflow-y vertical-align -moz-binding page-break-before page-break-after - scroll-snap-points-x scroll-snap-points-y transform""" %> + scroll-snap-points-x scroll-snap-points-y transform + scroll-snap-type-y""" %> <%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}"> // We manually-implement the |display| property until we get general @@ -1220,6 +1221,11 @@ fn static_assert() { pub fn copy_transform_from(&mut self, other: &Self) { unsafe { self.gecko.mSpecifiedTransform.set(&other.gecko.mSpecifiedTransform); } } + + <% scroll_snap_type_keyword = Keyword("scroll-snap-type", "none mandatory proximity") %> + + ${impl_keyword('scroll_snap_type_y', 'mScrollSnapTypeY', scroll_snap_type_keyword, need_clone=False)} + <%def name="simple_image_array_property(name, shorthand, field_name)"> diff --git a/servo/components/style/properties/longhand/box.mako.rs b/servo/components/style/properties/longhand/box.mako.rs index 41ab2e5909c0..fc16ba267d78 100644 --- a/servo/components/style/properties/longhand/box.mako.rs +++ b/servo/components/style/properties/longhand/box.mako.rs @@ -1474,11 +1474,12 @@ ${helpers.single_keyword("scroll-snap-type-x", animatable=False)} // Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type-y -${helpers.single_keyword("scroll-snap-type-y", - "none mandatory proximity", - products="gecko", - gecko_constant_prefix="NS_STYLE_SCROLL_SNAP_TYPE", - animatable=False)} +<%helpers:longhand products="gecko" name="scroll-snap-type-y" animatable="False"> + pub use super::scroll_snap_type_x::SpecifiedValue; + pub use super::scroll_snap_type_x::computed_value; + pub use super::scroll_snap_type_x::get_initial_value; + pub use super::scroll_snap_type_x::parse; + // Compositing and Blending Level 1 // http://www.w3.org/TR/compositing-1/ diff --git a/servo/components/style/properties/shorthand/box.mako.rs b/servo/components/style/properties/shorthand/box.mako.rs index 2465a91ae8a0..d21cba8195ba 100644 --- a/servo/components/style/properties/shorthand/box.mako.rs +++ b/servo/components/style/properties/shorthand/box.mako.rs @@ -297,3 +297,37 @@ macro_rules! try_parse_one { } } + +<%helpers:shorthand name="scroll-snap-type" products="gecko" + sub_properties="scroll-snap-type-x scroll-snap-type-y"> + use properties::longhands::scroll_snap_type_x; + + 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), + }) + } + + impl<'a> LonghandsToSerialize<'a> { + // Serializes into the single keyword value if both scroll-snap-type and scroll-snap-type-y are same. + // Otherwise into an empty string. This is done to match Gecko's behaviour. + fn to_css_declared(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + let x_and_y_equal = match (self.scroll_snap_type_x, self.scroll_snap_type_y) { + (&DeclaredValue::Value(ref x_value), &DeclaredValue::Value(ref y_value)) => { + *x_value == *y_value + }, + (&DeclaredValue::Initial, &DeclaredValue::Initial) => true, + (&DeclaredValue::Inherit, &DeclaredValue::Inherit) => true, + (x, y) => { *x == *y }, + }; + + if x_and_y_equal { + self.scroll_snap_type_x.to_css(dest) + } else { + Ok(()) + } + } + } + diff --git a/servo/tests/unit/style/properties/serialization.rs b/servo/tests/unit/style/properties/serialization.rs index 746a45b252ef..96b0004b8431 100644 --- a/servo/tests/unit/style/properties/serialization.rs +++ b/servo/tests/unit/style/properties/serialization.rs @@ -1006,4 +1006,53 @@ mod shorthand_serialization { ); } } + + mod scroll_snap_type { + pub use super::*; + use style::properties::longhands::scroll_snap_type_x::computed_value::T as ScrollSnapTypeXValue; + + #[test] + fn should_serialize_to_empty_string_if_sub_types_not_equal() { + let declarations = vec![ + (PropertyDeclaration::ScrollSnapTypeX(DeclaredValue::Value(ScrollSnapTypeXValue::mandatory)), + Importance::Normal), + (PropertyDeclaration::ScrollSnapTypeY(DeclaredValue::Value(ScrollSnapTypeXValue::none)), + Importance::Normal) + ]; + + let block = PropertyDeclarationBlock { + declarations: declarations, + important_count: 0 + }; + + let mut s = String::new(); + + let x = block.single_value_to_css("scroll-snap-type", &mut s); + + assert_eq!(x.is_ok(), true); + assert_eq!(s, ""); + } + + #[test] + fn should_serialize_to_single_value_if_sub_types_are_equal() { + let declarations = vec![ + (PropertyDeclaration::ScrollSnapTypeX(DeclaredValue::Value(ScrollSnapTypeXValue::mandatory)), + Importance::Normal), + (PropertyDeclaration::ScrollSnapTypeY(DeclaredValue::Value(ScrollSnapTypeXValue::mandatory)), + Importance::Normal) + ]; + + let block = PropertyDeclarationBlock { + declarations: declarations, + important_count: 0 + }; + + let mut s = String::new(); + + let x = block.single_value_to_css("scroll-snap-type", &mut s); + + assert_eq!(x.is_ok(), true); + assert_eq!(s, "mandatory"); + } + } }