mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Auto merge of #22738 - emilio:gecko-sync, r=emilio
style: Sync changes from mozilla-central. See each individual commit for details. <!-- 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/22738) <!-- Reviewable:end -->
This commit is contained in:
commit
ccc4149b30
35 changed files with 653 additions and 356 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -602,6 +602,7 @@ dependencies = [
|
|||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pixels 0.0.1",
|
||||
"profile_traits 0.0.1",
|
||||
"script_traits 0.0.1",
|
||||
|
@ -1041,6 +1042,8 @@ dependencies = [
|
|||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"msg 0.0.1",
|
||||
"num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
|
@ -2059,6 +2062,7 @@ dependencies = [
|
|||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"canvas_traits 0.0.1",
|
||||
"crossbeam-channel 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"embedder_traits 0.0.1",
|
||||
"euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -28,6 +28,7 @@ keyboard-types = "0.4.3"
|
|||
log = "0.4"
|
||||
msg = {path = "../msg"}
|
||||
net_traits = {path = "../net_traits"}
|
||||
num-traits = "0.2"
|
||||
pixels = {path = "../pixels", optional = true}
|
||||
profile_traits = {path = "../profile_traits"}
|
||||
script_traits = {path = "../script_traits"}
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::windowing::{
|
|||
use crate::CompositionPipeline;
|
||||
use crate::SendableFrameTree;
|
||||
use crossbeam_channel::Sender;
|
||||
use embedder_traits::Cursor;
|
||||
use euclid::{TypedPoint2D, TypedScale, TypedVector2D};
|
||||
use gfx_traits::Epoch;
|
||||
#[cfg(feature = "gl")]
|
||||
|
@ -21,6 +22,7 @@ use ipc_channel::ipc;
|
|||
use libc::c_void;
|
||||
use msg::constellation_msg::{PipelineId, PipelineIndex, PipelineNamespaceId};
|
||||
use net_traits::image::base::Image;
|
||||
use num_traits::FromPrimitive;
|
||||
#[cfg(feature = "gl")]
|
||||
use pixels::PixelFormat;
|
||||
use profile_traits::time::{self as profile_time, profile, ProfilerCategory};
|
||||
|
@ -36,7 +38,6 @@ use std::fs::{create_dir_all, File};
|
|||
use std::io::Write;
|
||||
use std::num::NonZeroU32;
|
||||
use std::rc::Rc;
|
||||
use style_traits::cursor::CursorKind;
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor};
|
||||
use time::{now, precise_time_ns, precise_time_s};
|
||||
|
@ -742,7 +743,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
warn!("Sending event to constellation failed ({:?}).", e);
|
||||
}
|
||||
|
||||
if let Some(cursor) = CursorKind::from_u8(item.tag.1 as _).ok() {
|
||||
if let Some(cursor) = Cursor::from_u8(item.tag.1 as _) {
|
||||
let msg = ConstellationMsg::SetCursor(cursor);
|
||||
if let Err(e) = self.constellation_chan.send(msg) {
|
||||
warn!("Sending event to constellation failed ({:?}).", e);
|
||||
|
|
|
@ -113,7 +113,7 @@ use compositing::compositor_thread::Msg as ToCompositorMsg;
|
|||
use compositing::SendableFrameTree;
|
||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg};
|
||||
use embedder_traits::{EmbedderMsg, EmbedderProxy};
|
||||
use embedder_traits::{Cursor, EmbedderMsg, EmbedderProxy};
|
||||
use euclid::{Size2D, TypedScale, TypedSize2D};
|
||||
use gfx::font_cache_thread::FontCacheThread;
|
||||
use gfx_traits::Epoch;
|
||||
|
@ -164,7 +164,6 @@ use std::process;
|
|||
use std::rc::{Rc, Weak};
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use style_traits::cursor::CursorKind;
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use style_traits::CSSPixel;
|
||||
use webvr_traits::{WebVREvent, WebVRMsg};
|
||||
|
@ -2135,7 +2134,7 @@ where
|
|||
.send(ToCompositorMsg::PendingPaintMetric(pipeline_id, epoch))
|
||||
}
|
||||
|
||||
fn handle_set_cursor_msg(&mut self, cursor: CursorKind) {
|
||||
fn handle_set_cursor_msg(&mut self, cursor: Cursor) {
|
||||
self.embedder_proxy
|
||||
.send((None, EmbedderMsg::SetCursor(cursor)))
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ keyboard-types = "0.4.3"
|
|||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
msg = {path = "../msg"}
|
||||
num-traits = "0.2"
|
||||
num-derive = "0.2"
|
||||
serde = "1.0"
|
||||
servo_url = {path = "../url"}
|
||||
style_traits = {path = "../style_traits", features = ["servo"]}
|
||||
|
|
|
@ -7,6 +7,8 @@ extern crate lazy_static;
|
|||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate num_derive;
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
|
||||
pub mod resources;
|
||||
|
@ -17,9 +19,50 @@ use keyboard_types::KeyboardEvent;
|
|||
use msg::constellation_msg::{InputMethodType, PipelineId, TopLevelBrowsingContextId};
|
||||
use servo_url::ServoUrl;
|
||||
use std::fmt::{Debug, Error, Formatter};
|
||||
use style_traits::cursor::CursorKind;
|
||||
use webrender_api::{DeviceIntPoint, DeviceIntSize};
|
||||
|
||||
/// A cursor for the window. This is different from a CSS cursor (see
|
||||
/// `CursorKind`) in that it has no `Auto` value.
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Deserialize, Eq, FromPrimitive, PartialEq, Serialize)]
|
||||
pub enum Cursor {
|
||||
None,
|
||||
Default,
|
||||
Pointer,
|
||||
ContextMenu,
|
||||
Help,
|
||||
Progress,
|
||||
Wait,
|
||||
Cell,
|
||||
Crosshair,
|
||||
Text,
|
||||
VerticalText,
|
||||
Alias,
|
||||
Copy,
|
||||
Move,
|
||||
NoDrop,
|
||||
NotAllowed,
|
||||
Grab,
|
||||
Grabbing,
|
||||
EResize,
|
||||
NResize,
|
||||
NeResize,
|
||||
NwResize,
|
||||
SResize,
|
||||
SeResize,
|
||||
SwResize,
|
||||
WResize,
|
||||
EwResize,
|
||||
NsResize,
|
||||
NeswResize,
|
||||
NwseResize,
|
||||
ColResize,
|
||||
RowResize,
|
||||
AllScroll,
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
}
|
||||
|
||||
/// Used to wake up the event loop, provided by the servo port/embedder.
|
||||
pub trait EventLoopWaker: 'static + Send {
|
||||
fn clone(&self) -> Box<EventLoopWaker + Send>;
|
||||
|
@ -90,7 +133,7 @@ pub enum EmbedderMsg {
|
|||
/// Sends an unconsumed key event back to the embedder.
|
||||
Keyboard(KeyboardEvent),
|
||||
/// Changes the cursor.
|
||||
SetCursor(CursorKind),
|
||||
SetCursor(Cursor),
|
||||
/// A favicon was detected
|
||||
NewFavicon(ServoUrl),
|
||||
/// <head> tag finished parsing
|
||||
|
|
|
@ -18,6 +18,7 @@ atomic_refcell = "0.1"
|
|||
bitflags = "1.0"
|
||||
canvas_traits = {path = "../canvas_traits"}
|
||||
crossbeam-channel = "0.3"
|
||||
embedder_traits = {path = "../embedder_traits"}
|
||||
euclid = "0.19"
|
||||
fnv = "1.0"
|
||||
fxhash = "0.2"
|
||||
|
|
|
@ -31,6 +31,7 @@ use crate::model::MaybeAuto;
|
|||
use crate::table_cell::CollapsedBordersForCell;
|
||||
use app_units::{Au, AU_PER_PX};
|
||||
use canvas_traits::canvas::{CanvasMsg, FromLayoutMsg};
|
||||
use embedder_traits::Cursor;
|
||||
use euclid::{rect, Point2D, Rect, SideOffsets2D, Size2D, TypedRect, TypedSize2D, Vector2D};
|
||||
use fnv::FnvHashMap;
|
||||
use gfx::text::glyph::ByteIndex;
|
||||
|
@ -60,8 +61,8 @@ use style::values::computed::image::Image as ComputedImage;
|
|||
use style::values::computed::Gradient;
|
||||
use style::values::generics::background::BackgroundSize;
|
||||
use style::values::generics::image::{GradientKind, Image, PaintWorklet};
|
||||
use style::values::specified::ui::CursorKind;
|
||||
use style::values::{Either, RGBA};
|
||||
use style_traits::cursor::CursorKind;
|
||||
use style_traits::ToCss;
|
||||
use webrender_api::{
|
||||
self, BorderDetails, BorderRadius, BorderSide, BoxShadowClipMode, ColorF, ColorU,
|
||||
|
@ -379,7 +380,7 @@ impl<'a> DisplayListBuildState<'a> {
|
|||
bounds: Rect<Au>,
|
||||
clip_rect: Rect<Au>,
|
||||
node: OpaqueNode,
|
||||
cursor: Option<CursorKind>,
|
||||
cursor: Option<Cursor>,
|
||||
section: DisplayListSection,
|
||||
) -> BaseDisplayItem {
|
||||
let clipping_and_scrolling = if self.is_background_or_border_of_clip_scroll_node(section) {
|
||||
|
@ -691,7 +692,7 @@ impl Fragment {
|
|||
bounds,
|
||||
bounds,
|
||||
self.node,
|
||||
get_cursor(&style, CursorKind::Default),
|
||||
get_cursor(&style, Cursor::Default),
|
||||
display_list_section,
|
||||
);
|
||||
state.add_display_item(DisplayItem::Rectangle(CommonDisplayItem::new(
|
||||
|
@ -822,7 +823,7 @@ impl Fragment {
|
|||
placement.bounds,
|
||||
placement.clip_rect,
|
||||
self.node,
|
||||
get_cursor(&style, CursorKind::Default),
|
||||
get_cursor(&style, Cursor::Default),
|
||||
display_list_section,
|
||||
);
|
||||
|
||||
|
@ -937,7 +938,7 @@ impl Fragment {
|
|||
placement.bounds,
|
||||
placement.clip_rect,
|
||||
self.node,
|
||||
get_cursor(&style, CursorKind::Default),
|
||||
get_cursor(&style, Cursor::Default),
|
||||
display_list_section,
|
||||
);
|
||||
|
||||
|
@ -1003,7 +1004,7 @@ impl Fragment {
|
|||
bounds,
|
||||
clip,
|
||||
self.node,
|
||||
get_cursor(&style, CursorKind::Default),
|
||||
get_cursor(&style, Cursor::Default),
|
||||
display_list_section,
|
||||
);
|
||||
let border_radius = border::radii(absolute_bounds, style.get_border());
|
||||
|
@ -1087,7 +1088,7 @@ impl Fragment {
|
|||
bounds,
|
||||
clip,
|
||||
self.node,
|
||||
get_cursor(&style, CursorKind::Default),
|
||||
get_cursor(&style, Cursor::Default),
|
||||
display_list_section,
|
||||
);
|
||||
|
||||
|
@ -1286,7 +1287,7 @@ impl Fragment {
|
|||
bounds,
|
||||
clip,
|
||||
self.node,
|
||||
get_cursor(&style, CursorKind::Default),
|
||||
get_cursor(&style, Cursor::Default),
|
||||
DisplayListSection::Outlines,
|
||||
);
|
||||
state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
|
||||
|
@ -1317,7 +1318,7 @@ impl Fragment {
|
|||
stacking_relative_border_box,
|
||||
clip,
|
||||
self.node,
|
||||
get_cursor(&style, CursorKind::Default),
|
||||
get_cursor(&style, Cursor::Default),
|
||||
DisplayListSection::Content,
|
||||
);
|
||||
state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
|
||||
|
@ -1346,7 +1347,7 @@ impl Fragment {
|
|||
baseline,
|
||||
clip,
|
||||
self.node,
|
||||
get_cursor(&style, CursorKind::Default),
|
||||
get_cursor(&style, Cursor::Default),
|
||||
DisplayListSection::Content,
|
||||
);
|
||||
// TODO(gw): Use a better estimate for wavy line thickness.
|
||||
|
@ -1374,7 +1375,7 @@ impl Fragment {
|
|||
stacking_relative_border_box,
|
||||
clip,
|
||||
self.node,
|
||||
get_cursor(&self.style, CursorKind::Default),
|
||||
get_cursor(&self.style, Cursor::Default),
|
||||
DisplayListSection::Content,
|
||||
);
|
||||
state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
|
||||
|
@ -1416,7 +1417,7 @@ impl Fragment {
|
|||
stacking_relative_border_box,
|
||||
clip,
|
||||
self.node,
|
||||
get_cursor(&self.style, CursorKind::Default),
|
||||
get_cursor(&self.style, Cursor::Default),
|
||||
display_list_section,
|
||||
);
|
||||
state.add_display_item(DisplayItem::Rectangle(CommonDisplayItem::new(
|
||||
|
@ -1447,7 +1448,7 @@ impl Fragment {
|
|||
INSERTION_POINT_LOGICAL_WIDTH,
|
||||
stacking_relative_border_box.size.height,
|
||||
);
|
||||
cursor = CursorKind::Text;
|
||||
cursor = Cursor::Text;
|
||||
} else {
|
||||
insertion_point_bounds = rect(
|
||||
stacking_relative_border_box.origin.x,
|
||||
|
@ -1455,7 +1456,7 @@ impl Fragment {
|
|||
stacking_relative_border_box.size.width,
|
||||
INSERTION_POINT_LOGICAL_WIDTH,
|
||||
);
|
||||
cursor = CursorKind::VerticalText;
|
||||
cursor = Cursor::VerticalText;
|
||||
};
|
||||
|
||||
let base = state.create_base_display_item(
|
||||
|
@ -1644,7 +1645,8 @@ impl Fragment {
|
|||
content_size,
|
||||
content_size,
|
||||
self.node,
|
||||
get_cursor(&self.style, CursorKind::Default).or(Some(CursorKind::Default)),
|
||||
// FIXME(emilio): Why does this ignore pointer-events?
|
||||
get_cursor(&self.style, Cursor::Default).or(Some(Cursor::Default)),
|
||||
DisplayListSection::Content,
|
||||
);
|
||||
state.add_display_item(DisplayItem::Rectangle(CommonDisplayItem::new(
|
||||
|
@ -1695,7 +1697,7 @@ impl Fragment {
|
|||
stacking_relative_content_box,
|
||||
stacking_relative_border_box,
|
||||
self.node,
|
||||
get_cursor(&self.style, CursorKind::Default),
|
||||
get_cursor(&self.style, Cursor::Default),
|
||||
DisplayListSection::Content,
|
||||
)
|
||||
};
|
||||
|
@ -1952,9 +1954,9 @@ impl Fragment {
|
|||
let (_orientation, cursor) = if self.style.writing_mode.is_vertical() {
|
||||
// TODO: Distinguish between 'sideways-lr' and 'sideways-rl' writing modes in CSS
|
||||
// Writing Modes Level 4.
|
||||
(TextOrientation::SidewaysRight, CursorKind::VerticalText)
|
||||
(TextOrientation::SidewaysRight, Cursor::VerticalText)
|
||||
} else {
|
||||
(TextOrientation::Upright, CursorKind::Text)
|
||||
(TextOrientation::Upright, Cursor::Text)
|
||||
};
|
||||
|
||||
// Compute location of the baseline.
|
||||
|
@ -2096,7 +2098,7 @@ impl Fragment {
|
|||
stacking_relative_box,
|
||||
clip,
|
||||
self.node,
|
||||
get_cursor(&self.style, CursorKind::Default),
|
||||
get_cursor(&self.style, Cursor::Default),
|
||||
DisplayListSection::Content,
|
||||
);
|
||||
|
||||
|
@ -2830,14 +2832,49 @@ impl BaseFlow {
|
|||
/// the cursor to use if `cursor` is `auto`. Typically, this will be `PointerCursor`, but for
|
||||
/// text display items it may be `TextCursor` or `VerticalTextCursor`.
|
||||
#[inline]
|
||||
fn get_cursor(values: &ComputedValues, default_cursor: CursorKind) -> Option<CursorKind> {
|
||||
fn get_cursor(values: &ComputedValues, default_cursor: Cursor) -> Option<Cursor> {
|
||||
let inherited_ui = values.get_inherited_ui();
|
||||
if inherited_ui.pointer_events == PointerEvents::None {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(match inherited_ui.cursor.keyword {
|
||||
CursorKind::Auto => default_cursor,
|
||||
keyword => keyword,
|
||||
CursorKind::None => Cursor::None,
|
||||
CursorKind::Default => Cursor::Default,
|
||||
CursorKind::Pointer => Cursor::Pointer,
|
||||
CursorKind::ContextMenu => Cursor::ContextMenu,
|
||||
CursorKind::Help => Cursor::Help,
|
||||
CursorKind::Progress => Cursor::Progress,
|
||||
CursorKind::Wait => Cursor::Wait,
|
||||
CursorKind::Cell => Cursor::Cell,
|
||||
CursorKind::Crosshair => Cursor::Crosshair,
|
||||
CursorKind::Text => Cursor::Text,
|
||||
CursorKind::VerticalText => Cursor::VerticalText,
|
||||
CursorKind::Alias => Cursor::Alias,
|
||||
CursorKind::Copy => Cursor::Copy,
|
||||
CursorKind::Move => Cursor::Move,
|
||||
CursorKind::NoDrop => Cursor::NoDrop,
|
||||
CursorKind::NotAllowed => Cursor::NotAllowed,
|
||||
CursorKind::Grab => Cursor::Grab,
|
||||
CursorKind::Grabbing => Cursor::Grabbing,
|
||||
CursorKind::EResize => Cursor::EResize,
|
||||
CursorKind::NResize => Cursor::NResize,
|
||||
CursorKind::NeResize => Cursor::NeResize,
|
||||
CursorKind::NwResize => Cursor::NwResize,
|
||||
CursorKind::SResize => Cursor::SResize,
|
||||
CursorKind::SeResize => Cursor::SeResize,
|
||||
CursorKind::SwResize => Cursor::SwResize,
|
||||
CursorKind::WResize => Cursor::WResize,
|
||||
CursorKind::EwResize => Cursor::EwResize,
|
||||
CursorKind::NsResize => Cursor::NsResize,
|
||||
CursorKind::NeswResize => Cursor::NeswResize,
|
||||
CursorKind::NwseResize => Cursor::NwseResize,
|
||||
CursorKind::ColResize => Cursor::ColResize,
|
||||
CursorKind::RowResize => Cursor::RowResize,
|
||||
CursorKind::AllScroll => Cursor::AllScroll,
|
||||
CursorKind::ZoomIn => Cursor::ZoomIn,
|
||||
CursorKind::ZoomOut => Cursor::ZoomOut,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -127,6 +127,18 @@ partial interface CSSStyleDeclaration {
|
|||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockEndWidth;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block-end-style;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockEndStyle;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block-color;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockColor;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block-style;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockStyle;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block-width;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockWidth;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block-start;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlock;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline-start-color;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInlineStartColor;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline-start-width;
|
||||
|
@ -139,14 +151,18 @@ partial interface CSSStyleDeclaration {
|
|||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInlineEndWidth;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline-end-style;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInlineEndStyle;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block-start;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-block-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderBlockEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline-color;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInlineColor;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline-style;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInlineStyle;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline-width;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInlineWidth;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline-start;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInlineStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInlineEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-inline;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderInline;
|
||||
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString content;
|
||||
|
||||
|
@ -300,10 +316,14 @@ partial interface CSSStyleDeclaration {
|
|||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString marginBlockStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString margin-block-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString marginBlockEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString margin-block;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString marginBlock;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString margin-inline-start;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString marginInlineStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString margin-inline-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString marginInlineEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString margin-inline;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString marginInline;
|
||||
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString padding;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString paddingBottom;
|
||||
|
@ -318,10 +338,14 @@ partial interface CSSStyleDeclaration {
|
|||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString paddingBlockStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString padding-block-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString paddingBlockEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString padding-block;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString paddingBlock;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString padding-inline-start;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString paddingInlineStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString padding-inline-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString paddingInlineEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString padding-inline;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString paddingInline;
|
||||
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString outline;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString outlineColor;
|
||||
|
@ -354,10 +378,14 @@ partial interface CSSStyleDeclaration {
|
|||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString insetBlockStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString inset-block-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString insetBlockEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString inset-block;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString insetBlock;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString inset-inline-start;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString insetInlineStart;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString inset-inline-end;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString insetInlineEnd;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString inset-inline;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString insetInline;
|
||||
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString height;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString minHeight;
|
||||
|
@ -454,4 +482,14 @@ partial interface CSSStyleDeclaration {
|
|||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString animationFillMode;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString animation-delay;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString animationDelay;
|
||||
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-end-end-radius;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderEndEndRadius;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-start-end-radius;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderStartEndRadius;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-start-start-radius;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderStartStartRadius;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString border-end-start-radius;
|
||||
[CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString borderEndStartRadius;
|
||||
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@ use bluetooth_traits::BluetoothRequest;
|
|||
use canvas_traits::webgl::WebGLPipeline;
|
||||
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
|
||||
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
|
||||
use embedder_traits::Cursor;
|
||||
use euclid::{Length, Point2D, Rect, TypedScale, TypedSize2D, Vector2D};
|
||||
use gfx_traits::Epoch;
|
||||
use http::HeaderMap;
|
||||
|
@ -50,7 +51,6 @@ use servo_url::ServoUrl;
|
|||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use style_traits::cursor::CursorKind;
|
||||
use style_traits::CSSPixel;
|
||||
use style_traits::SpeculativePainter;
|
||||
use webrender_api::{
|
||||
|
@ -775,7 +775,7 @@ pub enum ConstellationMsg {
|
|||
/// Forward an event to the script task of the given pipeline.
|
||||
ForwardEvent(PipelineId, CompositorEvent),
|
||||
/// Requesting a change to the onscreen cursor.
|
||||
SetCursor(CursorKind),
|
||||
SetCursor(Cursor),
|
||||
}
|
||||
|
||||
impl fmt::Debug for ConstellationMsg {
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::WorkerGlobalScopeInit;
|
|||
use crate::WorkerScriptLoadOrigin;
|
||||
use canvas_traits::canvas::{CanvasId, CanvasMsg};
|
||||
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
|
||||
use embedder_traits::EmbedderMsg;
|
||||
use embedder_traits::{Cursor, EmbedderMsg};
|
||||
use euclid::{Size2D, TypedSize2D};
|
||||
use gfx_traits::Epoch;
|
||||
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
||||
|
@ -26,7 +26,6 @@ use net_traits::CoreResourceMsg;
|
|||
use servo_url::ImmutableOrigin;
|
||||
use servo_url::ServoUrl;
|
||||
use std::fmt;
|
||||
use style_traits::cursor::CursorKind;
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use style_traits::CSSPixel;
|
||||
use webrender_api::{DeviceIntPoint, DeviceIntSize};
|
||||
|
@ -60,7 +59,7 @@ pub enum LayoutMsg {
|
|||
/// the time when the frame with the given ID (epoch) is painted.
|
||||
PendingPaintMetric(PipelineId, Epoch),
|
||||
/// Requests that the constellation inform the compositor of the a cursor change.
|
||||
SetCursor(CursorKind),
|
||||
SetCursor(Cursor),
|
||||
/// Notifies the constellation that the viewport has been constrained in some manner
|
||||
ViewportConstrained(PipelineId, ViewportConstraints),
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ include = [
|
|||
"ComputedFontStyleDescriptor",
|
||||
"ComputedFontWeightRange",
|
||||
"ComputedTimingFunction",
|
||||
"CursorKind",
|
||||
"Display",
|
||||
"DisplayMode",
|
||||
"ExtremumLength",
|
||||
|
@ -67,5 +68,6 @@ include = [
|
|||
"OverflowClipBox",
|
||||
"Resize",
|
||||
"Overflow",
|
||||
"LengthPercentage",
|
||||
]
|
||||
item_types = ["enums", "structs", "typedefs"]
|
||||
|
|
|
@ -36,15 +36,12 @@ use style_traits::values::specified::AllowedNumericType;
|
|||
impl From<LengthPercentage> for nsStyleCoord_CalcValue {
|
||||
fn from(other: LengthPercentage) -> nsStyleCoord_CalcValue {
|
||||
debug_assert!(
|
||||
other.was_calc ||
|
||||
other.percentage.is_none() ||
|
||||
other.unclamped_length() == Length::zero()
|
||||
other.was_calc || !other.has_percentage || other.unclamped_length() == Length::zero()
|
||||
);
|
||||
let has_percentage = other.percentage.is_some();
|
||||
nsStyleCoord_CalcValue {
|
||||
mLength: other.unclamped_length().to_i32_au(),
|
||||
mPercent: other.percentage.map_or(0., |p| p.0),
|
||||
mHasPercent: has_percentage,
|
||||
mPercent: other.percentage(),
|
||||
mHasPercent: other.has_percentage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -526,7 +526,7 @@ lazy_static! {
|
|||
/// to support new types in these entries and (2) ensuring that either
|
||||
/// nsPresContext::MediaFeatureValuesChanged is called when the value that
|
||||
/// would be returned by the evaluator function could change.
|
||||
pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 50] = [
|
||||
pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 52] = [
|
||||
feature!(
|
||||
atom!("width"),
|
||||
AllowsRanges::Yes,
|
||||
|
@ -719,10 +719,12 @@ lazy_static! {
|
|||
system_metric_feature!(atom!("-moz-menubar-drag")),
|
||||
system_metric_feature!(atom!("-moz-swipe-animation-enabled")),
|
||||
system_metric_feature!(atom!("-moz-gtk-csd-available")),
|
||||
system_metric_feature!(atom!("-moz-gtk-csd-hide-titlebar-by-default")),
|
||||
system_metric_feature!(atom!("-moz-gtk-csd-transparent-background")),
|
||||
system_metric_feature!(atom!("-moz-gtk-csd-minimize-button")),
|
||||
system_metric_feature!(atom!("-moz-gtk-csd-maximize-button")),
|
||||
system_metric_feature!(atom!("-moz-gtk-csd-close-button")),
|
||||
system_metric_feature!(atom!("-moz-gtk-csd-reversed-placement")),
|
||||
system_metric_feature!(atom!("-moz-system-dark-theme")),
|
||||
// This is the only system-metric media feature that's accessible to
|
||||
// content as of today.
|
||||
|
|
|
@ -151,9 +151,9 @@ impl GeckoStyleCoordConvertible for LengthPercentage {
|
|||
if self.was_calc {
|
||||
return coord.set_value(CoordDataValue::Calc((*self).into()));
|
||||
}
|
||||
debug_assert!(self.percentage.is_none() || self.unclamped_length() == Length::zero());
|
||||
if let Some(p) = self.percentage {
|
||||
return coord.set_value(CoordDataValue::Percent(p.0));
|
||||
debug_assert!(!self.has_percentage || self.unclamped_length() == Length::zero());
|
||||
if self.has_percentage {
|
||||
return coord.set_value(CoordDataValue::Percent(self.percentage()));
|
||||
}
|
||||
coord.set_value(CoordDataValue::Coord(self.unclamped_length().to_i32_au()))
|
||||
}
|
||||
|
|
|
@ -72,9 +72,9 @@ impl nsCSSValue {
|
|||
if lp.was_calc {
|
||||
return bindings::Gecko_CSSValue_SetCalc(self, lp.into());
|
||||
}
|
||||
debug_assert!(lp.percentage.is_none() || lp.unclamped_length() == Length::zero());
|
||||
if let Some(p) = lp.percentage {
|
||||
return self.set_percentage(p.0);
|
||||
debug_assert!(!lp.has_percentage || lp.unclamped_length() == Length::zero());
|
||||
if lp.has_percentage {
|
||||
return self.set_percentage(lp.percentage());
|
||||
}
|
||||
self.set_px(lp.unclamped_length().px());
|
||||
}
|
||||
|
|
|
@ -171,6 +171,58 @@ impl WritingMode {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn physical_sides_to_corner(
|
||||
block_side: PhysicalSide,
|
||||
inline_side: PhysicalSide,
|
||||
) -> PhysicalCorner {
|
||||
match (block_side, inline_side) {
|
||||
(PhysicalSide::Top, PhysicalSide::Left) | (PhysicalSide::Left, PhysicalSide::Top) => {
|
||||
PhysicalCorner::TopLeft
|
||||
},
|
||||
(PhysicalSide::Top, PhysicalSide::Right) | (PhysicalSide::Right, PhysicalSide::Top) => {
|
||||
PhysicalCorner::TopRight
|
||||
},
|
||||
(PhysicalSide::Bottom, PhysicalSide::Right) |
|
||||
(PhysicalSide::Right, PhysicalSide::Bottom) => PhysicalCorner::BottomRight,
|
||||
(PhysicalSide::Bottom, PhysicalSide::Left) |
|
||||
(PhysicalSide::Left, PhysicalSide::Bottom) => PhysicalCorner::BottomLeft,
|
||||
_ => unreachable!("block and inline sides must be orthogonal"),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn start_start_physical_corner(&self) -> PhysicalCorner {
|
||||
WritingMode::physical_sides_to_corner(
|
||||
self.block_start_physical_side(),
|
||||
self.inline_start_physical_side(),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn start_end_physical_corner(&self) -> PhysicalCorner {
|
||||
WritingMode::physical_sides_to_corner(
|
||||
self.block_start_physical_side(),
|
||||
self.inline_end_physical_side(),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn end_start_physical_corner(&self) -> PhysicalCorner {
|
||||
WritingMode::physical_sides_to_corner(
|
||||
self.block_end_physical_side(),
|
||||
self.inline_start_physical_side(),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn end_end_physical_corner(&self) -> PhysicalCorner {
|
||||
WritingMode::physical_sides_to_corner(
|
||||
self.block_end_physical_side(),
|
||||
self.inline_end_physical_side(),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn block_flow_direction(&self) -> BlockFlowDirection {
|
||||
match (self.is_vertical(), self.is_vertical_lr()) {
|
||||
|
@ -1314,3 +1366,11 @@ pub enum PhysicalSide {
|
|||
Bottom,
|
||||
Left,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum PhysicalCorner {
|
||||
TopLeft,
|
||||
TopRight,
|
||||
BottomRight,
|
||||
BottomLeft,
|
||||
}
|
||||
|
|
|
@ -8,10 +8,13 @@ PHYSICAL_SIDES = ["top", "right", "bottom", "left"]
|
|||
LOGICAL_SIDES = ["block-start", "block-end", "inline-start", "inline-end"]
|
||||
PHYSICAL_SIZES = ["width", "height"]
|
||||
LOGICAL_SIZES = ["block-size", "inline-size"]
|
||||
PHYSICAL_CORNERS = ["top-left", "top-right", "bottom-right", "bottom-left"]
|
||||
LOGICAL_CORNERS = ["start-start", "start-end", "end-start", "end-end"]
|
||||
|
||||
# bool is True when logical
|
||||
ALL_SIDES = [(side, False) for side in PHYSICAL_SIDES] + [(side, True) for side in LOGICAL_SIDES]
|
||||
ALL_SIZES = [(size, False) for size in PHYSICAL_SIZES] + [(size, True) for size in LOGICAL_SIZES]
|
||||
ALL_CORNERS = [(corner, False) for corner in PHYSICAL_CORNERS] + [(corner, True) for corner in LOGICAL_CORNERS]
|
||||
|
||||
SYSTEM_FONT_LONGHANDS = """font_family font_size font_style
|
||||
font_variant_caps font_stretch font_kerning
|
||||
|
@ -239,12 +242,14 @@ class Longhand(object):
|
|||
def all_physical_mapped_properties(self):
|
||||
assert self.logical
|
||||
logical_side = None
|
||||
for s in LOGICAL_SIDES + LOGICAL_SIZES:
|
||||
for s in LOGICAL_SIDES + LOGICAL_SIZES + LOGICAL_CORNERS:
|
||||
if s in self.name:
|
||||
assert not logical_side
|
||||
logical_side = s
|
||||
assert logical_side
|
||||
physical = PHYSICAL_SIDES if logical_side in LOGICAL_SIDES else PHYSICAL_SIZES
|
||||
physical = PHYSICAL_SIDES if logical_side in LOGICAL_SIDES \
|
||||
else PHYSICAL_SIZES if logical_side in LOGICAL_SIZES \
|
||||
else LOGICAL_CORNERS
|
||||
return [self.name.replace(logical_side, physical_side).replace("inset-", "")
|
||||
for physical_side in physical]
|
||||
|
||||
|
|
|
@ -5162,52 +5162,7 @@ clip-path
|
|||
<%self:impl_trait style_struct_name="InheritedUI"
|
||||
skip_longhands="cursor scrollbar-color">
|
||||
pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
|
||||
use style_traits::cursor::CursorKind;
|
||||
|
||||
self.gecko.mCursor = match v.keyword {
|
||||
CursorKind::Auto => structs::NS_STYLE_CURSOR_AUTO,
|
||||
CursorKind::None => structs::NS_STYLE_CURSOR_NONE,
|
||||
CursorKind::Default => structs::NS_STYLE_CURSOR_DEFAULT,
|
||||
CursorKind::Pointer => structs::NS_STYLE_CURSOR_POINTER,
|
||||
CursorKind::ContextMenu => structs::NS_STYLE_CURSOR_CONTEXT_MENU,
|
||||
CursorKind::Help => structs::NS_STYLE_CURSOR_HELP,
|
||||
CursorKind::Progress => structs::NS_STYLE_CURSOR_SPINNING,
|
||||
CursorKind::Wait => structs::NS_STYLE_CURSOR_WAIT,
|
||||
CursorKind::Cell => structs::NS_STYLE_CURSOR_CELL,
|
||||
CursorKind::Crosshair => structs::NS_STYLE_CURSOR_CROSSHAIR,
|
||||
CursorKind::Text => structs::NS_STYLE_CURSOR_TEXT,
|
||||
CursorKind::VerticalText => structs::NS_STYLE_CURSOR_VERTICAL_TEXT,
|
||||
CursorKind::Alias => structs::NS_STYLE_CURSOR_ALIAS,
|
||||
CursorKind::Copy => structs::NS_STYLE_CURSOR_COPY,
|
||||
CursorKind::Move => structs::NS_STYLE_CURSOR_MOVE,
|
||||
CursorKind::NoDrop => structs::NS_STYLE_CURSOR_NO_DROP,
|
||||
CursorKind::NotAllowed => structs::NS_STYLE_CURSOR_NOT_ALLOWED,
|
||||
CursorKind::Grab => structs::NS_STYLE_CURSOR_GRAB,
|
||||
CursorKind::Grabbing => structs::NS_STYLE_CURSOR_GRABBING,
|
||||
CursorKind::EResize => structs::NS_STYLE_CURSOR_E_RESIZE,
|
||||
CursorKind::NResize => structs::NS_STYLE_CURSOR_N_RESIZE,
|
||||
CursorKind::NeResize => structs::NS_STYLE_CURSOR_NE_RESIZE,
|
||||
CursorKind::NwResize => structs::NS_STYLE_CURSOR_NW_RESIZE,
|
||||
CursorKind::SResize => structs::NS_STYLE_CURSOR_S_RESIZE,
|
||||
CursorKind::SeResize => structs::NS_STYLE_CURSOR_SE_RESIZE,
|
||||
CursorKind::SwResize => structs::NS_STYLE_CURSOR_SW_RESIZE,
|
||||
CursorKind::WResize => structs::NS_STYLE_CURSOR_W_RESIZE,
|
||||
CursorKind::EwResize => structs::NS_STYLE_CURSOR_EW_RESIZE,
|
||||
CursorKind::NsResize => structs::NS_STYLE_CURSOR_NS_RESIZE,
|
||||
CursorKind::NeswResize => structs::NS_STYLE_CURSOR_NESW_RESIZE,
|
||||
CursorKind::NwseResize => structs::NS_STYLE_CURSOR_NWSE_RESIZE,
|
||||
CursorKind::ColResize => structs::NS_STYLE_CURSOR_COL_RESIZE,
|
||||
CursorKind::RowResize => structs::NS_STYLE_CURSOR_ROW_RESIZE,
|
||||
CursorKind::AllScroll => structs::NS_STYLE_CURSOR_ALL_SCROLL,
|
||||
CursorKind::ZoomIn => structs::NS_STYLE_CURSOR_ZOOM_IN,
|
||||
CursorKind::ZoomOut => structs::NS_STYLE_CURSOR_ZOOM_OUT,
|
||||
// note: the following properties are gecko-only.
|
||||
CursorKind::MozGrab => structs::NS_STYLE_CURSOR_GRAB,
|
||||
CursorKind::MozGrabbing => structs::NS_STYLE_CURSOR_GRABBING,
|
||||
CursorKind::MozZoomIn => structs::NS_STYLE_CURSOR_ZOOM_IN,
|
||||
CursorKind::MozZoomOut => structs::NS_STYLE_CURSOR_ZOOM_OUT,
|
||||
} as u8;
|
||||
|
||||
self.gecko.mCursor = v.keyword;
|
||||
unsafe {
|
||||
Gecko_SetCursorArrayLength(&mut self.gecko, v.images.len());
|
||||
}
|
||||
|
@ -5246,47 +5201,8 @@ clip-path
|
|||
pub fn clone_cursor(&self) -> longhands::cursor::computed_value::T {
|
||||
use crate::values::computed::ui::CursorImage;
|
||||
use crate::values::computed::url::ComputedImageUrl;
|
||||
use style_traits::cursor::CursorKind;
|
||||
|
||||
let keyword = match self.gecko.mCursor as u32 {
|
||||
structs::NS_STYLE_CURSOR_AUTO => CursorKind::Auto,
|
||||
structs::NS_STYLE_CURSOR_NONE => CursorKind::None,
|
||||
structs::NS_STYLE_CURSOR_DEFAULT => CursorKind::Default,
|
||||
structs::NS_STYLE_CURSOR_POINTER => CursorKind::Pointer,
|
||||
structs::NS_STYLE_CURSOR_CONTEXT_MENU => CursorKind::ContextMenu,
|
||||
structs::NS_STYLE_CURSOR_HELP => CursorKind::Help,
|
||||
structs::NS_STYLE_CURSOR_SPINNING => CursorKind::Progress,
|
||||
structs::NS_STYLE_CURSOR_WAIT => CursorKind::Wait,
|
||||
structs::NS_STYLE_CURSOR_CELL => CursorKind::Cell,
|
||||
structs::NS_STYLE_CURSOR_CROSSHAIR => CursorKind::Crosshair,
|
||||
structs::NS_STYLE_CURSOR_TEXT => CursorKind::Text,
|
||||
structs::NS_STYLE_CURSOR_VERTICAL_TEXT => CursorKind::VerticalText,
|
||||
structs::NS_STYLE_CURSOR_ALIAS => CursorKind::Alias,
|
||||
structs::NS_STYLE_CURSOR_COPY => CursorKind::Copy,
|
||||
structs::NS_STYLE_CURSOR_MOVE => CursorKind::Move,
|
||||
structs::NS_STYLE_CURSOR_NO_DROP => CursorKind::NoDrop,
|
||||
structs::NS_STYLE_CURSOR_NOT_ALLOWED => CursorKind::NotAllowed,
|
||||
structs::NS_STYLE_CURSOR_GRAB => CursorKind::Grab,
|
||||
structs::NS_STYLE_CURSOR_GRABBING => CursorKind::Grabbing,
|
||||
structs::NS_STYLE_CURSOR_E_RESIZE => CursorKind::EResize,
|
||||
structs::NS_STYLE_CURSOR_N_RESIZE => CursorKind::NResize,
|
||||
structs::NS_STYLE_CURSOR_NE_RESIZE => CursorKind::NeResize,
|
||||
structs::NS_STYLE_CURSOR_NW_RESIZE => CursorKind::NwResize,
|
||||
structs::NS_STYLE_CURSOR_S_RESIZE => CursorKind::SResize,
|
||||
structs::NS_STYLE_CURSOR_SE_RESIZE => CursorKind::SeResize,
|
||||
structs::NS_STYLE_CURSOR_SW_RESIZE => CursorKind::SwResize,
|
||||
structs::NS_STYLE_CURSOR_W_RESIZE => CursorKind::WResize,
|
||||
structs::NS_STYLE_CURSOR_EW_RESIZE => CursorKind::EwResize,
|
||||
structs::NS_STYLE_CURSOR_NS_RESIZE => CursorKind::NsResize,
|
||||
structs::NS_STYLE_CURSOR_NESW_RESIZE => CursorKind::NeswResize,
|
||||
structs::NS_STYLE_CURSOR_NWSE_RESIZE => CursorKind::NwseResize,
|
||||
structs::NS_STYLE_CURSOR_COL_RESIZE => CursorKind::ColResize,
|
||||
structs::NS_STYLE_CURSOR_ROW_RESIZE => CursorKind::RowResize,
|
||||
structs::NS_STYLE_CURSOR_ALL_SCROLL => CursorKind::AllScroll,
|
||||
structs::NS_STYLE_CURSOR_ZOOM_IN => CursorKind::ZoomIn,
|
||||
structs::NS_STYLE_CURSOR_ZOOM_OUT => CursorKind::ZoomOut,
|
||||
_ => panic!("Found unexpected value in style struct for cursor property"),
|
||||
};
|
||||
let keyword = self.gecko.mCursor;
|
||||
|
||||
let images = self.gecko.mCursorImages.iter().map(|gecko_cursor_image| {
|
||||
let url = unsafe {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%!
|
||||
from data import Keyword, to_rust_ident, to_camel_case
|
||||
from data import LOGICAL_SIDES, PHYSICAL_SIDES, LOGICAL_SIZES, SYSTEM_FONT_LONGHANDS
|
||||
from data import Keyword, to_rust_ident, to_camel_case, SYSTEM_FONT_LONGHANDS
|
||||
from data import LOGICAL_CORNERS, PHYSICAL_CORNERS, LOGICAL_SIDES, PHYSICAL_SIDES, LOGICAL_SIZES
|
||||
%>
|
||||
|
||||
<%def name="predefined_type(name, type, initial_value, parse_method='parse',
|
||||
|
@ -842,12 +842,16 @@
|
|||
<%
|
||||
side = None
|
||||
size = None
|
||||
corner = None
|
||||
maybe_side = [s for s in LOGICAL_SIDES if s in name]
|
||||
maybe_size = [s for s in LOGICAL_SIZES if s in name]
|
||||
maybe_corner = [s for s in LOGICAL_CORNERS if s in name]
|
||||
if len(maybe_side) == 1:
|
||||
side = maybe_side[0]
|
||||
elif len(maybe_size) == 1:
|
||||
size = maybe_size[0]
|
||||
elif len(maybe_corner) == 1:
|
||||
corner = maybe_corner[0]
|
||||
def phys_ident(side, phy_side):
|
||||
return to_rust_ident(name.replace(side, phy_side).replace("inset-", ""))
|
||||
%>
|
||||
|
@ -860,6 +864,15 @@
|
|||
}
|
||||
% endfor
|
||||
}
|
||||
% elif corner is not None:
|
||||
use crate::logical_geometry::PhysicalCorner;
|
||||
match wm.${to_rust_ident(corner)}_physical_corner() {
|
||||
% for phy_corner in PHYSICAL_CORNERS:
|
||||
PhysicalCorner::${to_camel_case(phy_corner)} => {
|
||||
${caller.inner(physical_ident=phys_ident(corner, phy_corner))}
|
||||
}
|
||||
% endfor
|
||||
}
|
||||
% elif size is not None:
|
||||
<%
|
||||
# (horizontal, vertical)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
<%namespace name="helpers" file="/helpers.mako.rs" />
|
||||
<% from data import Keyword, Method, PHYSICAL_SIDES, ALL_SIDES, maybe_moz_logical_alias %>
|
||||
<% from data import Keyword, Method, ALL_CORNERS, PHYSICAL_SIDES, ALL_SIDES, maybe_moz_logical_alias %>
|
||||
|
||||
<% data.new_style_struct("Border", inherited=False,
|
||||
additional_methods=[Method("border_" + side + "_has_nonzero_width",
|
||||
|
@ -70,17 +70,27 @@ ${helpers.gecko_keyword_conversion(
|
|||
)}
|
||||
|
||||
// FIXME(#4126): when gfx supports painting it, make this Size2D<LengthPercentage>
|
||||
% for corner in ["top-left", "top-right", "bottom-right", "bottom-left"]:
|
||||
% for corner in ALL_CORNERS:
|
||||
<%
|
||||
corner_name = corner[0]
|
||||
is_logical = corner[1]
|
||||
if is_logical:
|
||||
prefixes = None
|
||||
else:
|
||||
prefixes = "webkit"
|
||||
%>
|
||||
${helpers.predefined_type(
|
||||
"border-" + corner + "-radius",
|
||||
"border-%s-radius" % corner_name,
|
||||
"BorderCornerRadius",
|
||||
"computed::BorderCornerRadius::zero()",
|
||||
"parse",
|
||||
extra_prefixes="webkit",
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#border-%s-radius" % corner,
|
||||
extra_prefixes=prefixes,
|
||||
spec=maybe_logical_spec(corner, "radius"),
|
||||
boxed=True,
|
||||
flags="APPLIES_TO_FIRST_LETTER",
|
||||
animation_value_type="BorderCornerRadius",
|
||||
logical_group="border-radius",
|
||||
logical=is_logical,
|
||||
)}
|
||||
% endfor
|
||||
|
||||
|
|
|
@ -355,3 +355,95 @@ pub fn parse_border<'i, 't>(
|
|||
}
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
|
||||
% for axis in ["block", "inline"]:
|
||||
% for prop in ["width", "style", "color"]:
|
||||
<%
|
||||
spec = "https://drafts.csswg.org/css-logical/#propdef-border-%s-%s" % (axis, prop)
|
||||
%>
|
||||
<%helpers:shorthand
|
||||
name="border-${axis}-${prop}"
|
||||
sub_properties="${' '.join(
|
||||
'border-%s-%s-%s' % (axis, side, prop)
|
||||
for side in ['start', 'end']
|
||||
)}"
|
||||
spec="${spec}">
|
||||
|
||||
use crate::properties::longhands::border_${axis}_start_${prop};
|
||||
pub fn parse_value<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Longhands, ParseError<'i>> {
|
||||
let start_value = border_${axis}_start_${prop}::parse(context, input)?;
|
||||
let end_value =
|
||||
input.try(|input| border_${axis}_start_${prop}::parse(context, input))
|
||||
.unwrap_or_else(|_| start_value.clone());
|
||||
|
||||
Ok(expanded! {
|
||||
border_${axis}_start_${prop}: start_value,
|
||||
border_${axis}_end_${prop}: end_value,
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||
self.border_${axis}_start_${prop}.to_css(dest)?;
|
||||
|
||||
if self.border_${axis}_end_${prop} != self.border_${axis}_start_${prop} {
|
||||
dest.write_str(" ")?;
|
||||
self.border_${axis}_end_${prop}.to_css(dest)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
% endfor
|
||||
% endfor
|
||||
|
||||
% for axis in ["block", "inline"]:
|
||||
<%
|
||||
spec = "https://drafts.csswg.org/css-logical/#propdef-border-%s" % (axis)
|
||||
%>
|
||||
<%helpers:shorthand
|
||||
name="border-${axis}"
|
||||
sub_properties="${' '.join(
|
||||
'border-%s-%s-width' % (axis, side)
|
||||
for side in ['start', 'end']
|
||||
)} ${' '.join(
|
||||
'border-%s-%s-style' % (axis, side)
|
||||
for side in ['start', 'end']
|
||||
)} ${' '.join(
|
||||
'border-%s-%s-color' % (axis, side)
|
||||
for side in ['start', 'end']
|
||||
)}"
|
||||
spec="${spec}">
|
||||
|
||||
use crate::properties::shorthands::border_${axis}_start;
|
||||
pub fn parse_value<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Longhands, ParseError<'i>> {
|
||||
let start_value = border_${axis}_start::parse_value(context, input)?;
|
||||
Ok(expanded! {
|
||||
border_${axis}_start_width: start_value.border_${axis}_start_width.clone(),
|
||||
border_${axis}_end_width: start_value.border_${axis}_start_width,
|
||||
border_${axis}_start_style: start_value.border_${axis}_start_style.clone(),
|
||||
border_${axis}_end_style: start_value.border_${axis}_start_style,
|
||||
border_${axis}_start_color: start_value.border_${axis}_start_color.clone(),
|
||||
border_${axis}_end_color: start_value.border_${axis}_start_color,
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||
super::serialize_directional_border(
|
||||
dest,
|
||||
self.border_${axis}_start_width,
|
||||
self.border_${axis}_start_style,
|
||||
self.border_${axis}_start_color
|
||||
)
|
||||
}
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
% endfor
|
||||
|
|
|
@ -8,3 +8,47 @@ ${helpers.four_sides_shorthand("margin", "margin-%s", "specified::LengthPercenta
|
|||
spec="https://drafts.csswg.org/css-box/#propdef-margin",
|
||||
allowed_in_page_rule=True,
|
||||
allow_quirks=True)}
|
||||
|
||||
% for axis in ["block", "inline"]:
|
||||
<%
|
||||
spec = "https://drafts.csswg.org/css-logical/#propdef-margin-%s" % axis
|
||||
%>
|
||||
<%helpers:shorthand
|
||||
name="margin-${axis}"
|
||||
sub_properties="${' '.join(
|
||||
'margin-%s-%s' % (axis, side)
|
||||
for side in ['start', 'end']
|
||||
)}"
|
||||
spec="${spec}">
|
||||
|
||||
use crate::parser::Parse;
|
||||
use crate::values::specified::length::LengthPercentageOrAuto;
|
||||
pub fn parse_value<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Longhands, ParseError<'i>> {
|
||||
let start_value = LengthPercentageOrAuto::parse(context, input)?;
|
||||
let end_value =
|
||||
input.try(|input| LengthPercentageOrAuto::parse(context, input))
|
||||
.unwrap_or_else(|_| start_value.clone());
|
||||
|
||||
Ok(expanded! {
|
||||
margin_${axis}_start: start_value,
|
||||
margin_${axis}_end: end_value,
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||
self.margin_${axis}_start.to_css(dest)?;
|
||||
|
||||
if self.margin_${axis}_end != self.margin_${axis}_start {
|
||||
dest.write_str(" ")?;
|
||||
self.margin_${axis}_end.to_css(dest)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
% endfor
|
||||
|
|
|
@ -7,3 +7,47 @@
|
|||
${helpers.four_sides_shorthand("padding", "padding-%s", "specified::NonNegativeLengthPercentage::parse",
|
||||
spec="https://drafts.csswg.org/css-box-3/#propdef-padding",
|
||||
allow_quirks=True)}
|
||||
|
||||
% for axis in ["block", "inline"]:
|
||||
<%
|
||||
spec = "https://drafts.csswg.org/css-logical/#propdef-padding-%s" % axis
|
||||
%>
|
||||
<%helpers:shorthand
|
||||
name="padding-${axis}"
|
||||
sub_properties="${' '.join(
|
||||
'padding-%s-%s' % (axis, side)
|
||||
for side in ['start', 'end']
|
||||
)}"
|
||||
spec="${spec}">
|
||||
|
||||
use crate::parser::Parse;
|
||||
use crate::values::specified::length::NonNegativeLengthPercentage;
|
||||
pub fn parse_value<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Longhands, ParseError<'i>> {
|
||||
let start_value = NonNegativeLengthPercentage::parse(context, input)?;
|
||||
let end_value =
|
||||
input.try(|input| NonNegativeLengthPercentage::parse(context, input))
|
||||
.unwrap_or_else(|_| start_value.clone());
|
||||
|
||||
Ok(expanded! {
|
||||
padding_${axis}_start: start_value,
|
||||
padding_${axis}_end: end_value,
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||
self.padding_${axis}_start.to_css(dest)?;
|
||||
|
||||
if self.padding_${axis}_end != self.padding_${axis}_start {
|
||||
dest.write_str(" ")?;
|
||||
self.padding_${axis}_end.to_css(dest)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
% endfor
|
||||
|
|
|
@ -762,3 +762,47 @@
|
|||
}
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
|
||||
% for axis in ["block", "inline"]:
|
||||
<%
|
||||
spec = "https://drafts.csswg.org/css-logical/#propdef-inset-%s" % axis
|
||||
%>
|
||||
<%helpers:shorthand
|
||||
name="inset-${axis}"
|
||||
sub_properties="${' '.join(
|
||||
'inset-%s-%s' % (axis, side)
|
||||
for side in ['start', 'end']
|
||||
)}"
|
||||
spec="${spec}">
|
||||
|
||||
use crate::parser::Parse;
|
||||
use crate::values::specified::length::LengthPercentageOrAuto;
|
||||
pub fn parse_value<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Longhands, ParseError<'i>> {
|
||||
let start_value = LengthPercentageOrAuto::parse(context, input)?;
|
||||
let end_value =
|
||||
input.try(|input| LengthPercentageOrAuto::parse(context, input))
|
||||
.unwrap_or_else(|_| start_value.clone());
|
||||
|
||||
Ok(expanded! {
|
||||
inset_${axis}_start: start_value,
|
||||
inset_${axis}_end: end_value,
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||
self.inset_${axis}_start.to_css(dest)?;
|
||||
|
||||
if self.inset_${axis}_end != self.inset_${axis}_start {
|
||||
dest.write_str(" ")?;
|
||||
self.inset_${axis}_end.to_css(dest)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
</%helpers:shorthand>
|
||||
% endfor
|
||||
|
|
|
@ -26,10 +26,10 @@ impl Animate for LengthPercentage {
|
|||
let length = self
|
||||
.unclamped_length()
|
||||
.animate(&other.unclamped_length(), procedure)?;
|
||||
let percentage = animate_percentage_half(self.percentage, other.percentage)?;
|
||||
let is_calc = self.was_calc ||
|
||||
other.was_calc ||
|
||||
self.percentage.is_some() != other.percentage.is_some();
|
||||
let percentage =
|
||||
animate_percentage_half(self.specified_percentage(), other.specified_percentage())?;
|
||||
let is_calc =
|
||||
self.was_calc || other.was_calc || self.has_percentage != other.has_percentage;
|
||||
Ok(Self::with_clamping_mode(
|
||||
length,
|
||||
percentage,
|
||||
|
|
|
@ -32,7 +32,7 @@ fn to_number_or_percentage(
|
|||
value: &SvgLengthPercentageOrNumber<LengthPercentage, Number>,
|
||||
) -> Result<NumberOrPercentage, ()> {
|
||||
Ok(match *value {
|
||||
SvgLengthPercentageOrNumber::LengthPercentage(ref l) => match l.percentage {
|
||||
SvgLengthPercentageOrNumber::LengthPercentage(ref l) => match l.specified_percentage() {
|
||||
Some(p) => {
|
||||
if l.unclamped_length().px() != 0. {
|
||||
return Err(());
|
||||
|
|
|
@ -77,7 +77,10 @@ pub struct LengthPercentage {
|
|||
#[animation(constant)]
|
||||
pub clamping_mode: AllowedNumericType,
|
||||
length: Length,
|
||||
pub percentage: Option<Percentage>,
|
||||
percentage: Percentage,
|
||||
/// Whether we specified a percentage or not.
|
||||
#[animation(constant)]
|
||||
pub has_percentage: bool,
|
||||
/// Whether this was from a calc() expression. This is needed because right
|
||||
/// now we don't treat calc() the same way as non-calc everywhere, but
|
||||
/// that's a bug in most cases.
|
||||
|
@ -99,7 +102,9 @@ pub struct LengthPercentage {
|
|||
// like calc(0px + 5%) and such.
|
||||
impl PartialEq for LengthPercentage {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.length == other.length && self.percentage == other.percentage
|
||||
self.length == other.length &&
|
||||
self.percentage == other.percentage &&
|
||||
self.has_percentage == other.has_percentage
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,8 +116,8 @@ impl ComputeSquaredDistance for LengthPercentage {
|
|||
Ok(self
|
||||
.unclamped_length()
|
||||
.compute_squared_distance(&other.unclamped_length())? +
|
||||
self.percentage()
|
||||
.compute_squared_distance(&other.percentage())?)
|
||||
self.percentage
|
||||
.compute_squared_distance(&other.percentage)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,7 +149,8 @@ impl LengthPercentage {
|
|||
Self {
|
||||
clamping_mode,
|
||||
length,
|
||||
percentage,
|
||||
percentage: percentage.unwrap_or_default(),
|
||||
has_percentage: percentage.is_some(),
|
||||
was_calc,
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +160,7 @@ impl LengthPercentage {
|
|||
/// Panics in debug mode if a percentage is present in the expression.
|
||||
#[inline]
|
||||
pub fn length(&self) -> CSSPixelLength {
|
||||
debug_assert!(self.percentage.is_none());
|
||||
debug_assert!(!self.has_percentage);
|
||||
self.length_component()
|
||||
}
|
||||
|
||||
|
@ -173,22 +179,32 @@ impl LengthPercentage {
|
|||
/// Return the percentage value as CSSFloat.
|
||||
#[inline]
|
||||
pub fn percentage(&self) -> CSSFloat {
|
||||
self.percentage.map_or(0., |p| p.0)
|
||||
self.percentage.0
|
||||
}
|
||||
|
||||
/// Return the specified percentage if any.
|
||||
#[inline]
|
||||
pub fn specified_percentage(&self) -> Option<Percentage> {
|
||||
if self.has_percentage {
|
||||
Some(self.percentage)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the percentage component if this could be represented as a
|
||||
/// non-calc percentage.
|
||||
pub fn as_percentage(&self) -> Option<Percentage> {
|
||||
if self.length.px() != 0. {
|
||||
if !self.has_percentage || self.length.px() != 0. {
|
||||
return None;
|
||||
}
|
||||
|
||||
let p = self.percentage?;
|
||||
if self.clamping_mode.clamp(p.0) != p.0 {
|
||||
if self.clamping_mode.clamp(self.percentage.0) != self.percentage.0 {
|
||||
debug_assert!(self.was_calc);
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(p)
|
||||
Some(self.percentage)
|
||||
}
|
||||
|
||||
/// Convert the computed value into used value.
|
||||
|
@ -201,14 +217,12 @@ impl LengthPercentage {
|
|||
/// the height property), they apply whenever a calc() expression contains
|
||||
/// percentages.
|
||||
pub fn maybe_to_pixel_length(&self, container_len: Option<Au>) -> Option<Length> {
|
||||
match (container_len, self.percentage) {
|
||||
(Some(len), Some(percent)) => {
|
||||
let pixel = self.length.px() + len.scale_by(percent.0).to_f32_px();
|
||||
Some(Length::new(self.clamping_mode.clamp(pixel)))
|
||||
},
|
||||
(_, None) => Some(self.length()),
|
||||
_ => None,
|
||||
if self.has_percentage {
|
||||
let length = self.unclamped_length().px() +
|
||||
container_len?.scale_by(self.percentage.0).to_f32_px();
|
||||
return Some(Length::new(self.clamping_mode.clamp(length)));
|
||||
}
|
||||
Some(self.length())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,12 +276,12 @@ impl specified::CalcLengthPercentage {
|
|||
}
|
||||
}
|
||||
|
||||
LengthPercentage {
|
||||
clamping_mode: self.clamping_mode,
|
||||
length: Length::new(length.min(f32::MAX).max(f32::MIN)),
|
||||
percentage: self.percentage,
|
||||
was_calc: true,
|
||||
}
|
||||
LengthPercentage::with_clamping_mode(
|
||||
Length::new(length.min(f32::MAX).max(f32::MIN)),
|
||||
self.percentage,
|
||||
self.clamping_mode,
|
||||
/* was_calc = */ true,
|
||||
)
|
||||
}
|
||||
|
||||
/// Compute font-size or line-height taking into account text-zoom if necessary.
|
||||
|
@ -322,7 +336,7 @@ impl ToComputedValue for specified::CalcLengthPercentage {
|
|||
specified::CalcLengthPercentage {
|
||||
clamping_mode: computed.clamping_mode,
|
||||
absolute: Some(AbsoluteLength::from_computed_value(&computed.length)),
|
||||
percentage: computed.percentage,
|
||||
percentage: computed.specified_percentage(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -344,7 +358,7 @@ impl LengthPercentage {
|
|||
/// Returns true if the computed value is absolute 0 or 0%.
|
||||
#[inline]
|
||||
pub fn is_definitely_zero(&self) -> bool {
|
||||
self.unclamped_length().px() == 0.0 && self.percentage.map_or(true, |p| p.0 == 0.0)
|
||||
self.unclamped_length().px() == 0.0 && self.percentage.0 == 0.0
|
||||
}
|
||||
|
||||
// CSSFloat doesn't implement Hash, so does CSSPixelLength. Therefore, we still use Au as the
|
||||
|
@ -353,7 +367,7 @@ impl LengthPercentage {
|
|||
pub fn to_hash_key(&self) -> (Au, NotNan<f32>) {
|
||||
(
|
||||
Au::from(self.unclamped_length()),
|
||||
NotNan::new(self.percentage()).unwrap(),
|
||||
NotNan::new(self.percentage.0).unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -376,14 +390,14 @@ impl LengthPercentage {
|
|||
if self.was_calc {
|
||||
return Self::with_clamping_mode(
|
||||
self.length,
|
||||
self.percentage,
|
||||
self.specified_percentage(),
|
||||
AllowedNumericType::NonNegative,
|
||||
self.was_calc,
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(self.percentage.is_none() || self.unclamped_length() == Length::zero());
|
||||
if let Some(p) = self.percentage {
|
||||
debug_assert!(!self.has_percentage || self.unclamped_length() == Length::zero());
|
||||
if let Some(p) = self.specified_percentage() {
|
||||
return Self::with_clamping_mode(
|
||||
Length::zero(),
|
||||
Some(p.clamp_to_non_negative()),
|
||||
|
@ -420,8 +434,7 @@ impl ToComputedValue for specified::LengthPercentage {
|
|||
return specified::LengthPercentage::Percentage(p);
|
||||
}
|
||||
|
||||
let percentage = computed.percentage;
|
||||
if percentage.is_none() && computed.clamping_mode.clamp(length.px()) == length.px() {
|
||||
if !computed.has_percentage && computed.clamping_mode.clamp(length.px()) == length.px() {
|
||||
return specified::LengthPercentage::Length(ToComputedValue::from_computed_value(
|
||||
&length,
|
||||
));
|
||||
|
|
|
@ -28,7 +28,6 @@ use std::cell::RefCell;
|
|||
use std::cmp;
|
||||
use std::f32;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::cursor::CursorKind;
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -452,7 +451,6 @@ trivial_to_computed_value!(u8);
|
|||
trivial_to_computed_value!(u16);
|
||||
trivial_to_computed_value!(u32);
|
||||
trivial_to_computed_value!(Atom);
|
||||
trivial_to_computed_value!(CursorKind);
|
||||
#[cfg(feature = "servo")]
|
||||
trivial_to_computed_value!(Prefix);
|
||||
trivial_to_computed_value!(String);
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::values::computed::Number;
|
|||
use crate::values::generics::ui as generics;
|
||||
use crate::values::{Auto, Either};
|
||||
|
||||
pub use crate::values::specified::ui::CursorKind;
|
||||
pub use crate::values::specified::ui::{MozForceBrokenImageIcon, UserSelect};
|
||||
|
||||
/// auto | <color>
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
//! Generic values for UI properties.
|
||||
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::cursor::CursorKind;
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
use values::specified::ui::CursorKind;
|
||||
|
||||
/// A generic value for the `cursor` property.
|
||||
///
|
||||
|
|
|
@ -12,7 +12,6 @@ use crate::values::specified::Number;
|
|||
use crate::values::{Auto, Either};
|
||||
use cssparser::Parser;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::cursor::CursorKind;
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
|
||||
/// auto | <color>
|
||||
|
@ -40,23 +39,11 @@ impl Parse for Cursor {
|
|||
}
|
||||
Ok(Self {
|
||||
images: images.into_boxed_slice(),
|
||||
keyword: CursorKind::parse(context, input)?,
|
||||
keyword: CursorKind::parse(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for CursorImage {
|
||||
fn parse<'i, 't>(
|
||||
context: &ParserContext,
|
||||
|
@ -166,3 +153,68 @@ pub enum UserSelect {
|
|||
/// Force selection of all children.
|
||||
All,
|
||||
}
|
||||
|
||||
/// The keywords allowed in the Cursor property.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-ui-4/#propdef-cursor
|
||||
#[allow(missing_docs)]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
FromPrimitive,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
pub enum CursorKind {
|
||||
None,
|
||||
Default,
|
||||
Pointer,
|
||||
ContextMenu,
|
||||
Help,
|
||||
Progress,
|
||||
Wait,
|
||||
Cell,
|
||||
Crosshair,
|
||||
Text,
|
||||
VerticalText,
|
||||
Alias,
|
||||
Copy,
|
||||
Move,
|
||||
NoDrop,
|
||||
NotAllowed,
|
||||
Grab,
|
||||
Grabbing,
|
||||
EResize,
|
||||
NResize,
|
||||
NeResize,
|
||||
NwResize,
|
||||
SResize,
|
||||
SeResize,
|
||||
SwResize,
|
||||
WResize,
|
||||
EwResize,
|
||||
NsResize,
|
||||
NeswResize,
|
||||
NwseResize,
|
||||
ColResize,
|
||||
RowResize,
|
||||
AllScroll,
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
Auto,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozGrab,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozGrabbing,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozZoomIn,
|
||||
#[cfg(feature = "gecko")]
|
||||
MozZoomOut,
|
||||
}
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//! A list of common mouse cursors per CSS3-UI § 8.1.1.
|
||||
|
||||
use super::{CssWriter, KeywordsCollectFn, SpecifiedValueInfo, ToCss};
|
||||
|
||||
macro_rules! define_cursor {
|
||||
(
|
||||
common properties = [
|
||||
$( $c_css: expr => $c_variant: ident = $c_value: expr, )+
|
||||
]
|
||||
gecko properties = [
|
||||
$( $g_css: expr => $g_variant: ident = $g_value: expr, )+
|
||||
]
|
||||
) => {
|
||||
/// <https://drafts.csswg.org/css-ui/#cursor>
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
|
||||
#[repr(u8)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum CursorKind {
|
||||
$( $c_variant = $c_value, )+
|
||||
$( #[cfg(feature = "gecko")] $g_variant = $g_value, )+
|
||||
}
|
||||
|
||||
impl CursorKind {
|
||||
/// Given a CSS keyword, get the corresponding cursor enum.
|
||||
pub fn from_css_keyword(keyword: &str) -> Result<Self, ()> {
|
||||
match_ignore_ascii_case! { &keyword,
|
||||
$( $c_css => Ok(CursorKind::$c_variant), )+
|
||||
$( #[cfg(feature = "gecko")] $g_css => Ok(CursorKind::$g_variant), )+
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
/// From the C u8 value, get the corresponding Cursor enum.
|
||||
pub fn from_u8(value: u8) -> Result<Self, ()> {
|
||||
match value {
|
||||
$( $c_value => Ok(CursorKind::$c_variant), )+
|
||||
$( #[cfg(feature = "gecko")] $g_value => Ok(CursorKind::$g_variant), )+
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for CursorKind {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> ::std::fmt::Result where W: ::std::fmt::Write {
|
||||
match *self {
|
||||
$(CursorKind::$c_variant => {
|
||||
::std::fmt::Write::write_str(dest, $c_css)
|
||||
})+
|
||||
$(#[cfg(feature = "gecko")] CursorKind::$g_variant => {
|
||||
::std::fmt::Write::write_str(dest, $g_css)
|
||||
})+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecifiedValueInfo for CursorKind {
|
||||
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
||||
f(&[
|
||||
$($c_css,)+
|
||||
$($g_css,)+
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_cursor! {
|
||||
common properties = [
|
||||
"none" => None = 0,
|
||||
"default" => Default = 1,
|
||||
"pointer" => Pointer = 2,
|
||||
"context-menu" => ContextMenu = 3,
|
||||
"help" => Help = 4,
|
||||
"progress" => Progress = 5,
|
||||
"wait" => Wait = 6,
|
||||
"cell" => Cell = 7,
|
||||
"crosshair" => Crosshair = 8,
|
||||
"text" => Text = 9,
|
||||
"vertical-text" => VerticalText = 10,
|
||||
"alias" => Alias = 11,
|
||||
"copy" => Copy = 12,
|
||||
"move" => Move = 13,
|
||||
"no-drop" => NoDrop = 14,
|
||||
"not-allowed" => NotAllowed = 15,
|
||||
"grab" => Grab = 16,
|
||||
"grabbing" => Grabbing = 17,
|
||||
"e-resize" => EResize = 18,
|
||||
"n-resize" => NResize = 19,
|
||||
"ne-resize" => NeResize = 20,
|
||||
"nw-resize" => NwResize = 21,
|
||||
"s-resize" => SResize = 22,
|
||||
"se-resize" => SeResize = 23,
|
||||
"sw-resize" => SwResize = 24,
|
||||
"w-resize" => WResize = 25,
|
||||
"ew-resize" => EwResize = 26,
|
||||
"ns-resize" => NsResize = 27,
|
||||
"nesw-resize" => NeswResize = 28,
|
||||
"nwse-resize" => NwseResize = 29,
|
||||
"col-resize" => ColResize = 30,
|
||||
"row-resize" => RowResize = 31,
|
||||
"all-scroll" => AllScroll = 32,
|
||||
"zoom-in" => ZoomIn = 33,
|
||||
"zoom-out" => ZoomOut = 34,
|
||||
"auto" => Auto = 35,
|
||||
]
|
||||
// gecko only properties
|
||||
gecko properties = [
|
||||
"-moz-grab" => MozGrab = 36,
|
||||
"-moz-grabbing" => MozGrabbing = 37,
|
||||
"-moz-zoom-in" => MozZoomIn = 38,
|
||||
"-moz-zoom-out" => MozZoomOut = 39,
|
||||
]
|
||||
}
|
|
@ -81,7 +81,6 @@ pub enum CSSPixel {}
|
|||
// / hidpi_ratio => DeviceIndependentPixel
|
||||
// / desktop_zoom => CSSPixel
|
||||
|
||||
pub mod cursor;
|
||||
pub mod specified_value_info;
|
||||
#[macro_use]
|
||||
pub mod values;
|
||||
|
|
|
@ -10,12 +10,11 @@ use glutin::{Api, ContextBuilder, GlContext, GlRequest, GlWindow};
|
|||
use keyboard_types::{Key, KeyboardEvent, KeyState};
|
||||
use servo::compositing::windowing::{AnimationState, MouseWindowEvent, WindowEvent};
|
||||
use servo::compositing::windowing::{EmbedderCoordinates, WindowMethods};
|
||||
use servo::embedder_traits::EventLoopWaker;
|
||||
use servo::embedder_traits::{Cursor, EventLoopWaker};
|
||||
use servo::script_traits::TouchEventType;
|
||||
use servo::servo_config::opts;
|
||||
use servo::servo_geometry::DeviceIndependentPixel;
|
||||
use servo::style_traits::DevicePixel;
|
||||
use servo::style_traits::cursor::CursorKind;
|
||||
use servo::webrender_api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, ScrollLocation};
|
||||
use std::cell::{Cell, RefCell};
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
|
@ -617,47 +616,46 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_cursor(&self, cursor: CursorKind) {
|
||||
pub fn set_cursor(&self, cursor: Cursor) {
|
||||
match self.kind {
|
||||
WindowKind::Window(ref window, ..) => {
|
||||
use winit::MouseCursor;
|
||||
|
||||
let winit_cursor = match cursor {
|
||||
CursorKind::Auto => MouseCursor::Default,
|
||||
CursorKind::Default => MouseCursor::Default,
|
||||
CursorKind::Pointer => MouseCursor::Hand,
|
||||
CursorKind::ContextMenu => MouseCursor::ContextMenu,
|
||||
CursorKind::Help => MouseCursor::Help,
|
||||
CursorKind::Progress => MouseCursor::Progress,
|
||||
CursorKind::Wait => MouseCursor::Wait,
|
||||
CursorKind::Cell => MouseCursor::Cell,
|
||||
CursorKind::Crosshair => MouseCursor::Crosshair,
|
||||
CursorKind::Text => MouseCursor::Text,
|
||||
CursorKind::VerticalText => MouseCursor::VerticalText,
|
||||
CursorKind::Alias => MouseCursor::Alias,
|
||||
CursorKind::Copy => MouseCursor::Copy,
|
||||
CursorKind::Move => MouseCursor::Move,
|
||||
CursorKind::NoDrop => MouseCursor::NoDrop,
|
||||
CursorKind::NotAllowed => MouseCursor::NotAllowed,
|
||||
CursorKind::Grab => MouseCursor::Grab,
|
||||
CursorKind::Grabbing => MouseCursor::Grabbing,
|
||||
CursorKind::EResize => MouseCursor::EResize,
|
||||
CursorKind::NResize => MouseCursor::NResize,
|
||||
CursorKind::NeResize => MouseCursor::NeResize,
|
||||
CursorKind::NwResize => MouseCursor::NwResize,
|
||||
CursorKind::SResize => MouseCursor::SResize,
|
||||
CursorKind::SeResize => MouseCursor::SeResize,
|
||||
CursorKind::SwResize => MouseCursor::SwResize,
|
||||
CursorKind::WResize => MouseCursor::WResize,
|
||||
CursorKind::EwResize => MouseCursor::EwResize,
|
||||
CursorKind::NsResize => MouseCursor::NsResize,
|
||||
CursorKind::NeswResize => MouseCursor::NeswResize,
|
||||
CursorKind::NwseResize => MouseCursor::NwseResize,
|
||||
CursorKind::ColResize => MouseCursor::ColResize,
|
||||
CursorKind::RowResize => MouseCursor::RowResize,
|
||||
CursorKind::AllScroll => MouseCursor::AllScroll,
|
||||
CursorKind::ZoomIn => MouseCursor::ZoomIn,
|
||||
CursorKind::ZoomOut => MouseCursor::ZoomOut,
|
||||
Cursor::Default => MouseCursor::Default,
|
||||
Cursor::Pointer => MouseCursor::Hand,
|
||||
Cursor::ContextMenu => MouseCursor::ContextMenu,
|
||||
Cursor::Help => MouseCursor::Help,
|
||||
Cursor::Progress => MouseCursor::Progress,
|
||||
Cursor::Wait => MouseCursor::Wait,
|
||||
Cursor::Cell => MouseCursor::Cell,
|
||||
Cursor::Crosshair => MouseCursor::Crosshair,
|
||||
Cursor::Text => MouseCursor::Text,
|
||||
Cursor::VerticalText => MouseCursor::VerticalText,
|
||||
Cursor::Alias => MouseCursor::Alias,
|
||||
Cursor::Copy => MouseCursor::Copy,
|
||||
Cursor::Move => MouseCursor::Move,
|
||||
Cursor::NoDrop => MouseCursor::NoDrop,
|
||||
Cursor::NotAllowed => MouseCursor::NotAllowed,
|
||||
Cursor::Grab => MouseCursor::Grab,
|
||||
Cursor::Grabbing => MouseCursor::Grabbing,
|
||||
Cursor::EResize => MouseCursor::EResize,
|
||||
Cursor::NResize => MouseCursor::NResize,
|
||||
Cursor::NeResize => MouseCursor::NeResize,
|
||||
Cursor::NwResize => MouseCursor::NwResize,
|
||||
Cursor::SResize => MouseCursor::SResize,
|
||||
Cursor::SeResize => MouseCursor::SeResize,
|
||||
Cursor::SwResize => MouseCursor::SwResize,
|
||||
Cursor::WResize => MouseCursor::WResize,
|
||||
Cursor::EwResize => MouseCursor::EwResize,
|
||||
Cursor::NsResize => MouseCursor::NsResize,
|
||||
Cursor::NeswResize => MouseCursor::NeswResize,
|
||||
Cursor::NwseResize => MouseCursor::NwseResize,
|
||||
Cursor::ColResize => MouseCursor::ColResize,
|
||||
Cursor::RowResize => MouseCursor::RowResize,
|
||||
Cursor::AllScroll => MouseCursor::AllScroll,
|
||||
Cursor::ZoomIn => MouseCursor::ZoomIn,
|
||||
Cursor::ZoomOut => MouseCursor::ZoomOut,
|
||||
_ => MouseCursor::Default,
|
||||
};
|
||||
window.set_cursor(winit_cursor);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue