diff --git a/components/style/values/computed/pointing.rs b/components/style/values/computed/pointing.rs index a0102c12070..a89db9104c3 100644 --- a/components/style/values/computed/pointing.rs +++ b/components/style/values/computed/pointing.rs @@ -6,137 +6,16 @@ //! //! https://drafts.csswg.org/css-ui/#pointing-keyboard -use cssparser::Parser; -use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseErrorKind; -#[cfg(feature = "gecko")] -use std::fmt::{self, Write}; -#[cfg(feature = "gecko")] -use style_traits::{CssWriter, ToCss}; -use style_traits::ParseError; -use style_traits::cursor::CursorKind; +use values::computed::Number; use values::computed::color::Color; -use values::generics::pointing::CaretColor as GenericCaretColor; -#[cfg(feature = "gecko")] -use values::specified::url::SpecifiedImageUrl; - -/// The computed value for the `cursor` property. -/// -/// https://drafts.csswg.org/css-ui/#cursor -pub use values::specified::pointing::Cursor; -#[cfg(feature = "gecko")] -pub use values::specified::pointing::CursorImage; - -impl Cursor { - /// Set `cursor` to `auto` - #[cfg(feature = "servo")] - #[inline] - pub fn auto() -> Self { - Cursor(CursorKind::Auto) - } - - /// Set `cursor` to `auto` - #[cfg(feature = "gecko")] - #[inline] - pub fn auto() -> Self { - Self { - images: vec![].into_boxed_slice(), - keyword: CursorKind::Auto, - } - } -} - -impl Parse for Cursor { - /// cursor: [auto | default | ...] - #[cfg(feature = "servo")] - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - Ok(Cursor(CursorKind::parse(context, input)?)) - } - - /// cursor: [ [ ]?]# [auto | default | ...] - #[cfg(feature = "gecko")] - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let mut images = vec![]; - loop { - match input.try(|input| CursorImage::parse_image(context, input)) { - Ok(image) => images.push(image), - Err(_) => break, - } - input.expect_comma()?; - } - Ok(Self { - images: images.into_boxed_slice(), - keyword: CursorKind::parse(context, input)?, - }) - } -} - -#[cfg(feature = "gecko")] -impl ToCss for Cursor { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - for url in &*self.images { - url.to_css(dest)?; - dest.write_str(", ")?; - } - self.keyword.to_css(dest) - } -} - -impl Parse for CursorKind { - fn parse<'i, 't>( - _context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let location = input.current_source_location(); - let ident = input.expect_ident()?; - CursorKind::from_css_keyword(&ident).map_err(|_| { - location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())) - }) - } -} - -#[cfg(feature = "gecko")] -impl CursorImage { - fn parse_image<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - Ok(Self { - 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()?)), - Err(_) => None, - }, - }) - } -} - -#[cfg(feature = "gecko")] -impl ToCss for CursorImage { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - self.url.to_css(dest)?; - if let Some((x, y)) = self.hotspot { - dest.write_str(" ")?; - x.to_css(dest)?; - dest.write_str(" ")?; - y.to_css(dest)?; - } - Ok(()) - } -} +use values::computed::url::ComputedImageUrl; +use values::generics::pointing as generics; /// A computed value for the `caret-color` property. -pub type CaretColor = GenericCaretColor; +pub type CaretColor = generics::CaretColor; + +/// A computed value for the `cursor` property. +pub type Cursor = generics::Cursor; + +/// A computed value for item of `image cursors`. +pub type CursorImage = generics::CursorImage; diff --git a/components/style/values/generics/pointing.rs b/components/style/values/generics/pointing.rs index 7e55c4a5a75..f84e70b7bfa 100644 --- a/components/style/values/generics/pointing.rs +++ b/components/style/values/generics/pointing.rs @@ -4,6 +4,10 @@ //! Generic values for pointing properties. +use std::fmt::{self, Write}; +use style_traits::{CssWriter, ToCss}; +use style_traits::cursor::CursorKind; + /// A generic value for the `caret-color` property. #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss)] @@ -13,3 +17,63 @@ pub enum CaretColor { /// The keyword `auto`. Auto, } + +/// A generic value for the `cursor` property. +/// +/// https://drafts.csswg.org/css-ui/#cursor +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] +pub struct Cursor { + /// The parsed images for the cursor. + pub images: Box<[Image]>, + /// The kind of the cursor [default | help | ...]. + pub keyword: CursorKind, +} + +impl Cursor { + /// Set `cursor` to `auto` + #[inline] + pub fn auto() -> Self { + Self { + images: vec![].into_boxed_slice(), + keyword: CursorKind::Auto, + } + } +} + +impl ToCss for Cursor { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + for image in &*self.images { + image.to_css(dest)?; + dest.write_str(", ")?; + } + self.keyword.to_css(dest) + } +} + +/// A generic value for item of `image cursors`. +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] +pub struct CursorImage { + /// The url to parse images from. + pub url: ImageUrl, + /// The and coordinates. + pub hotspot: Option<(Number, Number)>, +} + +impl ToCss for CursorImage { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + self.url.to_css(dest)?; + if let Some((ref x, ref y)) = self.hotspot { + dest.write_str(" ")?; + x.to_css(dest)?; + dest.write_str(" ")?; + y.to_css(dest)?; + } + Ok(()) + } +} diff --git a/components/style/values/specified/pointing.rs b/components/style/values/specified/pointing.rs index d8da1305efb..cf718a1fd9d 100644 --- a/components/style/values/specified/pointing.rs +++ b/components/style/values/specified/pointing.rs @@ -8,44 +8,15 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; -use style_traits::ParseError; +use style_traits::{ParseError, StyleParseErrorKind}; use style_traits::cursor::CursorKind; -use values::generics::pointing::CaretColor as GenericCaretColor; +use values::generics::pointing as generics; +use values::specified::Number; use values::specified::color::Color; -#[cfg(feature = "gecko")] use values::specified::url::SpecifiedImageUrl; -/// The specified value for the `cursor` property. -/// -/// https://drafts.csswg.org/css-ui/#cursor -#[cfg(feature = "servo")] -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)] -pub struct Cursor(pub CursorKind); - -/// The specified value for the `cursor` property. -/// -/// https://drafts.csswg.org/css-ui/#cursor -#[cfg(feature = "gecko")] -#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] -pub struct Cursor { - /// The parsed images for the cursor. - pub images: Box<[CursorImage]>, - /// The kind of the cursor [default | help | ...]. - pub keyword: CursorKind, -} - -/// The specified value for the `image cursors`. -#[cfg(feature = "gecko")] -#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)] -pub struct CursorImage { - /// The url to parse images from. - pub url: SpecifiedImageUrl, - /// The and coordinates. - pub hotspot: Option<(f32, f32)>, -} - /// A specified value for the `caret-color` property. -pub type CaretColor = GenericCaretColor; +pub type CaretColor = generics::CaretColor; impl Parse for CaretColor { fn parse<'i, 't>( @@ -53,8 +24,63 @@ impl Parse for CaretColor { input: &mut Parser<'i, 't>, ) -> Result> { if input.try(|i| i.expect_ident_matching("auto")).is_ok() { - return Ok(GenericCaretColor::Auto); + return Ok(generics::CaretColor::Auto); } - Ok(GenericCaretColor::Color(Color::parse(context, input)?)) + Ok(generics::CaretColor::Color(Color::parse(context, input)?)) + } +} + +/// A specified value for the `cursor` property. +pub type Cursor = generics::Cursor; + +/// A specified value for item of `image cursors`. +pub type CursorImage = generics::CursorImage; + +impl Parse for Cursor { + /// cursor: [ [ ]?]# [auto | default | ...] + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + let mut images = vec![]; + loop { + match input.try(|input| CursorImage::parse(context, input)) { + Ok(image) => images.push(image), + Err(_) => break, + } + input.expect_comma()?; + } + Ok(Self { + images: images.into_boxed_slice(), + keyword: CursorKind::parse(context, input)?, + }) + } +} + +impl Parse for CursorKind { + fn parse<'i, 't>( + _context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + let location = input.current_source_location(); + let ident = input.expect_ident()?; + CursorKind::from_css_keyword(&ident).map_err(|_| { + location.new_custom_error(StyleParseErrorKind::UnspecifiedError) + }) + } +} + +impl Parse for CursorImage { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + Ok(Self { + url: SpecifiedImageUrl::parse(context, input)?, + hotspot: match input.try(|input| Number::parse(context, input)) { + Ok(number) => Some((number, Number::parse(context, input)?)), + Err(_) => None, + }, + }) } }