Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Side by Side Diff: third_party/WebKit/Source/core/input/EventHandler.cpp

Issue 1670073004: Send node transition events for touch events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing the comment Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 namespace blink { 103 namespace blink {
104 104
105 namespace { 105 namespace {
106 106
107 bool hasTouchHandlers(const EventHandlerRegistry& registry) 107 bool hasTouchHandlers(const EventHandlerRegistry& registry)
108 { 108 {
109 return registry.hasEventHandlers(EventHandlerRegistry::TouchEventBlocking) 109 return registry.hasEventHandlers(EventHandlerRegistry::TouchEventBlocking)
110 || registry.hasEventHandlers(EventHandlerRegistry::TouchEventPassive); 110 || registry.hasEventHandlers(EventHandlerRegistry::TouchEventPassive);
111 } 111 }
112 112
113 WebInputEventResult mergeEventResult(WebInputEventResult responseA, WebInputEven tResult responseB)
114 {
115 // The ordering of the enumeration is specific. There are times that
116 // multiple events fire and we need to combine them into a single
117 // result code. The enumeration is based on the level of consumption that
118 // is most significant. The enumeration is ordered with smaller specified
119 // numbers first. Examples of merged results are:
120 // (HandledApplication, HandledSystem) -> HandledSystem
121 // (NotHandled, HandledApplication) -> HandledApplication
122 static_assert(static_cast<int>(WebInputEventResult::NotHandled) == 0, "WebIn putEventResult not ordered");
123 static_assert(static_cast<int>(WebInputEventResult::HandledSuppressed) < sta tic_cast<int>(WebInputEventResult::HandledApplication), "WebInputEventResult not ordered");
124 static_assert(static_cast<int>(WebInputEventResult::HandledApplication) < st atic_cast<int>(WebInputEventResult::HandledSystem), "WebInputEventResult not ord ered");
125 return static_cast<WebInputEventResult>(max(static_cast<int>(responseA), sta tic_cast<int>(responseB)));
126 }
127
128 WebInputEventResult eventToEventResult(PassRefPtrWillBeRawPtr<Event> event, bool res)
129 {
130 if (event->defaultPrevented())
131 return WebInputEventResult::HandledApplication;
132 if (event->defaultHandled())
133 return WebInputEventResult::HandledSystem;
134
135 // TODO(dtapuska): There are cases in the code where dispatchEvent
136 // returns false (indicated handled) but event is not marked
137 // as default handled or default prevented. crbug.com/560355
138 if (!res)
139 return WebInputEventResult::HandledSuppressed;
140 return WebInputEventResult::NotHandled;
141 }
142
143 bool isNodeInDocument(Node* n)
144 {
145 return n && n->inDocument();
146 }
147
148 const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::State s tate) 113 const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::State s tate)
149 { 114 {
150 switch (state) { 115 switch (state) {
151 case PlatformTouchPoint::TouchReleased: 116 case PlatformTouchPoint::TouchReleased:
152 return EventTypeNames::touchend; 117 return EventTypeNames::touchend;
153 case PlatformTouchPoint::TouchCancelled: 118 case PlatformTouchPoint::TouchCancelled:
154 return EventTypeNames::touchcancel; 119 return EventTypeNames::touchcancel;
155 case PlatformTouchPoint::TouchPressed: 120 case PlatformTouchPoint::TouchPressed:
156 return EventTypeNames::touchstart; 121 return EventTypeNames::touchstart;
157 case PlatformTouchPoint::TouchMoved: 122 case PlatformTouchPoint::TouchMoved:
158 return EventTypeNames::touchmove; 123 return EventTypeNames::touchmove;
159 case PlatformTouchPoint::TouchStationary: 124 case PlatformTouchPoint::TouchStationary:
160 // Fall through to default 125 // Fall through to default
161 default: 126 default:
162 ASSERT_NOT_REACHED(); 127 ASSERT_NOT_REACHED();
163 return emptyAtom; 128 return emptyAtom;
164 } 129 }
165 } 130 }
166 131
167 const AtomicString& pointerEventNameForTouchPointState(PlatformTouchPoint::State state)
168 {
169 switch (state) {
170 case PlatformTouchPoint::TouchReleased:
171 return EventTypeNames::pointerup;
172 case PlatformTouchPoint::TouchCancelled:
173 return EventTypeNames::pointercancel;
174 case PlatformTouchPoint::TouchPressed:
175 return EventTypeNames::pointerdown;
176 case PlatformTouchPoint::TouchMoved:
177 return EventTypeNames::pointermove;
178 case PlatformTouchPoint::TouchStationary:
179 // Fall through to default
180 default:
181 ASSERT_NOT_REACHED();
182 return emptyAtom;
183 }
184 }
185
186 const AtomicString& pointerEventNameForMouseEventName(const AtomicString& mouseE ventName)
187 {
188 #define RETURN_CORRESPONDING_PE_NAME(eventSuffix) \
189 if (mouseEventName == EventTypeNames::mouse##eventSuffix) {\
190 return EventTypeNames::pointer##eventSuffix;\
191 }
192
193 RETURN_CORRESPONDING_PE_NAME(down);
194 RETURN_CORRESPONDING_PE_NAME(enter);
195 RETURN_CORRESPONDING_PE_NAME(leave);
196 RETURN_CORRESPONDING_PE_NAME(move);
197 RETURN_CORRESPONDING_PE_NAME(out);
198 RETURN_CORRESPONDING_PE_NAME(over);
199 RETURN_CORRESPONDING_PE_NAME(up);
200
201 #undef RETURN_CORRESPONDING_PE_NAME
202
203 ASSERT_NOT_REACHED();
204 return emptyAtom;
205 }
206
207 } // namespace 132 } // namespace
208 133
209 using namespace HTMLNames; 134 using namespace HTMLNames;
210 135
211 // The link drag hysteresis is much larger than the others because there 136 // The link drag hysteresis is much larger than the others because there
212 // needs to be enough space to cancel the link press without starting a link dra g, 137 // needs to be enough space to cancel the link press without starting a link dra g,
213 // and because dragging links is rare. 138 // and because dragging links is rare.
214 static const int LinkDragHysteresis = 40; 139 static const int LinkDragHysteresis = 40;
215 static const int ImageDragHysteresis = 5; 140 static const int ImageDragHysteresis = 5;
216 static const int TextDragHysteresis = 3; 141 static const int TextDragHysteresis = 3;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d) 251 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d)
327 , m_svgPan(false) 252 , m_svgPan(false)
328 , m_resizeScrollableArea(nullptr) 253 , m_resizeScrollableArea(nullptr)
329 , m_eventHandlerWillResetCapturingMouseEventsNode(0) 254 , m_eventHandlerWillResetCapturingMouseEventsNode(0)
330 , m_clickCount(0) 255 , m_clickCount(0)
331 , m_shouldOnlyFireDragOverEvent(false) 256 , m_shouldOnlyFireDragOverEvent(false)
332 , m_accumulatedRootOverscroll(FloatSize()) 257 , m_accumulatedRootOverscroll(FloatSize())
333 , m_mousePositionIsUnknown(true) 258 , m_mousePositionIsUnknown(true)
334 , m_mouseDownTimestamp(0) 259 , m_mouseDownTimestamp(0)
335 , m_touchPressed(false) 260 , m_touchPressed(false)
336 , m_preventMouseEventForPointerTypeMouse(false)
337 , m_inPointerCanceledState(false) 261 , m_inPointerCanceledState(false)
338 , m_scrollGestureHandlingNode(nullptr) 262 , m_scrollGestureHandlingNode(nullptr)
339 , m_lastGestureScrollOverWidget(false) 263 , m_lastGestureScrollOverWidget(false)
340 , m_longTapShouldInvokeContextMenu(false) 264 , m_longTapShouldInvokeContextMenu(false)
341 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) 265 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
342 , m_lastShowPressTimestamp(0) 266 , m_lastShowPressTimestamp(0)
343 , m_deltaConsumedForScrollSequence(false) 267 , m_deltaConsumedForScrollSequence(false)
344 { 268 {
345 } 269 }
346 270
(...skipping 16 matching lines...) Expand all
363 visitor->trace(m_dragTarget); 287 visitor->trace(m_dragTarget);
364 visitor->trace(m_frameSetBeingResized); 288 visitor->trace(m_frameSetBeingResized);
365 visitor->trace(m_previousWheelScrolledNode); 289 visitor->trace(m_previousWheelScrolledNode);
366 visitor->trace(m_scrollbarHandlingScrollGesture); 290 visitor->trace(m_scrollbarHandlingScrollGesture);
367 visitor->trace(m_targetForTouchID); 291 visitor->trace(m_targetForTouchID);
368 visitor->trace(m_touchSequenceDocument); 292 visitor->trace(m_touchSequenceDocument);
369 visitor->trace(m_scrollGestureHandlingNode); 293 visitor->trace(m_scrollGestureHandlingNode);
370 visitor->trace(m_previousGestureScrolledNode); 294 visitor->trace(m_previousGestureScrolledNode);
371 visitor->trace(m_lastDeferredTapElement); 295 visitor->trace(m_lastDeferredTapElement);
372 visitor->trace(m_selectionController); 296 visitor->trace(m_selectionController);
297 visitor->trace(m_pointerEventManager);
373 #endif 298 #endif
374 } 299 }
375 300
376 DragState& EventHandler::dragState() 301 DragState& EventHandler::dragState()
377 { 302 {
378 DEFINE_STATIC_LOCAL(Persistent<DragState>, state, (new DragState())); 303 DEFINE_STATIC_LOCAL(Persistent<DragState>, state, (new DragState()));
379 return *state; 304 return *state;
380 } 305 }
381 306
382 void EventHandler::clear() 307 void EventHandler::clear()
(...skipping 21 matching lines...) Expand all
404 m_capturingMouseEventsNode = nullptr; 329 m_capturingMouseEventsNode = nullptr;
405 m_previousWheelScrolledNode = nullptr; 330 m_previousWheelScrolledNode = nullptr;
406 m_targetForTouchID.clear(); 331 m_targetForTouchID.clear();
407 m_touchSequenceDocument.clear(); 332 m_touchSequenceDocument.clear();
408 m_touchSequenceUserGestureToken.clear(); 333 m_touchSequenceUserGestureToken.clear();
409 clearGestureScrollState(); 334 clearGestureScrollState();
410 m_lastGestureScrollOverWidget = false; 335 m_lastGestureScrollOverWidget = false;
411 m_scrollbarHandlingScrollGesture = nullptr; 336 m_scrollbarHandlingScrollGesture = nullptr;
412 m_touchPressed = false; 337 m_touchPressed = false;
413 m_pointerEventManager.clear(); 338 m_pointerEventManager.clear();
414 m_preventMouseEventForPointerTypeMouse = false;
415 m_inPointerCanceledState = false; 339 m_inPointerCanceledState = false;
416 m_mouseDownMayStartDrag = false; 340 m_mouseDownMayStartDrag = false;
417 m_lastShowPressTimestamp = 0; 341 m_lastShowPressTimestamp = 0;
418 m_lastDeferredTapElement = nullptr; 342 m_lastDeferredTapElement = nullptr;
419 m_eventHandlerWillResetCapturingMouseEventsNode = false; 343 m_eventHandlerWillResetCapturingMouseEventsNode = false;
420 m_mouseDownMayStartAutoscroll = false; 344 m_mouseDownMayStartAutoscroll = false;
421 m_svgPan = false; 345 m_svgPan = false;
422 m_mouseDownPos = IntPoint(); 346 m_mouseDownPos = IntPoint();
423 m_mouseDownTimestamp = 0; 347 m_mouseDownTimestamp = 0;
424 m_longTapShouldInvokeContextMenu = false; 348 m_longTapShouldInvokeContextMenu = false;
425 m_dragStartPos = LayoutPoint(); 349 m_dragStartPos = LayoutPoint();
426 m_offsetFromResizeCorner = LayoutSize(); 350 m_offsetFromResizeCorner = LayoutSize();
427 m_mouseDown = PlatformMouseEvent(); 351 m_mouseDown = PlatformMouseEvent();
428 } 352 }
429 353
354 WebInputEventResult EventHandler::mergeEventResult(
355 WebInputEventResult resultA, WebInputEventResult resultB)
356 {
357 // The ordering of the enumeration is specific. There are times that
358 // multiple events fire and we need to combine them into a single
359 // result code. The enumeration is based on the level of consumption that
360 // is most significant. The enumeration is ordered with smaller specified
361 // numbers first. Examples of merged results are:
362 // (HandledApplication, HandledSystem) -> HandledSystem
363 // (NotHandled, HandledApplication) -> HandledApplication
364 static_assert(static_cast<int>(WebInputEventResult::NotHandled) == 0, "WebIn putEventResult not ordered");
365 static_assert(static_cast<int>(WebInputEventResult::HandledSuppressed) < sta tic_cast<int>(WebInputEventResult::HandledApplication), "WebInputEventResult not ordered");
366 static_assert(static_cast<int>(WebInputEventResult::HandledApplication) < st atic_cast<int>(WebInputEventResult::HandledSystem), "WebInputEventResult not ord ered");
367 return static_cast<WebInputEventResult>(max(static_cast<int>(resultA), stati c_cast<int>(resultB)));
368 }
369
370 WebInputEventResult EventHandler::eventToEventResult(
371 PassRefPtrWillBeRawPtr<Event> event, bool result)
372 {
373 if (event->defaultPrevented())
374 return WebInputEventResult::HandledApplication;
375 if (event->defaultHandled())
376 return WebInputEventResult::HandledSystem;
377
378 // TODO(dtapuska): There are cases in the code where dispatchEvent
379 // returns false (indicated handled) but event is not marked
380 // as default handled or default prevented. crbug.com/560355
381 if (!result)
382 return WebInputEventResult::HandledSuppressed;
383 return WebInputEventResult::NotHandled;
384 }
385
430 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) 386 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
431 { 387 {
432 if (nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get())) { 388 if (nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get())) {
433 // We don't dispatch click events if the mousedown node is removed 389 // We don't dispatch click events if the mousedown node is removed
434 // before a mouseup event. It is compatible with IE and Firefox. 390 // before a mouseup event. It is compatible with IE and Firefox.
435 m_clickNode = nullptr; 391 m_clickNode = nullptr;
436 } 392 }
437 } 393 }
438 394
439 WebInputEventResult EventHandler::handleMousePressEvent(const MouseEventWithHitT estResults& event) 395 WebInputEventResult EventHandler::handleMousePressEvent(const MouseEventWithHitT estResults& event)
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 return scrollableArea; 1099 return scrollableArea;
1144 } 1100 }
1145 1101
1146 return nullptr; 1102 return nullptr;
1147 } 1103 }
1148 1104
1149 WebInputEventResult EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& event) 1105 WebInputEventResult EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& event)
1150 { 1106 {
1151 TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent"); 1107 TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent");
1152 1108
1153 conditionallyEnableMouseEventForPointerTypeMouse(event); 1109 m_pointerEventManager.conditionallyEnableMouseEventForPointerTypeMouse(
1110 event.modifiers());
1154 1111
1155 RefPtrWillBeRawPtr<FrameView> protector(m_frame->view()); 1112 RefPtrWillBeRawPtr<FrameView> protector(m_frame->view());
1156 1113
1157 HitTestResult hoveredNode = HitTestResult(); 1114 HitTestResult hoveredNode = HitTestResult();
1158 WebInputEventResult result = handleMouseMoveOrLeaveEvent(event, &hoveredNode ); 1115 WebInputEventResult result = handleMouseMoveOrLeaveEvent(event, &hoveredNode );
1159 1116
1160 Page* page = m_frame->page(); 1117 Page* page = m_frame->page();
1161 if (!page) 1118 if (!page)
1162 return result; 1119 return result;
1163 1120
1164 if (PaintLayer* layer = layerForNode(hoveredNode.innerNode())) { 1121 if (PaintLayer* layer = layerForNode(hoveredNode.innerNode())) {
1165 if (ScrollableArea* layerScrollableArea = associatedScrollableArea(layer )) 1122 if (ScrollableArea* layerScrollableArea = associatedScrollableArea(layer ))
1166 layerScrollableArea->mouseMovedInContentArea(); 1123 layerScrollableArea->mouseMovedInContentArea();
1167 } 1124 }
1168 1125
1169 if (FrameView* frameView = m_frame->view()) 1126 if (FrameView* frameView = m_frame->view())
1170 frameView->mouseMovedInContentArea(); 1127 frameView->mouseMovedInContentArea();
1171 1128
1172 hoveredNode.setToShadowHostIfInUserAgentShadowRoot(); 1129 hoveredNode.setToShadowHostIfInUserAgentShadowRoot();
1173 page->chromeClient().mouseDidMoveOverElement(hoveredNode); 1130 page->chromeClient().mouseDidMoveOverElement(hoveredNode);
1174 1131
1175 return result; 1132 return result;
1176 } 1133 }
1177 1134
1178 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event) 1135 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event)
1179 { 1136 {
1180 TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent"); 1137 TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent");
1181 1138
1182 conditionallyEnableMouseEventForPointerTypeMouse(event); 1139 m_pointerEventManager.conditionallyEnableMouseEventForPointerTypeMouse(
1140 event.modifiers());
1183 1141
1184 RefPtrWillBeRawPtr<FrameView> protector(m_frame->view()); 1142 RefPtrWillBeRawPtr<FrameView> protector(m_frame->view());
1185 handleMouseMoveOrLeaveEvent(event, 0, false, true); 1143 handleMouseMoveOrLeaveEvent(event, 0, false, true);
1186 } 1144 }
1187 1145
1188 WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMous eEvent& mouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars, bool forceLeave) 1146 WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMous eEvent& mouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars, bool forceLeave)
1189 { 1147 {
1190 ASSERT(m_frame); 1148 ASSERT(m_frame);
1191 ASSERT(m_frame->view()); 1149 ASSERT(m_frame->view());
1192 1150
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); 1314 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
1357 LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetN ode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev); 1315 LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetN ode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
1358 if (m_eventHandlerWillResetCapturingMouseEventsNode) 1316 if (m_eventHandlerWillResetCapturingMouseEventsNode)
1359 m_capturingMouseEventsNode = nullptr; 1317 m_capturingMouseEventsNode = nullptr;
1360 if (subframe) 1318 if (subframe)
1361 return passMouseReleaseEventToSubframe(mev, subframe); 1319 return passMouseReleaseEventToSubframe(mev, subframe);
1362 1320
1363 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(Event TypeNames::mouseup, mev.innerNode(), m_clickCount, mouseEvent); 1321 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(Event TypeNames::mouseup, mev.innerNode(), m_clickCount, mouseEvent);
1364 1322
1365 // TODO(crbug/545647): This state should reset with pointercancel too. 1323 // TODO(crbug/545647): This state should reset with pointercancel too.
1366 m_preventMouseEventForPointerTypeMouse = false; 1324 m_pointerEventManager.conditionallyEnableMouseEventForPointerTypeMouse(
1325 PlatformEvent::NoModifiers);
1367 1326
1368 bool contextMenuEvent = mouseEvent.button() == RightButton; 1327 bool contextMenuEvent = mouseEvent.button() == RightButton;
1369 #if OS(MACOSX) 1328 #if OS(MACOSX)
1370 // FIXME: The Mac port achieves the same behavior by checking whether the co ntext menu is currently open in WebPage::mouseEvent(). Consider merging the impl ementations. 1329 // FIXME: The Mac port achieves the same behavior by checking whether the co ntext menu is currently open in WebPage::mouseEvent(). Consider merging the impl ementations.
1371 if (mouseEvent.button() == LeftButton && mouseEvent.modifiers() & PlatformEv ent::CtrlKey) 1330 if (mouseEvent.button() == LeftButton && mouseEvent.modifiers() & PlatformEv ent::CtrlKey)
1372 contextMenuEvent = true; 1331 contextMenuEvent = true;
1373 #endif 1332 #endif
1374 1333
1375 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled; 1334 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled;
1376 if (m_clickCount > 0 && !contextMenuEvent && mev.innerNode() && m_clickNode && mev.innerNode()->canParticipateInFlatTree() && m_clickNode->canParticipateInF latTree()) { 1335 if (m_clickCount > 0 && !contextMenuEvent && mev.innerNode() && m_clickNode && mev.innerNode()->canParticipateInFlatTree() && m_clickNode->canParticipateInF latTree()) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 // The mouse has moved between layers. 1601 // The mouse has moved between layers.
1643 if (ScrollableArea* scrollableAreaForNodeUnderMouse = associatedScrollab leArea(layerForNodeUnderMouse)) 1602 if (ScrollableArea* scrollableAreaForNodeUnderMouse = associatedScrollab leArea(layerForNodeUnderMouse))
1644 scrollableAreaForNodeUnderMouse->mouseEnteredContentArea(); 1603 scrollableAreaForNodeUnderMouse->mouseEnteredContentArea();
1645 } 1604 }
1646 1605
1647 if (lastNodeUnderMouse && lastNodeUnderMouse->document() != m_frame->documen t()) { 1606 if (lastNodeUnderMouse && lastNodeUnderMouse->document() != m_frame->documen t()) {
1648 lastNodeUnderMouse = nullptr; 1607 lastNodeUnderMouse = nullptr;
1649 m_lastScrollbarUnderMouse = nullptr; 1608 m_lastScrollbarUnderMouse = nullptr;
1650 } 1609 }
1651 1610
1652 if (lastNodeUnderMouse != m_nodeUnderMouse) 1611 m_pointerEventManager.sendNodeTransitionEvents(lastNodeUnderMouse,
1653 sendNodeTransitionEvents(lastNodeUnderMouse.get(), m_nodeUnderMouse.get( ), mouseEvent); 1612 m_nodeUnderMouse, mouseEvent, m_frame->document()->domWindow());
1654 }
1655
1656 WebInputEventResult EventHandler::dispatchPointerEvent(EventTarget* target, Pass RefPtrWillBeRawPtr<PointerEvent> pointerEvent)
1657 {
1658 if (!RuntimeEnabledFeatures::pointerEventEnabled())
1659 return WebInputEventResult::NotHandled;
1660
1661 bool dispatchResult = target->dispatchEvent(pointerEvent.get());
1662 return eventToEventResult(pointerEvent, dispatchResult);
1663 }
1664
1665 void EventHandler::sendNodeTransitionEvents(Node* exitedNode, Node* enteredNode,
1666 const PlatformMouseEvent& mouseEvent)
1667 {
1668 ASSERT(exitedNode != enteredNode);
1669
1670 // Dispatch pointerout/mouseout events
1671 if (isNodeInDocument(exitedNode)) {
1672 sendPointerAndMouseTransitionEvents(exitedNode, EventTypeNames::mouseout , mouseEvent, enteredNode, false);
1673 }
1674
1675 // A note on mouseenter and mouseleave: These are non-bubbling events, and t hey are dispatched if there
1676 // is a capturing event handler on an ancestor or a normal event handler on the element itself. This special
1677 // handling is necessary to avoid O(n^2) capturing event handler checks.
1678 //
1679 // Note, however, that this optimization can possibly cause some unanswere d/missing/redundant mouseenter or
1680 // mouseleave events in certain contrived eventhandling scenarios, e.g., whe n:
1681 // - the mouseleave handler for a node sets the only capturing-mouseleave-li stener in its ancestor, or
1682 // - DOM mods in any mouseenter/mouseleave handler changes the common ancest or of exited & entered nodes, etc.
1683 // We think the spec specifies a "frozen" state to avoid such corner cases ( check the discussion on "candidate event
1684 // listeners" at http://www.w3.org/TR/uievents), but our code below preserve s one such behavior from past only to
1685 // match Firefox and IE behavior.
1686 //
1687 // TODO(mustaq): Confirm spec conformance, double-check with other browsers.
1688
1689 // Create lists of all exited/entered ancestors, locate the common ancestor & capturing listeners.
1690 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors;
1691 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors;
1692 if (isNodeInDocument(exitedNode)) {
1693 exitedNode->updateDistribution();
1694 for (Node* node = exitedNode; node; node = FlatTreeTraversal::parent(*no de)) {
1695 exitedAncestors.append(node);
1696 }
1697 }
1698 if (isNodeInDocument(enteredNode)) {
1699 enteredNode->updateDistribution();
1700 for (Node* node = enteredNode; node; node = FlatTreeTraversal::parent(*n ode)) {
1701 enteredAncestors.append(node);
1702 }
1703 }
1704
1705 size_t numExitedAncestors = exitedAncestors.size();
1706 size_t numEnteredAncestors = enteredAncestors.size();
1707
1708 size_t exitedAncestorIndex = numExitedAncestors;
1709 size_t enteredAncestorIndex = numEnteredAncestors;
1710 for (size_t j = 0; j < numExitedAncestors; j++) {
1711 for (size_t i = 0; i < numEnteredAncestors; i++) {
1712 if (exitedAncestors[j] == enteredAncestors[i]) {
1713 exitedAncestorIndex = j;
1714 enteredAncestorIndex = i;
1715 break;
1716 }
1717 }
1718 if (exitedAncestorIndex < numExitedAncestors)
1719 break;
1720 }
1721
1722 bool exitedNodeHasCapturingAncestor = false;
1723 for (size_t j = 0; j < numExitedAncestors; j++) {
1724 if (exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::mouse leave)
1725 || (RuntimeEnabledFeatures::pointerEventEnabled()
1726 && exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::po interleave)))
1727 exitedNodeHasCapturingAncestor = true;
1728 }
1729
1730 // Dispatch pointerleave/mouseleave events, in child-to-parent order.
1731 for (size_t j = 0; j < exitedAncestorIndex; j++) {
1732 sendPointerAndMouseTransitionEvents(exitedAncestors[j].get(), EventTypeN ames::mouseleave, mouseEvent, enteredNode, !exitedNodeHasCapturingAncestor);
1733 }
1734
1735 // Dispatch pointerover/mouseover.
1736 if (isNodeInDocument(enteredNode)) {
1737 sendPointerAndMouseTransitionEvents(enteredNode, EventTypeNames::mouseov er, mouseEvent, exitedNode, false);
1738 }
1739
1740 // Defer locating capturing pointeenter/mouseenter listener until /after/ di spatching the leave events because
1741 // the leave handlers might set a capturing enter handler.
1742 bool enteredNodeHasCapturingAncestor = false;
1743 for (size_t i = 0; i < numEnteredAncestors; i++) {
1744 if (enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::mous eenter)
1745 || (RuntimeEnabledFeatures::pointerEventEnabled()
1746 && enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::p ointerenter)))
1747 enteredNodeHasCapturingAncestor = true;
1748 }
1749
1750 // Dispatch pointerenter/mouseenter events, in parent-to-child order.
1751 for (size_t i = enteredAncestorIndex; i > 0; i--) {
1752 sendPointerAndMouseTransitionEvents(enteredAncestors[i-1].get(), EventTy peNames::mouseenter, mouseEvent, exitedNode, !enteredNodeHasCapturingAncestor);
1753 }
1754 } 1613 }
1755 1614
1756 WebInputEventResult EventHandler::dispatchMouseEvent(const AtomicString& eventTy pe, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent) 1615 WebInputEventResult EventHandler::dispatchMouseEvent(const AtomicString& eventTy pe, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent)
1757 { 1616 {
1758 updateMouseEventTargetNode(targetNode, mouseEvent); 1617 updateMouseEventTargetNode(targetNode, mouseEvent);
1759 if (!m_nodeUnderMouse) 1618 if (!m_nodeUnderMouse)
1760 return WebInputEventResult::NotHandled; 1619 return WebInputEventResult::NotHandled;
1761 1620
1762 RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(eventType, m_nodeU nderMouse->document().domWindow(), mouseEvent, clickCount, nullptr); 1621 RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(eventType, m_nodeU nderMouse->document().domWindow(), mouseEvent, clickCount, nullptr);
1763 bool dispatchResult = m_nodeUnderMouse->dispatchEvent(event); 1622 bool dispatchResult = m_nodeUnderMouse->dispatchEvent(event);
1764 return eventToEventResult(event, dispatchResult); 1623 return eventToEventResult(event, dispatchResult);
1765 } 1624 }
1766 1625
1767 EventTarget* EventHandler::getEffectiveTargetForPointerEvent(
1768 EventTarget* target, PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent)
1769 {
1770 EventTarget* capturingNode = m_pointerEventManager.getCapturingNode(pointerE vent.get());
1771 if (capturingNode)
1772 target = capturingNode;
1773 return target;
1774 }
1775
1776 void EventHandler::sendPointerAndMouseTransitionEvents(Node* target, const Atomi cString& mouseEventType,
1777 const PlatformMouseEvent& mouseEvent, Node* relatedTarget, bool checkForList ener)
1778 {
1779 ASSERT(mouseEventType == EventTypeNames::mouseenter
1780 || mouseEventType == EventTypeNames::mouseleave
1781 || mouseEventType == EventTypeNames::mouseover
1782 || mouseEventType == EventTypeNames::mouseout);
1783
1784 AtomicString pointerEventType = pointerEventNameForMouseEventName(mouseEvent Type);
1785 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.create (pointerEventType,
1786 mouseEvent, relatedTarget, m_frame->document()->domWindow());
1787
1788 // Suppress these events if the target is not the capturing element
1789 if (target != getEffectiveTargetForPointerEvent(target, pointerEvent))
1790 return;
1791
1792 if (!checkForListener || target->hasEventListeners(pointerEventType))
1793 dispatchPointerEvent(target, pointerEvent);
1794
1795 if (!checkForListener || target->hasEventListeners(mouseEventType))
1796 target->dispatchMouseEvent(mouseEvent, mouseEventType, 0, relatedTarget) ;
1797 }
1798
1799 // TODO(mustaq): Make PE drive ME dispatch & bookkeeping in EventHandler. 1626 // TODO(mustaq): Make PE drive ME dispatch & bookkeeping in EventHandler.
1800 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const Ato micString& mouseEventType, Node* targetNode, int clickCount, const PlatformMouse Event& mouseEvent) 1627 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const Ato micString& mouseEventType, Node* targetNode, int clickCount, const PlatformMouse Event& mouseEvent)
1801 { 1628 {
1802 ASSERT(mouseEventType == EventTypeNames::mousedown 1629 ASSERT(mouseEventType == EventTypeNames::mousedown
1803 || mouseEventType == EventTypeNames::mousemove 1630 || mouseEventType == EventTypeNames::mousemove
1804 || mouseEventType == EventTypeNames::mouseup); 1631 || mouseEventType == EventTypeNames::mouseup);
1805 1632
1806 updateMouseEventTargetNode(targetNode, mouseEvent); 1633 updateMouseEventTargetNode(targetNode, mouseEvent);
1807 if (!m_nodeUnderMouse) 1634 if (!m_nodeUnderMouse)
1808 return WebInputEventResult::NotHandled; 1635 return WebInputEventResult::NotHandled;
1809 1636
1810 AtomicString pointerEventType = pointerEventNameForMouseEventName(mouseEvent Type); 1637 WebInputEventResult result = m_pointerEventManager.sendMousePointerEvent(
1811 unsigned short pointerButtonsPressed = MouseEvent::platformModifiersToButton s(mouseEvent.modifiers()); 1638 m_nodeUnderMouse, mouseEventType, clickCount, mouseEvent, nullptr,
1812 1639 m_frame->document()->domWindow());
1813 // Make sure chorded buttons fire pointermove instead of pointerup/pointerdo wn.
1814 if ((pointerEventType == EventTypeNames::pointerdown && (pointerButtonsPress ed & ~MouseEvent::buttonToButtons(mouseEvent.button())) != 0)
1815 || (pointerEventType == EventTypeNames::pointerup && pointerButtonsPress ed != 0))
1816 pointerEventType = EventTypeNames::pointermove;
1817
1818 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.create (pointerEventType,
1819 mouseEvent, nullptr, m_frame->document()->domWindow());
1820
1821 EventTarget* target = getEffectiveTargetForPointerEvent(m_nodeUnderMouse.get (), pointerEvent);
1822 WebInputEventResult result = dispatchPointerEvent(target, pointerEvent);
1823
1824 if (result != WebInputEventResult::NotHandled && pointerEventType == EventTy peNames::pointerdown)
1825 m_preventMouseEventForPointerTypeMouse = true;
1826
1827 if (!m_preventMouseEventForPointerTypeMouse) {
1828 RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(mouseEventType , m_nodeUnderMouse->document().domWindow(), mouseEvent, clickCount, nullptr);
1829 bool dispatchResult = target->dispatchEvent(event);
1830 result = mergeEventResult(result, eventToEventResult(event, dispatchResu lt));
1831 }
1832 1640
1833 return result; 1641 return result;
1834 } 1642 }
1835 1643
1836 WebInputEventResult EventHandler::handleMouseFocus(const MouseEventWithHitTestRe sults& targetedEvent, InputDeviceCapabilities* sourceCapabilities) 1644 WebInputEventResult EventHandler::handleMouseFocus(const MouseEventWithHitTestRe sults& targetedEvent, InputDeviceCapabilities* sourceCapabilities)
1837 { 1645 {
1838 // If clicking on a frame scrollbar, do not mess up with content focus. 1646 // If clicking on a frame scrollbar, do not mess up with content focus.
1839 if (targetedEvent.hitTestResult().scrollbar() && m_frame->contentLayoutObjec t()) { 1647 if (targetedEvent.hitTestResult().scrollbar() && m_frame->contentLayoutObjec t()) {
1840 if (targetedEvent.hitTestResult().scrollbar()->scrollableArea() == m_fra me->contentLayoutObject()->scrollableArea()) 1648 if (targetedEvent.hitTestResult().scrollbar()->scrollableArea() == m_fra me->contentLayoutObject()->scrollableArea())
1841 return WebInputEventResult::NotHandled; 1649 return WebInputEventResult::NotHandled;
(...skipping 1894 matching lines...) Expand 10 before | Expand all | Expand 10 after
3736 void EventHandler::dispatchPointerEvents(const PlatformTouchEvent& event, 3544 void EventHandler::dispatchPointerEvents(const PlatformTouchEvent& event,
3737 WillBeHeapVector<TouchInfo>& touchInfos) 3545 WillBeHeapVector<TouchInfo>& touchInfos)
3738 { 3546 {
3739 if (!RuntimeEnabledFeatures::pointerEventEnabled()) 3547 if (!RuntimeEnabledFeatures::pointerEventEnabled())
3740 return; 3548 return;
3741 3549
3742 // Iterate through the touch points, sending PointerEvents to the targets as required. 3550 // Iterate through the touch points, sending PointerEvents to the targets as required.
3743 for (unsigned i = 0; i < touchInfos.size(); ++i) { 3551 for (unsigned i = 0; i < touchInfos.size(); ++i) {
3744 TouchInfo& touchInfo = touchInfos[i]; 3552 TouchInfo& touchInfo = touchInfos[i];
3745 const PlatformTouchPoint& touchPoint = touchInfo.point; 3553 const PlatformTouchPoint& touchPoint = touchInfo.point;
3746 const PlatformTouchPoint::State pointState = touchPoint.state();
3747 3554
3748 3555
3749 if (pointState == PlatformTouchPoint::TouchStationary || !touchInfo.know nTarget) 3556 if (touchPoint.state() == PlatformTouchPoint::TouchStationary
3557 || !touchInfo.knownTarget)
3750 continue; 3558 continue;
3751 3559
3752 bool pointerReleasedOrCancelled = pointState == PlatformTouchPoint::Touc hReleased 3560 WebInputEventResult result =
3753 || pointState == PlatformTouchPoint::TouchCancelled; 3561 m_pointerEventManager.sendTouchPointerEvent(
3754 3562 touchInfo.touchTarget, touchPoint, event.modifiers(),
3755 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.cr eate(
3756 pointerEventNameForTouchPointState(pointState),
3757 touchPoint, event.modifiers(),
3758 touchInfo.adjustedRadius.width(), touchInfo.adjustedRadius.height(), 3563 touchInfo.adjustedRadius.width(), touchInfo.adjustedRadius.height(),
3759 touchInfo.adjustedPagePoint.x(), touchInfo.adjustedPagePoint.y()); 3564 touchInfo.adjustedPagePoint.x(), touchInfo.adjustedPagePoint.y());
3760 3565 touchInfo.consumed = result != WebInputEventResult::NotHandled;
3761 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturi ng vs pointer event capturing
3762 touchInfo.touchTarget->dispatchEvent(pointerEvent.get());
3763
3764 touchInfo.consumed = pointerEvent->defaultPrevented() || pointerEvent->d efaultHandled();
3765
3766 // Remove the released/cancelled id at the end to correctly determine pr imary id above.
3767 if (pointerReleasedOrCancelled)
3768 m_pointerEventManager.remove(pointerEvent);
3769 } 3566 }
3770 } 3567 }
3771 3568
3772 void EventHandler::sendPointerCancels(WillBeHeapVector<TouchInfo>& touchInfos) 3569 void EventHandler::sendPointerCancels(WillBeHeapVector<TouchInfo>& touchInfos)
3773 { 3570 {
3774 if (!RuntimeEnabledFeatures::pointerEventEnabled()) 3571 if (!RuntimeEnabledFeatures::pointerEventEnabled())
3775 return; 3572 return;
3776 3573
3777 for (unsigned i = 0; i < touchInfos.size(); ++i) { 3574 for (unsigned i = 0; i < touchInfos.size(); ++i) {
3778 TouchInfo& touchInfo = touchInfos[i]; 3575 TouchInfo& touchInfo = touchInfos[i];
3779 const PlatformTouchPoint& point = touchInfo.point; 3576 const PlatformTouchPoint& point = touchInfo.point;
3780 const PlatformTouchPoint::State pointState = point.state(); 3577 const PlatformTouchPoint::State pointState = point.state();
3781 3578
3782 if (pointState == PlatformTouchPoint::TouchReleased 3579 if (pointState == PlatformTouchPoint::TouchReleased
3783 || pointState == PlatformTouchPoint::TouchCancelled) 3580 || pointState == PlatformTouchPoint::TouchCancelled)
3784 continue; 3581 continue;
3785 3582
3786 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.cr eatePointerCancel(point); 3583 m_pointerEventManager.sendTouchCancelPointerEvent(
3787 3584 touchInfo.touchTarget,
3788 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturi ng vs pointer event capturing 3585 point);
3789 touchInfo.touchTarget->dispatchEvent(pointerEvent.get());
3790
3791 m_pointerEventManager.remove(pointerEvent);
3792 } 3586 }
3793 } 3587 }
3794 3588
3795 namespace { 3589 namespace {
3796 3590
3797 // Defining this class type local to dispatchTouchEvents() and annotating 3591 // Defining this class type local to dispatchTouchEvents() and annotating
3798 // it with STACK_ALLOCATED(), runs into MSVC(VS 2013)'s C4822 warning 3592 // it with STACK_ALLOCATED(), runs into MSVC(VS 2013)'s C4822 warning
3799 // that the local class doesn't provide a local definition for 'operator new'. 3593 // that the local class doesn't provide a local definition for 'operator new'.
3800 // Which it intentionally doesn't and shouldn't. 3594 // Which it intentionally doesn't and shouldn't.
3801 // 3595 //
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
4109 return eventResult; 3903 return eventResult;
4110 } 3904 }
4111 3905
4112 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event) 3906 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
4113 { 3907 {
4114 m_mousePositionIsUnknown = false; 3908 m_mousePositionIsUnknown = false;
4115 m_lastKnownMousePosition = event.position(); 3909 m_lastKnownMousePosition = event.position();
4116 m_lastKnownMouseGlobalPosition = event.globalPosition(); 3910 m_lastKnownMouseGlobalPosition = event.globalPosition();
4117 } 3911 }
4118 3912
4119 void EventHandler::conditionallyEnableMouseEventForPointerTypeMouse(const Platfo rmMouseEvent& event)
4120 {
4121 if (event.button() == NoButton)
4122 m_preventMouseEventForPointerTypeMouse = false;
4123 }
4124
4125 WebInputEventResult EventHandler::passMousePressEventToSubframe(MouseEventWithHi tTestResults& mev, LocalFrame* subframe) 3913 WebInputEventResult EventHandler::passMousePressEventToSubframe(MouseEventWithHi tTestResults& mev, LocalFrame* subframe)
4126 { 3914 {
4127 selectionController().passMousePressEventToSubframe(mev); 3915 selectionController().passMousePressEventToSubframe(mev);
4128 WebInputEventResult result = subframe->eventHandler().handleMousePressEvent( mev.event()); 3916 WebInputEventResult result = subframe->eventHandler().handleMousePressEvent( mev.event());
4129 if (result != WebInputEventResult::NotHandled) 3917 if (result != WebInputEventResult::NotHandled)
4130 return result; 3918 return result;
4131 return WebInputEventResult::HandledSystem; 3919 return WebInputEventResult::HandledSystem;
4132 } 3920 }
4133 3921
4134 WebInputEventResult EventHandler::passMouseMoveEventToSubframe(MouseEventWithHit TestResults& mev, LocalFrame* subframe, HitTestResult* hoveredNode) 3922 WebInputEventResult EventHandler::passMouseMoveEventToSubframe(MouseEventWithHit TestResults& mev, LocalFrame* subframe, HitTestResult* hoveredNode)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4175 PlatformEvent::Modifiers EventHandler::accessKeyModifiers() 3963 PlatformEvent::Modifiers EventHandler::accessKeyModifiers()
4176 { 3964 {
4177 #if OS(MACOSX) 3965 #if OS(MACOSX)
4178 return static_cast<PlatformEvent::Modifiers>(PlatformEvent::CtrlKey | Platfo rmEvent::AltKey); 3966 return static_cast<PlatformEvent::Modifiers>(PlatformEvent::CtrlKey | Platfo rmEvent::AltKey);
4179 #else 3967 #else
4180 return PlatformEvent::AltKey; 3968 return PlatformEvent::AltKey;
4181 #endif 3969 #endif
4182 } 3970 }
4183 3971
4184 } // namespace blink 3972 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/input/EventHandler.h ('k') | third_party/WebKit/Source/core/input/PointerEventManager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698