aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/gfx/display_list/mod.rs27
-rw-r--r--components/layout/layout_task.rs2
-rw-r--r--components/style/properties/mod.rs.mako5
-rw-r--r--tests/html/pointer_events.html36
4 files changed, 58 insertions, 12 deletions
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 469d4121f6a..6d524a85cd2 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -39,10 +39,9 @@ use servo_util::range::Range;
use servo_util::smallvec::{SmallVec, SmallVec8};
use std::fmt;
use std::slice::Items;
-use style::ComputedValues;
-use style::computed_values::border_style;
-use style::computed_values::cursor;
use std::sync::Arc;
+use style::ComputedValues;
+use style::computed_values::{border_style, cursor, pointer_events};
// It seems cleaner to have layout code not mention Azure directly, so let's just reexport this for
// layout to use.
@@ -340,9 +339,9 @@ impl StackingContext {
tile_subrect.translate(&-child_stacking_context.bounds.to_azure_rect().origin)
}
- /// Places all nodes containing the point of interest into `result`, topmost first. If
- /// `topmost_only` is true, stops after placing one node into the list. `result` must be empty
- /// upon entry to this function.
+ /// Places all nodes containing the point of interest into `result`, topmost first. Respects
+ /// the `pointer-events` CSS property If `topmost_only` is true, stops after placing one node
+ /// into the list. `result` must be empty upon entry to this function.
pub fn hit_test(&self,
point: Point2D<Au>,
result: &mut Vec<DisplayItemMetadata>,
@@ -363,6 +362,10 @@ impl StackingContext {
// Can't possibly hit.
continue
}
+ if item.base().metadata.pointing.is_none() {
+ // `pointer-events` is `none`. Ignore this item.
+ continue
+ }
match *item {
DisplayItem::BorderClass(ref border) => {
// If the point is inside the border, it didn't hit the border!
@@ -632,8 +635,9 @@ impl ClippingRegion {
pub struct DisplayItemMetadata {
/// The DOM node from which this display item originated.
pub node: OpaqueNode,
- /// The value of the `cursor` property when the mouse hovers over this display item.
- pub cursor: Cursor,
+ /// 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`).
+ pub pointing: Option<Cursor>,
}
impl DisplayItemMetadata {
@@ -646,9 +650,10 @@ impl DisplayItemMetadata {
-> DisplayItemMetadata {
DisplayItemMetadata {
node: node,
- cursor: match style.get_pointing().cursor {
- cursor::T::AutoCursor => default_cursor,
- cursor::T::SpecifiedCursor(cursor) => cursor,
+ pointing: match (style.get_pointing().pointer_events, style.get_pointing().cursor) {
+ (pointer_events::T::none, _) => None,
+ (pointer_events::T::auto, cursor::T::AutoCursor) => Some(default_cursor),
+ (pointer_events::T::auto, cursor::T::SpecifiedCursor(cursor)) => Some(cursor),
},
}
}
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs
index 48c1bb10496..f5301c27867 100644
--- a/components/layout/layout_task.rs
+++ b/components/layout/layout_task.rs
@@ -998,7 +998,7 @@ impl LayoutRPC for LayoutRPCImpl {
// Compute the new cursor.
let cursor = if !mouse_over_list.is_empty() {
- mouse_over_list[0].cursor
+ mouse_over_list[0].pointing.unwrap()
} else {
Cursor::DefaultCursor
};
diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako
index 18c947f3dff..272b6bade4d 100644
--- a/components/style/properties/mod.rs.mako
+++ b/components/style/properties/mod.rs.mako
@@ -1543,6 +1543,11 @@ pub mod longhands {
}
</%self:single_component_value>
+ // NB: `pointer-events: auto` (and use of `pointer-events` in anything that isn't SVG, in fact)
+ // is nonstandard, slated for CSS4-UI.
+ // TODO(pcwalton): SVG-only values.
+ ${single_keyword("pointer-events", "auto none")}
+
// Box-shadow, etc.
${new_style_struct("Effects", is_inherited=False)}
diff --git a/tests/html/pointer_events.html b/tests/html/pointer_events.html
new file mode 100644
index 00000000000..dc1581f98c3
--- /dev/null
+++ b/tests/html/pointer_events.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#overlay {
+ width: 200px;
+ height: 150px;
+ background: green;
+ opacity: 0.5;
+ pointer-events: none;
+}
+
+button {
+ position: relative;
+ top: 10px;
+ width: 150px;
+ height: 50px;
+ border: solid black 2px;
+ box-sizing: border-box;
+ font: Helvetica bold;
+ font-size: 18px;
+ text-align: center;
+ background: black;
+ color: white;
+}
+</style>
+</head>
+<body>
+<button id=button>Click me!</button>
+<div id=overlay></div>
+<script>
+document.getElementById('button').addEventListener('click', function() { alert("Ouch!"); });
+</script>
+</body>
+</html>
+