style: Move cursor property out of mako

This commit is contained in:
Igor Gutorov 2018-01-15 16:21:44 +02:00
parent 671b69c0b7
commit 4ee9eb8563
17 changed files with 413 additions and 360 deletions

View file

@ -29,7 +29,7 @@ use std::rc::Rc;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor}; use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor};
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use time::{precise_time_ns, precise_time_s}; use time::{precise_time_ns, precise_time_s};
use touch::{TouchHandler, TouchAction}; use touch::{TouchHandler, TouchAction};
@ -769,7 +769,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
warn!("Sending event to constellation failed ({}).", e); warn!("Sending event to constellation failed ({}).", e);
} }
if let Some(cursor) = Cursor::from_u8(item.tag.1 as _).ok() { if let Some(cursor) = CursorKind::from_u8(item.tag.1 as _).ok() {
let msg = ConstellationMsg::SetCursor(cursor); let msg = ConstellationMsg::SetCursor(cursor);
if let Err(e) = self.constellation_chan.send(msg) { if let Err(e) = self.constellation_chan.send(msg) {
warn!("Sending event to constellation failed ({}).", e); warn!("Sending event to constellation failed ({}).", e);

View file

@ -17,7 +17,7 @@ use script_traits::{AnimationState, ConstellationMsg, EventResult, LoadData};
use servo_url::ServoUrl; use servo_url::ServoUrl;
use std::fmt::{Debug, Error, Formatter}; use std::fmt::{Debug, Error, Formatter};
use std::sync::mpsc::{Receiver, Sender}; use std::sync::mpsc::{Receiver, Sender};
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use webrender; use webrender;
use webrender_api; use webrender_api;
@ -133,7 +133,7 @@ pub enum EmbedderMsg {
/// Sends an unconsumed key event back to the embedder. /// Sends an unconsumed key event back to the embedder.
KeyEvent(Option<TopLevelBrowsingContextId>, Option<char>, Key, KeyState, KeyModifiers), KeyEvent(Option<TopLevelBrowsingContextId>, Option<char>, Key, KeyState, KeyModifiers),
/// Changes the cursor. /// Changes the cursor.
SetCursor(Cursor), SetCursor(CursorKind),
/// A favicon was detected /// A favicon was detected
NewFavicon(TopLevelBrowsingContextId, ServoUrl), NewFavicon(TopLevelBrowsingContextId, ServoUrl),
/// <head> tag finished parsing /// <head> tag finished parsing

View file

@ -17,7 +17,7 @@ use servo_url::ServoUrl;
use std::fmt::{Debug, Error, Formatter}; use std::fmt::{Debug, Error, Formatter};
use std::rc::Rc; use std::rc::Rc;
use style_traits::DevicePixel; use style_traits::DevicePixel;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use webrender_api::{DeviceUintSize, DeviceUintRect, ScrollLocation}; use webrender_api::{DeviceUintSize, DeviceUintRect, ScrollLocation};
#[derive(Clone)] #[derive(Clone)]
@ -173,7 +173,7 @@ pub trait WindowMethods {
fn prepare_for_composite(&self, width: usize, height: usize) -> bool; fn prepare_for_composite(&self, width: usize, height: usize) -> bool;
/// Sets the cursor to be used in the window. /// Sets the cursor to be used in the window.
fn set_cursor(&self, cursor: Cursor); fn set_cursor(&self, cursor: CursorKind);
/// Process a key event. /// Process a key event.
fn handle_key(&self, ctx: Option<TopLevelBrowsingContextId>, ch: Option<char>, key: Key, mods: KeyModifiers); fn handle_key(&self, ctx: Option<TopLevelBrowsingContextId>, ch: Option<char>, key: Key, mods: KeyModifiers);

View file

@ -154,7 +154,7 @@ use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender, channel}; use std::sync::mpsc::{Receiver, Sender, channel};
use std::thread; use std::thread;
use style_traits::CSSPixel; use style_traits::CSSPixel;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use timer_scheduler::TimerScheduler; use timer_scheduler::TimerScheduler;
use webrender_api; use webrender_api;
@ -1818,7 +1818,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
self.compositor_proxy.send(ToCompositorMsg::PendingPaintMetric(pipeline_id, epoch)) self.compositor_proxy.send(ToCompositorMsg::PendingPaintMetric(pipeline_id, epoch))
} }
fn handle_set_cursor_msg(&mut self, cursor: Cursor) { fn handle_set_cursor_msg(&mut self, cursor: CursorKind) {
self.embedder_proxy.send(EmbedderMsg::SetCursor(cursor)) self.embedder_proxy.send(EmbedderMsg::SetCursor(cursor))
} }

View file

@ -30,7 +30,7 @@ use std::f32;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::values::computed::Filter; use style::values::computed::Filter;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use text::TextRun; use text::TextRun;
use text::glyph::ByteIndex; use text::glyph::ByteIndex;
use webrender_api::{BoxShadowClipMode, ClipId, ColorF, ExtendMode, GradientStop, ImageKey}; use webrender_api::{BoxShadowClipMode, ClipId, ColorF, ExtendMode, GradientStop, ImageKey};
@ -646,7 +646,7 @@ pub struct DisplayItemMetadata {
pub node: OpaqueNode, pub node: OpaqueNode,
/// The value of the `cursor` property when the mouse hovers over this display item. If `None`, /// The value of the `cursor` property when the mouse hovers over this display item. If `None`,
/// this display item is ineligible for pointer events (`pointer-events: none`). /// this display item is ineligible for pointer events (`pointer-events: none`).
pub pointing: Option<Cursor>, pub pointing: Option<CursorKind>,
} }
/// Paints a solid color. /// Paints a solid color.

View file

@ -55,7 +55,6 @@ use style::computed_values::background_attachment::single_value::T as Background
use style::computed_values::background_clip::single_value::T as BackgroundClip; use style::computed_values::background_clip::single_value::T as BackgroundClip;
use style::computed_values::background_origin::single_value::T as BackgroundOrigin; use style::computed_values::background_origin::single_value::T as BackgroundOrigin;
use style::computed_values::border_style::T as BorderStyle; use style::computed_values::border_style::T as BorderStyle;
use style::computed_values::cursor;
use style::computed_values::overflow_x::T as StyleOverflow; use style::computed_values::overflow_x::T as StyleOverflow;
use style::computed_values::pointer_events::T as PointerEvents; use style::computed_values::pointer_events::T as PointerEvents;
use style::computed_values::position::T as StylePosition; use style::computed_values::position::T as StylePosition;
@ -67,12 +66,13 @@ use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::{Either, RGBA}; use style::values::{Either, RGBA};
use style::values::computed::{Gradient, NumberOrPercentage}; use style::values::computed::{Gradient, NumberOrPercentage};
use style::values::computed::effects::SimpleShadow; use style::values::computed::effects::SimpleShadow;
use style::values::computed::pointing::Cursor;
use style::values::generics::background::BackgroundSize; use style::values::generics::background::BackgroundSize;
use style::values::generics::effects::Filter; use style::values::generics::effects::Filter;
use style::values::generics::image::{GradientKind, Image, PaintWorklet}; use style::values::generics::image::{GradientKind, Image, PaintWorklet};
use style_traits::CSSPixel; use style_traits::CSSPixel;
use style_traits::ToCss; use style_traits::ToCss;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use table_cell::CollapsedBordersForCell; use table_cell::CollapsedBordersForCell;
use webrender_api::{self, BoxShadowClipMode, ClipId, ClipMode, ColorF, ComplexClipRegion}; use webrender_api::{self, BoxShadowClipMode, ClipId, ClipMode, ColorF, ComplexClipRegion};
use webrender_api::{ImageRendering, LayoutSize, LayoutVector2D, LineStyle}; use webrender_api::{ImageRendering, LayoutSize, LayoutVector2D, LineStyle};
@ -375,7 +375,7 @@ impl<'a> DisplayListBuildState<'a> {
bounds: &Rect<Au>, bounds: &Rect<Au>,
clip: LocalClip, clip: LocalClip,
node: OpaqueNode, node: OpaqueNode,
cursor: Option<Cursor>, cursor: Option<CursorKind>,
section: DisplayListSection, section: DisplayListSection,
) -> BaseDisplayItem { ) -> BaseDisplayItem {
let clipping_and_scrolling = if self.is_background_or_border_of_clip_scroll_node(section) { let clipping_and_scrolling = if self.is_background_or_border_of_clip_scroll_node(section) {
@ -930,7 +930,7 @@ impl FragmentDisplayListBuilding for Fragment {
&bounds, &bounds,
clip, clip,
self.node, self.node,
style.get_cursor(Cursor::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem {
@ -1121,7 +1121,7 @@ impl FragmentDisplayListBuilding for Fragment {
&placement.bounds, &placement.bounds,
LocalClip::Rect(placement.css_clip.to_layout()), LocalClip::Rect(placement.css_clip.to_layout()),
self.node, self.node,
style.get_cursor(Cursor::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
@ -1213,7 +1213,7 @@ impl FragmentDisplayListBuilding for Fragment {
&placement.bounds, &placement.bounds,
LocalClip::Rect(placement.css_clip.to_layout()), LocalClip::Rect(placement.css_clip.to_layout()),
self.node, self.node,
style.get_cursor(Cursor::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
@ -1274,7 +1274,7 @@ impl FragmentDisplayListBuilding for Fragment {
&bounds, &bounds,
LocalClip::from(clip.to_layout()), LocalClip::from(clip.to_layout()),
self.node, self.node,
style.get_cursor(Cursor::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
let border_radius = build_border_radius(absolute_bounds, style.get_border()); let border_radius = build_border_radius(absolute_bounds, style.get_border());
@ -1370,7 +1370,7 @@ impl FragmentDisplayListBuilding for Fragment {
&bounds, &bounds,
LocalClip::from(clip.to_layout()), LocalClip::from(clip.to_layout()),
self.node, self.node,
style.get_cursor(Cursor::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
@ -1544,7 +1544,7 @@ impl FragmentDisplayListBuilding for Fragment {
&bounds, &bounds,
LocalClip::from(clip.to_layout()), LocalClip::from(clip.to_layout()),
self.node, self.node,
style.get_cursor(Cursor::Default), style.get_cursor(CursorKind::Default),
DisplayListSection::Outlines, DisplayListSection::Outlines,
); );
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
@ -1571,7 +1571,7 @@ impl FragmentDisplayListBuilding for Fragment {
stacking_relative_border_box, stacking_relative_border_box,
LocalClip::from(clip.to_layout()), LocalClip::from(clip.to_layout()),
self.node, self.node,
style.get_cursor(Cursor::Default), style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
@ -1597,7 +1597,7 @@ impl FragmentDisplayListBuilding for Fragment {
&baseline, &baseline,
LocalClip::from(clip.to_layout()), LocalClip::from(clip.to_layout()),
self.node, self.node,
style.get_cursor(Cursor::Default), style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
state.add_display_item(DisplayItem::Line(Box::new(LineDisplayItem { state.add_display_item(DisplayItem::Line(Box::new(LineDisplayItem {
@ -1618,7 +1618,7 @@ impl FragmentDisplayListBuilding for Fragment {
stacking_relative_border_box, stacking_relative_border_box,
LocalClip::from(clip.to_layout()), LocalClip::from(clip.to_layout()),
self.node, self.node,
self.style.get_cursor(Cursor::Default), self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
@ -1655,7 +1655,7 @@ impl FragmentDisplayListBuilding for Fragment {
stacking_relative_border_box, stacking_relative_border_box,
LocalClip::from(clip.to_layout()), LocalClip::from(clip.to_layout()),
self.node, self.node,
self.style.get_cursor(Cursor::Default), self.style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem {
@ -1688,7 +1688,7 @@ impl FragmentDisplayListBuilding for Fragment {
stacking_relative_border_box.size.height, stacking_relative_border_box.size.height,
), ),
); );
cursor = Cursor::Text; cursor = CursorKind::Text;
} else { } else {
insertion_point_bounds = Rect::new( insertion_point_bounds = Rect::new(
Point2D::new( Point2D::new(
@ -1700,7 +1700,7 @@ impl FragmentDisplayListBuilding for Fragment {
INSERTION_POINT_LOGICAL_WIDTH, INSERTION_POINT_LOGICAL_WIDTH,
), ),
); );
cursor = Cursor::VerticalText; cursor = CursorKind::VerticalText;
}; };
let base = state.create_base_display_item( let base = state.create_base_display_item(
@ -1963,7 +1963,7 @@ impl FragmentDisplayListBuilding for Fragment {
&stacking_relative_content_box, &stacking_relative_content_box,
build_local_clip(&self.style), build_local_clip(&self.style),
self.node, self.node,
self.style.get_cursor(Cursor::Default), self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
let item = DisplayItem::Iframe(Box::new(IframeDisplayItem { let item = DisplayItem::Iframe(Box::new(IframeDisplayItem {
@ -1989,7 +1989,7 @@ impl FragmentDisplayListBuilding for Fragment {
&stacking_relative_content_box, &stacking_relative_content_box,
build_local_clip(&self.style), build_local_clip(&self.style),
self.node, self.node,
self.style.get_cursor(Cursor::Default), self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem { state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
@ -2025,7 +2025,7 @@ impl FragmentDisplayListBuilding for Fragment {
&stacking_relative_content_box, &stacking_relative_content_box,
build_local_clip(&self.style), build_local_clip(&self.style),
self.node, self.node,
self.style.get_cursor(Cursor::Default), self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
let display_item = DisplayItem::Image(Box::new(ImageDisplayItem { let display_item = DisplayItem::Image(Box::new(ImageDisplayItem {
@ -2128,9 +2128,9 @@ impl FragmentDisplayListBuilding for Fragment {
let (orientation, cursor) = if self.style.writing_mode.is_vertical() { let (orientation, cursor) = if self.style.writing_mode.is_vertical() {
// TODO: Distinguish between 'sideways-lr' and 'sideways-rl' writing modes in CSS // TODO: Distinguish between 'sideways-lr' and 'sideways-rl' writing modes in CSS
// Writing Modes Level 4. // Writing Modes Level 4.
(TextOrientation::SidewaysRight, Cursor::VerticalText) (TextOrientation::SidewaysRight, CursorKind::VerticalText)
} else { } else {
(TextOrientation::Upright, Cursor::Text) (TextOrientation::Upright, CursorKind::Text)
}; };
// Compute location of the baseline. // Compute location of the baseline.
@ -2256,7 +2256,7 @@ impl FragmentDisplayListBuilding for Fragment {
&stacking_relative_box, &stacking_relative_box,
LocalClip::from(clip.to_layout()), LocalClip::from(clip.to_layout()),
self.node, self.node,
self.style.get_cursor(Cursor::Default), self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
@ -3158,7 +3158,7 @@ impl BaseFlowDisplayListBuilding for BaseFlow {
} }
trait ComputedValuesCursorUtility { trait ComputedValuesCursorUtility {
fn get_cursor(&self, default_cursor: Cursor) -> Option<Cursor>; fn get_cursor(&self, default_cursor: CursorKind) -> Option<CursorKind>;
} }
impl ComputedValuesCursorUtility for ComputedValues { impl ComputedValuesCursorUtility for ComputedValues {
@ -3166,14 +3166,14 @@ impl ComputedValuesCursorUtility for ComputedValues {
/// the cursor to use if `cursor` is `auto`. Typically, this will be `PointerCursor`, but for /// the cursor to use if `cursor` is `auto`. Typically, this will be `PointerCursor`, but for
/// text display items it may be `TextCursor` or `VerticalTextCursor`. /// text display items it may be `TextCursor` or `VerticalTextCursor`.
#[inline] #[inline]
fn get_cursor(&self, default_cursor: Cursor) -> Option<Cursor> { fn get_cursor(&self, default_cursor: CursorKind) -> Option<CursorKind> {
match ( match (
self.get_pointing().pointer_events, self.get_pointing().pointer_events,
self.get_pointing().cursor, self.get_pointing().cursor,
) { ) {
(PointerEvents::None, _) => None, (PointerEvents::None, _) => None,
(PointerEvents::Auto, cursor::Keyword::Auto) => Some(default_cursor), (PointerEvents::Auto, Cursor(CursorKind::Auto)) => Some(default_cursor),
(PointerEvents::Auto, cursor::Keyword::Cursor(cursor)) => Some(cursor), (PointerEvents::Auto, Cursor(cursor)) => Some(cursor),
} }
} }
} }

View file

@ -68,7 +68,7 @@ use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender, RecvTimeoutError}; use std::sync::mpsc::{Receiver, Sender, RecvTimeoutError};
use style_traits::CSSPixel; use style_traits::CSSPixel;
use style_traits::SpeculativePainter; use style_traits::SpeculativePainter;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use webdriver_msg::{LoadStatus, WebDriverScriptCommand}; use webdriver_msg::{LoadStatus, WebDriverScriptCommand};
use webrender_api::{ClipId, DevicePixel, DocumentId, ImageKey}; use webrender_api::{ClipId, DevicePixel, DocumentId, ImageKey};
use webvr_traits::{WebVREvent, WebVRMsg}; use webvr_traits::{WebVREvent, WebVRMsg};
@ -807,7 +807,7 @@ pub enum ConstellationMsg {
/// Forward an event to the script task of the given pipeline. /// Forward an event to the script task of the given pipeline.
ForwardEvent(PipelineId, CompositorEvent), ForwardEvent(PipelineId, CompositorEvent),
/// Requesting a change to the onscreen cursor. /// Requesting a change to the onscreen cursor.
SetCursor(Cursor), SetCursor(CursorKind),
} }
/// Resources required by workerglobalscopes /// Resources required by workerglobalscopes

View file

@ -25,7 +25,7 @@ use net_traits::storage_thread::StorageType;
use servo_url::ImmutableOrigin; use servo_url::ImmutableOrigin;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use style_traits::CSSPixel; use style_traits::CSSPixel;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
/// Messages from the layout to the constellation. /// Messages from the layout to the constellation.
@ -39,7 +39,7 @@ pub enum LayoutMsg {
/// the time when the frame with the given ID (epoch) is painted. /// the time when the frame with the given ID (epoch) is painted.
PendingPaintMetric(PipelineId, Epoch), PendingPaintMetric(PipelineId, Epoch),
/// Requests that the constellation inform the compositor of the a cursor change. /// Requests that the constellation inform the compositor of the a cursor change.
SetCursor(Cursor), SetCursor(CursorKind),
/// Notifies the constellation that the viewport has been constrained in some manner /// Notifies the constellation that the viewport has been constrained in some manner
ViewportConstrained(PipelineId, ViewportConstraints), ViewportConstrained(PipelineId, ViewportConstraints),
} }

View file

@ -5302,53 +5302,50 @@ clip-path
<%self:impl_trait style_struct_name="Pointing" <%self:impl_trait style_struct_name="Pointing"
skip_longhands="cursor caret-color"> skip_longhands="cursor caret-color">
pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) { pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
use properties::longhands::cursor::computed_value::Keyword; use style_traits::cursor::CursorKind;
use style_traits::cursor::Cursor;
self.gecko.mCursor = match v.keyword { self.gecko.mCursor = match v.keyword {
Keyword::Auto => structs::NS_STYLE_CURSOR_AUTO, CursorKind::Auto => structs::NS_STYLE_CURSOR_AUTO,
Keyword::Cursor(cursor) => match cursor { CursorKind::None => structs::NS_STYLE_CURSOR_NONE,
Cursor::None => structs::NS_STYLE_CURSOR_NONE, CursorKind::Default => structs::NS_STYLE_CURSOR_DEFAULT,
Cursor::Default => structs::NS_STYLE_CURSOR_DEFAULT, CursorKind::Pointer => structs::NS_STYLE_CURSOR_POINTER,
Cursor::Pointer => structs::NS_STYLE_CURSOR_POINTER, CursorKind::ContextMenu => structs::NS_STYLE_CURSOR_CONTEXT_MENU,
Cursor::ContextMenu => structs::NS_STYLE_CURSOR_CONTEXT_MENU, CursorKind::Help => structs::NS_STYLE_CURSOR_HELP,
Cursor::Help => structs::NS_STYLE_CURSOR_HELP, CursorKind::Progress => structs::NS_STYLE_CURSOR_SPINNING,
Cursor::Progress => structs::NS_STYLE_CURSOR_SPINNING, CursorKind::Wait => structs::NS_STYLE_CURSOR_WAIT,
Cursor::Wait => structs::NS_STYLE_CURSOR_WAIT, CursorKind::Cell => structs::NS_STYLE_CURSOR_CELL,
Cursor::Cell => structs::NS_STYLE_CURSOR_CELL, CursorKind::Crosshair => structs::NS_STYLE_CURSOR_CROSSHAIR,
Cursor::Crosshair => structs::NS_STYLE_CURSOR_CROSSHAIR, CursorKind::Text => structs::NS_STYLE_CURSOR_TEXT,
Cursor::Text => structs::NS_STYLE_CURSOR_TEXT, CursorKind::VerticalText => structs::NS_STYLE_CURSOR_VERTICAL_TEXT,
Cursor::VerticalText => structs::NS_STYLE_CURSOR_VERTICAL_TEXT, CursorKind::Alias => structs::NS_STYLE_CURSOR_ALIAS,
Cursor::Alias => structs::NS_STYLE_CURSOR_ALIAS, CursorKind::Copy => structs::NS_STYLE_CURSOR_COPY,
Cursor::Copy => structs::NS_STYLE_CURSOR_COPY, CursorKind::Move => structs::NS_STYLE_CURSOR_MOVE,
Cursor::Move => structs::NS_STYLE_CURSOR_MOVE, CursorKind::NoDrop => structs::NS_STYLE_CURSOR_NO_DROP,
Cursor::NoDrop => structs::NS_STYLE_CURSOR_NO_DROP, CursorKind::NotAllowed => structs::NS_STYLE_CURSOR_NOT_ALLOWED,
Cursor::NotAllowed => structs::NS_STYLE_CURSOR_NOT_ALLOWED, CursorKind::Grab => structs::NS_STYLE_CURSOR_GRAB,
Cursor::Grab => structs::NS_STYLE_CURSOR_GRAB, CursorKind::Grabbing => structs::NS_STYLE_CURSOR_GRABBING,
Cursor::Grabbing => structs::NS_STYLE_CURSOR_GRABBING, CursorKind::EResize => structs::NS_STYLE_CURSOR_E_RESIZE,
Cursor::EResize => structs::NS_STYLE_CURSOR_E_RESIZE, CursorKind::NResize => structs::NS_STYLE_CURSOR_N_RESIZE,
Cursor::NResize => structs::NS_STYLE_CURSOR_N_RESIZE, CursorKind::NeResize => structs::NS_STYLE_CURSOR_NE_RESIZE,
Cursor::NeResize => structs::NS_STYLE_CURSOR_NE_RESIZE, CursorKind::NwResize => structs::NS_STYLE_CURSOR_NW_RESIZE,
Cursor::NwResize => structs::NS_STYLE_CURSOR_NW_RESIZE, CursorKind::SResize => structs::NS_STYLE_CURSOR_S_RESIZE,
Cursor::SResize => structs::NS_STYLE_CURSOR_S_RESIZE, CursorKind::SeResize => structs::NS_STYLE_CURSOR_SE_RESIZE,
Cursor::SeResize => structs::NS_STYLE_CURSOR_SE_RESIZE, CursorKind::SwResize => structs::NS_STYLE_CURSOR_SW_RESIZE,
Cursor::SwResize => structs::NS_STYLE_CURSOR_SW_RESIZE, CursorKind::WResize => structs::NS_STYLE_CURSOR_W_RESIZE,
Cursor::WResize => structs::NS_STYLE_CURSOR_W_RESIZE, CursorKind::EwResize => structs::NS_STYLE_CURSOR_EW_RESIZE,
Cursor::EwResize => structs::NS_STYLE_CURSOR_EW_RESIZE, CursorKind::NsResize => structs::NS_STYLE_CURSOR_NS_RESIZE,
Cursor::NsResize => structs::NS_STYLE_CURSOR_NS_RESIZE, CursorKind::NeswResize => structs::NS_STYLE_CURSOR_NESW_RESIZE,
Cursor::NeswResize => structs::NS_STYLE_CURSOR_NESW_RESIZE, CursorKind::NwseResize => structs::NS_STYLE_CURSOR_NWSE_RESIZE,
Cursor::NwseResize => structs::NS_STYLE_CURSOR_NWSE_RESIZE, CursorKind::ColResize => structs::NS_STYLE_CURSOR_COL_RESIZE,
Cursor::ColResize => structs::NS_STYLE_CURSOR_COL_RESIZE, CursorKind::RowResize => structs::NS_STYLE_CURSOR_ROW_RESIZE,
Cursor::RowResize => structs::NS_STYLE_CURSOR_ROW_RESIZE, CursorKind::AllScroll => structs::NS_STYLE_CURSOR_ALL_SCROLL,
Cursor::AllScroll => structs::NS_STYLE_CURSOR_ALL_SCROLL, CursorKind::ZoomIn => structs::NS_STYLE_CURSOR_ZOOM_IN,
Cursor::ZoomIn => structs::NS_STYLE_CURSOR_ZOOM_IN, CursorKind::ZoomOut => structs::NS_STYLE_CURSOR_ZOOM_OUT,
Cursor::ZoomOut => structs::NS_STYLE_CURSOR_ZOOM_OUT,
// note: the following properties are gecko-only. // note: the following properties are gecko-only.
Cursor::MozGrab => structs::NS_STYLE_CURSOR_GRAB, CursorKind::MozGrab => structs::NS_STYLE_CURSOR_GRAB,
Cursor::MozGrabbing => structs::NS_STYLE_CURSOR_GRABBING, CursorKind::MozGrabbing => structs::NS_STYLE_CURSOR_GRABBING,
Cursor::MozZoomIn => structs::NS_STYLE_CURSOR_ZOOM_IN, CursorKind::MozZoomIn => structs::NS_STYLE_CURSOR_ZOOM_IN,
Cursor::MozZoomOut => structs::NS_STYLE_CURSOR_ZOOM_OUT, CursorKind::MozZoomOut => structs::NS_STYLE_CURSOR_ZOOM_OUT,
}
} as u8; } as u8;
unsafe { unsafe {
@ -5390,47 +5387,47 @@ clip-path
} }
pub fn clone_cursor(&self) -> longhands::cursor::computed_value::T { pub fn clone_cursor(&self) -> longhands::cursor::computed_value::T {
use properties::longhands::cursor::computed_value::{Keyword, Image}; use values::computed::pointing::CursorImage;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use values::specified::url::SpecifiedUrl; use values::specified::url::SpecifiedUrl;
let keyword = match self.gecko.mCursor as u32 { let keyword = match self.gecko.mCursor as u32 {
structs::NS_STYLE_CURSOR_AUTO => Keyword::Auto, structs::NS_STYLE_CURSOR_AUTO => CursorKind::Auto,
structs::NS_STYLE_CURSOR_NONE => Keyword::Cursor(Cursor::None), structs::NS_STYLE_CURSOR_NONE => CursorKind::None,
structs::NS_STYLE_CURSOR_DEFAULT => Keyword::Cursor(Cursor::Default), structs::NS_STYLE_CURSOR_DEFAULT => CursorKind::Default,
structs::NS_STYLE_CURSOR_POINTER => Keyword::Cursor(Cursor::Pointer), structs::NS_STYLE_CURSOR_POINTER => CursorKind::Pointer,
structs::NS_STYLE_CURSOR_CONTEXT_MENU => Keyword::Cursor(Cursor::ContextMenu), structs::NS_STYLE_CURSOR_CONTEXT_MENU => CursorKind::ContextMenu,
structs::NS_STYLE_CURSOR_HELP => Keyword::Cursor(Cursor::Help), structs::NS_STYLE_CURSOR_HELP => CursorKind::Help,
structs::NS_STYLE_CURSOR_SPINNING => Keyword::Cursor(Cursor::Progress), structs::NS_STYLE_CURSOR_SPINNING => CursorKind::Progress,
structs::NS_STYLE_CURSOR_WAIT => Keyword::Cursor(Cursor::Wait), structs::NS_STYLE_CURSOR_WAIT => CursorKind::Wait,
structs::NS_STYLE_CURSOR_CELL => Keyword::Cursor(Cursor::Cell), structs::NS_STYLE_CURSOR_CELL => CursorKind::Cell,
structs::NS_STYLE_CURSOR_CROSSHAIR => Keyword::Cursor(Cursor::Crosshair), structs::NS_STYLE_CURSOR_CROSSHAIR => CursorKind::Crosshair,
structs::NS_STYLE_CURSOR_TEXT => Keyword::Cursor(Cursor::Text), structs::NS_STYLE_CURSOR_TEXT => CursorKind::Text,
structs::NS_STYLE_CURSOR_VERTICAL_TEXT => Keyword::Cursor(Cursor::VerticalText), structs::NS_STYLE_CURSOR_VERTICAL_TEXT => CursorKind::VerticalText,
structs::NS_STYLE_CURSOR_ALIAS => Keyword::Cursor(Cursor::Alias), structs::NS_STYLE_CURSOR_ALIAS => CursorKind::Alias,
structs::NS_STYLE_CURSOR_COPY => Keyword::Cursor(Cursor::Copy), structs::NS_STYLE_CURSOR_COPY => CursorKind::Copy,
structs::NS_STYLE_CURSOR_MOVE => Keyword::Cursor(Cursor::Move), structs::NS_STYLE_CURSOR_MOVE => CursorKind::Move,
structs::NS_STYLE_CURSOR_NO_DROP => Keyword::Cursor(Cursor::NoDrop), structs::NS_STYLE_CURSOR_NO_DROP => CursorKind::NoDrop,
structs::NS_STYLE_CURSOR_NOT_ALLOWED => Keyword::Cursor(Cursor::NotAllowed), structs::NS_STYLE_CURSOR_NOT_ALLOWED => CursorKind::NotAllowed,
structs::NS_STYLE_CURSOR_GRAB => Keyword::Cursor(Cursor::Grab), structs::NS_STYLE_CURSOR_GRAB => CursorKind::Grab,
structs::NS_STYLE_CURSOR_GRABBING => Keyword::Cursor(Cursor::Grabbing), structs::NS_STYLE_CURSOR_GRABBING => CursorKind::Grabbing,
structs::NS_STYLE_CURSOR_E_RESIZE => Keyword::Cursor(Cursor::EResize), structs::NS_STYLE_CURSOR_E_RESIZE => CursorKind::EResize,
structs::NS_STYLE_CURSOR_N_RESIZE => Keyword::Cursor(Cursor::NResize), structs::NS_STYLE_CURSOR_N_RESIZE => CursorKind::NResize,
structs::NS_STYLE_CURSOR_NE_RESIZE => Keyword::Cursor(Cursor::NeResize), structs::NS_STYLE_CURSOR_NE_RESIZE => CursorKind::NeResize,
structs::NS_STYLE_CURSOR_NW_RESIZE => Keyword::Cursor(Cursor::NwResize), structs::NS_STYLE_CURSOR_NW_RESIZE => CursorKind::NwResize,
structs::NS_STYLE_CURSOR_S_RESIZE => Keyword::Cursor(Cursor::SResize), structs::NS_STYLE_CURSOR_S_RESIZE => CursorKind::SResize,
structs::NS_STYLE_CURSOR_SE_RESIZE => Keyword::Cursor(Cursor::SeResize), structs::NS_STYLE_CURSOR_SE_RESIZE => CursorKind::SeResize,
structs::NS_STYLE_CURSOR_SW_RESIZE => Keyword::Cursor(Cursor::SwResize), structs::NS_STYLE_CURSOR_SW_RESIZE => CursorKind::SwResize,
structs::NS_STYLE_CURSOR_W_RESIZE => Keyword::Cursor(Cursor::WResize), structs::NS_STYLE_CURSOR_W_RESIZE => CursorKind::WResize,
structs::NS_STYLE_CURSOR_EW_RESIZE => Keyword::Cursor(Cursor::EwResize), structs::NS_STYLE_CURSOR_EW_RESIZE => CursorKind::EwResize,
structs::NS_STYLE_CURSOR_NS_RESIZE => Keyword::Cursor(Cursor::NsResize), structs::NS_STYLE_CURSOR_NS_RESIZE => CursorKind::NsResize,
structs::NS_STYLE_CURSOR_NESW_RESIZE => Keyword::Cursor(Cursor::NeswResize), structs::NS_STYLE_CURSOR_NESW_RESIZE => CursorKind::NeswResize,
structs::NS_STYLE_CURSOR_NWSE_RESIZE => Keyword::Cursor(Cursor::NwseResize), structs::NS_STYLE_CURSOR_NWSE_RESIZE => CursorKind::NwseResize,
structs::NS_STYLE_CURSOR_COL_RESIZE => Keyword::Cursor(Cursor::ColResize), structs::NS_STYLE_CURSOR_COL_RESIZE => CursorKind::ColResize,
structs::NS_STYLE_CURSOR_ROW_RESIZE => Keyword::Cursor(Cursor::RowResize), structs::NS_STYLE_CURSOR_ROW_RESIZE => CursorKind::RowResize,
structs::NS_STYLE_CURSOR_ALL_SCROLL => Keyword::Cursor(Cursor::AllScroll), structs::NS_STYLE_CURSOR_ALL_SCROLL => CursorKind::AllScroll,
structs::NS_STYLE_CURSOR_ZOOM_IN => Keyword::Cursor(Cursor::ZoomIn), structs::NS_STYLE_CURSOR_ZOOM_IN => CursorKind::ZoomIn,
structs::NS_STYLE_CURSOR_ZOOM_OUT => Keyword::Cursor(Cursor::ZoomOut), structs::NS_STYLE_CURSOR_ZOOM_OUT => CursorKind::ZoomOut,
_ => panic!("Found unexpected value in style struct for cursor property"), _ => panic!("Found unexpected value in style struct for cursor property"),
}; };
@ -5448,8 +5445,8 @@ clip-path
None None
}; };
Image { url, hotspot } CursorImage { url, hotspot }
}).collect(); }).collect::<Vec<_>>().into_boxed_slice();
longhands::cursor::computed_value::T { images, keyword } longhands::cursor::computed_value::T { images, keyword }
} }

View file

@ -6,142 +6,12 @@
<% data.new_style_struct("Pointing", inherited=True, gecko_name="UserInterface") %> <% data.new_style_struct("Pointing", inherited=True, gecko_name="UserInterface") %>
<%helpers:longhand name="cursor" boxed="${product == 'gecko'}" animation_value_type="discrete" ${helpers.predefined_type("cursor",
spec="https://drafts.csswg.org/css-ui/#cursor"> "Cursor",
pub use self::computed_value::T as SpecifiedValue; "computed::Cursor::auto()",
#[cfg(feature = "gecko")] initial_specified_value="specified::Cursor::auto()",
use values::specified::url::SpecifiedUrl; animation_value_type="discrete",
spec="https://drafts.csswg.org/css-ui/#cursor")}
pub mod computed_value {
#[cfg(feature = "gecko")]
use std::fmt;
#[cfg(feature = "gecko")]
use style_traits::ToCss;
use style_traits::cursor::Cursor;
#[cfg(feature = "gecko")]
use values::specified::url::SpecifiedUrl;
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub enum Keyword {
Auto,
Cursor(Cursor),
}
#[cfg(not(feature = "gecko"))]
pub type T = Keyword;
#[cfg(feature = "gecko")]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
pub struct Image {
pub url: SpecifiedUrl,
pub hotspot: Option<(f32, f32)>,
}
#[cfg(feature = "gecko")]
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue)]
pub struct T {
pub images: Vec<Image>,
pub keyword: Keyword,
}
#[cfg(feature = "gecko")]
impl ToCss for Image {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::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(())
}
}
#[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 {
url.to_css(dest)?;
dest.write_str(", ")?;
}
self.keyword.to_css(dest)
}
}
}
#[cfg(not(feature = "gecko"))]
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::Keyword::Auto
}
#[cfg(feature = "gecko")]
#[inline]
pub fn get_initial_value() -> computed_value::T {
computed_value::T {
images: vec![],
keyword: computed_value::Keyword::Auto
}
}
impl Parse for computed_value::Keyword {
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<computed_value::Keyword, ParseError<'i>> {
#[allow(unused_imports)] use std::ascii::AsciiExt;
use style_traits::cursor::Cursor;
let location = input.current_source_location();
let ident = input.expect_ident()?;
if ident.eq_ignore_ascii_case("auto") {
Ok(computed_value::Keyword::Auto)
} else {
Cursor::from_css_keyword(&ident)
.map(computed_value::Keyword::Cursor)
.map_err(|()| location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())))
}
}
}
#[cfg(feature = "gecko")]
fn parse_image<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<computed_value::Image, ParseError<'i>> {
Ok(computed_value::Image {
url: SpecifiedUrl::parse(context, input)?,
hotspot: match input.try(|input| input.expect_number()) {
Ok(number) => Some((number, input.expect_number()?)),
Err(_) => None,
},
})
}
#[cfg(not(feature = "gecko"))]
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> {
computed_value::Keyword::parse(context, input)
}
/// cursor: [<url> [<number> <number>]?]# [auto | default | ...]
#[cfg(feature = "gecko")]
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> {
let mut images = vec![];
loop {
match input.try(|input| parse_image(context, input)) {
Ok(mut image) => {
image.url.build_image_value();
images.push(image)
}
Err(_) => break,
}
input.expect_comma()?;
}
Ok(computed_value::T {
images: images,
keyword: computed_value::Keyword::parse(context, input)?,
})
}
</%helpers:longhand>
// NB: `pointer-events: auto` (and use of `pointer-events` in anything that isn't SVG, in fact) // NB: `pointer-events: auto` (and use of `pointer-events` in anything that isn't SVG, in fact)
// is nonstandard, slated for CSS4-UI. // is nonstandard, slated for CSS4-UI.

View file

@ -20,7 +20,7 @@ use std::cell::RefCell;
#[cfg(feature = "servo")] #[cfg(feature = "servo")]
use std::sync::Arc; use std::sync::Arc;
use style_traits::ToCss; use style_traits::ToCss;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use super::{CSSFloat, CSSInteger}; use super::{CSSFloat, CSSInteger};
use super::generics::{GreaterThanOrEqualToOne, NonNegative}; use super::generics::{GreaterThanOrEqualToOne, NonNegative};
use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth}; use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
@ -61,6 +61,9 @@ pub use self::list::ListStyleType;
pub use self::outline::OutlineStyle; pub use self::outline::OutlineStyle;
pub use self::percentage::Percentage; pub use self::percentage::Percentage;
pub use self::position::{Position, GridAutoFlow, GridTemplateAreas}; pub use self::position::{Position, GridAutoFlow, GridTemplateAreas};
pub use self::pointing::Cursor;
#[cfg(feature = "gecko")]
pub use self::pointing::CursorImage;
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind}; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth}; pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
pub use self::svg::MozContextProperties; pub use self::svg::MozContextProperties;
@ -90,6 +93,7 @@ pub mod length;
pub mod list; pub mod list;
pub mod outline; pub mod outline;
pub mod percentage; pub mod percentage;
pub mod pointing;
pub mod position; pub mod position;
pub mod rect; pub mod rect;
pub mod svg; pub mod svg;
@ -404,7 +408,7 @@ trivial_to_computed_value!(u16);
trivial_to_computed_value!(u32); trivial_to_computed_value!(u32);
trivial_to_computed_value!(Atom); trivial_to_computed_value!(Atom);
trivial_to_computed_value!(BorderStyle); trivial_to_computed_value!(BorderStyle);
trivial_to_computed_value!(Cursor); trivial_to_computed_value!(CursorKind);
trivial_to_computed_value!(Namespace); trivial_to_computed_value!(Namespace);
trivial_to_computed_value!(String); trivial_to_computed_value!(String);
trivial_to_computed_value!(Box<str>); trivial_to_computed_value!(Box<str>);

View file

@ -0,0 +1,138 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Computed values for Pointing properties.
//!
//! 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;
use style_traits::ParseError;
#[cfg(feature = "gecko")]
use style_traits::ToCss;
use style_traits::cursor::CursorKind;
/// 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;
#[cfg(feature = "gecko")]
use values::specified::url::SpecifiedUrl;
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<Self, ParseError<'i>> {
Ok(Cursor(CursorKind::parse(context, input)?))
}
/// cursor: [<url> [<number> <number>]?]# [auto | default | ...]
#[cfg(feature = "gecko")]
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>
) -> Result<Self, ParseError<'i>> {
let mut images = vec![];
loop {
match input.try(|input| CursorImage::parse_image(context, input)) {
Ok(mut image) => {
image.url.build_image_value();
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<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::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<Self, ParseError<'i>> {
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<Self, ParseError<'i>> {
Ok(Self {
url: SpecifiedUrl::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<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::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(())
}
}

View file

@ -57,6 +57,9 @@ pub use self::outline::OutlineStyle;
pub use self::rect::LengthOrNumberRect; pub use self::rect::LengthOrNumberRect;
pub use self::percentage::Percentage; pub use self::percentage::Percentage;
pub use self::position::{Position, PositionComponent, GridAutoFlow, GridTemplateAreas}; pub use self::position::{Position, PositionComponent, GridAutoFlow, GridTemplateAreas};
pub use self::pointing::Cursor;
#[cfg(feature = "gecko")]
pub use self::pointing::CursorImage;
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind}; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth}; pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
pub use self::svg::MozContextProperties; pub use self::svg::MozContextProperties;
@ -90,6 +93,7 @@ pub mod length;
pub mod list; pub mod list;
pub mod outline; pub mod outline;
pub mod percentage; pub mod percentage;
pub mod pointing;
pub mod position; pub mod position;
pub mod rect; pub mod rect;
pub mod source_size_list; pub mod source_size_list;

View file

@ -0,0 +1,40 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Specified values for Pointing properties.
//!
//! https://drafts.csswg.org/css-ui/#pointing-keyboard
use style_traits::cursor::CursorKind;
#[cfg(feature = "gecko")]
use values::specified::url::SpecifiedUrl;
/// 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: SpecifiedUrl,
/// The <x> and <y> coordinates.
pub hotspot: Option<(f32, f32)>,
}

View file

@ -20,43 +20,42 @@ macro_rules! define_cursor {
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
#[repr(u8)] #[repr(u8)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum Cursor { pub enum CursorKind {
$( $c_variant = $c_value, )+ $( $c_variant = $c_value, )+
$( #[cfg(feature = "gecko")] $g_variant = $g_value, )+ $( #[cfg(feature = "gecko")] $g_variant = $g_value, )+
} }
impl Cursor { impl CursorKind {
/// Given a CSS keyword, get the corresponding cursor enum. /// Given a CSS keyword, get the corresponding cursor enum.
pub fn from_css_keyword(keyword: &str) -> Result<Cursor, ()> { pub fn from_css_keyword(keyword: &str) -> Result<Self, ()> {
match_ignore_ascii_case! { &keyword, match_ignore_ascii_case! { &keyword,
$( $c_css => Ok(Cursor::$c_variant), )+ $( $c_css => Ok(CursorKind::$c_variant), )+
$( #[cfg(feature = "gecko")] $g_css => Ok(Cursor::$g_variant), )+ $( #[cfg(feature = "gecko")] $g_css => Ok(CursorKind::$g_variant), )+
_ => Err(()) _ => Err(())
} }
} }
/// From the C u8 value, get the corresponding Cursor enum. /// From the C u8 value, get the corresponding Cursor enum.
pub fn from_u8(value: u8) -> Result<Cursor, ()> { pub fn from_u8(value: u8) -> Result<Self, ()> {
match value { match value {
$( $c_value => Ok(Cursor::$c_variant), )+ $( $c_value => Ok(CursorKind::$c_variant), )+
$( #[cfg(feature = "gecko")] $g_value => Ok(Cursor::$g_variant), )+ $( #[cfg(feature = "gecko")] $g_value => Ok(CursorKind::$g_variant), )+
_ => Err(()) _ => Err(())
} }
} }
} }
impl ToCss for Cursor { impl ToCss for CursorKind {
fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result where W: ::std::fmt::Write { fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result where W: ::std::fmt::Write {
match *self { match *self {
$( Cursor::$c_variant => dest.write_str($c_css), )+ $( CursorKind::$c_variant => dest.write_str($c_css), )+
$( #[cfg(feature = "gecko")] Cursor::$g_variant => dest.write_str($g_css), )+ $( #[cfg(feature = "gecko")] CursorKind::$g_variant => dest.write_str($g_css), )+
} }
} }
} }
} }
} }
define_cursor! { define_cursor! {
common properties = [ common properties = [
"none" => None = 0, "none" => None = 0,
@ -94,12 +93,13 @@ define_cursor! {
"all-scroll" => AllScroll = 32, "all-scroll" => AllScroll = 32,
"zoom-in" => ZoomIn = 33, "zoom-in" => ZoomIn = 33,
"zoom-out" => ZoomOut = 34, "zoom-out" => ZoomOut = 34,
"auto" => Auto = 35,
] ]
// gecko only properties // gecko only properties
gecko properties = [ gecko properties = [
"-moz-grab" => MozGrab = 35, "-moz-grab" => MozGrab = 36,
"-moz-grabbing" => MozGrabbing = 36, "-moz-grabbing" => MozGrabbing = 37,
"-moz-zoom-in" => MozZoomIn = 37, "-moz-zoom-in" => MozZoomIn = 38,
"-moz-zoom-out" => MozZoomOut = 38, "-moz-zoom-out" => MozZoomOut = 39,
] ]
} }

View file

@ -33,7 +33,7 @@ use std::os::raw::{c_char, c_void};
use std::ptr; use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
use style_traits::DevicePixel; use style_traits::DevicePixel;
#[cfg(target_os="linux")] #[cfg(target_os="linux")]
extern crate x11; extern crate x11;
@ -104,69 +104,68 @@ impl Window {
vec![WindowEvent::Idle] vec![WindowEvent::Idle]
} }
fn cursor_type_for_cursor(&self, cursor: Cursor) -> cef_cursor_type_t { fn cursor_type_for_cursor(&self, cursor: CursorKind) -> cef_cursor_type_t {
match cursor { match cursor {
Cursor::None => return cef_cursor_type_t::CT_NONE, CursorKind::None => cef_cursor_type_t::CT_NONE,
Cursor::ContextMenu => return cef_cursor_type_t::CT_CONTEXTMENU, CursorKind::ContextMenu => cef_cursor_type_t::CT_CONTEXTMENU,
Cursor::Grabbing => return cef_cursor_type_t::CT_GRABBING, CursorKind::Grabbing => cef_cursor_type_t::CT_GRABBING,
Cursor::Crosshair => return cef_cursor_type_t::CT_CROSS, CursorKind::Crosshair => cef_cursor_type_t::CT_CROSS,
Cursor::Copy => return cef_cursor_type_t::CT_COPY, CursorKind::Copy => cef_cursor_type_t::CT_COPY,
Cursor::Alias => return cef_cursor_type_t::CT_ALIAS, CursorKind::Alias => cef_cursor_type_t::CT_ALIAS,
Cursor::Text => return cef_cursor_type_t::CT_IBEAM, CursorKind::Text => cef_cursor_type_t::CT_IBEAM,
Cursor::Grab | Cursor::AllScroll => CursorKind::Grab | CursorKind::AllScroll => cef_cursor_type_t::CT_GRAB,
return cef_cursor_type_t::CT_GRAB, CursorKind::NoDrop => cef_cursor_type_t::CT_NODROP,
Cursor::NoDrop => return cef_cursor_type_t::CT_NODROP, CursorKind::NotAllowed => cef_cursor_type_t::CT_NOTALLOWED,
Cursor::NotAllowed => return cef_cursor_type_t::CT_NOTALLOWED, CursorKind::Pointer => cef_cursor_type_t::CT_POINTER,
Cursor::Pointer => return cef_cursor_type_t::CT_POINTER, CursorKind::SResize => cef_cursor_type_t::CT_SOUTHRESIZE,
Cursor::SResize => return cef_cursor_type_t::CT_SOUTHRESIZE, CursorKind::WResize => cef_cursor_type_t::CT_WESTRESIZE,
Cursor::WResize => return cef_cursor_type_t::CT_WESTRESIZE, CursorKind::EwResize => cef_cursor_type_t::CT_EASTWESTRESIZE,
Cursor::EwResize => return cef_cursor_type_t::CT_EASTWESTRESIZE, CursorKind::ColResize => cef_cursor_type_t::CT_COLUMNRESIZE,
Cursor::ColResize => return cef_cursor_type_t::CT_COLUMNRESIZE, CursorKind::EResize => cef_cursor_type_t::CT_EASTRESIZE,
Cursor::EResize => return cef_cursor_type_t::CT_EASTRESIZE, CursorKind::NResize => cef_cursor_type_t::CT_NORTHRESIZE,
Cursor::NResize => return cef_cursor_type_t::CT_NORTHRESIZE, CursorKind::NsResize => cef_cursor_type_t::CT_NORTHSOUTHRESIZE,
Cursor::NsResize => return cef_cursor_type_t::CT_NORTHSOUTHRESIZE, CursorKind::RowResize => cef_cursor_type_t::CT_ROWRESIZE,
Cursor::RowResize => return cef_cursor_type_t::CT_ROWRESIZE, CursorKind::VerticalText => cef_cursor_type_t::CT_VERTICALTEXT,
Cursor::VerticalText => return cef_cursor_type_t::CT_VERTICALTEXT, _ => cef_cursor_type_t::CT_POINTER,
_ => return cef_cursor_type_t::CT_POINTER,
} }
} }
/// Returns the Cocoa cursor for a CSS cursor. These match Firefox, except where Firefox /// Returns the Cocoa cursor for a CSS cursor. These match Firefox, except where Firefox
/// bundles custom resources (which we don't yet do). /// bundles custom resources (which we don't yet do).
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
fn cursor_handle_for_cursor(&self, cursor: Cursor) -> cef_cursor_handle_t { fn cursor_handle_for_cursor(&self, cursor: CursorKind) -> cef_cursor_handle_t {
use cocoa::base::class; use cocoa::base::class;
unsafe { unsafe {
match cursor { match cursor {
Cursor::None => return 0 as cef_cursor_handle_t, CursorKind::None => return 0 as cef_cursor_handle_t,
Cursor::ContextMenu => msg_send![class("NSCursor"), contextualMenuCursor], CursorKind::ContextMenu => msg_send![class("NSCursor"), contextualMenuCursor],
Cursor::Grabbing => msg_send![class("NSCursor"), closedHandCursor], CursorKind::Grabbing => msg_send![class("NSCursor"), closedHandCursor],
Cursor::Crosshair => msg_send![class("NSCursor"), crosshairCursor], CursorKind::Crosshair => msg_send![class("NSCursor"), crosshairCursor],
Cursor::Copy => msg_send![class("NSCursor"), dragCopyCursor], CursorKind::Copy => msg_send![class("NSCursor"), dragCopyCursor],
Cursor::Alias => msg_send![class("NSCursor"), dragLinkCursor], CursorKind::Alias => msg_send![class("NSCursor"), dragLinkCursor],
Cursor::Text => msg_send![class("NSCursor"), IBeamCursor], CursorKind::Text => msg_send![class("NSCursor"), IBeamCursor],
Cursor::Grab | Cursor::AllScroll => CursorKind::Grab | CursorKind::AllScroll =>
msg_send![class("NSCursor"), openHandCursor], msg_send![class("NSCursor"), openHandCursor],
Cursor::NoDrop | Cursor::NotAllowed => CursorKind::NoDrop | CursorKind::NotAllowed =>
msg_send![class("NSCursor"), operationNotAllowedCursor], msg_send![class("NSCursor"), operationNotAllowedCursor],
Cursor::Pointer => msg_send![class("NSCursor"), pointingHandCursor], CursorKind::Pointer => msg_send![class("NSCursor"), pointingHandCursor],
Cursor::SResize => msg_send![class("NSCursor"), resizeDownCursor], CursorKind::SResize => msg_send![class("NSCursor"), resizeDownCursor],
Cursor::WResize => msg_send![class("NSCursor"), resizeLeftCursor], CursorKind::WResize => msg_send![class("NSCursor"), resizeLeftCursor],
Cursor::EwResize | Cursor::ColResize => CursorKind::EwResize | CursorKind::ColResize =>
msg_send![class("NSCursor"), resizeLeftRightCursor], msg_send![class("NSCursor"), resizeLeftRightCursor],
Cursor::EResize => msg_send![class("NSCursor"), resizeRightCursor], CursorKind::EResize => msg_send![class("NSCursor"), resizeRightCursor],
Cursor::NResize => msg_send![class("NSCursor"), resizeUpCursor], CursorKind::NResize => msg_send![class("NSCursor"), resizeUpCursor],
Cursor::NsResize | Cursor::RowResize => CursorKind::NsResize | CursorKind::RowResize =>
msg_send![class("NSCursor"), resizeUpDownCursor], msg_send![class("NSCursor"), resizeUpDownCursor],
Cursor::VerticalText => msg_send![class("NSCursor"), IBeamCursorForVerticalLayout], CursorKind::VerticalText => msg_send![class("NSCursor"), IBeamCursorForVerticalLayout],
_ => msg_send![class("NSCursor"), arrowCursor], _ => msg_send![class("NSCursor"), arrowCursor],
} }
} }
} }
#[cfg(not(target_os="macos"))] #[cfg(not(target_os="macos"))]
fn cursor_handle_for_cursor(&self, _: Cursor) -> cef_cursor_handle_t { fn cursor_handle_for_cursor(&self, _: CursorKind) -> cef_cursor_handle_t {
0 0
} }
@ -488,7 +487,7 @@ impl WindowMethods for Window {
// TODO(negge) // TODO(negge)
} }
fn set_cursor(&self, cursor: Cursor) { fn set_cursor(&self, cursor: CursorKind) {
use types::{CefCursorInfo,cef_point_t,cef_size_t}; use types::{CefCursorInfo,cef_point_t,cef_size_t};
let browser = self.cef_browser.borrow(); let browser = self.cef_browser.borrow();
if let Some(ref browser) = *browser { if let Some(ref browser) = *browser {

View file

@ -42,7 +42,7 @@ use std::rc::Rc;
use std::thread; use std::thread;
use std::time; use std::time;
use style_traits::DevicePixel; use style_traits::DevicePixel;
use style_traits::cursor::Cursor; use style_traits::cursor::CursorKind;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use user32; use user32;
use webrender_api::{DeviceUintRect, DeviceUintSize, ScrollLocation}; use webrender_api::{DeviceUintRect, DeviceUintSize, ScrollLocation};
@ -1190,47 +1190,48 @@ impl WindowMethods for Window {
} }
/// Has no effect on Android. /// Has no effect on Android.
fn set_cursor(&self, c: Cursor) { fn set_cursor(&self, cursor: CursorKind) {
match self.kind { match self.kind {
WindowKind::Window(ref window) => { WindowKind::Window(ref window) => {
use glutin::MouseCursor; use glutin::MouseCursor;
let glutin_cursor = match c { let glutin_cursor = match cursor {
Cursor::None => MouseCursor::NoneCursor, CursorKind::Auto => MouseCursor::Default,
Cursor::Default => MouseCursor::Default, CursorKind::None => MouseCursor::NoneCursor,
Cursor::Pointer => MouseCursor::Hand, CursorKind::Default => MouseCursor::Default,
Cursor::ContextMenu => MouseCursor::ContextMenu, CursorKind::Pointer => MouseCursor::Hand,
Cursor::Help => MouseCursor::Help, CursorKind::ContextMenu => MouseCursor::ContextMenu,
Cursor::Progress => MouseCursor::Progress, CursorKind::Help => MouseCursor::Help,
Cursor::Wait => MouseCursor::Wait, CursorKind::Progress => MouseCursor::Progress,
Cursor::Cell => MouseCursor::Cell, CursorKind::Wait => MouseCursor::Wait,
Cursor::Crosshair => MouseCursor::Crosshair, CursorKind::Cell => MouseCursor::Cell,
Cursor::Text => MouseCursor::Text, CursorKind::Crosshair => MouseCursor::Crosshair,
Cursor::VerticalText => MouseCursor::VerticalText, CursorKind::Text => MouseCursor::Text,
Cursor::Alias => MouseCursor::Alias, CursorKind::VerticalText => MouseCursor::VerticalText,
Cursor::Copy => MouseCursor::Copy, CursorKind::Alias => MouseCursor::Alias,
Cursor::Move => MouseCursor::Move, CursorKind::Copy => MouseCursor::Copy,
Cursor::NoDrop => MouseCursor::NoDrop, CursorKind::Move => MouseCursor::Move,
Cursor::NotAllowed => MouseCursor::NotAllowed, CursorKind::NoDrop => MouseCursor::NoDrop,
Cursor::Grab => MouseCursor::Grab, CursorKind::NotAllowed => MouseCursor::NotAllowed,
Cursor::Grabbing => MouseCursor::Grabbing, CursorKind::Grab => MouseCursor::Grab,
Cursor::EResize => MouseCursor::EResize, CursorKind::Grabbing => MouseCursor::Grabbing,
Cursor::NResize => MouseCursor::NResize, CursorKind::EResize => MouseCursor::EResize,
Cursor::NeResize => MouseCursor::NeResize, CursorKind::NResize => MouseCursor::NResize,
Cursor::NwResize => MouseCursor::NwResize, CursorKind::NeResize => MouseCursor::NeResize,
Cursor::SResize => MouseCursor::SResize, CursorKind::NwResize => MouseCursor::NwResize,
Cursor::SeResize => MouseCursor::SeResize, CursorKind::SResize => MouseCursor::SResize,
Cursor::SwResize => MouseCursor::SwResize, CursorKind::SeResize => MouseCursor::SeResize,
Cursor::WResize => MouseCursor::WResize, CursorKind::SwResize => MouseCursor::SwResize,
Cursor::EwResize => MouseCursor::EwResize, CursorKind::WResize => MouseCursor::WResize,
Cursor::NsResize => MouseCursor::NsResize, CursorKind::EwResize => MouseCursor::EwResize,
Cursor::NeswResize => MouseCursor::NeswResize, CursorKind::NsResize => MouseCursor::NsResize,
Cursor::NwseResize => MouseCursor::NwseResize, CursorKind::NeswResize => MouseCursor::NeswResize,
Cursor::ColResize => MouseCursor::ColResize, CursorKind::NwseResize => MouseCursor::NwseResize,
Cursor::RowResize => MouseCursor::RowResize, CursorKind::ColResize => MouseCursor::ColResize,
Cursor::AllScroll => MouseCursor::AllScroll, CursorKind::RowResize => MouseCursor::RowResize,
Cursor::ZoomIn => MouseCursor::ZoomIn, CursorKind::AllScroll => MouseCursor::AllScroll,
Cursor::ZoomOut => MouseCursor::ZoomOut, CursorKind::ZoomIn => MouseCursor::ZoomIn,
CursorKind::ZoomOut => MouseCursor::ZoomOut,
}; };
window.set_cursor(glutin_cursor); window.set_cursor(glutin_cursor);
} }