diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-05-15 18:04:59 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-15 18:04:59 -0500 |
commit | 5bd6b92494d6b9527c1639c358eea3c4822bed84 (patch) | |
tree | f5059ca69b9ac378b63d5ba03e8f70c73a9702c1 | |
parent | a51da06dd9c680a7e3f49247181d49a48a787f47 (diff) | |
parent | cc67f37d4e02cf3f0303985300e952238b5d97a6 (diff) | |
download | servo-5bd6b92494d6b9527c1639c358eea3c4822bed84.tar.gz servo-5bd6b92494d6b9527c1639c358eea3c4822bed84.zip |
Auto merge of #16862 - CJKu:bug-1310885-part-6, r=heycam
stylo: Pass Cached ImageValue from stylo back to gecko
<!-- Please describe your changes on the following line: -->
This is part 6 ~ part 9 patch in bug 1310885
gecko bug link:
https://bugzilla.mozilla.org/show_bug.cgi?id=1310885
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16862)
<!-- Reviewable:end -->
-rw-r--r-- | components/layout/construct.rs | 5 | ||||
-rw-r--r-- | components/style/gecko/conversions.rs | 6 | ||||
-rw-r--r-- | components/style/gecko/generated/bindings.rs | 19 | ||||
-rw-r--r-- | components/style/gecko/url.rs | 21 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 24 | ||||
-rw-r--r-- | components/style/properties/longhand/box.mako.rs | 1 | ||||
-rw-r--r-- | components/style/properties/longhand/counters.mako.rs | 3 | ||||
-rw-r--r-- | components/style/properties/longhand/inherited_svg.mako.rs | 3 | ||||
-rw-r--r-- | components/style/properties/longhand/list.mako.rs | 52 | ||||
-rw-r--r-- | components/style/properties/longhand/pointing.mako.rs | 5 | ||||
-rw-r--r-- | components/style/properties/shorthand/list.mako.rs | 6 | ||||
-rw-r--r-- | components/style/values/specified/image.rs | 28 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 3 | ||||
-rw-r--r-- | tests/unit/style/properties/serialization.rs | 10 |
14 files changed, 148 insertions, 38 deletions
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/gecko/conversions.rs b/components/style/gecko/conversions.rs index 720c1bd2315..980ef36b280 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -10,7 +10,7 @@ use app_units::Au; use gecko::values::{convert_rgba_to_nscolor, GeckoStyleCoordConvertible}; -use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetUrlImageValue}; +use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetLayerImageImageValue}; use gecko_bindings::bindings::{Gecko_InitializeImageCropRect, Gecko_SetImageElement}; use gecko_bindings::structs::{nsCSSUnit, nsStyleCoord_CalcValue, nsStyleImage}; use gecko_bindings::structs::{nsresult, SheetType}; @@ -144,7 +144,7 @@ impl nsStyleImage { }, GenericImage::Url(ref url) => { unsafe { - Gecko_SetUrlImageValue(self, url.for_ffi()); + Gecko_SetLayerImageImageValue(self, url.image_value.clone().unwrap().get()); // We unfortunately must make any url() value uncacheable, since // the applicable declarations cache is not per document, but // global, and the imgRequestProxy objects we store in the style @@ -157,7 +157,7 @@ impl nsStyleImage { }, GenericImage::Rect(ref image_rect) => { unsafe { - Gecko_SetUrlImageValue(self, image_rect.url.for_ffi()); + Gecko_SetLayerImageImageValue(self, image_rect.url.image_value.clone().unwrap().get()); Gecko_InitializeImageCropRect(self); // We unfortunately must make any url() value uncacheable, since diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 00e623b931f..62e1797dcb5 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -832,8 +832,11 @@ extern "C" { pub fn Gecko_ReleaseImageValueArbitraryThread(aPtr: *mut ImageValue); } extern "C" { - pub fn Gecko_SetUrlImageValue(image: *mut nsStyleImage, - uri: ServoBundledURI); + pub fn Gecko_ImageValue_Create(uri: ServoBundledURI) -> *mut ImageValue; +} +extern "C" { + pub fn Gecko_SetLayerImageImageValue(image: *mut nsStyleImage, + imageValue: *mut ImageValue); } extern "C" { pub fn Gecko_SetImageElement(image: *mut nsStyleImage, @@ -855,8 +858,8 @@ extern "C" { pub fn Gecko_SetListStyleImageNone(style_struct: *mut nsStyleList); } extern "C" { - pub fn Gecko_SetListStyleImage(style_struct: *mut nsStyleList, - uri: ServoBundledURI); + pub fn Gecko_SetListStyleImageImageValue(style_struct: *mut nsStyleList, + imageValue: *mut ImageValue); } extern "C" { pub fn Gecko_CopyListStyleImageFrom(dest: *mut nsStyleList, @@ -867,16 +870,16 @@ extern "C" { len: usize); } extern "C" { - pub fn Gecko_SetCursorImage(cursor: *mut nsCursorImage, - uri: ServoBundledURI); + pub fn Gecko_SetCursorImageValue(cursor: *mut nsCursorImage, + imageValue: *mut ImageValue); } extern "C" { pub fn Gecko_CopyCursorArrayFrom(dest: *mut nsStyleUserInterface, src: *const nsStyleUserInterface); } extern "C" { - pub fn Gecko_SetContentDataImage(content_data: *mut nsStyleContentData, - uri: ServoBundledURI); + pub fn Gecko_SetContentDataImageValue(content_data: *mut nsStyleContentData, + imageValue: *mut ImageValue); } extern "C" { pub fn Gecko_SetContentDataArray(content_data: *mut nsStyleContentData, diff --git a/components/style/gecko/url.rs b/components/style/gecko/url.rs index 191ae082726..1dfc04d100b 100644 --- a/components/style/gecko/url.rs +++ b/components/style/gecko/url.rs @@ -6,6 +6,7 @@ use cssparser::CssStringWriter; use gecko_bindings::structs::{ServoBundledURI, URLExtraData}; +use gecko_bindings::structs::root::mozilla::css::ImageValue; use gecko_bindings::sugar::refptr::RefPtr; use parser::ParserContext; use std::borrow::Cow; @@ -24,6 +25,10 @@ pub struct SpecifiedUrl { /// The URL extra data. pub extra_data: RefPtr<URLExtraData>, + + /// Cache ImageValue, if any, so that we can reuse it while rematching a + /// a property with this specified url value. + pub image_value: Option<RefPtr<ImageValue>>, } impl SpecifiedUrl { @@ -37,6 +42,7 @@ impl SpecifiedUrl { Ok(SpecifiedUrl { serialization: Arc::new(url.into_owned()), extra_data: context.url_data.clone(), + image_value: None, }) } @@ -76,6 +82,21 @@ 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 ToCss for SpecifiedUrl { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index b86f18534cf..49cf7695833 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -32,13 +32,13 @@ use gecko_bindings::bindings::Gecko_FontFamilyList_AppendGeneric; use gecko_bindings::bindings::Gecko_FontFamilyList_AppendNamed; use gecko_bindings::bindings::Gecko_FontFamilyList_Clear; use gecko_bindings::bindings::Gecko_SetCursorArrayLength; -use gecko_bindings::bindings::Gecko_SetCursorImage; +use gecko_bindings::bindings::Gecko_SetCursorImageValue; 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 @@ -3995,10 +3995,11 @@ clip-path Gecko_SetCursorArrayLength(&mut self.gecko, v.images.len()); } for i in 0..v.images.len() { - let image = &v.images[i]; unsafe { - Gecko_SetCursorImage(&mut self.gecko.mCursorImages[i], image.url.for_ffi()); + Gecko_SetCursorImageValue(&mut self.gecko.mCursorImages[i], + v.images[i].url.clone().image_value.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 // are re-used from the applicable declaration cache, and the Pointing struct @@ -4160,8 +4161,11 @@ clip-path // When we support <custom-ident> values for list-style-type this will need to be updated array[2].set_atom_ident(style.to_css_string().into()); } - ContentItem::Url(url) => { - unsafe { bindings::Gecko_SetContentDataImage(&mut self.gecko.mContents[i], url.for_ffi()) } + ContentItem::Url(ref url) => { + unsafe { + bindings::Gecko_SetContentDataImageValue(&mut self.gecko.mContents[i], + url.image_value.clone().unwrap().get()) + } } } } diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index eeb2100b11e..86b2e7d95e2 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -2441,6 +2441,7 @@ ${helpers.single_keyword("-moz-appearance", ${helpers.predefined_type("-moz-binding", "UrlOrNone", "Either::Second(None_)", products="gecko", + boxed="True" if product == "gecko" else "False", 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/counters.mako.rs b/components/style/properties/longhand/counters.mako.rs index e9e23d54dc0..054746bdc7a 100644 --- a/components/style/properties/longhand/counters.mako.rs +++ b/components/style/properties/longhand/counters.mako.rs @@ -148,7 +148,8 @@ let mut content = vec![]; loop { % if product == "gecko": - if let Ok(url) = input.try(|i| SpecifiedUrl::parse(context, i)) { + if let Ok(mut url) = input.try(|i| SpecifiedUrl::parse(context, i)) { + url.build_image_value(); content.push(ContentItem::Url(url)); continue; } diff --git a/components/style/properties/longhand/inherited_svg.mako.rs b/components/style/properties/longhand/inherited_svg.mako.rs index 33cda168d50..d7acf552e89 100644 --- a/components/style/properties/longhand/inherited_svg.mako.rs +++ b/components/style/properties/longhand/inherited_svg.mako.rs @@ -120,16 +120,19 @@ ${helpers.single_keyword("clip-rule", "nonzero evenodd", ${helpers.predefined_type("marker-start", "UrlOrNone", "Either::Second(None_)", products="gecko", + boxed="True" if product == "gecko" else "False", animation_value_type="none", spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")} ${helpers.predefined_type("marker-mid", "UrlOrNone", "Either::Second(None_)", products="gecko", + boxed="True" if product == "gecko" else "False", animation_value_type="none", spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties")} ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", products="gecko", + boxed="True" if product == "gecko" else "False", animation_value_type="none", 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 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<W>(&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<SpecifiedValue,()> { + % 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> <%helpers:longhand name="quotes" animation_value_type="none" spec="https://drafts.csswg.org/css-content/#propdef-quotes"> diff --git a/components/style/properties/longhand/pointing.mako.rs b/components/style/properties/longhand/pointing.mako.rs index b15d5cfce5c..77edc71e000 100644 --- a/components/style/properties/longhand/pointing.mako.rs +++ b/components/style/properties/longhand/pointing.mako.rs @@ -131,7 +131,10 @@ let mut images = vec![]; loop { match input.try(|input| parse_image(context, input)) { - Ok(image) => images.push(image), + Ok(mut image) => { + image.url.build_image_value(); + images.push(image) + } Err(()) => break, } try!(input.expect_comma()); 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/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index dcbc5db1c5c..9266bec885b 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -82,14 +82,34 @@ pub type ImageRect = GenericImageRect<NumberOrPercentage>; impl Parse for Image { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Image, ()> { - if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) { - return Ok(GenericImage::Url(url)); + #[cfg(feature = "gecko")] + { + if let Ok(mut url) = input.try(|input| SpecifiedUrl::parse(context, input)) { + url.build_image_value(); + return Ok(GenericImage::Url(url)); + } + } + #[cfg(feature = "servo")] + { + if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) { + return Ok(GenericImage::Url(url)); + } } if let Ok(gradient) = input.try(|i| Gradient::parse(context, i)) { return Ok(GenericImage::Gradient(gradient)); } - if let Ok(image_rect) = input.try(|input| ImageRect::parse(context, input)) { - return Ok(GenericImage::Rect(image_rect)); + #[cfg(feature = "gecko")] + { + if let Ok(mut image_rect) = input.try(|input| ImageRect::parse(context, input)) { + image_rect.url.build_image_value(); + return Ok(GenericImage::Rect(image_rect)); + } + } + #[cfg(feature = "servo")] + { + if let Ok(image_rect) = input.try(|input| ImageRect::parse(context, input)) { + return Ok(GenericImage::Rect(image_rect)); + } } Ok(GenericImage::Element(Image::parse_element(input)?)) diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index adb25ae19a0..2d439ccef59 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -1845,7 +1845,8 @@ pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage(declarations: let context = ParserContext::new(Origin::Author, url_data, &error_reporter, Some(CssRuleType::Style), PARSING_MODE_DEFAULT, QuirksMode::NoQuirks); - if let Ok(url) = SpecifiedUrl::parse_from_string(string.into(), &context) { + if let Ok(mut url) = SpecifiedUrl::parse_from_string(string.into(), &context) { + url.build_image_value(); let decl = PropertyDeclaration::BackgroundImage(BackgroundImage( vec![Either::Second(Image::Url(url))] )); 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); |