diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 2f24629b5e4..a3b062a5f4b 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -53,6 +53,7 @@ use style::computed_values::position; use style::context::SharedStyleContext; use style::logical_geometry::Direction; use style::properties::ServoComputedValues; +use style::properties::longhands::list_style_image; use style::selector_parser::{PseudoElement, RestyleDamage}; use style::servo::restyle_damage::{BUBBLE_ISIZES, RECONSTRUCT_FLOW}; use style::values::Either; @@ -1206,13 +1207,13 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> -> ConstructionResult { let flotation = FloatKind::from_property(flotation); let marker_fragments = match node.style(self.style_context()).get_list().list_style_image { - Either::First(ref url_value) => { + list_style_image::computed_value::T(Either::First(ref url_value)) => { let image_info = box ImageFragmentInfo::new(url_value.url().map(|u| u.clone()), node, &self.layout_context); vec![Fragment::new(node, SpecificFragmentInfo::Image(image_info), self.layout_context)] } - Either::Second(_none) => { + list_style_image::computed_value::T(Either::Second(_none)) => { match ListStyleTypeContent::from_list_style_type(node.style(self.style_context()) .get_list() .list_style_type) { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 832aa8114dd..49cf7695833 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -37,8 +37,8 @@ use gecko_bindings::bindings::Gecko_StyleTransition_SetUnsupportedProperty; use gecko_bindings::bindings::Gecko_NewCSSShadowArray; use gecko_bindings::bindings::Gecko_nsStyleFont_SetLang; use gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom; -use gecko_bindings::bindings::Gecko_SetListStyleImage; use gecko_bindings::bindings::Gecko_SetListStyleImageNone; +use gecko_bindings::bindings::Gecko_SetListStyleImageImageValue; use gecko_bindings::bindings::Gecko_SetListStyleType; use gecko_bindings::bindings::Gecko_SetNullImageValue; use gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull; @@ -2964,15 +2964,15 @@ fn static_assert() { pub fn set_list_style_image(&mut self, image: longhands::list_style_image::computed_value::T) { use values::Either; match image { - Either::Second(_none) => { + longhands::list_style_image::computed_value::T(Either::Second(_none)) => { unsafe { Gecko_SetListStyleImageNone(&mut self.gecko); } } - Either::First(ref url) => { + longhands::list_style_image::computed_value::T(Either::First(ref url)) => { unsafe { - Gecko_SetListStyleImage(&mut self.gecko, - url.for_ffi()); + Gecko_SetListStyleImageImageValue(&mut self.gecko, + url.image_value.clone().unwrap().get()); } // We don't need to record this struct as uncacheable, like when setting // background-image to a url() value, since only properties in reset structs diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index cf9cc65122d..ece28aaf4ec 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -37,9 +37,55 @@ ${helpers.single_keyword("list-style-type", """ animation_value_type="none", spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type")} -${helpers.predefined_type("list-style-image", "UrlOrNone", "Either::Second(None_)", - initial_specified_value="Either::Second(None_)", animation_value_type="none", - spec="https://drafts.csswg.org/css-lists/#propdef-list-style-image")} +<%helpers:longhand name="list-style-image" animation_value_type="none" + boxed="${product == 'gecko'}" + spec="https://drafts.csswg.org/css-lists/#propdef-list-style-image"> + use std::fmt; + use values::HasViewportPercentage; + use values::computed::ComputedValueAsSpecified; + use values::specified::UrlOrNone; + pub use self::computed_value::T as SpecifiedValue; + use style_traits::ToCss; + + pub mod computed_value { + use values::specified::UrlOrNone; + + #[derive(Debug, Clone, PartialEq)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub struct T(pub UrlOrNone); + } + + + impl ComputedValueAsSpecified for SpecifiedValue {} + 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) + } + } + + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T(Either::Second(None_)) + } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue(Either::Second(None_)) + } + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + % if product == "gecko": + let mut value = input.try(|input| UrlOrNone::parse(context, input))?; + if let Either::First(ref mut url) = value { + url.build_image_value(); + } + % else : + let value = input.try(|input| UrlOrNone::parse(context, input))?; + % endif + + return Ok(SpecifiedValue(value)); + } + <%helpers:longhand name="quotes" animation_value_type="none" spec="https://drafts.csswg.org/css-content/#propdef-quotes"> diff --git a/components/style/properties/shorthand/list.mako.rs b/components/style/properties/shorthand/list.mako.rs index cd8cc0775dd..55a3448cf3f 100644 --- a/components/style/properties/shorthand/list.mako.rs +++ b/components/style/properties/shorthand/list.mako.rs @@ -60,7 +60,7 @@ (true, 2, None, None) => { Ok(Longhands { list_style_position: position, - list_style_image: Either::Second(None_), + list_style_image: list_style_image::SpecifiedValue(Either::Second(None_)), list_style_type: list_style_type::SpecifiedValue::none, }) } @@ -74,14 +74,14 @@ (true, 1, Some(list_style_type), None) => { Ok(Longhands { list_style_position: position, - list_style_image: Either::Second(None_), + list_style_image: list_style_image::SpecifiedValue(Either::Second(None_)), list_style_type: list_style_type, }) } (true, 1, None, None) => { Ok(Longhands { list_style_position: position, - list_style_image: Either::Second(None_), + list_style_image: list_style_image::SpecifiedValue(Either::Second(None_)), list_style_type: list_style_type::SpecifiedValue::none, }) } diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index 385aa900214..1f04847771d 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -493,6 +493,7 @@ mod shorthand_serialization { } mod list_style { + use style::properties::longhands::list_style_image::SpecifiedValue as ListStyleImage; use style::properties::longhands::list_style_position::SpecifiedValue as ListStylePosition; use style::properties::longhands::list_style_type::SpecifiedValue as ListStyleType; use style::values::Either; @@ -503,12 +504,17 @@ mod shorthand_serialization { let mut properties = Vec::new(); let position = ListStylePosition::inside; - let image = Either::First( - SpecifiedUrl::new_for_testing("http://servo/test.png")); + let image = + ListStyleImage(Either::First(SpecifiedUrl::new_for_testing("http://servo/test.png"))); let style_type = ListStyleType::disc; properties.push(PropertyDeclaration::ListStylePosition(position)); + + #[cfg(feature = "gecko")] + properties.push(PropertyDeclaration::ListStyleImage(Box::new(image))); + #[cfg(not(feature = "gecko"))] properties.push(PropertyDeclaration::ListStyleImage(image)); + properties.push(PropertyDeclaration::ListStyleType(style_type)); let serialization = shorthand_properties_to_string(properties);