--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -763,30 +763,16 @@ ServoBundledURI::IntoCssUrl()
RefPtr<css::URLValue> urlValue = new css::URLValue(urlBuffer,
do_AddRef(mBaseURI),
do_AddRef(mReferrer),
do_AddRef(mPrincipal));
return urlValue.forget();
}
void
-Gecko_SetMozBinding(nsStyleDisplay* aDisplay, ServoBundledURI aBundledURI)
-{
- MOZ_ASSERT(aDisplay);
- aDisplay->mBinding = aBundledURI.IntoCssUrl();
-}
-
-void
-Gecko_CopyMozBindingFrom(nsStyleDisplay* aDest, const nsStyleDisplay* aSrc)
-{
- aDest->mBinding = aSrc->mBinding;
-}
-
-
-void
Gecko_SetNullImageValue(nsStyleImage* aImage)
{
MOZ_ASSERT(aImage);
aImage->SetNull();
}
void
Gecko_SetGradientImageValue(nsStyleImage* aImage, nsStyleGradient* aGradient)
@@ -1088,16 +1074,25 @@ Gecko_nsStyleSVGPaint_SetURLValue(nsStyl
aPaint->SetPaintServer(url.get(), NS_RGB(0, 0, 0));
}
void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* aPaint)
{
aPaint->SetNone();
}
+css::URLValue*
+Gecko_NewURLValue(ServoBundledURI aURI)
+{
+ RefPtr<css::URLValue> url = aURI.IntoCssUrl();
+ return url.forget().take();
+}
+
+NS_IMPL_THREADSAFE_FFI_REFCOUNTING(css::URLValue, CSSURLValue);
+
NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
nsCSSShadowArray*
Gecko_NewCSSShadowArray(uint32_t aLen)
{
RefPtr<nsCSSShadowArray> arr = new(aLen) nsCSSShadowArray(aLen);
return arr.forget().take();
}
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -228,20 +228,16 @@ void Gecko_SetCursorArrayLength(nsStyleU
void Gecko_SetCursorImage(nsCursorImage* cursor,
const uint8_t* string_bytes, uint32_t string_length,
ThreadSafeURIHolder* base_uri,
ThreadSafeURIHolder* referrer,
ThreadSafePrincipalHolder* principal);
void Gecko_CopyCursorArrayFrom(nsStyleUserInterface* dest,
const nsStyleUserInterface* src);
-// Display style.
-void Gecko_SetMozBinding(nsStyleDisplay* style_struct, ServoBundledURI bundled_uri);
-void Gecko_CopyMozBindingFrom(nsStyleDisplay* des, const nsStyleDisplay* src);
-
// Dirtiness tracking.
uint32_t Gecko_GetNodeFlags(RawGeckoNodeBorrowed node);
void Gecko_SetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
void Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
void Gecko_SetOwnerDocumentNeedsStyleFlush(RawGeckoElementBorrowed element);
// Incremental restyle.
// Also, we might want a ComputedValues to ComputedValues API for animations?
@@ -297,16 +293,19 @@ void Gecko_StyleClipPath_SetURLValue(moz
void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len);
void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest);
void Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* effects, ServoBundledURI uri);
void Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* dest, const nsStyleSVGPaint* src);
void Gecko_nsStyleSVGPaint_SetURLValue(nsStyleSVGPaint* paint, ServoBundledURI uri);
void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* paint);
+mozilla::css::URLValue* Gecko_NewURLValue(ServoBundledURI uri);
+NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::URLValue, CSSURLValue);
+
void Gecko_FillAllBackgroundLists(nsStyleImageLayers* layers, uint32_t max_len);
void Gecko_FillAllMaskLists(nsStyleImageLayers* layers, uint32_t max_len);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
nsCSSShadowArray* Gecko_NewCSSShadowArray(uint32_t len);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSShadowArray, CSSShadowArray);
nsStyleQuoteValues* Gecko_NewStyleQuoteValues(uint32_t len);
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -503,16 +503,17 @@ mod bindings {
.hide_type("nsACString_internal")
.hide_type("nsAString_internal")
.raw_line("pub use nsstring::{nsACString, nsAString};")
.raw_line("type nsACString_internal = nsACString;")
.raw_line("type nsAString_internal = nsAString;")
.whitelisted_function("Servo_.*")
.whitelisted_function("Gecko_.*");
let structs_types = [
+ "mozilla::css::URLValue",
"RawGeckoDocument",
"RawGeckoElement",
"RawGeckoKeyframeList",
"RawGeckoNode",
"RawGeckoAnimationValueList",
"RawServoAnimationValue",
"RawServoDeclarationBlock",
"RawGeckoPresContext",
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -1,13 +1,14 @@
/* automatically generated by rust-bindgen */
pub use nsstring::{nsACString, nsAString};
type nsACString_internal = nsACString;
type nsAString_internal = nsAString;
+use gecko_bindings::structs::mozilla::css::URLValue;
use gecko_bindings::structs::RawGeckoDocument;
use gecko_bindings::structs::RawGeckoElement;
use gecko_bindings::structs::RawGeckoKeyframeList;
use gecko_bindings::structs::RawGeckoNode;
use gecko_bindings::structs::RawGeckoAnimationValueList;
use gecko_bindings::structs::RawServoAnimationValue;
use gecko_bindings::structs::RawServoDeclarationBlock;
use gecko_bindings::structs::RawGeckoPresContext;
@@ -614,24 +615,16 @@ extern "C" {
referrer: *mut ThreadSafeURIHolder,
principal: *mut ThreadSafePrincipalHolder);
}
extern "C" {
pub fn Gecko_CopyCursorArrayFrom(dest: *mut nsStyleUserInterface,
src: *const nsStyleUserInterface);
}
extern "C" {
- pub fn Gecko_SetMozBinding(style_struct: *mut nsStyleDisplay,
- bundled_uri: ServoBundledURI);
-}
-extern "C" {
- pub fn Gecko_CopyMozBindingFrom(des: *mut nsStyleDisplay,
- src: *const nsStyleDisplay);
-}
-extern "C" {
pub fn Gecko_GetNodeFlags(node: RawGeckoNodeBorrowed) -> u32;
}
extern "C" {
pub fn Gecko_SetNodeFlags(node: RawGeckoNodeBorrowed, flags: u32);
}
extern "C" {
pub fn Gecko_UnsetNodeFlags(node: RawGeckoNodeBorrowed, flags: u32);
}
@@ -725,16 +718,25 @@ extern "C" {
extern "C" {
pub fn Gecko_nsStyleSVGPaint_SetURLValue(paint: *mut nsStyleSVGPaint,
uri: ServoBundledURI);
}
extern "C" {
pub fn Gecko_nsStyleSVGPaint_Reset(paint: *mut nsStyleSVGPaint);
}
extern "C" {
+ pub fn Gecko_NewURLValue(uri: ServoBundledURI) -> *mut URLValue;
+}
+extern "C" {
+ pub fn Gecko_AddRefCSSURLValueArbitraryThread(aPtr: *mut URLValue);
+}
+extern "C" {
+ pub fn Gecko_ReleaseCSSURLValueArbitraryThread(aPtr: *mut URLValue);
+}
+extern "C" {
pub fn Gecko_FillAllBackgroundLists(layers: *mut nsStyleImageLayers,
max_len: u32);
}
extern "C" {
pub fn Gecko_FillAllMaskLists(layers: *mut nsStyleImageLayers,
max_len: u32);
}
extern "C" {
--- a/servo/components/style/gecko_bindings/sugar/refptr.rs
+++ b/servo/components/style/gecko_bindings/sugar/refptr.rs
@@ -259,15 +259,18 @@ impl_threadsafe_refcount!(::gecko_bindin
Gecko_AddRefURIArbitraryThread,
Gecko_ReleaseURIArbitraryThread);
impl_threadsafe_refcount!(::gecko_bindings::structs::nsStyleQuoteValues,
Gecko_AddRefQuoteValuesArbitraryThread,
Gecko_ReleaseQuoteValuesArbitraryThread);
impl_threadsafe_refcount!(::gecko_bindings::structs::nsCSSValueSharedList,
Gecko_AddRefCSSValueSharedListArbitraryThread,
Gecko_ReleaseCSSValueSharedListArbitraryThread);
+impl_threadsafe_refcount!(::gecko_bindings::structs::mozilla::css::URLValue,
+ Gecko_AddRefCSSURLValueArbitraryThread,
+ Gecko_ReleaseCSSURLValueArbitraryThread);
/// A Gecko `ThreadSafePrincipalHolder` wrapped in a safe refcounted pointer, to
/// use during stylesheet parsing and style computation.
pub type GeckoArcPrincipal = RefPtr<::gecko_bindings::structs::ThreadSafePrincipalHolder>;
/// A Gecko `ThreadSafeURIHolder` wrapped in a safe refcounted pointer, to use
/// during stylesheet parsing and style computation.
pub type GeckoArcURI = RefPtr<::gecko_bindings::structs::ThreadSafeURIHolder>;
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -21,28 +21,26 @@ use gecko_bindings::bindings::Gecko_Copy
use gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name};
% endfor
use gecko_bindings::bindings::Gecko_Construct_nsStyleVariables;
use gecko_bindings::bindings::Gecko_CopyCursorArrayFrom;
use gecko_bindings::bindings::Gecko_CopyFontFamilyFrom;
use gecko_bindings::bindings::Gecko_CopyImageValueFrom;
use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom;
use gecko_bindings::bindings::Gecko_CopyListStyleTypeFrom;
-use gecko_bindings::bindings::Gecko_CopyMozBindingFrom;
use gecko_bindings::bindings::Gecko_EnsureImageLayersLength;
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_NewCSSShadowArray;
use gecko_bindings::bindings::Gecko_SetListStyleImage;
use gecko_bindings::bindings::Gecko_SetListStyleImageNone;
use gecko_bindings::bindings::Gecko_SetListStyleType;
-use gecko_bindings::bindings::Gecko_SetMozBinding;
use gecko_bindings::bindings::Gecko_SetNullImageValue;
use gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
use gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom};
use gecko_bindings::bindings::RawGeckoPresContextBorrowed;
use gecko_bindings::structs;
use gecko_bindings::structs::nsStyleVariables;
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use gecko_bindings::sugar::ownership::HasArcFFI;
@@ -393,17 +391,21 @@ fn color_to_nscolor_zero_currentcolor(co
SVGPaintKind::ContextFill => {
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_ContextFill;
}
SVGPaintKind::ContextStroke => {
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_ContextStroke;
}
SVGPaintKind::PaintServer(url) => {
unsafe {
- bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, url.for_ffi());
+ if let Some(ffi) = url.for_ffi() {
+ bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, ffi);
+ } else {
+ return;
+ }
}
}
SVGPaintKind::Color(color) => {
paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_Color;
unsafe {
*paint.mPaint.mColor.as_mut() = color_to_nscolor_zero_currentcolor(color);
}
}
@@ -506,16 +508,51 @@ fn color_to_nscolor_zero_currentcolor(co
let height = GeckoStyleCoordConvertible::from_gecko_style_coord(
&self.gecko.${gecko_ffi_name}.data_at(${y_index}))
.expect("Failed to clone ${ident}");
T(Size2D::new(width, height))
}
% endif
</%def>
+<%def name="impl_css_url(ident, gecko_ffi_name, need_clone=False)">
+ #[allow(non_snake_case)]
+ pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
+ use gecko_bindings::sugar::refptr::RefPtr;
+ match v {
+ Either::First(url) => {
+ let refptr = unsafe {
+ if let Some(ffi) = url.for_ffi() {
+ let ptr = bindings::Gecko_NewURLValue(ffi);
+ RefPtr::from_addrefed(ptr)
+ } else {
+ self.gecko.${gecko_ffi_name}.clear();
+ return;
+ }
+ };
+ self.gecko.${gecko_ffi_name}.set_move(refptr)
+ }
+ Either::Second(_none) => {
+ unsafe {
+ self.gecko.${gecko_ffi_name}.clear();
+ }
+ }
+ }
+ }
+ #[allow(non_snake_case)]
+ pub fn copy_${ident}_from(&mut self, other: &Self) {
+ unsafe {
+ self.gecko.${gecko_ffi_name}.set(&other.gecko.${gecko_ffi_name});
+ }
+ }
+ % if need_clone:
+ <% raise Exception("Do not know how to handle clone ") %>
+ % endif
+</%def>
+
<%def name="impl_logical(name, need_clone=False, **kwargs)">
${helpers.logical_setter(name, need_clone)}
</%def>
<%def name="impl_style_struct(style_struct)">
impl ${style_struct.gecko_struct_name} {
#[allow(dead_code, unused_variables)]
pub fn default(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> {
@@ -595,16 +632,17 @@ impl Debug for ${style_struct.gecko_stru
"LengthOrPercentage": impl_style_coord,
"LengthOrPercentageOrAuto": impl_style_coord,
"LengthOrPercentageOrNone": impl_style_coord,
"LengthOrNone": impl_style_coord,
"Number": impl_simple,
"Opacity": impl_simple,
"CSSColor": impl_color,
"SVGPaint": impl_svg_paint,
+ "UrlOrNone": impl_css_url,
}
def longhand_method(longhand):
args = dict(ident=longhand.ident, gecko_ffi_name=longhand.gecko_ffi_name,
need_clone=longhand.need_clone)
# get the method and pass additional keyword or type-specific arguments
if longhand.logical:
@@ -1273,17 +1311,17 @@ fn static_assert() {
${impl_animation_count(ident, gecko_ffi_name)}
${impl_copy_animation_value(ident, gecko_ffi_name)}
</%def>
<% skip_box_longhands= """display overflow-y vertical-align
animation-name animation-delay animation-duration
animation-direction animation-fill-mode animation-play-state
animation-iteration-count animation-timing-function
- -moz-binding page-break-before page-break-after
+ page-break-before page-break-after
scroll-snap-points-x scroll-snap-points-y transform
scroll-snap-type-y scroll-snap-coordinate
perspective-origin transform-origin""" %>
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
// We manually-implement the |display| property until we get general
// infrastructure for preffing certain values.
<% display_keyword = Keyword("display", "inline block inline-block table inline-table table-row-group " +
@@ -1368,34 +1406,16 @@ fn static_assert() {
.expect("Expected length or percentage for vertical-align");
T::LengthOrPercentage(v)
}
}
}
<%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call>
- #[allow(non_snake_case)]
- pub fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
- use values::Either;
- match v {
- Either::Second(_none) => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()),
- Either::First(ref url) => {
-
- unsafe {
- Gecko_SetMozBinding(&mut self.gecko, url.for_ffi());
- }
- }
- }
- }
- #[allow(non_snake_case)]
- pub fn copy__moz_binding_from(&mut self, other: &Self) {
- unsafe { Gecko_CopyMozBindingFrom(&mut self.gecko, &other.gecko); }
- }
-
// Temp fix for Bugzilla bug 24000.
// Map 'auto' and 'avoid' to false, and 'always', 'left', and 'right' to true.
// "A conforming user agent may interpret the values 'left' and 'right'
// as 'always'." - CSS2.1, section 13.3.1
pub fn set_page_break_before(&mut self, v: longhands::page_break_before::computed_value::T) {
use computed_values::page_break_before::T;
let result = match v {
T::auto => false,
@@ -2110,18 +2130,22 @@ fn static_assert() {
match image {
Either::Second(_none) => {
unsafe {
Gecko_SetListStyleImageNone(&mut self.gecko);
}
}
Either::First(ref url) => {
unsafe {
- Gecko_SetListStyleImage(&mut self.gecko,
- url.for_ffi());
+ if let Some(ffi) = url.for_ffi() {
+ Gecko_SetListStyleImage(&mut self.gecko,
+ ffi);
+ } else {
+ Gecko_SetListStyleImageNone(&mut self.gecko);
+ }
}
// 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 List struct
// is an inherited struct.
}
}
}
@@ -2312,17 +2336,19 @@ fn static_assert() {
},
// TODO handle currentColor
// https://bugzilla.mozilla.org/show_bug.cgi?id=760345
Color::CurrentColor => 0,
};
}
Url(ref url) => {
unsafe {
- bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, url.for_ffi());
+ if let Some(ffi) = url.for_ffi() {
+ bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, ffi);
+ }
}
}
}
}
}
pub fn copy_filter_from(&mut self, other: &Self) {
unsafe {
@@ -2672,17 +2698,19 @@ clip-path
// clean up existing struct
unsafe { Gecko_DestroyClipPath(clip_path) };
clip_path.mType = StyleShapeSourceType::None;
match v {
ShapeSource::Url(ref url) => {
unsafe {
- bindings::Gecko_StyleClipPath_SetURLValue(clip_path, url.for_ffi());
+ if let Some(ffi) = url.for_ffi() {
+ bindings::Gecko_StyleClipPath_SetURLValue(clip_path, ffi);
+ }
}
}
ShapeSource::None => {} // don't change the type
ShapeSource::Box(reference) => {
clip_path.mReferenceBox = reference.into();
clip_path.mType = StyleShapeSourceType::Box;
}
ShapeSource::Shape(servo_shape, maybe_box) => {
--- a/servo/components/style/properties/longhand/box.mako.rs
+++ b/servo/components/style/properties/longhand/box.mako.rs
@@ -1917,16 +1917,17 @@
gecko_constant_prefix="NS_THEME",
products="gecko",
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-appearance)",
animatable=False)}
${helpers.predefined_type("-moz-binding", "UrlOrNone", "Either::Second(None_)",
products="gecko",
animatable="False",
+ gecko_ffi_name="mBinding",
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)",
disable_when_testing="True",
boxed=True)}
${helpers.single_keyword("-moz-orient",
"inline block horizontal vertical",
products="gecko",
gecko_ffi_name="mOrient",
--- a/servo/components/style/properties/longhand/inherited_svg.mako.rs
+++ b/servo/components/style/properties/longhand/inherited_svg.mako.rs
@@ -95,8 +95,27 @@
// Section 14 - Clipping, Masking and Compositing
${helpers.single_keyword("clip-rule", "nonzero evenodd",
products="gecko",
gecko_enum_prefix="StyleFillRule",
gecko_inexhaustive=True,
animatable=False,
spec="https://www.w3.org/TR/SVG11/masking.html#ClipRuleProperty")}
+
+${helpers.predefined_type("marker-start", "UrlOrNone", "Either::Second(None_)",
+ products="gecko",
+ animatable="False",
+ spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties",
+ boxed=True)}
+
+${helpers.predefined_type("marker-mid", "UrlOrNone", "Either::Second(None_)",
+ products="gecko",
+ animatable="False",
+ spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties",
+ boxed=True)}
+
+${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
+ products="gecko",
+ animatable="False",
+ spec="https://www.w3.org/TR/SVG2/painting.html#VertexMarkerProperties",
+ boxed=True)}
+
--- a/servo/components/style/values/specified/url.rs
+++ b/servo/components/style/values/specified/url.rs
@@ -167,30 +167,29 @@ impl SpecifiedUrl {
original: Some(Arc::new(url.into())),
resolved: ServoUrl::parse(url).ok(),
extra_data: UrlExtraData {}
}
}
/// Create a bundled URI suitable for sending to Gecko
/// to be constructed into a css::URLValue
- pub fn for_ffi(&self) -> ServoBundledURI {
- use std::ptr;
+ pub fn for_ffi(&self) -> Option<ServoBundledURI> {
let extra_data = self.extra_data();
let (ptr, len) = match self.as_slice_components() {
Ok(value) => value,
- Err(_) => (ptr::null(), 0),
+ Err(_) => return None,
};
- ServoBundledURI {
+ Some(ServoBundledURI {
mURLString: ptr,
mURLStringLength: len as u32,
mBaseURI: extra_data.base.get(),
mReferrer: extra_data.referrer.get(),
mPrincipal: extra_data.principal.get(),
- }
+ })
}
}
impl PartialEq for SpecifiedUrl {
fn eq(&self, other: &Self) -> bool {
// TODO(emilio): maybe we care about equality of the specified values if
// present? Seems not.
self.resolved == other.resolved &&