| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/input/MouseEventManager.h" | 5 #include "core/input/MouseEventManager.h" |
| 6 | 6 |
| 7 #include "core/clipboard/DataObject.h" | 7 #include "core/clipboard/DataObject.h" |
| 8 #include "core/clipboard/DataTransfer.h" | 8 #include "core/clipboard/DataTransfer.h" |
| 9 #include "core/dom/Element.h" | 9 #include "core/dom/Element.h" |
| 10 #include "core/dom/ElementTraversal.h" | 10 #include "core/dom/ElementTraversal.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "core/input/InputDeviceCapabilities.h" | 23 #include "core/input/InputDeviceCapabilities.h" |
| 24 #include "core/input/KeyboardEventManager.h" | 24 #include "core/input/KeyboardEventManager.h" |
| 25 #include "core/layout/HitTestResult.h" | 25 #include "core/layout/HitTestResult.h" |
| 26 #include "core/layout/api/LayoutViewItem.h" | 26 #include "core/layout/api/LayoutViewItem.h" |
| 27 #include "core/page/AutoscrollController.h" | 27 #include "core/page/AutoscrollController.h" |
| 28 #include "core/page/DragController.h" | 28 #include "core/page/DragController.h" |
| 29 #include "core/page/DragState.h" | 29 #include "core/page/DragState.h" |
| 30 #include "core/page/FocusController.h" | 30 #include "core/page/FocusController.h" |
| 31 #include "core/paint/PaintLayer.h" | 31 #include "core/paint/PaintLayer.h" |
| 32 #include "core/svg/SVGDocumentExtensions.h" | 32 #include "core/svg/SVGDocumentExtensions.h" |
| 33 #include "platform/Histogram.h" |
| 33 #include "platform/geometry/FloatQuad.h" | 34 #include "platform/geometry/FloatQuad.h" |
| 34 | 35 |
| 35 namespace blink { | 36 namespace blink { |
| 36 | 37 |
| 37 namespace { | 38 namespace { |
| 38 | 39 |
| 39 String CanvasRegionId(Node* node, const WebMouseEvent& mouse_event) { | 40 String CanvasRegionId(Node* node, const WebMouseEvent& mouse_event) { |
| 40 if (!node->IsElementNode()) | 41 if (!node->IsElementNode()) |
| 41 return String(); | 42 return String(); |
| 42 | 43 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 mouse_press_node_ = nullptr; | 89 mouse_press_node_ = nullptr; |
| 89 mouse_down_may_start_autoscroll_ = false; | 90 mouse_down_may_start_autoscroll_ = false; |
| 90 mouse_down_may_start_drag_ = false; | 91 mouse_down_may_start_drag_ = false; |
| 91 captures_dragging_ = false; | 92 captures_dragging_ = false; |
| 92 is_mouse_position_unknown_ = true; | 93 is_mouse_position_unknown_ = true; |
| 93 last_known_mouse_position_ = IntPoint(); | 94 last_known_mouse_position_ = IntPoint(); |
| 94 last_known_mouse_global_position_ = IntPoint(); | 95 last_known_mouse_global_position_ = IntPoint(); |
| 95 mouse_pressed_ = false; | 96 mouse_pressed_ = false; |
| 96 click_count_ = 0; | 97 click_count_ = 0; |
| 97 click_element_ = nullptr; | 98 click_element_ = nullptr; |
| 99 mouse_down_element_ = nullptr; |
| 98 mouse_down_pos_ = IntPoint(); | 100 mouse_down_pos_ = IntPoint(); |
| 99 mouse_down_timestamp_ = TimeTicks(); | 101 mouse_down_timestamp_ = TimeTicks(); |
| 100 mouse_down_ = WebMouseEvent(); | 102 mouse_down_ = WebMouseEvent(); |
| 101 svg_pan_ = false; | 103 svg_pan_ = false; |
| 102 drag_start_pos_ = LayoutPoint(); | 104 drag_start_pos_ = LayoutPoint(); |
| 103 fake_mouse_move_event_timer_.Stop(); | 105 fake_mouse_move_event_timer_.Stop(); |
| 104 ResetDragState(); | 106 ResetDragState(); |
| 105 } | 107 } |
| 106 | 108 |
| 107 MouseEventManager::~MouseEventManager() = default; | 109 MouseEventManager::~MouseEventManager() = default; |
| 108 | 110 |
| 109 DEFINE_TRACE(MouseEventManager) { | 111 DEFINE_TRACE(MouseEventManager) { |
| 110 visitor->Trace(frame_); | 112 visitor->Trace(frame_); |
| 111 visitor->Trace(scroll_manager_); | 113 visitor->Trace(scroll_manager_); |
| 112 visitor->Trace(node_under_mouse_); | 114 visitor->Trace(node_under_mouse_); |
| 113 visitor->Trace(mouse_press_node_); | 115 visitor->Trace(mouse_press_node_); |
| 114 visitor->Trace(click_element_); | 116 visitor->Trace(click_element_); |
| 117 visitor->Trace(mouse_down_element_); |
| 115 SynchronousMutationObserver::Trace(visitor); | 118 SynchronousMutationObserver::Trace(visitor); |
| 116 } | 119 } |
| 117 | 120 |
| 118 MouseEventManager::MouseEventBoundaryEventDispatcher:: | 121 MouseEventManager::MouseEventBoundaryEventDispatcher:: |
| 119 MouseEventBoundaryEventDispatcher(MouseEventManager* mouse_event_manager, | 122 MouseEventBoundaryEventDispatcher(MouseEventManager* mouse_event_manager, |
| 120 const WebMouseEvent* web_mouse_event, | 123 const WebMouseEvent* web_mouse_event, |
| 121 EventTarget* exited_target, | 124 EventTarget* exited_target, |
| 122 const String& canvas_region_id) | 125 const String& canvas_region_id) |
| 123 : mouse_event_manager_(mouse_event_manager), | 126 : mouse_event_manager_(mouse_event_manager), |
| 124 web_mouse_event_(web_mouse_event), | 127 web_mouse_event_(web_mouse_event), |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 #if OS(MACOSX) | 245 #if OS(MACOSX) |
| 243 // FIXME: The Mac port achieves the same behavior by checking whether the | 246 // FIXME: The Mac port achieves the same behavior by checking whether the |
| 244 // context menu is currently open in WebPage::mouseEvent(). Consider merging | 247 // context menu is currently open in WebPage::mouseEvent(). Consider merging |
| 245 // the implementations. | 248 // the implementations. |
| 246 if (mev.Event().button == WebPointerProperties::Button::kLeft && | 249 if (mev.Event().button == WebPointerProperties::Button::kLeft && |
| 247 mev.Event().GetModifiers() & WebInputEvent::Modifiers::kControlKey) | 250 mev.Event().GetModifiers() & WebInputEvent::Modifiers::kControlKey) |
| 248 context_menu_event = true; | 251 context_menu_event = true; |
| 249 #endif | 252 #endif |
| 250 | 253 |
| 251 const bool should_dispatch_click_event = | 254 const bool should_dispatch_click_event = |
| 252 click_count_ > 0 && !context_menu_event && click_element_ && | 255 click_count_ > 0 && !context_menu_event && mouse_down_element_ && |
| 253 mouse_release_target.CanParticipateInFlatTree() && | 256 mouse_release_target.CanParticipateInFlatTree() && |
| 254 click_element_->CanParticipateInFlatTree() && | 257 mouse_down_element_->CanParticipateInFlatTree() && |
| 258 mouse_down_element_->isConnected() && |
| 255 !(frame_->GetEventHandler() | 259 !(frame_->GetEventHandler() |
| 256 .GetSelectionController() | 260 .GetSelectionController() |
| 257 .HasExtendedSelection() && | 261 .HasExtendedSelection() && |
| 258 IsLinkSelection(mev)); | 262 IsLinkSelection(mev)); |
| 259 if (!should_dispatch_click_event) | 263 if (!should_dispatch_click_event) |
| 260 return WebInputEventResult::kNotHandled; | 264 return WebInputEventResult::kNotHandled; |
| 261 | 265 |
| 262 Node* click_target_node = nullptr; | 266 Node* click_target_node = nullptr; |
| 263 if (click_element_ == mouse_release_target) { | 267 if (mouse_down_element_ == mouse_release_target) { |
| 264 click_target_node = click_element_; | 268 click_target_node = mouse_down_element_; |
| 265 } else if (click_element_->GetDocument() == | 269 } else if (mouse_down_element_->GetDocument() == |
| 266 mouse_release_target.GetDocument()) { | 270 mouse_release_target.GetDocument()) { |
| 267 // Updates distribution because a 'mouseup' event listener can make the | 271 // Updates distribution because a 'mouseup' event listener can make the |
| 268 // tree dirty at dispatchMouseEvent() invocation above. | 272 // tree dirty at dispatchMouseEvent() invocation above. |
| 269 // Unless distribution is updated, commonAncestor would hit ASSERT. | 273 // Unless distribution is updated, commonAncestor would hit ASSERT. |
| 270 click_element_->UpdateDistribution(); | 274 mouse_down_element_->UpdateDistribution(); |
| 271 mouse_release_target.UpdateDistribution(); | 275 mouse_release_target.UpdateDistribution(); |
| 272 click_target_node = mouse_release_target.CommonAncestor( | 276 click_target_node = mouse_release_target.CommonAncestor( |
| 273 *click_element_, EventHandlingUtil::ParentForClickEvent); | 277 *mouse_down_element_, EventHandlingUtil::ParentForClickEvent); |
| 274 } | 278 } |
| 275 if (!click_target_node) | 279 if (!click_target_node) |
| 276 return WebInputEventResult::kNotHandled; | 280 return WebInputEventResult::kNotHandled; |
| 277 return DispatchMouseEvent( | 281 |
| 278 click_target_node, | 282 DEFINE_STATIC_LOCAL(BooleanHistogram, histogram, |
| 279 !RuntimeEnabledFeatures::auxclickEnabled() || | 283 ("Event.ClickNotFiredDueToDomManipulation")); |
| 280 (mev.Event().button == WebPointerProperties::Button::kLeft) | 284 |
| 281 ? EventTypeNames::click | 285 if (click_element_ && click_element_->CanParticipateInFlatTree() && |
| 282 : EventTypeNames::auxclick, | 286 click_element_->isConnected()) { |
| 283 mev.Event(), mev.CanvasRegionId(), nullptr); | 287 DCHECK(click_element_ == mouse_down_element_); |
| 288 histogram.Count(false); |
| 289 } else { |
| 290 histogram.Count(true); |
| 291 } |
| 292 |
| 293 if ((click_element_ && click_element_->CanParticipateInFlatTree() && |
| 294 click_element_->isConnected()) || |
| 295 RuntimeEnabledFeatures::clickRetargettingEnabled()) { |
| 296 return DispatchMouseEvent( |
| 297 click_target_node, |
| 298 !RuntimeEnabledFeatures::auxclickEnabled() || |
| 299 (mev.Event().button == WebPointerProperties::Button::kLeft) |
| 300 ? EventTypeNames::click |
| 301 : EventTypeNames::auxclick, |
| 302 mev.Event(), mev.CanvasRegionId(), nullptr); |
| 303 } |
| 304 |
| 305 return WebInputEventResult::kNotHandled; |
| 284 } | 306 } |
| 285 | 307 |
| 286 void MouseEventManager::FakeMouseMoveEventTimerFired(TimerBase* timer) { | 308 void MouseEventManager::FakeMouseMoveEventTimerFired(TimerBase* timer) { |
| 287 TRACE_EVENT0("input", "MouseEventManager::fakeMouseMoveEventTimerFired"); | 309 TRACE_EVENT0("input", "MouseEventManager::fakeMouseMoveEventTimerFired"); |
| 288 DCHECK(timer == &fake_mouse_move_event_timer_); | 310 DCHECK(timer == &fake_mouse_move_event_timer_); |
| 289 DCHECK(!mouse_pressed_); | 311 DCHECK(!mouse_pressed_); |
| 290 | 312 |
| 291 if (is_mouse_position_unknown_) | 313 if (is_mouse_position_unknown_) |
| 292 return; | 314 return; |
| 293 | 315 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 SendBoundaryEvents(last_node_under_mouse, node_under_mouse_, canvas_region_id, | 401 SendBoundaryEvents(last_node_under_mouse, node_under_mouse_, canvas_region_id, |
| 380 web_mouse_event); | 402 web_mouse_event); |
| 381 } | 403 } |
| 382 | 404 |
| 383 void MouseEventManager::NodeChildrenWillBeRemoved(ContainerNode& container) { | 405 void MouseEventManager::NodeChildrenWillBeRemoved(ContainerNode& container) { |
| 384 if (container == click_element_) | 406 if (container == click_element_) |
| 385 return; | 407 return; |
| 386 if (!container.IsShadowIncludingInclusiveAncestorOf(click_element_.Get())) | 408 if (!container.IsShadowIncludingInclusiveAncestorOf(click_element_.Get())) |
| 387 return; | 409 return; |
| 388 click_element_ = nullptr; | 410 click_element_ = nullptr; |
| 411 |
| 412 // TODO(crbug.com/716694): Do not reset mouse_down_element_ for the purpose of |
| 413 // gathering data. |
| 389 } | 414 } |
| 390 | 415 |
| 391 void MouseEventManager::NodeWillBeRemoved(Node& node_to_be_removed) { | 416 void MouseEventManager::NodeWillBeRemoved(Node& node_to_be_removed) { |
| 392 if (node_to_be_removed.IsShadowIncludingInclusiveAncestorOf( | 417 if (node_to_be_removed.IsShadowIncludingInclusiveAncestorOf( |
| 393 click_element_.Get())) { | 418 click_element_.Get())) { |
| 394 // We don't dispatch click events if the mousedown node is removed | 419 // We don't dispatch click events if the mousedown node is removed |
| 395 // before a mouseup event. It is compatible with IE and Firefox. | 420 // before a mouseup event. It is compatible with IE and Firefox. |
| 396 click_element_ = nullptr; | 421 click_element_ = nullptr; |
| 422 |
| 423 // TODO(crbug.com/716694): Do not reset mouse_down_element_ for the purpose |
| 424 // of gathering data. |
| 397 } | 425 } |
| 398 } | 426 } |
| 399 | 427 |
| 400 Node* MouseEventManager::GetNodeUnderMouse() { | 428 Node* MouseEventManager::GetNodeUnderMouse() { |
| 401 return node_under_mouse_; | 429 return node_under_mouse_; |
| 402 } | 430 } |
| 403 | 431 |
| 404 WebInputEventResult MouseEventManager::HandleMouseFocus( | 432 WebInputEventResult MouseEventManager::HandleMouseFocus( |
| 405 const HitTestResult& hit_test_result, | 433 const HitTestResult& hit_test_result, |
| 406 InputDeviceCapabilities* source_capabilities) { | 434 InputDeviceCapabilities* source_capabilities) { |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 return false; | 1020 return false; |
| 993 svg_pan_ = !is_release_event; | 1021 svg_pan_ = !is_release_event; |
| 994 frame_->GetDocument()->AccessSVGExtensions().UpdatePan( | 1022 frame_->GetDocument()->AccessSVGExtensions().UpdatePan( |
| 995 frame_->View()->RootFrameToContents(last_known_mouse_position_)); | 1023 frame_->View()->RootFrameToContents(last_known_mouse_position_)); |
| 996 return true; | 1024 return true; |
| 997 } | 1025 } |
| 998 | 1026 |
| 999 void MouseEventManager::InvalidateClick() { | 1027 void MouseEventManager::InvalidateClick() { |
| 1000 click_count_ = 0; | 1028 click_count_ = 0; |
| 1001 click_element_ = nullptr; | 1029 click_element_ = nullptr; |
| 1030 mouse_down_element_ = nullptr; |
| 1002 } | 1031 } |
| 1003 | 1032 |
| 1004 bool MouseEventManager::MousePressed() { | 1033 bool MouseEventManager::MousePressed() { |
| 1005 return mouse_pressed_; | 1034 return mouse_pressed_; |
| 1006 } | 1035 } |
| 1007 | 1036 |
| 1008 void MouseEventManager::SetMousePressed(bool mouse_pressed) { | 1037 void MouseEventManager::SetMousePressed(bool mouse_pressed) { |
| 1009 mouse_pressed_ = mouse_pressed; | 1038 mouse_pressed_ = mouse_pressed; |
| 1010 } | 1039 } |
| 1011 | 1040 |
| 1012 bool MouseEventManager::CapturesDragging() const { | 1041 bool MouseEventManager::CapturesDragging() const { |
| 1013 return captures_dragging_; | 1042 return captures_dragging_; |
| 1014 } | 1043 } |
| 1015 | 1044 |
| 1016 void MouseEventManager::SetCapturesDragging(bool captures_dragging) { | 1045 void MouseEventManager::SetCapturesDragging(bool captures_dragging) { |
| 1017 captures_dragging_ = captures_dragging; | 1046 captures_dragging_ = captures_dragging; |
| 1018 } | 1047 } |
| 1019 | 1048 |
| 1020 Node* MouseEventManager::MousePressNode() { | 1049 Node* MouseEventManager::MousePressNode() { |
| 1021 return mouse_press_node_; | 1050 return mouse_press_node_; |
| 1022 } | 1051 } |
| 1023 | 1052 |
| 1024 void MouseEventManager::SetMousePressNode(Node* node) { | 1053 void MouseEventManager::SetMousePressNode(Node* node) { |
| 1025 mouse_press_node_ = node; | 1054 mouse_press_node_ = node; |
| 1026 } | 1055 } |
| 1027 | 1056 |
| 1028 void MouseEventManager::SetClickElement(Element* element) { | 1057 void MouseEventManager::SetClickElement(Element* element) { |
| 1029 SetContext(element ? element->ownerDocument() : nullptr); | 1058 SetContext(element ? element->ownerDocument() : nullptr); |
| 1030 click_element_ = element; | 1059 click_element_ = element; |
| 1060 mouse_down_element_ = element; |
| 1031 } | 1061 } |
| 1032 | 1062 |
| 1033 void MouseEventManager::SetClickCount(int click_count) { | 1063 void MouseEventManager::SetClickCount(int click_count) { |
| 1034 click_count_ = click_count; | 1064 click_count_ = click_count; |
| 1035 } | 1065 } |
| 1036 | 1066 |
| 1037 bool MouseEventManager::MouseDownMayStartDrag() { | 1067 bool MouseEventManager::MouseDownMayStartDrag() { |
| 1038 return mouse_down_may_start_drag_; | 1068 return mouse_down_may_start_drag_; |
| 1039 } | 1069 } |
| 1040 | 1070 |
| 1041 } // namespace blink | 1071 } // namespace blink |
| OLD | NEW |