aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter <ptrgonda@gmail.com>2015-04-16 10:41:02 -0400
committerPeter <ptrgonda@gmail.com>2015-04-29 21:32:18 -0400
commitc069d1753eb5c22cefa80bba648b74dbda291502 (patch)
tree86ab15922907d0c28ab09077866437505ab2e497
parentb0a7d1bf865eff7b6ca3bae874004a61c19b3c27 (diff)
downloadservo-c069d1753eb5c22cefa80bba648b74dbda291502.tar.gz
servo-c069d1753eb5c22cefa80bba648b74dbda291502.zip
added dispatching for mousedown and mouseup events, fixes #5705
-rw-r--r--components/script/dom/document.rs49
-rw-r--r--components/script/script_task.rs32
-rw-r--r--ports/glutin/window.rs15
-rw-r--r--tests/html/test_mouse_down_mouse_up_click.html14
4 files changed, 79 insertions, 31 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index cbfc214f040..08a287c3fe5 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -220,8 +220,6 @@ pub trait DocumentHelpers<'a> {
fn title_changed(self);
fn send_title_to_compositor(self);
fn dirty_all_nodes(self);
- fn handle_click_event(self, js_runtime: *mut JSRuntime,
- button: MouseButton, point: Point2D<f32>);
fn dispatch_key_event(self, key: Key, state: KeyState,
modifiers: KeyModifiers, compositor: &mut Box<ScriptListener+'static>);
fn node_from_nodes_and_strings(self, nodes: Vec<NodeOrString>)
@@ -229,6 +227,9 @@ pub trait DocumentHelpers<'a> {
fn get_body_attribute(self, local_name: &Atom) -> DOMString;
fn set_body_attribute(self, local_name: &Atom, value: DOMString);
+ fn handle_mouse_event(self, js_runtime: *mut JSRuntime,
+ button: MouseButton, point: Point2D<f32>,
+ mouse_event_type: MouseEventType);
/// Handles a mouse-move event coming from the compositor.
fn handle_mouse_move_event(self,
js_runtime: *mut JSRuntime,
@@ -511,9 +512,15 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
}
}
- fn handle_click_event(self, js_runtime: *mut JSRuntime,
- _button: MouseButton, point: Point2D<f32>) {
- debug!("ClickEvent: clicked at {:?}", point);
+ fn handle_mouse_event(self, js_runtime: *mut JSRuntime,
+ _button: MouseButton, point: Point2D<f32>,
+ mouse_event_type: MouseEventType) {
+ let mouse_event_type_string = match mouse_event_type {
+ MouseEventType::Click => "click".to_owned(),
+ MouseEventType::MouseUp => "mouseup".to_owned(),
+ MouseEventType::MouseDown => "mousedown".to_owned(),
+ };
+ debug!("{}: at {:?}", mouse_event_type_string, point);
let node = match self.hit_test(&point) {
Some(node_address) => {
debug!("node address is {:?}", node_address.0);
@@ -534,13 +541,15 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
}.root();
let node: JSRef<Node> = NodeCast::from_ref(el.r());
- debug!("clicked on {:?}", node.debug_str());
+ debug!("{} on {:?}", mouse_event_type_string, node.debug_str());
// Prevent click event if form control element is disabled.
- if node.click_event_filter_by_disabled_state() {
- return;
- }
+ if let MouseEventType::Click = mouse_event_type {
+ if node.click_event_filter_by_disabled_state() {
+ return;
+ }
- self.begin_focus_transaction();
+ self.begin_focus_transaction();
+ }
let window = self.window.root();
@@ -548,7 +557,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
let x = point.x as i32;
let y = point.y as i32;
let event = MouseEvent::new(window.r(),
- "click".to_owned(),
+ mouse_event_type_string,
EventBubbles::Bubbles,
EventCancelable::Cancelable,
Some(window.r()),
@@ -562,9 +571,17 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#trusted-events
event.set_trusted(true);
// https://html.spec.whatwg.org/multipage/#run-authentic-click-activation-steps
- el.r().authentic_click_activation(event);
+ match mouse_event_type {
+ MouseEventType::Click => el.r().authentic_click_activation(event),
+ _ => {
+ let target: JSRef<EventTarget> = EventTargetCast::from_ref(node);
+ event.fire(target);
+ },
+ }
- self.commit_focus_transaction(FocusType::Element);
+ if let MouseEventType::Click = mouse_event_type {
+ self.commit_focus_transaction(FocusType::Element);
+ }
window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::MouseEvent);
}
@@ -778,6 +795,12 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
}
}
+pub enum MouseEventType {
+ Click,
+ MouseDown,
+ MouseUp,
+}
+
#[derive(PartialEq)]
pub enum DocumentSource {
FromParser,
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index f1f469212aa..a9afc1ad468 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -30,7 +30,7 @@ use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference};
use dom::bindings::structuredclone::StructuredCloneData;
use dom::bindings::trace::{JSTraceable, trace_collections, RootedVec};
use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap};
-use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentProgressHandler, DocumentProgressTask, DocumentSource};
+use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentProgressHandler, DocumentProgressTask, DocumentSource, MouseEventType};
use dom::element::{Element, AttributeHandlers};
use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable};
use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementHelpers};
@@ -50,7 +50,7 @@ use webdriver_handlers;
use devtools_traits::{DevtoolsControlChan, DevtoolsControlPort, DevtoolsPageInfo};
use devtools_traits::{DevtoolsControlMsg, DevtoolScriptControlMsg};
use devtools_traits::{TimelineMarker, TimelineMarkerType, TracingMetadata};
-use script_traits::CompositorEvent;
+use script_traits::{CompositorEvent, MouseButton};
use script_traits::CompositorEvent::{ResizeEvent, ClickEvent};
use script_traits::CompositorEvent::{MouseDownEvent, MouseUpEvent};
use script_traits::CompositorEvent::{MouseMoveEvent, KeyEvent};
@@ -1229,17 +1229,17 @@ impl ScriptTask {
}
ClickEvent(button, point) => {
- let _marker;
- if self.need_emit_timeline_marker(TimelineMarkerType::DOMEvent) {
- _marker = AutoDOMEventMarker::new(self);
- }
- let page = get_page(&self.root_page(), pipeline_id);
- let document = page.document().root();
- document.r().handle_click_event(self.js_runtime.rt(), button, point);
+ self.handle_mouse_event(pipeline_id, MouseEventType::Click, button, point);
+ }
+
+ MouseDownEvent(button, point) => {
+ self.handle_mouse_event(pipeline_id, MouseEventType::MouseDown, button, point);
+ }
+
+ MouseUpEvent(button, point) => {
+ self.handle_mouse_event(pipeline_id, MouseEventType::MouseUp, button, point);
}
- MouseDownEvent(..) => {}
- MouseUpEvent(..) => {}
MouseMoveEvent(point) => {
let _marker;
if self.need_emit_timeline_marker(TimelineMarkerType::DOMEvent) {
@@ -1267,6 +1267,16 @@ impl ScriptTask {
}
}
+ fn handle_mouse_event(&self, pipeline_id: PipelineId, mouse_event_type: MouseEventType, button: MouseButton, point: Point2D<f32>) {
+ let _marker;
+ if self.need_emit_timeline_marker(TimelineMarkerType::DOMEvent) {
+ _marker = AutoDOMEventMarker::new(self);
+ }
+ let page = get_page(&self.root_page(), pipeline_id);
+ let document = page.document().root();
+ document.r().handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type);
+ }
+
/// https://html.spec.whatwg.org/multipage/#navigating-across-documents
/// The entry point for content to notify that a new load has been requested
/// for the given pipeline (specifically the "navigate" algorithm).
diff --git a/ports/glutin/window.rs b/ports/glutin/window.rs
index 8e47004e938..a13dbd56ff2 100644
--- a/ports/glutin/window.rs
+++ b/ports/glutin/window.rs
@@ -237,21 +237,22 @@ impl Window {
MouseWindowEvent::MouseDown(MouseButton::Left, TypedPoint2D(x as f32, y as f32))
}
ElementState::Released => {
+ let mouse_up_event = MouseWindowEvent::MouseUp(MouseButton::Left, TypedPoint2D(x as f32, y as f32));
match self.mouse_down_button.get() {
- None => (),
+ None => mouse_up_event,
Some(but) if button == but => {
let pixel_dist = self.mouse_down_point.get() - Point2D(x, y);
let pixel_dist = ((pixel_dist.x * pixel_dist.x +
pixel_dist.y * pixel_dist.y) as f64).sqrt();
if pixel_dist < max_pixel_dist {
- let click_event = MouseWindowEvent::Click(
- MouseButton::Left, TypedPoint2D(x as f32, y as f32));
- self.event_queue.borrow_mut().push(WindowEvent::MouseWindowEventClass(click_event));
+ self.event_queue.borrow_mut().push(WindowEvent::MouseWindowEventClass(mouse_up_event));
+ MouseWindowEvent::Click(MouseButton::Left, TypedPoint2D(x as f32, y as f32))
+ } else {
+ mouse_up_event
}
- }
- Some(_) => (),
+ },
+ Some(_) => mouse_up_event,
}
- MouseWindowEvent::MouseUp(MouseButton::Left, TypedPoint2D(x as f32, y as f32))
}
};
self.event_queue.borrow_mut().push(WindowEvent::MouseWindowEventClass(event));
diff --git a/tests/html/test_mouse_down_mouse_up_click.html b/tests/html/test_mouse_down_mouse_up_click.html
new file mode 100644
index 00000000000..84cf8d7c954
--- /dev/null
+++ b/tests/html/test_mouse_down_mouse_up_click.html
@@ -0,0 +1,14 @@
+<body>
+<input id="clicked">
+<script>
+ document.getElementById("clicked").addEventListener("mousedown", function () {
+ window.alert("mousedown"); },
+ false);
+ document.getElementById("clicked").addEventListener('mouseup', function() {
+ window.alert("mouseup"); },
+ false);
+ document.getElementById("clicked").addEventListener("click", function() {
+ window.alert("clicked"); },
+ false);
+</script>
+</body>