OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |