diff options
-rw-r--r-- | components/layout/display_list_builder.rs | 4 | ||||
-rwxr-xr-x | components/style/binding_tools/regen.py | 1 | ||||
-rw-r--r-- | components/style/gecko_bindings/bindings.rs | 16 | ||||
-rw-r--r-- | components/style/gecko_bindings/structs_debug.rs | 2 | ||||
-rw-r--r-- | components/style/gecko_bindings/structs_release.rs | 2 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 38 | ||||
-rw-r--r-- | components/style/properties/longhand/pointing.mako.rs | 118 |
7 files changed, 158 insertions, 23 deletions
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 500af800939..4505ac10192 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -2246,8 +2246,8 @@ impl ServoComputedValuesCursorUtility for ServoComputedValues { fn get_cursor(&self, default_cursor: Cursor) -> Option<Cursor> { match (self.get_pointing().pointer_events, self.get_pointing().cursor) { (pointer_events::T::none, _) => None, - (pointer_events::T::auto, cursor::T::AutoCursor) => Some(default_cursor), - (pointer_events::T::auto, cursor::T::SpecifiedCursor(cursor)) => Some(cursor), + (pointer_events::T::auto, cursor::Keyword::AutoCursor) => Some(default_cursor), + (pointer_events::T::auto, cursor::Keyword::SpecifiedCursor(cursor)) => Some(cursor), } } } diff --git a/components/style/binding_tools/regen.py b/components/style/binding_tools/regen.py index 78a22738f1a..88ed56baf00 100755 --- a/components/style/binding_tools/regen.py +++ b/components/style/binding_tools/regen.py @@ -278,6 +278,7 @@ COMPILATION_TARGETS = { "nsCSSValue", "nsCSSValueSharedList", "nsChangeHint", + "nsCursorImage", "nsFont", "nsIAtom", "nsIDocument", diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index a17d2df57bc..dcd961263c6 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -60,6 +60,7 @@ use gecko_bindings::structs::nsCSSShadowArray; use gecko_bindings::structs::nsCSSValue; use gecko_bindings::structs::nsCSSValueSharedList; use gecko_bindings::structs::nsChangeHint; +use gecko_bindings::structs::nsCursorImage; use gecko_bindings::structs::nsFont; use gecko_bindings::structs::nsIAtom; use gecko_bindings::structs::nsIDocument; @@ -511,6 +512,21 @@ extern "C" { src: *const nsStyleList); } extern "C" { + pub fn Gecko_SetCursorArrayLength(ui: *mut nsStyleUserInterface, + len: usize); +} +extern "C" { + pub fn Gecko_SetCursorImage(cursor: *mut nsCursorImage, + string_bytes: *const u8, string_length: u32, + base_uri: *mut ThreadSafeURIHolder, + 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, string_bytes: *const u8, string_length: u32, base_uri: *mut ThreadSafeURIHolder, diff --git a/components/style/gecko_bindings/structs_debug.rs b/components/style/gecko_bindings/structs_debug.rs index 298f661ac28..eaa06e839e2 100644 --- a/components/style/gecko_bindings/structs_debug.rs +++ b/components/style/gecko_bindings/structs_debug.rs @@ -11866,7 +11866,7 @@ pub struct nsCursorImage { pub mHaveHotspot: bool, pub mHotspotX: f32, pub mHotspotY: f32, - pub mImage: nsCOMPtr<imgIRequest>, + pub mImage: RefPtr<nsStyleImageRequest>, } #[test] fn bindgen_test_layout_nsCursorImage() { diff --git a/components/style/gecko_bindings/structs_release.rs b/components/style/gecko_bindings/structs_release.rs index c8e67da2070..9a2686b93f7 100644 --- a/components/style/gecko_bindings/structs_release.rs +++ b/components/style/gecko_bindings/structs_release.rs @@ -11822,7 +11822,7 @@ pub struct nsCursorImage { pub mHaveHotspot: bool, pub mHotspotX: f32, pub mHotspotY: f32, - pub mImage: nsCOMPtr<imgIRequest>, + pub mImage: RefPtr<nsStyleImageRequest>, } #[test] fn bindgen_test_layout_nsCursorImage() { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index a82dcd4a4e0..b8d02879368 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -19,6 +19,7 @@ use gecko_bindings::bindings::Gecko_Construct_${style_struct.gecko_ffi_name}; use gecko_bindings::bindings::Gecko_CopyConstruct_${style_struct.gecko_ffi_name}; use gecko_bindings::bindings::Gecko_Destroy_${style_struct.gecko_ffi_name}; % endfor +use gecko_bindings::bindings::Gecko_CopyCursorArrayFrom; use gecko_bindings::bindings::Gecko_CopyFontFamilyFrom; use gecko_bindings::bindings::Gecko_CopyImageValueFrom; use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom; @@ -28,6 +29,8 @@ 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_SetListStyleImage; use gecko_bindings::bindings::Gecko_SetListStyleImageNone; use gecko_bindings::bindings::Gecko_SetListStyleType; @@ -2195,12 +2198,12 @@ clip-path <%self:impl_trait style_struct_name="Pointing" skip_longhands="cursor"> pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) { - use properties::longhands::cursor::computed_value::T; + use properties::longhands::cursor::computed_value::Keyword; use style_traits::cursor::Cursor; - self.gecko.mCursor = match v { - T::AutoCursor => structs::NS_STYLE_CURSOR_AUTO, - T::SpecifiedCursor(cursor) => match cursor { + self.gecko.mCursor = match v.keyword { + Keyword::AutoCursor => structs::NS_STYLE_CURSOR_AUTO, + Keyword::SpecifiedCursor(cursor) => match cursor { Cursor::None => structs::NS_STYLE_CURSOR_NONE, Cursor::Default => structs::NS_STYLE_CURSOR_DEFAULT, Cursor::Pointer => structs::NS_STYLE_CURSOR_POINTER, @@ -2238,9 +2241,34 @@ clip-path Cursor::ZoomOut => structs::NS_STYLE_CURSOR_ZOOM_OUT, } } as u8; + + unsafe { + Gecko_SetCursorArrayLength(&mut self.gecko, v.images.len()); + } + for i in 0..v.images.len() { + let image = &v.images[i]; + let extra_data = image.url.extra_data(); + let (ptr, len) = image.url.as_slice_components(); + unsafe { + Gecko_SetCursorImage(&mut self.gecko.mCursorImages[i], + ptr, len as u32, + extra_data.base.get(), + extra_data.referrer.get(), + extra_data.principal.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 + // is an inherited struct. + } } - ${impl_simple_copy('cursor', 'mCursor')} + pub fn copy_cursor_from(&mut self, other: &Self) { + self.gecko.mCursor = other.gecko.mCursor; + unsafe { + Gecko_CopyCursorArrayFrom(&mut self.gecko, &other.gecko); + } + } </%self:impl_trait> <%self:impl_trait style_struct_name="Column" diff --git a/components/style/properties/longhand/pointing.mako.rs b/components/style/properties/longhand/pointing.mako.rs index f140b32336e..c46e4fdb841 100644 --- a/components/style/properties/longhand/pointing.mako.rs +++ b/components/style/properties/longhand/pointing.mako.rs @@ -10,6 +10,7 @@ pub use self::computed_value::T as SpecifiedValue; use values::NoViewportPercentage; use values::computed::ComputedValueAsSpecified; + use values::specified::url::SpecifiedUrl; impl ComputedValueAsSpecified for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {} @@ -18,38 +19,127 @@ use std::fmt; use style_traits::cursor::Cursor; use style_traits::ToCss; + use values::specified::url::SpecifiedUrl; - #[derive(Clone, PartialEq, Eq, Copy, Debug)] + #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum T { + pub enum Keyword { AutoCursor, SpecifiedCursor(Cursor), } - impl ToCss for T { + #[cfg(not(feature = "gecko"))] + pub type T = Keyword; + + #[cfg(feature = "gecko")] + #[derive(Clone, PartialEq, Debug)] + pub struct Image { + pub url: SpecifiedUrl, + pub hotspot: Option<(f32, f32)>, + } + + #[cfg(feature = "gecko")] + #[derive(Clone, PartialEq, Debug)] + pub struct T { + pub images: Vec<Image>, + pub keyword: Keyword, + } + + impl ToCss for Keyword { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { - T::AutoCursor => dest.write_str("auto"), - T::SpecifiedCursor(c) => c.to_css(dest), + Keyword::AutoCursor => dest.write_str("auto"), + Keyword::SpecifiedCursor(c) => c.to_css(dest), + } + } + } + + #[cfg(feature = "gecko")] + impl ToCss for Image { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + try!(self.url.to_css(dest)); + if let Some((x, y)) = self.hotspot { + try!(dest.write_str(" ")); + try!(x.to_css(dest)); + try!(dest.write_str(" ")); + try!(y.to_css(dest)); + } + Ok(()) + } + } + + #[cfg(feature = "gecko")] + impl ToCss for T { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + for url in &self.images { + try!(url.to_css(dest)); + try!(dest.write_str(", ")); } + self.keyword.to_css(dest) } } } + #[cfg(not(feature = "gecko"))] #[inline] pub fn get_initial_value() -> computed_value::T { - computed_value::T::AutoCursor + computed_value::Keyword::AutoCursor } + + #[cfg(feature = "gecko")] + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T { + images: vec![], + keyword: computed_value::Keyword::AutoCursor + } + } + + impl Parse for computed_value::Keyword { + fn parse(input: &mut Parser) -> Result<computed_value::Keyword, ()> { + use std::ascii::AsciiExt; + use style_traits::cursor::Cursor; + let ident = try!(input.expect_ident()); + if ident.eq_ignore_ascii_case("auto") { + Ok(computed_value::Keyword::AutoCursor) + } else { + Cursor::from_css_keyword(&ident).map(computed_value::Keyword::SpecifiedCursor) + } + } + } + + #[cfg(feature = "gecko")] + fn parse_image(context: &ParserContext, input: &mut Parser) -> Result<computed_value::Image, ()> { + Ok(computed_value::Image { + url: try!(SpecifiedUrl::parse(context, input)), + hotspot: match input.try(|input| input.expect_number()) { + Ok(number) => Some((number, try!(input.expect_number()))), + Err(()) => None, + }, + }) + } + + #[cfg(not(feature = "gecko"))] pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - use std::ascii::AsciiExt; - use style_traits::cursor::Cursor; - let ident = try!(input.expect_ident()); - if ident.eq_ignore_ascii_case("auto") { - Ok(SpecifiedValue::AutoCursor) - } else { - Cursor::from_css_keyword(&ident) - .map(SpecifiedValue::SpecifiedCursor) + computed_value::Keyword::parse(input) + } + + /// cursor: [<url> [<number> <number>]?]# [auto | default | ...] + #[cfg(feature = "gecko")] + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + let mut images = vec![]; + loop { + match input.try(|input| parse_image(context, input)) { + Ok(image) => images.push(image), + Err(()) => break, + } + try!(input.expect_comma()); } + + Ok(computed_value::T { + images: images, + keyword: try!(computed_value::Keyword::parse(input)), + }) } </%helpers:longhand> |