diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index e44057bab5d..b4171abb2a8 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -17,7 +17,7 @@ use gecko_bindings::structs::{nsStyleImage, nsresult, SheetType}; use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut}; use std::f32::consts::PI; use stylesheets::{Origin, RulesMutateError}; -use values::computed::{Angle, CalcLengthOrPercentage, ComputedUrl, Gradient, Image}; +use values::computed::{Angle, CalcLengthOrPercentage, ComputedImageUrl, Gradient, Image}; use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto, Percentage, TextAlign}; use values::generics::box_::VerticalAlign; use values::generics::grid::{TrackListValue, TrackSize}; @@ -155,12 +155,12 @@ impl nsStyleImage { }, GenericImage::Url(ref url) => { unsafe { - Gecko_SetLayerImageImageValue(self, url.image_value.as_ref().unwrap().get()); + Gecko_SetLayerImageImageValue(self, url.image_value.get()); } }, GenericImage::Rect(ref image_rect) => { unsafe { - Gecko_SetLayerImageImageValue(self, image_rect.url.image_value.as_ref().unwrap().get()); + Gecko_SetLayerImageImageValue(self, image_rect.url.image_value.get()); Gecko_InitializeImageCropRect(self); // Set CropRect @@ -419,13 +419,11 @@ impl nsStyleImage { } } - unsafe fn get_image_url(self: &nsStyleImage) -> ComputedUrl { + unsafe fn get_image_url(self: &nsStyleImage) -> ComputedImageUrl { use gecko_bindings::bindings::Gecko_GetURLValue; let url_value = Gecko_GetURLValue(self); - let mut url = ComputedUrl::from_url_value_data(url_value.as_ref().unwrap()) - .expect("Could not convert to ComputedUrl"); - url.build_image_value(); - url + ComputedImageUrl::from_url_value_data(url_value.as_ref().unwrap()) + .expect("Could not convert to ComputedUrl") } unsafe fn get_gradient(self: &nsStyleImage) -> Box { diff --git a/components/style/gecko/url.rs b/components/style/gecko/url.rs index ffe0ddea03b..83d4b05b033 100644 --- a/components/style/gecko/url.rs +++ b/components/style/gecko/url.rs @@ -4,13 +4,15 @@ //! Common handling for the specified value CSS url() values. +use cssparser::Parser; +use gecko_bindings::bindings; use gecko_bindings::structs::{ServoBundledURI, URLExtraData}; use gecko_bindings::structs::mozilla::css::URLValueData; use gecko_bindings::structs::root::{nsStyleImageRequest, RustString}; use gecko_bindings::structs::root::mozilla::css::ImageValue; use gecko_bindings::sugar::refptr::RefPtr; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; -use parser::ParserContext; +use parser::{Parse, ParserContext}; use servo_arc::{Arc, RawOffsetArc}; use std::mem; use style_traits::ParseError; @@ -28,11 +30,6 @@ pub struct SpecifiedUrl { /// The URL extra data. #[css(skip)] pub extra_data: RefPtr, - - /// Cache ImageValue, if any, so that we can reuse it while rematching a - /// a property with this specified url value. - #[css(skip)] - pub image_value: Option>, } trivial_to_computed_value!(SpecifiedUrl); @@ -47,7 +44,6 @@ impl SpecifiedUrl { Ok(SpecifiedUrl { serialization: Arc::new(url), extra_data: context.url_data.clone(), - image_value: None, }) } @@ -71,23 +67,9 @@ impl SpecifiedUrl { Arc::new(url.mStrings.mString.as_ref().to_string()) }, extra_data: url.mExtraData.to_safe(), - image_value: None, }) } - /// Convert from nsStyleImageRequest to SpecifiedUrl. - pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Result { - if image_request.mImageValue.mRawPtr.is_null() { - return Err(()); - } - - let image_value = image_request.mImageValue.mRawPtr.as_ref().unwrap(); - let ref url_value_data = image_value._base; - let mut result = Self::from_url_value_data(url_value_data)?; - result.build_image_value(); - Ok(result) - } - /// Returns true if this URL looks like a fragment. /// See https://drafts.csswg.org/css-values/#local-urls pub fn is_fragment(&self) -> bool { @@ -118,41 +100,90 @@ impl SpecifiedUrl { mExtraData: self.extra_data.get(), } } - - /// Build and carry an image value on request. - pub fn build_image_value(&mut self) { - use gecko_bindings::bindings::Gecko_ImageValue_Create; - - debug_assert_eq!(self.image_value, None); - self.image_value = { - unsafe { - let ptr = Gecko_ImageValue_Create(self.for_ffi()); - // We do not expect Gecko_ImageValue_Create returns null. - debug_assert!(!ptr.is_null()); - Some(RefPtr::from_addrefed(ptr)) - } - } - } } impl MallocSizeOf for SpecifiedUrl { fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { - use gecko_bindings::bindings::Gecko_ImageValue_SizeOfIncludingThis; - - let mut n = 0; - // XXX: measure `serialization` once bug 1397971 lands // We ignore `extra_data`, because RefPtr is tricky, and there aren't // many of them in practise (sharing is common). - if let Some(ref image_value) = self.image_value { - // Although this is a RefPtr, this is the primary reference because - // SpecifiedUrl is responsible for creating the image_value. So we - // measure unconditionally here. - n += unsafe { Gecko_ImageValue_SizeOfIncludingThis(image_value.get()) }; + 0 + } +} + +/// A specified url() value for image. +/// +/// This exists so that we can construct `ImageValue` and reuse it. +#[derive(Clone, Debug, ToCss)] +pub struct SpecifiedImageUrl { + /// The specified url value. + pub url: SpecifiedUrl, + /// Gecko's ImageValue so that we can reuse it while rematching a + /// property with this specified value. + #[css(skip)] + pub image_value: RefPtr, +} +trivial_to_computed_value!(SpecifiedImageUrl); + +impl SpecifiedImageUrl { + fn from_specified_url(url: SpecifiedUrl) -> Self { + let image_value = unsafe { + let ptr = bindings::Gecko_ImageValue_Create(url.for_ffi()); + // We do not expect Gecko_ImageValue_Create returns null. + debug_assert!(!ptr.is_null()); + RefPtr::from_addrefed(ptr) + }; + SpecifiedImageUrl { url, image_value } + } + + /// Parse a URL from a string value. See SpecifiedUrl::parse_from_string. + pub fn parse_from_string<'a>( + url: String, + context: &ParserContext + ) -> Result> { + SpecifiedUrl::parse_from_string(url, context).map(Self::from_specified_url) + } + + /// Convert from URLValueData to SpecifiedUrl. + pub unsafe fn from_url_value_data(url: &URLValueData) -> Result { + SpecifiedUrl::from_url_value_data(url).map(Self::from_specified_url) + } + + /// Convert from nsStyleImageRequest to SpecifiedUrl. + pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Result { + if image_request.mImageValue.mRawPtr.is_null() { + return Err(()); } + let image_value = image_request.mImageValue.mRawPtr.as_ref().unwrap(); + let url_value_data = &image_value._base; + Self::from_url_value_data(url_value_data) + } +} + +impl Parse for SpecifiedImageUrl { + fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + SpecifiedUrl::parse(context, input).map(Self::from_specified_url) + } +} + +impl PartialEq for SpecifiedImageUrl { + fn eq(&self, other: &Self) -> bool { + self.url.eq(&other.url) + } +} + +impl Eq for SpecifiedImageUrl {} + +impl MallocSizeOf for SpecifiedImageUrl { + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + let mut n = self.url.size_of(ops); + // Although this is a RefPtr, this is the primary reference because + // SpecifiedUrl is responsible for creating the image_value. So we + // measure unconditionally here. + n += unsafe { bindings::Gecko_ImageValue_SizeOfIncludingThis(self.image_value.get()) }; n } } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 6ff85be6d1c..35b3f0bc96c 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -4072,8 +4072,7 @@ fn static_assert() { } longhands::list_style_image::computed_value::T(Either::First(ref url)) => { unsafe { - Gecko_SetListStyleImageImageValue(&mut self.gecko, - url.image_value.as_ref().unwrap().get()); + Gecko_SetListStyleImageImageValue(&mut self.gecko, url.image_value.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 @@ -4092,7 +4091,7 @@ fn static_assert() { } pub fn clone_list_style_image(&self) -> longhands::list_style_image::computed_value::T { - use values::specified::url::SpecifiedUrl; + use values::specified::url::SpecifiedImageUrl; use values::{Either, None_}; longhands::list_style_image::computed_value::T( @@ -4101,8 +4100,8 @@ fn static_assert() { false => { unsafe { let ref gecko_image_request = *self.gecko.mListStyleImage.mRawPtr; - Either::First(SpecifiedUrl::from_image_request(gecko_image_request) - .expect("mListStyleImage could not convert to SpecifiedUrl")) + Either::First(SpecifiedImageUrl::from_image_request(gecko_image_request) + .expect("mListStyleImage could not convert to SpecifiedImageUrl")) } } } @@ -5290,8 +5289,10 @@ clip-path } for i in 0..v.images.len() { unsafe { - Gecko_SetCursorImageValue(&mut self.gecko.mCursorImages[i], - v.images[i].url.image_value.as_ref().unwrap().get()); + Gecko_SetCursorImageValue( + &mut self.gecko.mCursorImages[i], + v.images[i].url.image_value.get(), + ); } // We don't need to record this struct as uncacheable, like when setting @@ -5326,7 +5327,7 @@ clip-path pub fn clone_cursor(&self) -> longhands::cursor::computed_value::T { use values::computed::pointing::CursorImage; use style_traits::cursor::CursorKind; - use values::specified::url::SpecifiedUrl; + use values::specified::url::SpecifiedImageUrl; let keyword = match self.gecko.mCursor as u32 { structs::NS_STYLE_CURSOR_AUTO => CursorKind::Auto, @@ -5371,8 +5372,8 @@ clip-path let images = self.gecko.mCursorImages.iter().map(|gecko_cursor_image| { let url = unsafe { let gecko_image_request = gecko_cursor_image.mImage.mRawPtr.as_ref().unwrap(); - SpecifiedUrl::from_image_request(&gecko_image_request) - .expect("mCursorImages.mImage could not convert to SpecifiedUrl") + SpecifiedImageUrl::from_image_request(&gecko_image_request) + .expect("mCursorImages.mImage could not convert to SpecifiedImageUrl") }; let hotspot = @@ -5550,8 +5551,10 @@ clip-path } ContentItem::Url(ref url) => { unsafe { - bindings::Gecko_SetContentDataImageValue(&mut self.gecko.mContents[i], - url.image_value.as_ref().unwrap().get()) + bindings::Gecko_SetContentDataImageValue( + &mut self.gecko.mContents[i], + url.image_value.get(), + ) } } } @@ -5578,7 +5581,7 @@ clip-path use values::computed::counters::{Content, ContentItem}; use values::{CustomIdent, Either}; use values::generics::CounterStyleOrNone; - use values::specified::url::SpecifiedUrl; + use values::specified::url::SpecifiedImageUrl; use values::specified::Attr; if self.gecko.mContents.is_empty() { @@ -5641,8 +5644,8 @@ clip-path let gecko_image_request = &**gecko_content.mContent.mImage.as_ref(); ContentItem::Url( - SpecifiedUrl::from_image_request(gecko_image_request) - .expect("mContent could not convert to SpecifiedUrl") + SpecifiedImageUrl::from_image_request(gecko_image_request) + .expect("mContent could not convert to SpecifiedImageUrl") ) } }, diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index b02590c7e24..d0da5476bfe 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -611,7 +611,6 @@ ${helpers.single_keyword("-moz-appearance", ${helpers.predefined_type("-moz-binding", "UrlOrNone", "Either::Second(None_)", products="gecko", - boxed= product == "gecko", animation_value_type="none", gecko_ffi_name="mBinding", spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)")} diff --git a/components/style/properties/longhand/inherited_svg.mako.rs b/components/style/properties/longhand/inherited_svg.mako.rs index 9e341e8b7c8..a3ab5c3754e 100644 --- a/components/style/properties/longhand/inherited_svg.mako.rs +++ b/components/style/properties/longhand/inherited_svg.mako.rs @@ -114,19 +114,16 @@ ${helpers.single_keyword("clip-rule", "nonzero evenodd", ${helpers.predefined_type("marker-start", "UrlOrNone", "Either::Second(None_)", products="gecko", - boxed= product == "gecko", animation_value_type="discrete", spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")} ${helpers.predefined_type("marker-mid", "UrlOrNone", "Either::Second(None_)", products="gecko", - boxed= product == "gecko", animation_value_type="discrete", spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")} ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", products="gecko", - boxed= product == "gecko", animation_value_type="discrete", spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")} diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index 3b330c9066f..12a73d0466e 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -47,7 +47,6 @@ ${helpers.predefined_type("list-style-image", initial_value="specified::ListStyleImage::none()", initial_specified_value="specified::ListStyleImage::none()", animation_value_type="discrete", - boxed=product == "gecko", spec="https://drafts.csswg.org/css-lists/#propdef-list-style-image", servo_restyle_damage="rebuild_and_reflow")} diff --git a/components/style/servo/url.rs b/components/style/servo/url.rs index 25a4aa5297d..7cfca564dbf 100644 --- a/components/style/servo/url.rs +++ b/components/style/servo/url.rs @@ -163,3 +163,5 @@ impl ToComputedValue for SpecifiedUrl { } } +/// A specified image url() value for servo. +pub type SpecifiedImageUrl = SpecifiedUrl; diff --git a/components/style/values/computed/counters.rs b/components/style/values/computed/counters.rs index 0e3510b8265..1d7659c9d47 100644 --- a/components/style/values/computed/counters.rs +++ b/components/style/values/computed/counters.rs @@ -18,7 +18,7 @@ use values::generics::counters::CounterReset as GenericCounterReset; #[cfg(feature = "gecko")] use values::specified::Attr; #[cfg(feature = "gecko")] -use values::specified::url::SpecifiedUrl; +use values::specified::url::SpecifiedImageUrl; pub use values::specified::{Content, ContentItem}; /// A computed value for the `counter-increment` property. @@ -79,8 +79,7 @@ impl Parse for Content { let mut content = vec![]; loop { #[cfg(feature = "gecko")] { - if let Ok(mut url) = input.try(|i| SpecifiedUrl::parse(_context, i)) { - url.build_image_value(); + if let Ok(url) = input.try(|i| SpecifiedImageUrl::parse(_context, i)) { content.push(ContentItem::Url(url)); continue; } diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs index 93fa627a41d..e0b3e3bbd91 100644 --- a/components/style/values/computed/image.rs +++ b/components/style/values/computed/image.rs @@ -12,7 +12,8 @@ use std::f32::consts::PI; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; use values::{Either, None_}; -use values::computed::{Angle, ComputedUrl, Context, Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue}; +use values::computed::{Angle, ComputedImageUrl, Context}; +use values::computed::{Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue}; #[cfg(feature = "gecko")] use values::computed::Percentage; use values::computed::position::Position; @@ -28,7 +29,7 @@ pub type ImageLayer = Either; /// Computed values for an image according to CSS-IMAGES. /// -pub type Image = GenericImage; +pub type Image = GenericImage; /// Computed values for a CSS gradient. /// @@ -76,7 +77,7 @@ pub type GradientItem = GenericGradientItem; pub type ColorStop = GenericColorStop; /// Computed values for `-moz-image-rect(...)`. -pub type MozImageRect = GenericMozImageRect; +pub type MozImageRect = GenericMozImageRect; impl GenericLineDirection for LineDirection { fn points_downwards(&self, compat_mode: CompatMode) -> bool { diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 64e9e389dde..be9985d8cb4 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -646,9 +646,17 @@ pub enum ComputedUrl { Valid(ServoUrl), } -/// TODO: Properly build ComputedUrl for gecko +/// The computed value of a CSS `url()` for image. +#[cfg(feature = "servo")] +pub type ComputedImageUrl = ComputedUrl; + +// TODO: Properly build ComputedUrl for gecko +/// The computed value of a CSS `url()`. #[cfg(feature = "gecko")] pub type ComputedUrl = specified::url::SpecifiedUrl; +/// The computed value of a CSS `url()` for image. +#[cfg(feature = "gecko")] +pub type ComputedImageUrl = specified::url::SpecifiedImageUrl; #[cfg(feature = "servo")] impl ComputedUrl { @@ -680,3 +688,6 @@ impl ToCss for ComputedUrl { /// | pub type UrlOrNone = Either; + +/// | for image +pub type ImageUrlOrNone = Either; diff --git a/components/style/values/computed/pointing.rs b/components/style/values/computed/pointing.rs index 1c44be7681c..9c79462abd6 100644 --- a/components/style/values/computed/pointing.rs +++ b/components/style/values/computed/pointing.rs @@ -18,7 +18,7 @@ use style_traits::cursor::CursorKind; use values::computed::color::Color; use values::generics::pointing::CaretColor as GenericCaretColor; #[cfg(feature = "gecko")] -use values::specified::url::SpecifiedUrl; +use values::specified::url::SpecifiedImageUrl; /// The computed value for the `cursor` property. /// @@ -65,10 +65,7 @@ impl Parse for Cursor { let mut images = vec![]; loop { match input.try(|input| CursorImage::parse_image(context, input)) { - Ok(mut image) => { - image.url.build_image_value(); - images.push(image) - } + Ok(image) => images.push(image), Err(_) => break, } input.expect_comma()?; @@ -114,7 +111,7 @@ impl CursorImage { input: &mut Parser<'i, 't> ) -> Result> { Ok(Self { - url: SpecifiedUrl::parse(context, input)?, + url: SpecifiedImageUrl::parse(context, input)?, // FIXME(emilio): Should use Number::parse to handle calc() correctly. hotspot: match input.try(|input| input.expect_number()) { Ok(number) => Some((number, input.expect_number()?)), diff --git a/components/style/values/specified/counters.rs b/components/style/values/specified/counters.rs index 3252001f142..f7130a79b2f 100644 --- a/components/style/values/specified/counters.rs +++ b/components/style/values/specified/counters.rs @@ -18,7 +18,7 @@ use values::generics::counters::CounterReset as GenericCounterReset; use values::specified::Attr; use values::specified::Integer; #[cfg(feature = "gecko")] -use values::specified::url::SpecifiedUrl; +use values::specified::url::SpecifiedImageUrl; /// A specified value for the `counter-increment` property. pub type CounterIncrement = GenericCounterIncrement; @@ -119,5 +119,5 @@ pub enum ContentItem { Attr(Attr), /// `url(url)` #[cfg(feature = "gecko")] - Url(SpecifiedUrl), + Url(SpecifiedImageUrl), } diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index 001e8c09976..331b10be453 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -31,14 +31,14 @@ use values::generics::position::Position as GenericPosition; use values::specified::{Angle, Color, Length, LengthOrPercentage}; use values::specified::{Number, NumberOrPercentage, Percentage, RGBAColor}; use values::specified::position::{LegacyPosition, Position, PositionComponent, Side, X, Y}; -use values::specified::url::SpecifiedUrl; +use values::specified::url::SpecifiedImageUrl; /// A specified image layer. pub type ImageLayer = Either; /// Specified values for an image according to CSS-IMAGES. /// -pub type Image = GenericImage; +pub type Image = GenericImage; /// Specified values for a CSS gradient. /// @@ -124,16 +124,11 @@ pub type ColorStop = GenericColorStop; /// Specified values for `moz-image-rect` /// -moz-image-rect(, top, right, bottom, left); -pub type MozImageRect = GenericMozImageRect; +pub type MozImageRect = GenericMozImageRect; impl Parse for Image { - #[cfg_attr(not(feature = "gecko"), allow(unused_mut))] fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { - if let Ok(mut url) = input.try(|input| SpecifiedUrl::parse(context, input)) { - #[cfg(feature = "gecko")] - { - url.build_image_value(); - } + if let Ok(url) = input.try(|input| SpecifiedImageUrl::parse(context, input)) { return Ok(GenericImage::Url(url)); } if let Ok(gradient) = input.try(|i| Gradient::parse(context, i)) { @@ -145,11 +140,7 @@ impl Parse for Image { return Ok(GenericImage::PaintWorklet(paint_worklet)); } } - if let Ok(mut image_rect) = input.try(|input| MozImageRect::parse(context, input)) { - #[cfg(feature = "gecko")] - { - image_rect.url.build_image_value(); - } + if let Ok(image_rect) = input.try(|input| MozImageRect::parse(context, input)) { return Ok(GenericImage::Rect(Box::new(image_rect))); } Ok(GenericImage::Element(Image::parse_element(input)?)) @@ -944,7 +935,7 @@ impl Parse for MozImageRect { input.try(|i| i.expect_function_matching("-moz-image-rect"))?; input.parse_nested_block(|i| { let string = i.expect_url_or_string()?; - let url = SpecifiedUrl::parse_from_string(string.as_ref().to_owned(), context)?; + let url = SpecifiedImageUrl::parse_from_string(string.as_ref().to_owned(), context)?; i.expect_comma()?; let top = NumberOrPercentage::parse_non_negative(context, i)?; i.expect_comma()?; @@ -953,14 +944,7 @@ impl Parse for MozImageRect { let bottom = NumberOrPercentage::parse_non_negative(context, i)?; i.expect_comma()?; let left = NumberOrPercentage::parse_non_negative(context, i)?; - - Ok(MozImageRect { - url: url, - top: top, - right: right, - bottom: bottom, - left: left, - }) + Ok(MozImageRect { url, top, right, bottom, left }) }) } } diff --git a/components/style/values/specified/list.rs b/components/style/values/specified/list.rs index 9acba5ca1e5..f2bc6068790 100644 --- a/components/style/values/specified/list.rs +++ b/components/style/values/specified/list.rs @@ -13,7 +13,7 @@ use values::{Either, None_}; use values::CustomIdent; #[cfg(feature = "gecko")] use values::generics::CounterStyleOrNone; -use values::specified::UrlOrNone; +use values::specified::ImageUrlOrNone; /// Specified and computed `list-style-type` property. #[cfg(feature = "gecko")] @@ -75,7 +75,7 @@ impl Parse for ListStyleType { /// Specified and computed `list-style-image` property. #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] -pub struct ListStyleImage(pub UrlOrNone); +pub struct ListStyleImage(pub ImageUrlOrNone); // FIXME(nox): This is wrong, there are different types for specified // and computed URLs in Servo. @@ -90,19 +90,11 @@ impl ListStyleImage { } impl Parse for ListStyleImage { - fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result> { - #[allow(unused_mut)] - let mut value = input.try(|input| UrlOrNone::parse(context, input))?; - - #[cfg(feature = "gecko")] - { - if let Either::First(ref mut url) = value { - url.build_image_value(); - } - } - - return Ok(ListStyleImage(value)); + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + ImageUrlOrNone::parse(context, input).map(ListStyleImage) } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 017d1dfccb1..56126fa7d34 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -11,7 +11,7 @@ use context::QuirksMode; use cssparser::{Parser, Token, serialize_identifier}; use num_traits::One; use parser::{ParserContext, Parse}; -use self::url::SpecifiedUrl; +use self::url::{SpecifiedImageUrl, SpecifiedUrl}; use std::f32; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; @@ -534,6 +534,9 @@ impl Parse for PositiveInteger { #[allow(missing_docs)] pub type UrlOrNone = Either; +/// The specified value of a `` for image or `none`. +pub type ImageUrlOrNone = Either; + /// The specified value of a grid `` pub type TrackBreadth = GenericTrackBreadth; diff --git a/components/style/values/specified/pointing.rs b/components/style/values/specified/pointing.rs index 0628746f261..d8da1305efb 100644 --- a/components/style/values/specified/pointing.rs +++ b/components/style/values/specified/pointing.rs @@ -13,7 +13,7 @@ use style_traits::cursor::CursorKind; use values::generics::pointing::CaretColor as GenericCaretColor; use values::specified::color::Color; #[cfg(feature = "gecko")] -use values::specified::url::SpecifiedUrl; +use values::specified::url::SpecifiedImageUrl; /// The specified value for the `cursor` property. /// @@ -39,7 +39,7 @@ pub struct Cursor { #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] pub struct CursorImage { /// The url to parse images from. - pub url: SpecifiedUrl, + pub url: SpecifiedImageUrl, /// The and coordinates. pub hotspot: Option<(f32, f32)>, } diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 40f5bae66eb..8e0ee71738b 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -3544,7 +3544,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage( use style::properties::longhands::background_image::SpecifiedValue as BackgroundImage; use style::values::Either; use style::values::generics::image::Image; - use style::values::specified::url::SpecifiedUrl; + use style::values::specified::url::SpecifiedImageUrl; let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) }; let string = unsafe { (*value).to_string() }; @@ -3555,8 +3555,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage( ParsingMode::DEFAULT, QuirksMode::NoQuirks, ); - if let Ok(mut url) = SpecifiedUrl::parse_from_string(string.into(), &context) { - url.build_image_value(); + if let Ok(url) = SpecifiedImageUrl::parse_from_string(string.into(), &context) { let decl = PropertyDeclaration::BackgroundImage(BackgroundImage( vec![Either::Second(Image::Url(url))] )); diff --git a/ports/geckolib/tests/size_of.rs b/ports/geckolib/tests/size_of.rs index 0f24603fb4e..9691c4cd385 100644 --- a/ports/geckolib/tests/size_of.rs +++ b/ports/geckolib/tests/size_of.rs @@ -42,10 +42,10 @@ size_of_test!(test_size_of_rule_node, RuleNode, 80); // we only pass `&mut SourcePropertyDeclaration` references around. size_of_test!(test_size_of_parsed_declaration, style::properties::SourcePropertyDeclaration, 608); -size_of_test!(test_size_of_computed_image, computed::image::Image, 40); -size_of_test!(test_size_of_specified_image, specified::image::Image, 40); +size_of_test!(test_size_of_computed_image, computed::image::Image, 32); +size_of_test!(test_size_of_specified_image, specified::image::Image, 32); // FIXME(bz): These can shrink if we move the None_ value inside the // enum instead of paying an extra word for the Either discriminant. -size_of_test!(test_size_of_computed_image_layer, computed::image::ImageLayer, 40); -size_of_test!(test_size_of_specified_image_layer, specified::image::ImageLayer, 40); +size_of_test!(test_size_of_computed_image_layer, computed::image::ImageLayer, 32); +size_of_test!(test_size_of_specified_image_layer, specified::image::ImageLayer, 32);