Skip to content

Commit

Permalink
Implement MouseEvent's x/y and offsetX/offsetY attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
Micah Tigley committed Oct 22, 2019
1 parent 927dfd1 commit b336735
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 27 deletions.
8 changes: 8 additions & 0 deletions components/script/dom/domrect.rs
Expand Up @@ -32,6 +32,14 @@ impl DOMRect {
)
}

pub fn left(&self) -> f64 {
self.rect.Left()
}

pub fn top(&self) -> f64 {
self.rect.Top()
}

pub fn Constructor(
global: &GlobalScope,
x: f64,
Expand Down
61 changes: 61 additions & 0 deletions components/script/dom/mouseevent.rs
Expand Up @@ -2,6 +2,8 @@
* 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/. */

use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementBinding::ElementMethods;
use crate::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
use crate::dom::bindings::codegen::Bindings::MouseEventBinding;
use crate::dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods;
use crate::dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
Expand All @@ -10,6 +12,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::element::Element;
use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::eventtarget::EventTarget;
use crate::dom::uievent::UIEvent;
Expand All @@ -29,6 +32,10 @@ pub struct MouseEvent {
client_y: Cell<i32>,
page_x: Cell<i32>,
page_y: Cell<i32>,
x: Cell<i32>,
y: Cell<i32>,
offset_x: Cell<i32>,
offset_y: Cell<i32>,
ctrl_key: Cell<bool>,
shift_key: Cell<bool>,
alt_key: Cell<bool>,
Expand All @@ -49,6 +56,10 @@ impl MouseEvent {
client_y: Cell::new(0),
page_x: Cell::new(0),
page_y: Cell::new(0),
x: Cell::new(0),
y: Cell::new(0),
offset_x: Cell::new(0),
offset_y: Cell::new(0),
ctrl_key: Cell::new(false),
shift_key: Cell::new(false),
alt_key: Cell::new(false),
Expand Down Expand Up @@ -192,6 +203,56 @@ impl MouseEventMethods for MouseEvent {
}
}

// https://drafts.csswg.org/cssom-view/#dom-mouseevent-x
fn X(&self) -> i32 {
self.client_x.get()
}

// https://drafts.csswg.org/cssom-view/#dom-mouseevent-y
fn Y(&self) -> i32 {
self.client_y.get()
}

// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
fn OffsetX(&self) -> i32 {
let event = self.upcast::<Event>();
if event.dispatching() {
match event.GetTarget() {
Some(target) => {
if let Some(element) = target.downcast::<Element>() {
let rect = element.GetBoundingClientRect();
self.client_x.get() - rect.left() as i32
} else {
self.offset_x.get()
}
},
None => self.offset_x.get(),
}
} else {
self.PageX()
}
}

// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsety
fn OffsetY(&self) -> i32 {
let event = self.upcast::<Event>();
if event.dispatching() {
match event.GetTarget() {
Some(target) => {
if let Some(element) = target.downcast::<Element>() {
let rect = element.GetBoundingClientRect();
self.client_y.get() - rect.top() as i32
} else {
self.offset_y.get()
}
},
None => self.offset_y.get(),
}
} else {
self.PageY()
}
}

// https://w3c.github.io/uievents/#widl-MouseEvent-ctrlKey
fn CtrlKey(&self) -> bool {
self.ctrl_key.get()
Expand Down
4 changes: 4 additions & 0 deletions components/script/dom/webidls/MouseEvent.webidl
Expand Up @@ -12,6 +12,10 @@ interface MouseEvent : UIEvent {
readonly attribute long clientY;
readonly attribute long pageX;
readonly attribute long pageY;
readonly attribute long x;
readonly attribute long y;
readonly attribute long offsetX;
readonly attribute long offsetY;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean altKey;
Expand Down
24 changes: 0 additions & 24 deletions tests/wpt/metadata/css/cssom-view/idlharness.html.ini
Expand Up @@ -128,12 +128,6 @@
[Range interface: operation getClientRects()]
expected: FAIL

[MouseEvent interface: attribute y]
expected: FAIL

[MouseEvent interface: attribute x]
expected: FAIL

[Element interface: calling scrollIntoView([object Object\],[object Object\]) on document.createElement("img") with too few arguments must throw TypeError]
expected: FAIL

Expand Down Expand Up @@ -251,12 +245,6 @@
[Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError]
expected: FAIL
[MouseEvent interface: attribute offsetX]
expected: FAIL
[MouseEvent interface: attribute offsetY]
expected: FAIL
[CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, ConvertCoordinateOptions)]
expected: FAIL
Expand Down Expand Up @@ -298,15 +286,3 @@

[Partial dictionary MouseEventInit: member names are unique]
expected: FAIL

[MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type]
expected: FAIL

[MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type]
expected: FAIL

[MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type]
expected: FAIL

[MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type]
expected: FAIL
3 changes: 0 additions & 3 deletions tests/wpt/metadata/css/cssom-view/mouseEvent.html.ini
@@ -1,4 +1 @@
[mouseEvent.html]
[MouseEvent's x and y must be equal to clientX and clientY.]
expected: FAIL
9 changes: 9 additions & 0 deletions tests/wpt/web-platform-tests/css/cssom-view/mouseEvent.html
Expand Up @@ -29,5 +29,14 @@
assert_equals(mouseEvent2.pageX, 10);
assert_equals(mouseEvent2.pageY, 5020);
}, 'MouseEvent\'s pageX and pageY attributes should be the sum of the scroll offset and clientX/clientY');

test(function () {
var mouseEvent = new MouseEvent('mousedown', {clientX: 10, clientY: 20});
assert_equals(mouseEvent.offsetX, mouseEvent.pageX);
assert_equals(mouseEvent.offsetY, mouseEvent.pageY);
scrollBy(0, 5000);
assert_equals(mouseEvent.offsetX, mouseEvent.pageX);
assert_equals(mouseEvent.offsetY, mouseEvent.pageY);
}, 'MouseEvent\'s offsetX/offsetY attributes should be the same value as its pageX/pageY attributes.');
</script>
</head>

0 comments on commit b336735

Please sign in to comment.