diff options
author | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-25 03:30:34 +0000 |
---|---|---|
committer | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-25 03:30:34 +0000 |
commit | 42be0ca594ed7980c7ee73ef04919cd890463e9a (patch) | |
tree | 2a842c204463a24dd792734ab7d4867974ca5381 /webkit | |
parent | 4fb105e615d1ee15127f8b293e7e3361ed7c74b0 (diff) | |
download | chromium_src-42be0ca594ed7980c7ee73ef04919cd890463e9a.zip chromium_src-42be0ca594ed7980c7ee73ef04919cd890463e9a.tar.gz chromium_src-42be0ca594ed7980c7ee73ef04919cd890463e9a.tar.bz2 |
Ensure "contextmenu" event is dispatched _after_ "mouseup".
BUG=1330688
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1299 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
6 files changed, 133 insertions, 30 deletions
diff --git a/webkit/data/layout_tests/chrome/fast/events/contextmenu-event-ordering-expected.txt b/webkit/data/layout_tests/chrome/fast/events/contextmenu-event-ordering-expected.txt new file mode 100644 index 0000000..7a94cda --- /dev/null +++ b/webkit/data/layout_tests/chrome/fast/events/contextmenu-event-ordering-expected.txt @@ -0,0 +1,7 @@ +[Click target] +Right click in the red box: the event sequence should match (mousedown, mouseup, contextmenu) + +Dispatched event mousedown (button=2) +Dispatched event mouseup (button=2) +Dispatched event contextmenu (button=2) + diff --git a/webkit/data/layout_tests/chrome/fast/events/contextmenu-event-ordering.html b/webkit/data/layout_tests/chrome/fast/events/contextmenu-event-ordering.html new file mode 100644 index 0000000..932ad89 --- /dev/null +++ b/webkit/data/layout_tests/chrome/fast/events/contextmenu-event-ordering.html @@ -0,0 +1,71 @@ +<html> + <head> + <title>Context menu event ordering</title> + <style> + #clickTarget { + width: 100%; + height: 50px; + background: red; + text-align: center; + } + </style> + <script> + + function startTest() { + var target = document.getElementById("clickTarget"); + + traceMouseEvent(target, "click"); + traceMouseEvent(target, "mousedown"); + traceMouseEvent(target, "mouseup"); + traceMouseEvent(target, "contextmenu"); + + if (window.layoutTestController) { + window.layoutTestController.dumpAsText(); + + // Right click inside clickTarget + window.eventSender.mouseMoveTo(20,20); + window.eventSender.mouseDown(2 /*right button*/); + window.eventSender.mouseUp(2 /*right button*/); + } + } + + function traceMouseEvent(target, eventName) { + + var callback = function(e) { + log ("Dispatched event " + e.type + " (button=" + e.button + ")"); + + if (eventName == "contextmenu") { + // Prevent the context menu from being displayed. + e.returnValue = false; + if (e.stopPropagation) { + e.stopPropagation(); + } + } + }; + + if (target.addEventListener) { + target.addEventListener(eventName, callback, false); + } else if (target.attachEvent) /*Internet Explorer*/ { + target.attachEvent("on" + eventName, callback); + } else { + log ("!!! Failed registering " + eventName); + } + } + + function log(msg) { + var log = document.getElementById("log"); + log.appendChild(document.createTextNode(msg)); + log.appendChild(document.createElement("br")); + } + </script> + </head> + + <body onload="startTest()"> + <div id=clickTarget> + [Click target] + </div> + + <p>Right click in the red box: the event sequence should match (mousedown, mouseup, contextmenu)</p> + <pre id=log></pre> + </body> +</html> diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc index bad4d06..7121ecd 100644 --- a/webkit/glue/webview_impl.cc +++ b/webkit/glue/webview_impl.cc @@ -221,39 +221,43 @@ void WebViewImpl::MouseDown(const WebMouseEvent& event) { MakePlatformMouseEvent(main_frame_->frameview(), event)); } -void WebViewImpl::MouseUp(const WebMouseEvent& event) { - if (event.button == WebMouseEvent::BUTTON_RIGHT) { - page_->contextMenuController()->clearContextMenu(); - - MakePlatformMouseEvent pme(main_frame_->frameview(), event); - - // Find the right target frame. See issue 1186900. - IntPoint doc_point( - main_frame_->frame()->view()->windowToContents(pme.pos())); - HitTestResult result = - main_frame_->frame()->eventHandler()->hitTestResultAtPoint(doc_point, - false); - Frame* target_frame; - if (result.innerNonSharedNode()) - target_frame = result.innerNonSharedNode()->document()->frame(); - else - target_frame = page_->focusController()->focusedOrMainFrame(); - - target_frame->view()->setCursor(pointerCursor()); - - context_menu_allowed_ = true; - target_frame->eventHandler()->sendContextMenuEvent(pme); - context_menu_allowed_ = false; - // Actually showing the context menu is handled by the ContextMenuClient - // implementation... - } +void WebViewImpl::MouseContextMenu(const WebMouseEvent& event) { + page_->contextMenuController()->clearContextMenu(); + + MakePlatformMouseEvent pme(main_frame_->frameview(), event); + + // Find the right target frame. See issue 1186900. + IntPoint doc_point( + main_frame_->frame()->view()->windowToContents(pme.pos())); + HitTestResult result = + main_frame_->frame()->eventHandler()->hitTestResultAtPoint(doc_point, + false); + Frame* target_frame; + if (result.innerNonSharedNode()) + target_frame = result.innerNonSharedNode()->document()->frame(); + else + target_frame = page_->focusController()->focusedOrMainFrame(); + + target_frame->view()->setCursor(pointerCursor()); + context_menu_allowed_ = true; + target_frame->eventHandler()->sendContextMenuEvent(pme); + context_menu_allowed_ = false; + // Actually showing the context menu is handled by the ContextMenuClient + // implementation... +} + +void WebViewImpl::MouseUp(const WebMouseEvent& event) { if (!main_frame_->frameview()) return; MouseCaptureLost(); main_frame_->frameview()->frame()->eventHandler()->handleMouseReleaseEvent( MakePlatformMouseEvent(main_frame_->frameview(), event)); + + // Dispatch the contextmenu event regardless of if the click was swallowed. + if (event.button == WebMouseEvent::BUTTON_RIGHT) + MouseContextMenu(event); } void WebViewImpl::MouseWheel(const WebMouseWheelEvent& event) { diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h index 5249942..693b90b 100644 --- a/webkit/glue/webview_impl.h +++ b/webkit/glue/webview_impl.h @@ -132,6 +132,7 @@ class WebViewImpl : public WebView, void MouseLeave(const WebMouseEvent& mouse_event); void MouseDown(const WebMouseEvent& mouse_event); void MouseUp(const WebMouseEvent& mouse_event); + void MouseContextMenu(const WebMouseEvent& mouse_event); void MouseDoubleClick(const WebMouseEvent& mouse_event); void MouseWheel(const WebMouseWheelEvent& wheel_event); bool KeyEvent(const WebKeyboardEvent& key_event); diff --git a/webkit/tools/test_shell/event_sending_controller.cc b/webkit/tools/test_shell/event_sending_controller.cc index 16ee691..448c0b5 100644 --- a/webkit/tools/test_shell/event_sending_controller.cc +++ b/webkit/tools/test_shell/event_sending_controller.cc @@ -154,6 +154,19 @@ void EventSendingController::Reset() { ReplaySavedEvents(); } +// static +WebMouseEvent::Button EventSendingController::GetButtonTypeFromSingleArg( + const CppArgumentList& args) { + if (args.size() > 0 && args[0].isNumber()) { + int button_code = args[0].ToInt32(); + if (button_code == 1) + return WebMouseEvent::BUTTON_MIDDLE; + else if (button_code == 2) + return WebMouseEvent::BUTTON_RIGHT; + } + return WebMouseEvent::BUTTON_LEFT; +} + // // Implemented javascript methods. // @@ -164,6 +177,8 @@ void EventSendingController::Reset() { webview()->Layout(); + WebMouseEvent::Button button_type = GetButtonTypeFromSingleArg(args); + if ((GetCurrentEventTimeSec() - last_click_time_sec >= kMultiClickTimeSec) || outside_multiclick_radius(last_mouse_pos_, last_click_pos)) { click_count = 1; @@ -172,11 +187,10 @@ void EventSendingController::Reset() { } WebMouseEvent event; - pressed_button_ = WebMouseEvent::BUTTON_LEFT; - InitMouseEvent(WebInputEvent::MOUSE_DOWN, WebMouseEvent::BUTTON_LEFT, + pressed_button_ = button_type; + InitMouseEvent(WebInputEvent::MOUSE_DOWN, button_type, last_mouse_pos_, &event); webview()->HandleInputEvent(&event); - } void EventSendingController::mouseUp( @@ -185,8 +199,10 @@ void EventSendingController::Reset() { webview()->Layout(); + WebMouseEvent::Button button_type = GetButtonTypeFromSingleArg(args); + WebMouseEvent event; - InitMouseEvent(WebInputEvent::MOUSE_UP, WebMouseEvent::BUTTON_LEFT, + InitMouseEvent(WebInputEvent::MOUSE_UP, button_type, last_mouse_pos_, &event); if (drag_mode() && !replaying_saved_events) { mouse_event_queue.push(event); diff --git a/webkit/tools/test_shell/event_sending_controller.h b/webkit/tools/test_shell/event_sending_controller.h index b25d5e90..4edb60e 100644 --- a/webkit/tools/test_shell/event_sending_controller.h +++ b/webkit/tools/test_shell/event_sending_controller.h @@ -66,6 +66,10 @@ class EventSendingController : public CppBoundClass { static void DoMouseUp(const WebMouseEvent& e); static void ReplaySavedEvents(); + // Helper to extract the optional arg from mouseDown() and mouseUp() + static WebMouseEvent::Button GetButtonTypeFromSingleArg( + const CppArgumentList& args); + // Returns true if the key_code passed in needs a shift key modifier to // be passed into the generated event. bool NeedsShiftModifer(wchar_t key_code); |