| 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" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 return EventTypeNames::pointerup; | 29 return EventTypeNames::pointerup; |
| 30 case PlatformTouchPoint::TouchCancelled: | 30 case PlatformTouchPoint::TouchCancelled: |
| 31 return EventTypeNames::pointercancel; | 31 return EventTypeNames::pointercancel; |
| 32 case PlatformTouchPoint::TouchPressed: | 32 case PlatformTouchPoint::TouchPressed: |
| 33 return EventTypeNames::pointerdown; | 33 return EventTypeNames::pointerdown; |
| 34 case PlatformTouchPoint::TouchMoved: | 34 case PlatformTouchPoint::TouchMoved: |
| 35 return EventTypeNames::pointermove; | 35 return EventTypeNames::pointermove; |
| 36 case PlatformTouchPoint::TouchStationary: | 36 case PlatformTouchPoint::TouchStationary: |
| 37 // Fall through to default | 37 // Fall through to default |
| 38 default: | 38 default: |
| 39 ASSERT_NOT_REACHED(); | 39 NOTREACHED(); |
| 40 return emptyAtom; | 40 return emptyAtom; |
| 41 } | 41 } |
| 42 } | 42 } |
| 43 | 43 |
| 44 bool isInDocument(EventTarget* n) | 44 bool isInDocument(EventTarget* n) |
| 45 { | 45 { |
| 46 return n && n->toNode() && n->toNode()->isConnected(); | 46 return n && n->toNode() && n->toNode()->isConnected(); |
| 47 } | 47 } |
| 48 | 48 |
| 49 WebInputEventResult dispatchMouseEvent( | 49 WebInputEventResult dispatchMouseEvent( |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 | 203 |
| 204 void PointerEventManager::sendBoundaryEvents( | 204 void PointerEventManager::sendBoundaryEvents( |
| 205 EventTarget* exitedTarget, | 205 EventTarget* exitedTarget, |
| 206 EventTarget* enteredTarget, | 206 EventTarget* enteredTarget, |
| 207 PointerEvent* pointerEvent, | 207 PointerEvent* pointerEvent, |
| 208 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) | 208 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) |
| 209 { | 209 { |
| 210 if (exitedTarget == enteredTarget) | 210 if (exitedTarget == enteredTarget) |
| 211 return; | 211 return; |
| 212 | 212 |
| 213 if (EventTarget* capturingTarget = getCapturingNode(pointerEvent->pointerId(
))) { | |
| 214 if (capturingTarget == exitedTarget) | |
| 215 enteredTarget = nullptr; | |
| 216 else if (capturingTarget == enteredTarget) | |
| 217 exitedTarget = nullptr; | |
| 218 else | |
| 219 return; | |
| 220 } | |
| 221 | |
| 222 // Dispatch pointerout/mouseout events | 213 // Dispatch pointerout/mouseout events |
| 223 if (isInDocument(exitedTarget)) { | 214 if (isInDocument(exitedTarget)) { |
| 224 if (!sendMouseEvent) { | 215 if (!sendMouseEvent) { |
| 225 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPoint
erBoundaryEvent( | 216 dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPoint
erBoundaryEvent( |
| 226 pointerEvent, EventTypeNames::pointerout, enteredTarget)); | 217 pointerEvent, EventTypeNames::pointerout, enteredTarget)); |
| 227 } else { | 218 } else { |
| 228 dispatchMouseEvent(exitedTarget, | 219 dispatchMouseEvent(exitedTarget, |
| 229 EventTypeNames::mouseout, | 220 EventTypeNames::mouseout, |
| 230 mouseEventWithRegion(exitedTarget->toNode(), mouseEvent), | 221 mouseEventWithRegion(exitedTarget->toNode(), mouseEvent), |
| 231 enteredTarget); | 222 enteredTarget); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 } else { | 304 } else { |
| 314 dispatchMouseEvent(enteredAncestors[i-1].get(), | 305 dispatchMouseEvent(enteredAncestors[i-1].get(), |
| 315 EventTypeNames::mouseenter, mouseEvent, exitedTarget, | 306 EventTypeNames::mouseenter, mouseEvent, exitedTarget, |
| 316 0, !enteredNodeHasCapturingAncestor); | 307 0, !enteredNodeHasCapturingAncestor); |
| 317 } | 308 } |
| 318 } | 309 } |
| 319 } | 310 } |
| 320 | 311 |
| 321 void PointerEventManager::setNodeUnderPointer( | 312 void PointerEventManager::setNodeUnderPointer( |
| 322 PointerEvent* pointerEvent, | 313 PointerEvent* pointerEvent, |
| 323 EventTarget* target, | 314 EventTarget* target) |
| 324 bool sendEvent) | |
| 325 { | 315 { |
| 326 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) { | 316 if (m_nodeUnderPointer.contains(pointerEvent->pointerId())) { |
| 327 EventTargetAttributes node = m_nodeUnderPointer.get( | 317 EventTargetAttributes node = m_nodeUnderPointer.get( |
| 328 pointerEvent->pointerId()); | 318 pointerEvent->pointerId()); |
| 329 if (!target) { | 319 if (!target) { |
| 330 m_nodeUnderPointer.remove(pointerEvent->pointerId()); | 320 m_nodeUnderPointer.remove(pointerEvent->pointerId()); |
| 331 } else if (target | 321 } else if (target |
| 332 != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) { | 322 != m_nodeUnderPointer.get(pointerEvent->pointerId()).target) { |
| 333 m_nodeUnderPointer.set(pointerEvent->pointerId(), | 323 m_nodeUnderPointer.set(pointerEvent->pointerId(), |
| 334 EventTargetAttributes(target, false)); | 324 EventTargetAttributes(target, false)); |
| 335 } | 325 } |
| 336 if (sendEvent) | 326 sendBoundaryEvents(node.target, target, pointerEvent); |
| 337 sendBoundaryEvents(node.target, target, pointerEvent); | |
| 338 } else if (target) { | 327 } else if (target) { |
| 339 m_nodeUnderPointer.add(pointerEvent->pointerId(), | 328 m_nodeUnderPointer.add(pointerEvent->pointerId(), |
| 340 EventTargetAttributes(target, false)); | 329 EventTargetAttributes(target, false)); |
| 341 if (sendEvent) | 330 sendBoundaryEvents(nullptr, target, pointerEvent); |
| 342 sendBoundaryEvents(nullptr, target, pointerEvent); | |
| 343 } | 331 } |
| 344 } | 332 } |
| 345 | 333 |
| 346 void PointerEventManager::blockTouchPointers() | 334 void PointerEventManager::blockTouchPointers() |
| 347 { | 335 { |
| 348 if (m_inCanceledStateForPointerTypeTouch) | 336 if (m_inCanceledStateForPointerTypeTouch) |
| 349 return; | 337 return; |
| 350 m_inCanceledStateForPointerTypeTouch = true; | 338 m_inCanceledStateForPointerTypeTouch = true; |
| 351 | 339 |
| 352 Vector<int> touchPointerIds | 340 Vector<int> touchPointerIds |
| 353 = m_pointerEventFactory.getPointerIdsOfType(WebPointerProperties::Pointe
rType::Touch); | 341 = m_pointerEventFactory.getPointerIdsOfType(WebPointerProperties::Pointe
rType::Touch); |
| 354 | 342 |
| 355 for (int pointerId : touchPointerIds) { | 343 for (int pointerId : touchPointerIds) { |
| 356 PointerEvent* pointerEvent | 344 PointerEvent* pointerEvent |
| 357 = m_pointerEventFactory.createPointerCancelEvent( | 345 = m_pointerEventFactory.createPointerCancelEvent( |
| 358 pointerId, WebPointerProperties::PointerType::Touch); | 346 pointerId, WebPointerProperties::PointerType::Touch); |
| 359 | 347 |
| 360 ASSERT(m_nodeUnderPointer.contains(pointerId)); | 348 DCHECK(m_nodeUnderPointer.contains(pointerId)); |
| 361 EventTarget* target = m_nodeUnderPointer.get(pointerId).target; | 349 EventTarget* target = m_nodeUnderPointer.get(pointerId).target; |
| 362 | 350 |
| 363 processCaptureAndPositionOfPointerEvent(pointerEvent, target); | 351 processCaptureAndPositionOfPointerEvent(pointerEvent, target); |
| 364 | 352 |
| 365 // TODO(nzolghadr): This event follows implicit TE capture. The actual t
arget | 353 // TODO(nzolghadr): This event follows implicit TE capture. The actual t
arget |
| 366 // would depend on PE capturing. Perhaps need to split TE/PE event path
upstream? | 354 // would depend on PE capturing. Perhaps need to split TE/PE event path
upstream? |
| 367 // crbug.com/579553. | 355 // crbug.com/579553. |
| 368 dispatchPointerEvent( | 356 dispatchPointerEvent( |
| 369 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId())
, | 357 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId())
, |
| 370 pointerEvent); | 358 pointerEvent); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 setPointerCapture(pointerEvent->pointerId(), target); | 498 setPointerCapture(pointerEvent->pointerId(), target); |
| 511 | 499 |
| 512 WebInputEventResult result = dispatchPointerEvent( | 500 WebInputEventResult result = dispatchPointerEvent( |
| 513 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), | 501 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), |
| 514 pointerEvent); | 502 pointerEvent); |
| 515 | 503 |
| 516 if (pointerEvent->type() == EventTypeNames::pointerup | 504 if (pointerEvent->type() == EventTypeNames::pointerup |
| 517 || pointerEvent->type() == EventTypeNames::pointercancel) { | 505 || pointerEvent->type() == EventTypeNames::pointercancel) { |
| 518 releasePointerCapture(pointerEvent->pointerId()); | 506 releasePointerCapture(pointerEvent->pointerId()); |
| 519 | 507 |
| 520 // Sending the leave/out events and lostpointercapture | 508 // Sending the leave/out events and lostpointercapture because the next |
| 521 // because the next touch event will have a different id. So delayed | 509 // touch event will have a different id. |
| 522 // sending of lostpointercapture won't work here. | |
| 523 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); | 510 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); |
| 524 | 511 |
| 525 removePointer(pointerEvent); | 512 removePointer(pointerEvent); |
| 526 } | 513 } |
| 527 | 514 |
| 528 return result; | 515 return result; |
| 529 } | 516 } |
| 530 | 517 |
| 531 WebInputEventResult PointerEventManager::sendMousePointerEvent( | 518 WebInputEventResult PointerEventManager::sendMousePointerEvent( |
| 532 Node* target, const AtomicString& mouseEventType, | 519 Node* target, const AtomicString& mouseEventType, |
| 533 int clickCount, const PlatformMouseEvent& mouseEvent, | 520 int clickCount, const PlatformMouseEvent& mouseEvent, |
| 534 Node* relatedTarget, | 521 Node* relatedTarget, |
| 535 Node* lastNodeUnderMouse) | 522 Node* lastNodeUnderMouse, |
| 523 Node** newNodeUnderMouse) |
| 536 { | 524 { |
| 537 PointerEvent* pointerEvent = | 525 PointerEvent* pointerEvent = |
| 538 m_pointerEventFactory.create(mouseEventType, mouseEvent, | 526 m_pointerEventFactory.create(mouseEventType, mouseEvent, |
| 539 relatedTarget, m_frame->document()->domWindow()); | 527 relatedTarget, m_frame->document()->domWindow()); |
| 540 | 528 |
| 541 // This is for when the mouse is released outside of the page. | 529 // This is for when the mouse is released outside of the page. |
| 542 if (pointerEvent->type() == EventTypeNames::pointermove | 530 if (pointerEvent->type() == EventTypeNames::pointermove |
| 543 && !pointerEvent->buttons() | 531 && !pointerEvent->buttons() |
| 544 && pointerEvent->isPrimary()) { | 532 && pointerEvent->isPrimary()) { |
| 545 m_preventMouseEventForPointerType[toPointerTypeIndex( | 533 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 546 mouseEvent.pointerProperties().pointerType)] = false; | 534 mouseEvent.pointerProperties().pointerType)] = false; |
| 547 } | 535 } |
| 548 | 536 |
| 549 processCaptureAndPositionOfPointerEvent(pointerEvent, target, | 537 EventTarget* pointerEventTarget = processCaptureAndPositionOfPointerEvent(po
interEvent, target, |
| 550 lastNodeUnderMouse, mouseEvent, true, true); | 538 lastNodeUnderMouse, mouseEvent, true, true); |
| 551 | 539 |
| 540 if (pointerEventTarget) { |
| 541 // This is to prevent incorrect boundary events if capturing transition
was |
| 542 // delayed. |
| 543 *newNodeUnderMouse = pointerEventTarget->toNode(); |
| 544 DCHECK(*newNodeUnderMouse); |
| 545 } |
| 546 |
| 552 EventTarget* effectiveTarget = | 547 EventTarget* effectiveTarget = |
| 553 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()); | 548 getEffectiveTargetForPointerEvent(pointerEventTarget, pointerEvent->poin
terId()); |
| 554 | 549 |
| 555 WebInputEventResult result = | 550 WebInputEventResult result = |
| 556 dispatchPointerEvent(effectiveTarget, pointerEvent); | 551 dispatchPointerEvent(effectiveTarget, pointerEvent); |
| 557 | 552 |
| 558 if (result != WebInputEventResult::NotHandled | 553 if (result != WebInputEventResult::NotHandled |
| 559 && pointerEvent->type() == EventTypeNames::pointerdown | 554 && pointerEvent->type() == EventTypeNames::pointerdown |
| 560 && pointerEvent->isPrimary()) { | 555 && pointerEvent->isPrimary()) { |
| 561 m_preventMouseEventForPointerType[toPointerTypeIndex( | 556 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 562 mouseEvent.pointerProperties().pointerType)] = true; | 557 mouseEvent.pointerProperties().pointerType)] = true; |
| 563 } | 558 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 575 } | 570 } |
| 576 } | 571 } |
| 577 } | 572 } |
| 578 result = EventHandler::mergeEventResult(result, | 573 result = EventHandler::mergeEventResult(result, |
| 579 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, | 574 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, |
| 580 nullptr, clickCount)); | 575 nullptr, clickCount)); |
| 581 } | 576 } |
| 582 | 577 |
| 583 if (pointerEvent->buttons() == 0) { | 578 if (pointerEvent->buttons() == 0) { |
| 584 releasePointerCapture(pointerEvent->pointerId()); | 579 releasePointerCapture(pointerEvent->pointerId()); |
| 580 |
| 581 // Send got/lostpointercapture rightaway if necessary. |
| 582 processPendingPointerCapture(pointerEvent); |
| 583 |
| 585 if (pointerEvent->isPrimary()) { | 584 if (pointerEvent->isPrimary()) { |
| 586 m_preventMouseEventForPointerType[toPointerTypeIndex( | 585 m_preventMouseEventForPointerType[toPointerTypeIndex( |
| 587 mouseEvent.pointerProperties().pointerType)] = false; | 586 mouseEvent.pointerProperties().pointerType)] = false; |
| 588 } | 587 } |
| 589 } | 588 } |
| 590 | 589 |
| 591 return result; | 590 return result; |
| 592 } | 591 } |
| 593 | 592 |
| 594 PointerEventManager::PointerEventManager(LocalFrame* frame) | 593 PointerEventManager::PointerEventManager(LocalFrame* frame) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 608 entry = false; | 607 entry = false; |
| 609 m_touchEventManager.clear(); | 608 m_touchEventManager.clear(); |
| 610 m_inCanceledStateForPointerTypeTouch = false; | 609 m_inCanceledStateForPointerTypeTouch = false; |
| 611 m_pointerEventFactory.clear(); | 610 m_pointerEventFactory.clear(); |
| 612 m_touchIdsForCanceledPointerdowns.clear(); | 611 m_touchIdsForCanceledPointerdowns.clear(); |
| 613 m_nodeUnderPointer.clear(); | 612 m_nodeUnderPointer.clear(); |
| 614 m_pointerCaptureTarget.clear(); | 613 m_pointerCaptureTarget.clear(); |
| 615 m_pendingPointerCaptureTarget.clear(); | 614 m_pendingPointerCaptureTarget.clear(); |
| 616 } | 615 } |
| 617 | 616 |
| 618 void PointerEventManager::processCaptureAndPositionOfPointerEvent( | 617 bool PointerEventManager::getPointerCaptureState(int pointerId, |
| 618 EventTarget** pointerCaptureTarget, |
| 619 EventTarget** pendingPointerCaptureTarget) |
| 620 { |
| 621 PointerCapturingMap::const_iterator it; |
| 622 |
| 623 it = m_pointerCaptureTarget.find(pointerId); |
| 624 EventTarget* pointerCaptureTargetTemp = (it != m_pointerCaptureTarget.end())
? it->value : nullptr; |
| 625 it = m_pendingPointerCaptureTarget.find(pointerId); |
| 626 EventTarget* pendingPointercaptureTargetTemp = (it != m_pendingPointerCaptur
eTarget.end()) ? it->value : nullptr; |
| 627 |
| 628 if (pointerCaptureTarget) |
| 629 *pointerCaptureTarget = pointerCaptureTargetTemp; |
| 630 if (pendingPointerCaptureTarget) |
| 631 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp; |
| 632 |
| 633 return pointerCaptureTargetTemp != pendingPointercaptureTargetTemp; |
| 634 } |
| 635 |
| 636 EventTarget* PointerEventManager::processCaptureAndPositionOfPointerEvent( |
| 619 PointerEvent* pointerEvent, | 637 PointerEvent* pointerEvent, |
| 620 EventTarget* hitTestTarget, | 638 EventTarget* hitTestTarget, |
| 621 EventTarget* lastNodeUnderMouse, | 639 EventTarget* lastNodeUnderMouse, |
| 622 const PlatformMouseEvent& mouseEvent, | 640 const PlatformMouseEvent& mouseEvent, |
| 623 bool sendMouseEvent, bool setPointerPosition) | 641 bool sendMouseEvent, bool setPointerPosition) |
| 624 { | 642 { |
| 625 bool isCaptureChanged = false; | 643 if (setPointerPosition) { |
| 644 processPendingPointerCapture(pointerEvent); |
| 626 | 645 |
| 627 if (setPointerPosition) { | 646 PointerCapturingMap::const_iterator it = m_pointerCaptureTarget.find(poi
nterEvent->pointerId()); |
| 628 isCaptureChanged = processPendingPointerCapture(pointerEvent, | 647 if (EventTarget* pointercaptureTarget = (it != m_pointerCaptureTarget.en
d()) ? it->value : nullptr) |
| 629 hitTestTarget, mouseEvent, sendMouseEvent); | 648 hitTestTarget = pointercaptureTarget; |
| 630 // If there was a change in capturing processPendingPointerCapture has | 649 |
| 631 // already taken care of transition events. So we don't need to send the | 650 setNodeUnderPointer(pointerEvent, hitTestTarget); |
| 632 // transition events here. | |
| 633 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged); | |
| 634 } | 651 } |
| 635 if (sendMouseEvent && !isCaptureChanged) { | 652 if (sendMouseEvent) { |
| 636 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. | 653 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. |
| 637 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, | 654 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, |
| 638 pointerEvent, mouseEvent, true); | 655 pointerEvent, mouseEvent, true); |
| 639 } | 656 } |
| 657 return hitTestTarget; |
| 640 } | 658 } |
| 641 | 659 |
| 642 bool PointerEventManager::processPendingPointerCapture( | 660 void PointerEventManager::processPendingPointerCapture( |
| 643 PointerEvent* pointerEvent, | 661 PointerEvent* pointerEvent) |
| 644 EventTarget* hitTestTarget, | |
| 645 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) | |
| 646 { | 662 { |
| 647 int pointerId = pointerEvent->pointerId(); | 663 EventTarget* pointerCaptureTarget; |
| 648 EventTarget* pointerCaptureTarget = | 664 EventTarget* pendingPointerCaptureTarget; |
| 649 m_pointerCaptureTarget.contains(pointerId) | 665 const int pointerId = pointerEvent->pointerId(); |
| 650 ? m_pointerCaptureTarget.get(pointerId) : nullptr; | 666 const bool isCaptureChanged = getPointerCaptureState( |
| 651 EventTarget* pendingPointerCaptureTarget = | 667 pointerId, |
| 652 m_pendingPointerCaptureTarget.contains(pointerId) | 668 &pointerCaptureTarget, &pendingPointerCaptureTarget); |
| 653 ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr; | |
| 654 const EventTargetAttributes &nodeUnderPointerAtt = | |
| 655 m_nodeUnderPointer.contains(pointerId) | |
| 656 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); | |
| 657 const bool isCaptureChanged = | |
| 658 pointerCaptureTarget != pendingPointerCaptureTarget; | |
| 659 | 669 |
| 660 if (isCaptureChanged) { | 670 if (!isCaptureChanged) |
| 661 if ((hitTestTarget != nodeUnderPointerAtt.target | 671 return; |
| 662 || (pendingPointerCaptureTarget | 672 |
| 663 && pendingPointerCaptureTarget != nodeUnderPointerAtt.target)) | 673 // We have to check whether the pointerCaptureTarget is null or not because |
| 664 && nodeUnderPointerAtt.hasRecievedOverEvent) { | 674 // we are checking whether it is still connected to its document or not. |
| 665 if (sendMouseEvent) { | 675 if (pointerCaptureTarget) { |
| 666 // Send pointer event transitions as the line after this if | 676 // Re-target lostpointercapture to the document when the element is |
| 667 // block sends the mouse events | 677 // no longer participating in the tree. |
| 668 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, | 678 EventTarget* target = pointerCaptureTarget; |
| 669 pointerEvent); | 679 if (target->toNode() |
| 670 } | 680 && !target->toNode()->isConnected()) { |
| 671 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, | 681 target = target->toNode()->ownerDocument(); |
| 672 pointerEvent, mouseEvent, sendMouseEvent); | |
| 673 } | 682 } |
| 674 if (pointerCaptureTarget) { | 683 dispatchPointerEvent(target, |
| 675 // Re-target lostpointercapture to the document when the element is | 684 m_pointerEventFactory.createPointerCaptureEvent( |
| 676 // no longer participating in the tree. | |
| 677 EventTarget* target = pointerCaptureTarget; | |
| 678 if (target->toNode() | |
| 679 && !target->toNode()->isConnected()) { | |
| 680 target = target->toNode()->ownerDocument(); | |
| 681 } | |
| 682 dispatchPointerEvent(target, | |
| 683 m_pointerEventFactory.createPointerCaptureEvent( | |
| 684 pointerEvent, EventTypeNames::lostpointercapture)); | 685 pointerEvent, EventTypeNames::lostpointercapture)); |
| 685 } | |
| 686 } | 686 } |
| 687 // Note that If pendingPointerCaptureTarget is null dispatchPointerEvent |
| 688 // automatically does nothing. |
| 689 dispatchPointerEvent(pendingPointerCaptureTarget, |
| 690 m_pointerEventFactory.createPointerCaptureEvent( |
| 691 pointerEvent, EventTypeNames::gotpointercapture)); |
| 687 | 692 |
| 688 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does | |
| 689 // affect the behavior of sendBoundaryEvents function. So the | |
| 690 // ordering of the surrounding blocks of code for sending transition events | |
| 691 // are important. | |
| 692 if (pendingPointerCaptureTarget) | 693 if (pendingPointerCaptureTarget) |
| 693 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); | 694 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); |
| 694 else | 695 else |
| 695 m_pointerCaptureTarget.remove(pointerId); | 696 m_pointerCaptureTarget.remove(pointerId); |
| 696 | |
| 697 if (isCaptureChanged) { | |
| 698 dispatchPointerEvent(pendingPointerCaptureTarget, | |
| 699 m_pointerEventFactory.createPointerCaptureEvent( | |
| 700 pointerEvent, EventTypeNames::gotpointercapture)); | |
| 701 if ((pendingPointerCaptureTarget == hitTestTarget | |
| 702 || !pendingPointerCaptureTarget) | |
| 703 && (nodeUnderPointerAtt.target != hitTestTarget | |
| 704 || !nodeUnderPointerAtt.hasRecievedOverEvent)) { | |
| 705 if (sendMouseEvent) { | |
| 706 // Send pointer event transitions as the line after this if | |
| 707 // block sends the mouse events | |
| 708 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent); | |
| 709 } | |
| 710 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent, | |
| 711 mouseEvent, sendMouseEvent); | |
| 712 } | |
| 713 } | |
| 714 return isCaptureChanged; | |
| 715 } | 697 } |
| 716 | 698 |
| 717 void PointerEventManager::removeTargetFromPointerCapturingMapping( | 699 void PointerEventManager::removeTargetFromPointerCapturingMapping( |
| 718 PointerCapturingMap& map, const EventTarget* target) | 700 PointerCapturingMap& map, const EventTarget* target) |
| 719 { | 701 { |
| 720 // We could have kept a reverse mapping to make this deletion possibly | 702 // We could have kept a reverse mapping to make this deletion possibly |
| 721 // faster but it adds some code complication which might not be worth of | 703 // faster but it adds some code complication which might not be worth of |
| 722 // the performance improvement considering there might not be a lot of | 704 // the performance improvement considering there might not be a lot of |
| 723 // active pointer or pointer captures at the same time. | 705 // active pointer or pointer captures at the same time. |
| 724 PointerCapturingMap tmp = map; | 706 PointerCapturingMap tmp = map; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 795 uint32_t firstId = m_touchIdsForCanceledPointerdowns.first(); | 777 uint32_t firstId = m_touchIdsForCanceledPointerdowns.first(); |
| 796 if (firstId > uniqueTouchEventId) | 778 if (firstId > uniqueTouchEventId) |
| 797 return false; | 779 return false; |
| 798 m_touchIdsForCanceledPointerdowns.takeFirst(); | 780 m_touchIdsForCanceledPointerdowns.takeFirst(); |
| 799 if (firstId == uniqueTouchEventId) | 781 if (firstId == uniqueTouchEventId) |
| 800 return true; | 782 return true; |
| 801 } | 783 } |
| 802 return false; | 784 return false; |
| 803 } | 785 } |
| 804 | 786 |
| 787 EventTarget* PointerEventManager::getMouseCapturingNode() |
| 788 { |
| 789 return getCapturingNode(PointerEventFactory::s_mouseId); |
| 790 } |
| 791 |
| 805 DEFINE_TRACE(PointerEventManager) | 792 DEFINE_TRACE(PointerEventManager) |
| 806 { | 793 { |
| 807 visitor->trace(m_frame); | 794 visitor->trace(m_frame); |
| 808 visitor->trace(m_nodeUnderPointer); | 795 visitor->trace(m_nodeUnderPointer); |
| 809 visitor->trace(m_pointerCaptureTarget); | 796 visitor->trace(m_pointerCaptureTarget); |
| 810 visitor->trace(m_pendingPointerCaptureTarget); | 797 visitor->trace(m_pendingPointerCaptureTarget); |
| 811 visitor->trace(m_touchEventManager); | 798 visitor->trace(m_touchEventManager); |
| 812 } | 799 } |
| 813 | 800 |
| 814 | 801 |
| 815 } // namespace blink | 802 } // namespace blink |
| OLD | NEW |