diff options
author | Peter <ptrgonda@gmail.com> | 2015-04-16 10:41:02 -0400 |
---|---|---|
committer | Peter <ptrgonda@gmail.com> | 2015-04-29 21:32:18 -0400 |
commit | c069d1753eb5c22cefa80bba648b74dbda291502 (patch) | |
tree | 86ab15922907d0c28ab09077866437505ab2e497 | |
parent | b0a7d1bf865eff7b6ca3bae874004a61c19b3c27 (diff) | |
download | servo-c069d1753eb5c22cefa80bba648b74dbda291502.tar.gz servo-c069d1753eb5c22cefa80bba648b74dbda291502.zip |
added dispatching for mousedown and mouseup events, fixes #5705
-rw-r--r-- | components/script/dom/document.rs | 49 | ||||
-rw-r--r-- | components/script/script_task.rs | 32 | ||||
-rw-r--r-- | ports/glutin/window.rs | 15 | ||||
-rw-r--r-- | tests/html/test_mouse_down_mouse_up_click.html | 14 |
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> |