| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/input/PointerEventManager.h" | 5 #include "core/input/PointerEventManager.h" |
| 6 | 6 |
| 7 #include "core/dom/ElementTraversal.h" | 7 #include "core/dom/ElementTraversal.h" |
| 8 #include "core/dom/shadow/FlatTreeTraversal.h" | 8 #include "core/dom/shadow/FlatTreeTraversal.h" |
| 9 #include "core/events/MouseEvent.h" | 9 #include "core/events/MouseEvent.h" |
| 10 #include "core/frame/FrameView.h" | 10 #include "core/frame/FrameView.h" |
| 11 #include "core/frame/UseCounter.h" | 11 #include "core/frame/UseCounter.h" |
| 12 #include "core/html/HTMLCanvasElement.h" | 12 #include "core/html/HTMLCanvasElement.h" |
| 13 #include "core/input/EventHandler.h" | 13 #include "core/input/EventHandler.h" |
| 14 #include "core/input/EventHandlingUtil.h" |
| 15 #include "core/input/MouseEventManager.h" |
| 14 #include "core/input/TouchActionUtil.h" | 16 #include "core/input/TouchActionUtil.h" |
| 15 #include "core/layout/HitTestCanvasResult.h" | 17 #include "core/layout/HitTestCanvasResult.h" |
| 16 #include "core/page/ChromeClient.h" | 18 #include "core/page/ChromeClient.h" |
| 17 #include "core/page/Page.h" | 19 #include "core/page/Page.h" |
| 18 #include "platform/PlatformTouchEvent.h" | 20 #include "platform/PlatformTouchEvent.h" |
| 19 | 21 |
| 20 namespace blink { | 22 namespace blink { |
| 21 | 23 |
| 22 namespace { | 24 namespace { |
| 23 | 25 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 40 NOTREACHED(); | 42 NOTREACHED(); |
| 41 return emptyAtom; | 43 return emptyAtom; |
| 42 } | 44 } |
| 43 } | 45 } |
| 44 | 46 |
| 45 bool isInDocument(EventTarget* n) | 47 bool isInDocument(EventTarget* n) |
| 46 { | 48 { |
| 47 return n && n->toNode() && n->toNode()->isConnected(); | 49 return n && n->toNode() && n->toNode()->isConnected(); |
| 48 } | 50 } |
| 49 | 51 |
| 50 WebInputEventResult dispatchMouseEvent( | |
| 51 EventTarget* target, | |
| 52 const AtomicString& mouseEventType, | |
| 53 const PlatformMouseEvent& mouseEvent, | |
| 54 EventTarget* relatedTarget, | |
| 55 int detail = 0, | |
| 56 bool checkForListener = false) | |
| 57 { | |
| 58 if (target && target->toNode() | |
| 59 && (!checkForListener || target->hasEventListeners(mouseEventType))) { | |
| 60 Node* targetNode = target->toNode(); | |
| 61 MouseEvent* event = MouseEvent::create(mouseEventType, | |
| 62 targetNode->document().domWindow(), mouseEvent, detail, | |
| 63 relatedTarget ? relatedTarget->toNode() : nullptr); | |
| 64 DispatchEventResult dispatchResult = target->dispatchEvent(event); | |
| 65 return EventHandler::toWebInputEventResult(dispatchResult); | |
| 66 } | |
| 67 return WebInputEventResult::NotHandled; | |
| 68 } | |
| 69 | |
| 70 PlatformMouseEvent mouseEventWithRegion(Node* node, const PlatformMouseEvent& mo
useEvent) | |
| 71 { | |
| 72 if (!node->isElementNode()) | |
| 73 return mouseEvent; | |
| 74 | |
| 75 Element* element = toElement(node); | |
| 76 if (!element->isInCanvasSubtree()) | |
| 77 return mouseEvent; | |
| 78 | |
| 79 HTMLCanvasElement* canvas = Traversal<HTMLCanvasElement>::firstAncestorOrSel
f(*element); | |
| 80 // In this case, the event target is canvas and mouse rerouting doesn't happ
en. | |
| 81 if (canvas == element) | |
| 82 return mouseEvent; | |
| 83 String region = canvas->getIdFromControl(element); | |
| 84 PlatformMouseEvent newMouseEvent = mouseEvent; | |
| 85 newMouseEvent.setRegion(region); | |
| 86 return newMouseEvent; | |
| 87 } | |
| 88 | |
| 89 void buildAncestorChain( | |
| 90 EventTarget* target, | |
| 91 HeapVector<Member<Node>, 20>* ancestors) | |
| 92 { | |
| 93 if (!isInDocument(target)) | |
| 94 return; | |
| 95 Node* targetNode = target->toNode(); | |
| 96 DCHECK(targetNode); | |
| 97 targetNode->updateDistribution(); | |
| 98 // Index 0 element in the ancestors arrays will be the corresponding | |
| 99 // target. So the root of their document will be their last element. | |
| 100 for (Node* node = targetNode; node; node = FlatTreeTraversal::parent(*node)) | |
| 101 ancestors->append(node); | |
| 102 } | |
| 103 | |
| 104 void buildAncestorChainsAndFindCommonAncestors( | |
| 105 EventTarget* exitedTarget, EventTarget* enteredTarget, | |
| 106 HeapVector<Member<Node>, 20>* exitedAncestorsOut, | |
| 107 HeapVector<Member<Node>, 20>* enteredAncestorsOut, | |
| 108 size_t* exitedAncestorsCommonParentIndexOut, | |
| 109 size_t* enteredAncestorsCommonParentIndexOut) | |
| 110 { | |
| 111 DCHECK(exitedAncestorsOut); | |
| 112 DCHECK(enteredAncestorsOut); | |
| 113 DCHECK(exitedAncestorsCommonParentIndexOut); | |
| 114 DCHECK(enteredAncestorsCommonParentIndexOut); | |
| 115 | |
| 116 buildAncestorChain(exitedTarget, exitedAncestorsOut); | |
| 117 buildAncestorChain(enteredTarget, enteredAncestorsOut); | |
| 118 | |
| 119 *exitedAncestorsCommonParentIndexOut = exitedAncestorsOut->size(); | |
| 120 *enteredAncestorsCommonParentIndexOut = enteredAncestorsOut->size(); | |
| 121 while (*exitedAncestorsCommonParentIndexOut > 0 | |
| 122 && *enteredAncestorsCommonParentIndexOut > 0) { | |
| 123 if ((*exitedAncestorsOut)[(*exitedAncestorsCommonParentIndexOut)-1] | |
| 124 != (*enteredAncestorsOut)[(*enteredAncestorsCommonParentIndexOut)-1]
) | |
| 125 break; | |
| 126 (*exitedAncestorsCommonParentIndexOut)--; | |
| 127 (*enteredAncestorsCommonParentIndexOut)--; | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 } // namespace | 52 } // namespace |
| 132 | 53 |
| 54 PointerEventManager::PointerEventBoundaryEventDispatcher::PointerEventBoundaryEv
entDispatcher( |
| 55 PointerEventManager* pointerEventManager, |
| 56 PointerEvent* pointerEvent) |
| 57 : m_pointerEventManager(pointerEventManager) |
| 58 , m_pointerEvent(pointerEvent) |
| 59 { |
| 60 } |
| 61 |
| 62 void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchOut( |
| 63 EventTarget* target, EventTarget* relatedTarget) |
| 64 { |
| 65 dispatch(target, relatedTarget, EventTypeNames::pointerout, false); |
| 66 } |
| 67 |
| 68 void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchOver( |
| 69 EventTarget* target, EventTarget* relatedTarget) |
| 70 { |
| 71 dispatch(target, relatedTarget, EventTypeNames::pointerover, false); |
| 72 } |
| 73 |
| 74 void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchLeave( |
| 75 EventTarget* target, EventTarget* relatedTarget, bool checkForListener) |
| 76 { |
| 77 dispatch(target, relatedTarget, EventTypeNames::pointerleave, checkForListen
er); |
| 78 } |
| 79 |
| 80 void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchEnter( |
| 81 EventTarget* target, EventTarget* relatedTarget, bool checkForListener) |
| 82 { |
| 83 dispatch(target, relatedTarget, EventTypeNames::pointerenter, checkForListen
er); |
| 84 } |
| 85 |
| 86 AtomicString PointerEventManager::PointerEventBoundaryEventDispatcher::getLeaveE
vent() |
| 87 { |
| 88 return EventTypeNames::pointerleave; |
| 89 } |
| 90 |
| 91 AtomicString PointerEventManager::PointerEventBoundaryEventDispatcher::getEnterE
vent() |
| 92 { |
| 93 return EventTypeNames::pointerenter; |
| 94 } |
| 95 |
| 96 void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatch( |
| 97 EventTarget* target, EventTarget* relatedTarget, const AtomicString& type, |
| 98 bool checkForListener) |
| 99 { |
| 100 m_pointerEventManager->dispatchPointerEvent(target, |
| 101 m_pointerEventManager->m_pointerEventFactory.createPointerBoundaryEvent( |
| 102 m_pointerEvent, type, relatedTarget), |
| 103 checkForListener); |
| 104 } |
| 105 |
| 133 WebInputEventResult PointerEventManager::dispatchPointerEvent( | 106 WebInputEventResult PointerEventManager::dispatchPointerEvent( |
| 134 EventTarget* target, | 107 EventTarget* target, |
| 135 PointerEvent* pointerEvent, | 108 PointerEvent* pointerEvent, |
| 136 bool checkForListener) | 109 bool checkForListener) |
| 137 { | 110 { |
| 138 if (!target) | 111 if (!target) |
| 139 return WebInputEventResult::NotHandled; | 112 return WebInputEventResult::NotHandled; |
| 140 | 113 |
| 141 // Set whether node under pointer has received pointerover or not. | 114 // Set whether node under pointer has received pointerover or not. |
| 142 const int pointerId = pointerEvent->pointerId(); | 115 const int pointerId = pointerEvent->pointerId(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 154 } | 127 } |
| 155 | 128 |
| 156 if (!RuntimeEnabledFeatures::pointerEventEnabled()) | 129 if (!RuntimeEnabledFeatures::pointerEventEnabled()) |
| 157 return WebInputEventResult::NotHandled; | 130 return WebInputEventResult::NotHandled; |
| 158 if (!checkForListener || target->hasEventListeners(eventType)) { | 131 if (!checkForListener || target->hasEventListeners(eventType)) { |
| 159 UseCounter::count(m_frame->document(), UseCounter::PointerEventDispatch)
; | 132 UseCounter::count(m_frame->document(), UseCounter::PointerEventDispatch)
; |
| 160 if (eventType == EventTypeNames::pointerdown) | 133 if (eventType == EventTypeNames::pointerdown) |
| 161 UseCounter::count(m_frame->document(), UseCounter::PointerEventDispa
tchPointerDown); | 134 UseCounter::count(m_frame->document(), UseCounter::PointerEventDispa
tchPointerDown); |
| 162 | 135 |
| 163 DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent)
; | 136 DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent)
; |
| 164 return EventHandler::toWebInputEventResult(dispatchResult); | 137 return EventHandlingUtil::toWebInputEventResult(dispatchResult); |
| 165 } | 138 } |
| 166 return WebInputEventResult::NotHandled; | 139 return WebInputEventResult::NotHandled; |
| 167 } | 140 } |
| 168 | 141 |
| 169 EventTarget* PointerEventManager::getEffectiveTargetForPointerEvent( | 142 EventTarget* PointerEventManager::getEffectiveTargetForPointerEvent( |
| 170 EventTarget* target, int pointerId) | 143 EventTarget* target, int pointerId) |
| 171 { | 144 { |
| 172 if (EventTarget* capturingTarget = getCapturingNode(pointerId)) | 145 if (EventTarget* capturingTarget = getCapturingNode(pointerId)) |
| 173 return capturingTarget; | 146 return capturingTarget; |
| 174 return target; | 147 return target; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 198 mouseEvent.pointerProperties().pointerType)] = false; | 171 mouseEvent.pointerProperties().pointerType)] = false; |
| 199 } | 172 } |
| 200 | 173 |
| 201 processCaptureAndPositionOfPointerEvent(dummyPointerEvent, enteredNode, | 174 processCaptureAndPositionOfPointerEvent(dummyPointerEvent, enteredNode, |
| 202 exitedNode, mouseEvent, true, isFrameBoundaryTransition); | 175 exitedNode, mouseEvent, true, isFrameBoundaryTransition); |
| 203 } | 176 } |
| 204 | 177 |
| 205 void PointerEventManager::sendBoundaryEvents( | 178 void PointerEventManager::sendBoundaryEvents( |
| 206 EventTarget* exitedTarget, | 179 EventTarget* exitedTarget, |
| 207 EventTarget* enteredTarget, | 180 EventTarget* enteredTarget, |
| 208 PointerEvent* pointerEvent, | 181 PointerEvent* pointerEvent) |
| 209 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) | |
| 210 { | 182 { |
| 211 if (exitedTarget == enteredTarget) | 183 PointerEventBoundaryEventDispatcher boundaryEventDispatcher(this, pointerEve
nt); |
| 212 return; | 184 boundaryEventDispatcher.sendBoundaryEvents(exitedTarget, enteredTarget); |
| 213 | |
| 214 // Dispatch pointerout/mouseout events | |
| 215 if (isInDocument(exitedTarget)) { | |
| 216 if (!sendMouseEvent) { | |
| 217 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPoint
erBoundaryEvent( | |
| 218 pointerEvent, EventTypeNames::pointerout, enteredTarget)); | |
| 219 } else { | |
| 220 dispatchMouseEvent(exitedTarget, | |
| 221 EventTypeNames::mouseout, | |
| 222 mouseEventWithRegion(exitedTarget->toNode(), mouseEvent), | |
| 223 enteredTarget); | |
| 224 } | |
| 225 } | |
| 226 | |
| 227 // Create lists of all exited/entered ancestors, locate the common ancestor | |
| 228 // Based on httparchive, in more than 97% cases the depth of DOM is less | |
| 229 // than 20. | |
| 230 HeapVector<Member<Node>, 20> exitedAncestors; | |
| 231 HeapVector<Member<Node>, 20> enteredAncestors; | |
| 232 size_t exitedAncestorsCommonParentIndex = 0; | |
| 233 size_t enteredAncestorsCommonParentIndex = 0; | |
| 234 | |
| 235 // A note on mouseenter and mouseleave: These are non-bubbling events, and t
hey are dispatched if there | |
| 236 // is a capturing event handler on an ancestor or a normal event handler on
the element itself. This special | |
| 237 // handling is necessary to avoid O(n^2) capturing event handler checks. | |
| 238 // | |
| 239 // Note, however, that this optimization can possibly cause some unanswere
d/missing/redundant mouseenter or | |
| 240 // mouseleave events in certain contrived eventhandling scenarios, e.g., whe
n: | |
| 241 // - the mouseleave handler for a node sets the only capturing-mouseleave-li
stener in its ancestor, or | |
| 242 // - DOM mods in any mouseenter/mouseleave handler changes the common ancest
or of exited & entered nodes, etc. | |
| 243 // We think the spec specifies a "frozen" state to avoid such corner cases (
check the discussion on "candidate event | |
| 244 // listeners" at http://www.w3.org/TR/uievents), but our code below preserve
s one such behavior from past only to | |
| 245 // match Firefox and IE behavior. | |
| 246 // | |
| 247 // TODO(mustaq): Confirm spec conformance, double-check with other browsers. | |
| 248 | |
| 249 buildAncestorChainsAndFindCommonAncestors( | |
| 250 exitedTarget, enteredTarget, | |
| 251 &exitedAncestors, &enteredAncestors, | |
| 252 &exitedAncestorsCommonParentIndex, &enteredAncestorsCommonParentIndex); | |
| 253 | |
| 254 bool exitedNodeHasCapturingAncestor = false; | |
| 255 for (size_t j = 0; j < exitedAncestors.size(); j++) { | |
| 256 if (exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::mouse
leave) | |
| 257 || (RuntimeEnabledFeatures::pointerEventEnabled() | |
| 258 && exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::po
interleave))) | |
| 259 exitedNodeHasCapturingAncestor = true; | |
| 260 } | |
| 261 | |
| 262 // Dispatch pointerleave/mouseleave events, in child-to-parent order. | |
| 263 for (size_t j = 0; j < exitedAncestorsCommonParentIndex; j++) { | |
| 264 if (!sendMouseEvent) { | |
| 265 dispatchPointerEvent(exitedAncestors[j].get(), | |
| 266 m_pointerEventFactory.createPointerBoundaryEvent( | |
| 267 pointerEvent, EventTypeNames::pointerleave, enteredTarget), | |
| 268 !exitedNodeHasCapturingAncestor); | |
| 269 } else { | |
| 270 dispatchMouseEvent(exitedAncestors[j].get(), | |
| 271 EventTypeNames::mouseleave, | |
| 272 mouseEventWithRegion(exitedTarget->toNode(), mouseEvent), | |
| 273 enteredTarget, 0, !exitedNodeHasCapturingAncestor); | |
| 274 } | |
| 275 } | |
| 276 | |
| 277 // Dispatch pointerover/mouseover. | |
| 278 if (isInDocument(enteredTarget)) { | |
| 279 if (!sendMouseEvent) { | |
| 280 dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPoin
terBoundaryEvent( | |
| 281 pointerEvent, EventTypeNames::pointerover, exitedTarget)); | |
| 282 } else { | |
| 283 dispatchMouseEvent(enteredTarget, | |
| 284 EventTypeNames::mouseover, mouseEvent, exitedTarget); | |
| 285 } | |
| 286 } | |
| 287 | |
| 288 // Defer locating capturing pointeenter/mouseenter listener until /after/ di
spatching the leave events because | |
| 289 // the leave handlers might set a capturing enter handler. | |
| 290 bool enteredNodeHasCapturingAncestor = false; | |
| 291 for (size_t i = 0; i < enteredAncestors.size(); i++) { | |
| 292 if (enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::mous
eenter) | |
| 293 || (RuntimeEnabledFeatures::pointerEventEnabled() | |
| 294 && enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::p
ointerenter))) | |
| 295 enteredNodeHasCapturingAncestor = true; | |
| 296 } | |
| 297 | |
| 298 // Dispatch pointerenter/mouseenter events, in parent-to-child order. | |
| 299 for (size_t i = enteredAncestorsCommonParentIndex; i > 0; i--) { | |
| 300 if (!sendMouseEvent) { | |
| 301 dispatchPointerEvent(enteredAncestors[i-1].get(), | |
| 302 m_pointerEventFactory.createPointerBoundaryEvent( | |
| 303 pointerEvent, EventTypeNames::pointerenter, exitedTarget), | |
| 304 !enteredNodeHasCapturingAncestor); | |
| 305 } else { | |
| 306 dispatchMouseEvent(enteredAncestors[i-1].get(), | |
| 307 EventTypeNames::mouseenter, mouseEvent, exitedTarget, | |
| 308 0, !enteredNodeHasCapturingAncestor); | |
| 309 } | |
| 310 } | |
| 311 } | 185 } |
| 312 | 186 |
| 313 void PointerEventManager::setNodeUnderPointer( | 187 void PointerEventManager::setNodeUnderPointer( |
| 314 PointerEvent* pointerEvent, | 188 PointerEvent* pointerEvent, |
| 315 EventTarget* target) | 189 EventTarget* target) |
| 316 { | 190 { |
| 317 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) { | 191 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) { |
| 318 EventTargetAttributes node = m_nodeUnderPointer.get( | 192 EventTargetAttributes node = m_nodeUnderPointer.get( |
| 319 pointerEvent->pointerId()); | 193 pointerEvent->pointerId()); |
| 320 if (!target) { | 194 if (!target) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 { | 247 { |
| 374 m_inCanceledStateForPointerTypeTouch = false; | 248 m_inCanceledStateForPointerTypeTouch = false; |
| 375 } | 249 } |
| 376 | 250 |
| 377 WebInputEventResult PointerEventManager::handleTouchEvents( | 251 WebInputEventResult PointerEventManager::handleTouchEvents( |
| 378 const PlatformTouchEvent& event) | 252 const PlatformTouchEvent& event) |
| 379 { | 253 { |
| 380 | 254 |
| 381 if (event.type() == PlatformEvent::TouchScrollStarted) { | 255 if (event.type() == PlatformEvent::TouchScrollStarted) { |
| 382 blockTouchPointers(); | 256 blockTouchPointers(); |
| 383 m_touchEventManager.setTouchScrollStarted(); | 257 m_touchEventManager->setTouchScrollStarted(); |
| 384 return WebInputEventResult::HandledSystem; | 258 return WebInputEventResult::HandledSystem; |
| 385 } | 259 } |
| 386 | 260 |
| 387 bool newTouchSequence = true; | 261 bool newTouchSequence = true; |
| 388 for (const auto &touchPoint : event.touchPoints()) { | 262 for (const auto &touchPoint : event.touchPoints()) { |
| 389 if (touchPoint.state() != PlatformTouchPoint::TouchPressed) { | 263 if (touchPoint.state() != PlatformTouchPoint::TouchPressed) { |
| 390 newTouchSequence = false; | 264 newTouchSequence = false; |
| 391 break; | 265 break; |
| 392 } | 266 } |
| 393 } | 267 } |
| 394 if (newTouchSequence) | 268 if (newTouchSequence) |
| 395 unblockTouchPointers(); | 269 unblockTouchPointers(); |
| 396 HeapVector<TouchEventManager::TouchInfo> touchInfos; | 270 HeapVector<TouchEventManager::TouchInfo> touchInfos; |
| 397 | 271 |
| 398 dispatchTouchPointerEvents(event, touchInfos); | 272 dispatchTouchPointerEvents(event, touchInfos); |
| 399 | 273 |
| 400 return m_touchEventManager.handleTouchEvent(event, touchInfos); | 274 return m_touchEventManager->handleTouchEvent(event, touchInfos); |
| 401 } | 275 } |
| 402 | 276 |
| 403 void PointerEventManager::dispatchTouchPointerEvents( | 277 void PointerEventManager::dispatchTouchPointerEvents( |
| 404 const PlatformTouchEvent& event, | 278 const PlatformTouchEvent& event, |
| 405 HeapVector<TouchEventManager::TouchInfo>& touchInfos) | 279 HeapVector<TouchEventManager::TouchInfo>& touchInfos) |
| 406 { | 280 { |
| 407 // Iterate through the touch points, sending PointerEvents to the targets as
required. | 281 // Iterate through the touch points, sending PointerEvents to the targets as
required. |
| 408 for (const auto& touchPoint : event.touchPoints()) { | 282 for (const auto& touchPoint : event.touchPoints()) { |
| 409 TouchEventManager::TouchInfo touchInfo; | 283 TouchEventManager::TouchInfo touchInfo; |
| 410 touchInfo.point = touchPoint; | 284 touchInfo.point = touchPoint; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 // Event path could be null if pointer event is not dispatched and | 444 // Event path could be null if pointer event is not dispatched and |
| 571 // that happens for example when pointer event feature is not enabled. | 445 // that happens for example when pointer event feature is not enabled. |
| 572 if (!isInDocument(mouseTarget) && pointerEvent->hasEventPath()) { | 446 if (!isInDocument(mouseTarget) && pointerEvent->hasEventPath()) { |
| 573 for (size_t i = 0; i < pointerEvent->eventPath().size(); i++) { | 447 for (size_t i = 0; i < pointerEvent->eventPath().size(); i++) { |
| 574 if (isInDocument(pointerEvent->eventPath()[i].node())) { | 448 if (isInDocument(pointerEvent->eventPath()[i].node())) { |
| 575 mouseTarget = pointerEvent->eventPath()[i].node(); | 449 mouseTarget = pointerEvent->eventPath()[i].node(); |
| 576 break; | 450 break; |
| 577 } | 451 } |
| 578 } | 452 } |
| 579 } | 453 } |
| 580 result = EventHandler::mergeEventResult(result, | 454 result = EventHandlingUtil::mergeEventResult(result, |
| 581 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, | 455 m_mouseEventManager->dispatchMouseEvent(mouseTarget, mouseEventType, |
| 582 nullptr, clickCount)); | 456 mouseEvent, nullptr, clickCount)); |
| 583 } | 457 } |
| 584 | 458 |
| 585 if (pointerEvent->type() == EventTypeNames::pointerup | 459 if (pointerEvent->type() == EventTypeNames::pointerup |
| 586 || pointerEvent->type() == EventTypeNames::pointercancel) { | 460 || pointerEvent->type() == EventTypeNames::pointercancel) { |
| 587 | 461 |
| 588 releasePointerCapture(pointerEvent->pointerId()); | 462 releasePointerCapture(pointerEvent->pointerId()); |
| 589 // Send got/lostpointercapture rightaway if necessary. | 463 // Send got/lostpointercapture rightaway if necessary. |
| 590 processPendingPointerCapture(pointerEvent); | 464 processPendingPointerCapture(pointerEvent); |
| 591 | 465 |
| 592 if (pointerEvent->isPrimary()) { | 466 if (pointerEvent->isPrimary()) { |
| 593 m_preventMouseEventForPointerType[toPointerTypeIndex( | 467 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 594 mouseEvent.pointerProperties().pointerType)] = false; | 468 mouseEvent.pointerProperties().pointerType)] = false; |
| 595 } | 469 } |
| 596 } | 470 } |
| 597 | 471 |
| 598 return result; | 472 return result; |
| 599 } | 473 } |
| 600 | 474 |
| 601 PointerEventManager::PointerEventManager(LocalFrame* frame) | 475 PointerEventManager::PointerEventManager(LocalFrame* frame, |
| 602 : m_frame(frame) | 476 MouseEventManager* mouseEventManager) |
| 603 , m_touchEventManager(frame) | 477 : m_frame(frame) |
| 478 , m_touchEventManager(new TouchEventManager(frame)) |
| 479 , m_mouseEventManager(mouseEventManager) |
| 604 { | 480 { |
| 605 clear(); | 481 clear(); |
| 606 } | 482 } |
| 607 | 483 |
| 608 PointerEventManager::~PointerEventManager() | |
| 609 { | |
| 610 } | |
| 611 | |
| 612 void PointerEventManager::clear() | 484 void PointerEventManager::clear() |
| 613 { | 485 { |
| 614 for (auto& entry : m_preventMouseEventForPointerType) | 486 for (auto& entry : m_preventMouseEventForPointerType) |
| 615 entry = false; | 487 entry = false; |
| 616 m_touchEventManager.clear(); | 488 m_touchEventManager->clear(); |
| 617 m_inCanceledStateForPointerTypeTouch = false; | 489 m_inCanceledStateForPointerTypeTouch = false; |
| 618 m_pointerEventFactory.clear(); | 490 m_pointerEventFactory.clear(); |
| 619 m_touchIdsForCanceledPointerdowns.clear(); | 491 m_touchIdsForCanceledPointerdowns.clear(); |
| 620 m_nodeUnderPointer.clear(); | 492 m_nodeUnderPointer.clear(); |
| 621 m_pointerCaptureTarget.clear(); | 493 m_pointerCaptureTarget.clear(); |
| 622 m_pendingPointerCaptureTarget.clear(); | 494 m_pendingPointerCaptureTarget.clear(); |
| 623 } | 495 } |
| 624 | 496 |
| 625 bool PointerEventManager::getPointerCaptureState(int pointerId, | 497 bool PointerEventManager::getPointerCaptureState(int pointerId, |
| 626 EventTarget** pointerCaptureTarget, | 498 EventTarget** pointerCaptureTarget, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 652 processPendingPointerCapture(pointerEvent); | 524 processPendingPointerCapture(pointerEvent); |
| 653 | 525 |
| 654 PointerCapturingMap::const_iterator it = m_pointerCaptureTarget.find(poi
nterEvent->pointerId()); | 526 PointerCapturingMap::const_iterator it = m_pointerCaptureTarget.find(poi
nterEvent->pointerId()); |
| 655 if (EventTarget* pointercaptureTarget = (it != m_pointerCaptureTarget.en
d()) ? it->value : nullptr) | 527 if (EventTarget* pointercaptureTarget = (it != m_pointerCaptureTarget.en
d()) ? it->value : nullptr) |
| 656 hitTestTarget = pointercaptureTarget; | 528 hitTestTarget = pointercaptureTarget; |
| 657 | 529 |
| 658 setNodeUnderPointer(pointerEvent, hitTestTarget); | 530 setNodeUnderPointer(pointerEvent, hitTestTarget); |
| 659 } | 531 } |
| 660 if (sendMouseEvent) { | 532 if (sendMouseEvent) { |
| 661 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. | 533 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. |
| 662 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, | 534 m_mouseEventManager->sendBoundaryEvents(lastNodeUnderMouse, |
| 663 pointerEvent, mouseEvent, true); | 535 hitTestTarget, mouseEvent); |
| 664 } | 536 } |
| 665 return hitTestTarget; | 537 return hitTestTarget; |
| 666 } | 538 } |
| 667 | 539 |
| 668 void PointerEventManager::processPendingPointerCapture( | 540 void PointerEventManager::processPendingPointerCapture( |
| 669 PointerEvent* pointerEvent) | 541 PointerEvent* pointerEvent) |
| 670 { | 542 { |
| 671 EventTarget* pointerCaptureTarget; | 543 EventTarget* pointerCaptureTarget; |
| 672 EventTarget* pendingPointerCaptureTarget; | 544 EventTarget* pendingPointerCaptureTarget; |
| 673 const int pointerId = pointerEvent->pointerId(); | 545 const int pointerId = pointerEvent->pointerId(); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 m_pendingPointerCaptureTarget.remove(pointerId); | 648 m_pendingPointerCaptureTarget.remove(pointerId); |
| 777 } | 649 } |
| 778 | 650 |
| 779 bool PointerEventManager::isActive(const int pointerId) const | 651 bool PointerEventManager::isActive(const int pointerId) const |
| 780 { | 652 { |
| 781 return m_pointerEventFactory.isActive(pointerId); | 653 return m_pointerEventFactory.isActive(pointerId); |
| 782 } | 654 } |
| 783 | 655 |
| 784 bool PointerEventManager::isAnyTouchActive() const | 656 bool PointerEventManager::isAnyTouchActive() const |
| 785 { | 657 { |
| 786 return m_touchEventManager.isAnyTouchActive(); | 658 return m_touchEventManager->isAnyTouchActive(); |
| 787 } | 659 } |
| 788 | 660 |
| 789 bool PointerEventManager::primaryPointerdownCanceled(uint32_t uniqueTouchEventId
) | 661 bool PointerEventManager::primaryPointerdownCanceled(uint32_t uniqueTouchEventId
) |
| 790 { | 662 { |
| 791 // It's safe to assume that uniqueTouchEventIds won't wrap back to 0 from | 663 // It's safe to assume that uniqueTouchEventIds won't wrap back to 0 from |
| 792 // 2^32-1 (>4.2 billion): even with a generous 100 unique ids per touch | 664 // 2^32-1 (>4.2 billion): even with a generous 100 unique ids per touch |
| 793 // sequence & one sequence per 10 second, it takes 13+ years to wrap back. | 665 // sequence & one sequence per 10 second, it takes 13+ years to wrap back. |
| 794 while (!m_touchIdsForCanceledPointerdowns.isEmpty()) { | 666 while (!m_touchIdsForCanceledPointerdowns.isEmpty()) { |
| 795 uint32_t firstId = m_touchIdsForCanceledPointerdowns.first(); | 667 uint32_t firstId = m_touchIdsForCanceledPointerdowns.first(); |
| 796 if (firstId > uniqueTouchEventId) | 668 if (firstId > uniqueTouchEventId) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 807 return getCapturingNode(PointerEventFactory::s_mouseId); | 679 return getCapturingNode(PointerEventFactory::s_mouseId); |
| 808 } | 680 } |
| 809 | 681 |
| 810 DEFINE_TRACE(PointerEventManager) | 682 DEFINE_TRACE(PointerEventManager) |
| 811 { | 683 { |
| 812 visitor->trace(m_frame); | 684 visitor->trace(m_frame); |
| 813 visitor->trace(m_nodeUnderPointer); | 685 visitor->trace(m_nodeUnderPointer); |
| 814 visitor->trace(m_pointerCaptureTarget); | 686 visitor->trace(m_pointerCaptureTarget); |
| 815 visitor->trace(m_pendingPointerCaptureTarget); | 687 visitor->trace(m_pendingPointerCaptureTarget); |
| 816 visitor->trace(m_touchEventManager); | 688 visitor->trace(m_touchEventManager); |
| 689 visitor->trace(m_mouseEventManager); |
| 817 } | 690 } |
| 818 | 691 |
| 819 | 692 |
| 820 } // namespace blink | 693 } // namespace blink |
| OLD | NEW |