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

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: Add the tests 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 responseA, WebInputEventResult responseB)
mustaq 2016/02/11 16:15:16 s/response/result/
Navid Zolghadr 2016/02/11 16:34:52 Will do.
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>(responseA), sta tic_cast<int>(responseB)));
368 }
369
370 WebInputEventResult EventHandler::eventToEventResult(
371 PassRefPtrWillBeRawPtr<Event> event, bool res)
mustaq 2016/02/11 16:15:16 s/res/result/
Navid Zolghadr 2016/02/11 16:34:52 Will do.
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 (!res)
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 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); 1312 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
1357 LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetN ode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev); 1313 LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetN ode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
1358 if (m_eventHandlerWillResetCapturingMouseEventsNode) 1314 if (m_eventHandlerWillResetCapturingMouseEventsNode)
1359 m_capturingMouseEventsNode = nullptr; 1315 m_capturingMouseEventsNode = nullptr;
1360 if (subframe) 1316 if (subframe)
1361 return passMouseReleaseEventToSubframe(mev, subframe); 1317 return passMouseReleaseEventToSubframe(mev, subframe);
1362 1318
1363 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(Event TypeNames::mouseup, mev.innerNode(), m_clickCount, mouseEvent); 1319 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(Event TypeNames::mouseup, mev.innerNode(), m_clickCount, mouseEvent);
1364 1320
1365 // TODO(crbug/545647): This state should reset with pointercancel too. 1321 // TODO(crbug/545647): This state should reset with pointercancel too.
1366 m_preventMouseEventForPointerTypeMouse = false; 1322 m_pointerEventManager.clearPreventMouseEventForPointerTypeMouse();
1367 1323
1368 bool contextMenuEvent = mouseEvent.button() == RightButton; 1324 bool contextMenuEvent = mouseEvent.button() == RightButton;
1369 #if OS(MACOSX) 1325 #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. 1326 // 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) 1327 if (mouseEvent.button() == LeftButton && mouseEvent.modifiers() & PlatformEv ent::CtrlKey)
1372 contextMenuEvent = true; 1328 contextMenuEvent = true;
1373 #endif 1329 #endif
1374 1330
1375 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled; 1331 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled;
1376 if (m_clickCount > 0 && !contextMenuEvent && mev.innerNode() && m_clickNode && mev.innerNode()->canParticipateInFlatTree() && m_clickNode->canParticipateInF latTree()) { 1332 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. 1598 // The mouse has moved between layers.
1643 if (ScrollableArea* scrollableAreaForNodeUnderMouse = associatedScrollab leArea(layerForNodeUnderMouse)) 1599 if (ScrollableArea* scrollableAreaForNodeUnderMouse = associatedScrollab leArea(layerForNodeUnderMouse))
1644 scrollableAreaForNodeUnderMouse->mouseEnteredContentArea(); 1600 scrollableAreaForNodeUnderMouse->mouseEnteredContentArea();
1645 } 1601 }
1646 1602
1647 if (lastNodeUnderMouse && lastNodeUnderMouse->document() != m_frame->documen t()) { 1603 if (lastNodeUnderMouse && lastNodeUnderMouse->document() != m_frame->documen t()) {
1648 lastNodeUnderMouse = nullptr; 1604 lastNodeUnderMouse = nullptr;
1649 m_lastScrollbarUnderMouse = nullptr; 1605 m_lastScrollbarUnderMouse = nullptr;
1650 } 1606 }
1651 1607
1652 if (lastNodeUnderMouse != m_nodeUnderMouse) 1608 m_pointerEventManager.sendNodeTransitionEvents(lastNodeUnderMouse.get(),
mustaq 2016/02/11 16:15:16 I think you can pass the RefPtrWillBeMember params
Navid Zolghadr 2016/02/11 16:34:51 Yup. I later changed the interface of setNodeTrans
mustaq 2016/02/11 20:37:29 Same applies for enteredNode.
Navid Zolghadr 2016/02/12 16:30:47 Done.
1653 sendNodeTransitionEvents(lastNodeUnderMouse.get(), m_nodeUnderMouse.get( ), mouseEvent); 1609 m_nodeUnderMouse.get(), 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 } 1610 }
1755 1611
1756 WebInputEventResult EventHandler::dispatchMouseEvent(const AtomicString& eventTy pe, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent) 1612 WebInputEventResult EventHandler::dispatchMouseEvent(const AtomicString& eventTy pe, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent)
1757 { 1613 {
1758 updateMouseEventTargetNode(targetNode, mouseEvent); 1614 updateMouseEventTargetNode(targetNode, mouseEvent);
1759 if (!m_nodeUnderMouse) 1615 if (!m_nodeUnderMouse)
1760 return WebInputEventResult::NotHandled; 1616 return WebInputEventResult::NotHandled;
1761 1617
1762 RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(eventType, m_nodeU nderMouse->document().domWindow(), mouseEvent, clickCount, nullptr); 1618 RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(eventType, m_nodeU nderMouse->document().domWindow(), mouseEvent, clickCount, nullptr);
1763 bool dispatchResult = m_nodeUnderMouse->dispatchEvent(event); 1619 bool dispatchResult = m_nodeUnderMouse->dispatchEvent(event);
1764 return eventToEventResult(event, dispatchResult); 1620 return eventToEventResult(event, dispatchResult);
1765 } 1621 }
1766 1622
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. 1623 // 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) 1624 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const Ato micString& mouseEventType, Node* targetNode, int clickCount, const PlatformMouse Event& mouseEvent)
1801 { 1625 {
1802 ASSERT(mouseEventType == EventTypeNames::mousedown 1626 ASSERT(mouseEventType == EventTypeNames::mousedown
1803 || mouseEventType == EventTypeNames::mousemove 1627 || mouseEventType == EventTypeNames::mousemove
1804 || mouseEventType == EventTypeNames::mouseup); 1628 || mouseEventType == EventTypeNames::mouseup);
1805 1629
1806 updateMouseEventTargetNode(targetNode, mouseEvent); 1630 updateMouseEventTargetNode(targetNode, mouseEvent);
1807 if (!m_nodeUnderMouse) 1631 if (!m_nodeUnderMouse)
1808 return WebInputEventResult::NotHandled; 1632 return WebInputEventResult::NotHandled;
1809 1633
1810 AtomicString pointerEventType = pointerEventNameForMouseEventName(mouseEvent Type); 1634 WebInputEventResult result = m_pointerEventManager.sendMousePointerEvent(
1811 unsigned short pointerButtonsPressed = MouseEvent::platformModifiersToButton s(mouseEvent.modifiers()); 1635 m_nodeUnderMouse, mouseEventType, clickCount, mouseEvent, nullptr,
1812 1636 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 1637
1833 return result; 1638 return result;
1834 } 1639 }
1835 1640
1836 WebInputEventResult EventHandler::handleMouseFocus(const MouseEventWithHitTestRe sults& targetedEvent, InputDeviceCapabilities* sourceCapabilities) 1641 WebInputEventResult EventHandler::handleMouseFocus(const MouseEventWithHitTestRe sults& targetedEvent, InputDeviceCapabilities* sourceCapabilities)
1837 { 1642 {
1838 // If clicking on a frame scrollbar, do not mess up with content focus. 1643 // If clicking on a frame scrollbar, do not mess up with content focus.
1839 if (targetedEvent.hitTestResult().scrollbar() && m_frame->contentLayoutObjec t()) { 1644 if (targetedEvent.hitTestResult().scrollbar() && m_frame->contentLayoutObjec t()) {
1840 if (targetedEvent.hitTestResult().scrollbar()->scrollableArea() == m_fra me->contentLayoutObject()->scrollableArea()) 1645 if (targetedEvent.hitTestResult().scrollbar()->scrollableArea() == m_fra me->contentLayoutObject()->scrollableArea())
1841 return WebInputEventResult::NotHandled; 1646 return WebInputEventResult::NotHandled;
(...skipping 1894 matching lines...) Expand 10 before | Expand all | Expand 10 after
3736 void EventHandler::dispatchPointerEvents(const PlatformTouchEvent& event, 3541 void EventHandler::dispatchPointerEvents(const PlatformTouchEvent& event,
3737 WillBeHeapVector<TouchInfo>& touchInfos) 3542 WillBeHeapVector<TouchInfo>& touchInfos)
3738 { 3543 {
3739 if (!RuntimeEnabledFeatures::pointerEventEnabled()) 3544 if (!RuntimeEnabledFeatures::pointerEventEnabled())
3740 return; 3545 return;
3741 3546
3742 // Iterate through the touch points, sending PointerEvents to the targets as required. 3547 // Iterate through the touch points, sending PointerEvents to the targets as required.
3743 for (unsigned i = 0; i < touchInfos.size(); ++i) { 3548 for (unsigned i = 0; i < touchInfos.size(); ++i) {
3744 TouchInfo& touchInfo = touchInfos[i]; 3549 TouchInfo& touchInfo = touchInfos[i];
3745 const PlatformTouchPoint& touchPoint = touchInfo.point; 3550 const PlatformTouchPoint& touchPoint = touchInfo.point;
3746 const PlatformTouchPoint::State pointState = touchPoint.state();
3747 3551
3748 3552
3749 if (pointState == PlatformTouchPoint::TouchStationary || !touchInfo.know nTarget) 3553 if (touchPoint.state() == PlatformTouchPoint::TouchStationary
3554 || !touchInfo.knownTarget)
3750 continue; 3555 continue;
3751 3556
3752 bool pointerReleasedOrCancelled = pointState == PlatformTouchPoint::Touc hReleased 3557 touchInfo.consumed = m_pointerEventManager.sendTouchPointerEvent(
mustaq 2016/02/11 16:15:16 Please split the line into two, long "x = y != z"
Navid Zolghadr 2016/02/11 16:34:52 Sure.
3753 || pointState == PlatformTouchPoint::TouchCancelled; 3558 touchInfo.touchTarget, touchPoint, event.modifiers(),
3754
3755 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.cr eate(
3756 pointerEventNameForTouchPointState(pointState),
3757 touchPoint, event.modifiers(),
3758 touchInfo.adjustedRadius.width(), touchInfo.adjustedRadius.height(), 3559 touchInfo.adjustedRadius.width(), touchInfo.adjustedRadius.height(),
3759 touchInfo.adjustedPagePoint.x(), touchInfo.adjustedPagePoint.y()); 3560 touchInfo.adjustedPagePoint.x(), touchInfo.adjustedPagePoint.y()) !=
3760 3561 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 } 3562 }
3770 } 3563 }
3771 3564
3772 void EventHandler::sendPointerCancels(WillBeHeapVector<TouchInfo>& touchInfos) 3565 void EventHandler::sendPointerCancels(WillBeHeapVector<TouchInfo>& touchInfos)
3773 { 3566 {
3774 if (!RuntimeEnabledFeatures::pointerEventEnabled()) 3567 if (!RuntimeEnabledFeatures::pointerEventEnabled())
3775 return; 3568 return;
3776 3569
3777 for (unsigned i = 0; i < touchInfos.size(); ++i) { 3570 for (unsigned i = 0; i < touchInfos.size(); ++i) {
3778 TouchInfo& touchInfo = touchInfos[i]; 3571 TouchInfo& touchInfo = touchInfos[i];
3779 const PlatformTouchPoint& point = touchInfo.point; 3572 const PlatformTouchPoint& point = touchInfo.point;
3780 const PlatformTouchPoint::State pointState = point.state(); 3573 const PlatformTouchPoint::State pointState = point.state();
3781 3574
3782 if (pointState == PlatformTouchPoint::TouchReleased 3575 if (pointState == PlatformTouchPoint::TouchReleased
3783 || pointState == PlatformTouchPoint::TouchCancelled) 3576 || pointState == PlatformTouchPoint::TouchCancelled)
3784 continue; 3577 continue;
3785 3578
3786 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.cr eatePointerCancel(point); 3579 m_pointerEventManager.sendTouchCancelPointerEvent(
3787 3580 touchInfo.touchTarget,
3788 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturi ng vs pointer event capturing 3581 point);
3789 touchInfo.touchTarget->dispatchEvent(pointerEvent.get());
3790
3791 m_pointerEventManager.remove(pointerEvent);
3792 } 3582 }
3793 } 3583 }
3794 3584
3795 namespace { 3585 namespace {
3796 3586
3797 // Defining this class type local to dispatchTouchEvents() and annotating 3587 // Defining this class type local to dispatchTouchEvents() and annotating
3798 // it with STACK_ALLOCATED(), runs into MSVC(VS 2013)'s C4822 warning 3588 // 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'. 3589 // that the local class doesn't provide a local definition for 'operator new'.
3800 // Which it intentionally doesn't and shouldn't. 3590 // Which it intentionally doesn't and shouldn't.
3801 // 3591 //
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
4112 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event) 3902 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
4113 { 3903 {
4114 m_mousePositionIsUnknown = false; 3904 m_mousePositionIsUnknown = false;
4115 m_lastKnownMousePosition = event.position(); 3905 m_lastKnownMousePosition = event.position();
4116 m_lastKnownMouseGlobalPosition = event.globalPosition(); 3906 m_lastKnownMouseGlobalPosition = event.globalPosition();
4117 } 3907 }
4118 3908
4119 void EventHandler::conditionallyEnableMouseEventForPointerTypeMouse(const Platfo rmMouseEvent& event) 3909 void EventHandler::conditionallyEnableMouseEventForPointerTypeMouse(const Platfo rmMouseEvent& event)
4120 { 3910 {
4121 if (event.button() == NoButton) 3911 if (event.button() == NoButton)
4122 m_preventMouseEventForPointerTypeMouse = false; 3912 m_pointerEventManager.clearPreventMouseEventForPointerTypeMouse();
mustaq 2016/02/11 16:15:16 PE manager's clearPreventMouseEventForPointerTypeM
Navid Zolghadr 2016/02/11 16:34:52 I wanted to totally hid this from EventHandler but
mustaq 2016/02/11 16:51:12 Can't you just call m_pointerEventManager.conditio
Navid Zolghadr 2016/02/11 17:47:49 Sure. I will move that function to PointerEventMan
4123 } 3913 }
4124 3914
4125 WebInputEventResult EventHandler::passMousePressEventToSubframe(MouseEventWithHi tTestResults& mev, LocalFrame* subframe) 3915 WebInputEventResult EventHandler::passMousePressEventToSubframe(MouseEventWithHi tTestResults& mev, LocalFrame* subframe)
4126 { 3916 {
4127 selectionController().passMousePressEventToSubframe(mev); 3917 selectionController().passMousePressEventToSubframe(mev);
4128 WebInputEventResult result = subframe->eventHandler().handleMousePressEvent( mev.event()); 3918 WebInputEventResult result = subframe->eventHandler().handleMousePressEvent( mev.event());
4129 if (result != WebInputEventResult::NotHandled) 3919 if (result != WebInputEventResult::NotHandled)
4130 return result; 3920 return result;
4131 return WebInputEventResult::HandledSystem; 3921 return WebInputEventResult::HandledSystem;
4132 } 3922 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4175 PlatformEvent::Modifiers EventHandler::accessKeyModifiers() 3965 PlatformEvent::Modifiers EventHandler::accessKeyModifiers()
4176 { 3966 {
4177 #if OS(MACOSX) 3967 #if OS(MACOSX)
4178 return static_cast<PlatformEvent::Modifiers>(PlatformEvent::CtrlKey | Platfo rmEvent::AltKey); 3968 return static_cast<PlatformEvent::Modifiers>(PlatformEvent::CtrlKey | Platfo rmEvent::AltKey);
4179 #else 3969 #else
4180 return PlatformEvent::AltKey; 3970 return PlatformEvent::AltKey;
4181 #endif 3971 #endif
4182 } 3972 }
4183 3973
4184 } // namespace blink 3974 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698