aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-11-21 05:49:05 -0600
committerGitHub <noreply@github.com>2016-11-21 05:49:05 -0600
commiteb531c15d990391f73f3a1030b103dfc3e023427 (patch)
treeba06b83b07a8dc70a0b89972fb649251bada323b
parent87a0809606d5a7c59f9f34cfe4cb6a09d1618cc5 (diff)
parent830cc88283d3cf92f378cd104efd2743aa38da11 (diff)
downloadservo-eb531c15d990391f73f3a1030b103dfc3e023427.tar.gz
servo-eb531c15d990391f73f3a1030b103dfc3e023427.zip
Auto merge of #14055 - heycam:cursor, r=Manishearth
support cursor property url() values in stylo <!-- Please describe your changes on the following line: --> This is the Servo-side change for [bug 1310560](https://bugzilla.mozilla.org/show_bug.cgi?id=1310560), which @Manishearth has already r+ed. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [ ] `./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 _____ <!-- 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/14055) <!-- Reviewable:end -->
-rw-r--r--components/layout/display_list_builder.rs4
-rwxr-xr-xcomponents/style/binding_tools/regen.py1
-rw-r--r--components/style/gecko_bindings/bindings.rs16
-rw-r--r--components/style/gecko_bindings/structs_debug.rs2
-rw-r--r--components/style/gecko_bindings/structs_release.rs2
-rw-r--r--components/style/properties/gecko.mako.rs38
-rw-r--r--components/style/properties/longhand/pointing.mako.rs118
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>