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/ExecutionContextTask.h" | |
9 #include "core/dom/shadow/FlatTreeTraversal.h" | 8 #include "core/dom/shadow/FlatTreeTraversal.h" |
10 #include "core/events/MouseEvent.h" | 9 #include "core/events/MouseEvent.h" |
11 #include "core/frame/FrameView.h" | 10 #include "core/frame/FrameView.h" |
12 #include "core/frame/UseCounter.h" | 11 #include "core/frame/UseCounter.h" |
13 #include "core/html/HTMLCanvasElement.h" | 12 #include "core/html/HTMLCanvasElement.h" |
14 #include "core/input/EventHandler.h" | 13 #include "core/input/EventHandler.h" |
15 #include "core/input/TouchActionUtil.h" | 14 #include "core/input/TouchActionUtil.h" |
16 #include "core/page/ChromeClient.h" | 15 #include "core/page/ChromeClient.h" |
17 #include "core/page/Page.h" | 16 #include "core/page/Page.h" |
18 #include "platform/PlatformTouchEvent.h" | 17 #include "platform/PlatformTouchEvent.h" |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 | 362 |
364 processCaptureAndPositionOfPointerEvent(pointerEvent, target); | 363 processCaptureAndPositionOfPointerEvent(pointerEvent, target); |
365 | 364 |
366 // TODO(nzolghadr): This event follows implicit TE capture. The actual t
arget | 365 // TODO(nzolghadr): This event follows implicit TE capture. The actual t
arget |
367 // would depend on PE capturing. Perhaps need to split TE/PE event path
upstream? | 366 // would depend on PE capturing. Perhaps need to split TE/PE event path
upstream? |
368 // crbug.com/579553. | 367 // crbug.com/579553. |
369 dispatchPointerEvent( | 368 dispatchPointerEvent( |
370 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId())
, | 369 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId())
, |
371 pointerEvent); | 370 pointerEvent); |
372 | 371 |
373 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); | 372 releasePointerCapture(pointerEvent->pointerId()); |
374 | 373 |
375 // Sending the leave/out events and lostpointercapture | 374 // Sending the leave/out events and lostpointercapture |
376 // because the next touch event will have a different id. So delayed | 375 // because the next touch event will have a different id. So delayed |
377 // sending of lostpointercapture won't work here. | 376 // sending of lostpointercapture won't work here. |
378 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); | 377 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); |
379 | 378 |
380 removePointer(pointerEvent); | 379 removePointer(pointerEvent); |
381 } | 380 } |
382 } | 381 } |
383 | 382 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 // Setting the implicit capture for touch | 508 // Setting the implicit capture for touch |
510 if (pointerEvent->type() == EventTypeNames::pointerdown) | 509 if (pointerEvent->type() == EventTypeNames::pointerdown) |
511 setPointerCapture(pointerEvent->pointerId(), target); | 510 setPointerCapture(pointerEvent->pointerId(), target); |
512 | 511 |
513 WebInputEventResult result = dispatchPointerEvent( | 512 WebInputEventResult result = dispatchPointerEvent( |
514 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), | 513 getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId()), |
515 pointerEvent); | 514 pointerEvent); |
516 | 515 |
517 if (pointerEvent->type() == EventTypeNames::pointerup | 516 if (pointerEvent->type() == EventTypeNames::pointerup |
518 || pointerEvent->type() == EventTypeNames::pointercancel) { | 517 || pointerEvent->type() == EventTypeNames::pointercancel) { |
519 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); | 518 releasePointerCapture(pointerEvent->pointerId()); |
520 | 519 |
521 // Sending the leave/out events and lostpointercapture | 520 // Sending the leave/out events and lostpointercapture |
522 // because the next touch event will have a different id. So delayed | 521 // because the next touch event will have a different id. So delayed |
523 // sending of lostpointercapture won't work here. | 522 // sending of lostpointercapture won't work here. |
524 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); | 523 processCaptureAndPositionOfPointerEvent(pointerEvent, nullptr); |
525 | 524 |
526 removePointer(pointerEvent); | 525 removePointer(pointerEvent); |
527 } | 526 } |
528 | 527 |
529 return result; | 528 return result; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 break; | 574 break; |
576 } | 575 } |
577 } | 576 } |
578 } | 577 } |
579 result = EventHandler::mergeEventResult(result, | 578 result = EventHandler::mergeEventResult(result, |
580 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, | 579 dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent, |
581 nullptr, clickCount)); | 580 nullptr, clickCount)); |
582 } | 581 } |
583 | 582 |
584 if (pointerEvent->buttons() == 0) { | 583 if (pointerEvent->buttons() == 0) { |
585 modifyPendingPointerCapture(pointerEvent->pointerId(), nullptr); | 584 releasePointerCapture(pointerEvent->pointerId()); |
586 if (pointerEvent->isPrimary()) { | 585 if (pointerEvent->isPrimary()) { |
587 m_preventMouseEventForPointerType[toPointerTypeIndex( | 586 m_preventMouseEventForPointerType[toPointerTypeIndex( |
588 mouseEvent.pointerProperties().pointerType)] = false; | 587 mouseEvent.pointerProperties().pointerType)] = false; |
589 } | 588 } |
590 } | 589 } |
591 | 590 |
592 return result; | 591 return result; |
593 } | 592 } |
594 | 593 |
595 PointerEventManager::PointerEventManager(LocalFrame* frame) | 594 PointerEventManager::PointerEventManager(LocalFrame* frame) |
(...skipping 13 matching lines...) Expand all Loading... |
609 entry = false; | 608 entry = false; |
610 m_touchEventManager.clear(); | 609 m_touchEventManager.clear(); |
611 m_inCanceledStateForPointerTypeTouch = false; | 610 m_inCanceledStateForPointerTypeTouch = false; |
612 m_pointerEventFactory.clear(); | 611 m_pointerEventFactory.clear(); |
613 m_touchIdsForCanceledPointerdowns.clear(); | 612 m_touchIdsForCanceledPointerdowns.clear(); |
614 m_nodeUnderPointer.clear(); | 613 m_nodeUnderPointer.clear(); |
615 m_pointerCaptureTarget.clear(); | 614 m_pointerCaptureTarget.clear(); |
616 m_pendingPointerCaptureTarget.clear(); | 615 m_pendingPointerCaptureTarget.clear(); |
617 } | 616 } |
618 | 617 |
619 bool PointerEventManager::getPointerCaptureState(int pointerId, | |
620 EventTarget** pointerCaptureTarget, | |
621 EventTarget** pendingPointerCaptureTarget) | |
622 { | |
623 PointerCapturingMap::iterator it; | |
624 | |
625 it = m_pointerCaptureTarget.find(pointerId); | |
626 EventTarget* pointercaptureTargetTemp = (it != m_pointerCaptureTarget.end())
? it->value : nullptr; | |
627 it = m_pendingPointerCaptureTarget.find(pointerId); | |
628 EventTarget* pendingPointercaptureTargetTemp = (it != m_pendingPointerCaptur
eTarget.end()) ? it->value : nullptr; | |
629 | |
630 if (pointerCaptureTarget) | |
631 *pointerCaptureTarget = pointercaptureTargetTemp; | |
632 if (pendingPointerCaptureTarget) | |
633 *pendingPointerCaptureTarget = pendingPointercaptureTargetTemp; | |
634 | |
635 return pointercaptureTargetTemp != pendingPointercaptureTargetTemp; | |
636 } | |
637 | |
638 void PointerEventManager::processCaptureAndPositionOfPointerEvent( | 618 void PointerEventManager::processCaptureAndPositionOfPointerEvent( |
639 PointerEvent* pointerEvent, | 619 PointerEvent* pointerEvent, |
640 EventTarget* hitTestTarget, | 620 EventTarget* hitTestTarget, |
641 EventTarget* lastNodeUnderMouse, | 621 EventTarget* lastNodeUnderMouse, |
642 const PlatformMouseEvent& mouseEvent, | 622 const PlatformMouseEvent& mouseEvent, |
643 bool sendMouseEvent, bool setPointerPosition) | 623 bool sendMouseEvent, bool setPointerPosition) |
644 { | 624 { |
645 bool isCaptureChanged = false; | 625 bool isCaptureChanged = false; |
646 | 626 |
647 if (setPointerPosition) { | 627 if (setPointerPosition) { |
648 isCaptureChanged = processPendingPointerCapture(pointerEvent, | 628 isCaptureChanged = processPendingPointerCapture(pointerEvent, |
649 hitTestTarget, mouseEvent, sendMouseEvent); | 629 hitTestTarget, mouseEvent, sendMouseEvent); |
650 // If there was a change in capturing processPendingPointerCapture has | 630 // If there was a change in capturing processPendingPointerCapture has |
651 // already taken care of transition events. So we don't need to send the | 631 // already taken care of transition events. So we don't need to send the |
652 // transition events here. | 632 // transition events here. |
653 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged); | 633 setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged); |
654 } | 634 } |
655 if (sendMouseEvent && !isCaptureChanged) { | 635 if (sendMouseEvent && !isCaptureChanged) { |
656 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. | 636 // lastNodeUnderMouse is needed here because it is still stored in Event
Handler. |
657 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, | 637 sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget, |
658 pointerEvent, mouseEvent, true); | 638 pointerEvent, mouseEvent, true); |
659 } | 639 } |
660 } | 640 } |
661 | 641 |
662 void PointerEventManager::immediatelyProcessPendingPointerCapture(int pointerId) | |
663 { | |
664 EventTarget* pointerCaptureTarget; | |
665 EventTarget* pendingPointerCaptureTarget; | |
666 const bool isCaptureChanged = getPointerCaptureState(pointerId, | |
667 &pointerCaptureTarget, &pendingPointerCaptureTarget); | |
668 | |
669 if (!isCaptureChanged) | |
670 return; | |
671 | |
672 if (pointerCaptureTarget) { | |
673 // Re-target lostpointercapture to the document when the element is | |
674 // no longer participating in the tree. | |
675 EventTarget* target = pointerCaptureTarget; | |
676 if (target->toNode() | |
677 && !target->toNode()->isConnected()) { | |
678 target = target->toNode()->ownerDocument(); | |
679 } | |
680 dispatchPointerEvent(target, | |
681 m_pointerEventFactory.createPointerCaptureEvent( | |
682 pointerId, EventTypeNames::lostpointercapture)); | |
683 } | |
684 dispatchPointerEvent(pendingPointerCaptureTarget, | |
685 m_pointerEventFactory.createPointerCaptureEvent( | |
686 pointerId, EventTypeNames::gotpointercapture)); | |
687 | |
688 // Setting |m_pointerCaptureTarget| comes at the end to prevent the infinite | |
689 // loop if js calls set/releasepointercapture in got/lostpointercapture | |
690 // handlers. | |
691 if (pendingPointerCaptureTarget) | |
692 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); | |
693 else | |
694 m_pointerCaptureTarget.remove(pointerId); | |
695 } | |
696 | |
697 // TODO(crbug.com/629921): This function should be merged with |immediatelyProce
ssPendingPointerCapture| | |
698 // when we stop hit-testing while a pointer is captured. | |
699 bool PointerEventManager::processPendingPointerCapture( | 642 bool PointerEventManager::processPendingPointerCapture( |
700 PointerEvent* pointerEvent, | 643 PointerEvent* pointerEvent, |
701 EventTarget* hitTestTarget, | 644 EventTarget* hitTestTarget, |
702 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) | 645 const PlatformMouseEvent& mouseEvent, bool sendMouseEvent) |
703 { | 646 { |
704 int pointerId = pointerEvent->pointerId(); | 647 int pointerId = pointerEvent->pointerId(); |
705 EventTarget* pointerCaptureTarget; | 648 EventTarget* pointerCaptureTarget = |
706 EventTarget* pendingPointerCaptureTarget; | 649 m_pointerCaptureTarget.contains(pointerId) |
707 const bool isCaptureChanged = getPointerCaptureState(pointerId, | 650 ? m_pointerCaptureTarget.get(pointerId) : nullptr; |
708 &pointerCaptureTarget, &pendingPointerCaptureTarget); | 651 EventTarget* pendingPointerCaptureTarget = |
| 652 m_pendingPointerCaptureTarget.contains(pointerId) |
| 653 ? m_pendingPointerCaptureTarget.get(pointerId) : nullptr; |
709 const EventTargetAttributes &nodeUnderPointerAtt = | 654 const EventTargetAttributes &nodeUnderPointerAtt = |
710 m_nodeUnderPointer.contains(pointerId) | 655 m_nodeUnderPointer.contains(pointerId) |
711 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); | 656 ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes(); |
| 657 const bool isCaptureChanged = |
| 658 pointerCaptureTarget != pendingPointerCaptureTarget; |
712 | 659 |
713 if (isCaptureChanged) { | 660 if (isCaptureChanged) { |
714 if ((hitTestTarget != nodeUnderPointerAtt.target | 661 if ((hitTestTarget != nodeUnderPointerAtt.target |
715 || (pendingPointerCaptureTarget | 662 || (pendingPointerCaptureTarget |
716 && pendingPointerCaptureTarget != nodeUnderPointerAtt.target)) | 663 && pendingPointerCaptureTarget != nodeUnderPointerAtt.target)) |
717 && nodeUnderPointerAtt.hasRecievedOverEvent) { | 664 && nodeUnderPointerAtt.hasRecievedOverEvent) { |
718 if (sendMouseEvent) { | 665 if (sendMouseEvent) { |
719 // Send pointer event transitions as the line after this if | 666 // Send pointer event transitions as the line after this if |
720 // block sends the mouse events | 667 // block sends the mouse events |
721 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, | 668 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, |
722 pointerEvent); | 669 pointerEvent); |
723 } | 670 } |
724 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, | 671 sendBoundaryEvents(nodeUnderPointerAtt.target, nullptr, |
725 pointerEvent, mouseEvent, sendMouseEvent); | 672 pointerEvent, mouseEvent, sendMouseEvent); |
726 } | 673 } |
727 if (pointerCaptureTarget) { | 674 if (pointerCaptureTarget) { |
728 // Re-target lostpointercapture to the document when the element is | 675 // Re-target lostpointercapture to the document when the element is |
729 // no longer participating in the tree. | 676 // no longer participating in the tree. |
730 EventTarget* target = pointerCaptureTarget; | 677 EventTarget* target = pointerCaptureTarget; |
731 if (target->toNode() | 678 if (target->toNode() |
732 && !target->toNode()->isConnected()) { | 679 && !target->toNode()->isConnected()) { |
733 target = target->toNode()->ownerDocument(); | 680 target = target->toNode()->ownerDocument(); |
734 } | 681 } |
735 dispatchPointerEvent(target, | 682 dispatchPointerEvent(target, |
736 m_pointerEventFactory.createPointerCaptureEvent( | 683 m_pointerEventFactory.createPointerCaptureEvent( |
737 pointerId, EventTypeNames::lostpointercapture)); | 684 pointerEvent, EventTypeNames::lostpointercapture)); |
738 } | 685 } |
739 } | 686 } |
740 | 687 |
741 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does | 688 // Set pointerCaptureTarget from pendingPointerCaptureTarget. This does |
742 // affect the behavior of sendBoundaryEvents function. So the | 689 // affect the behavior of sendBoundaryEvents function. So the |
743 // ordering of the surrounding blocks of code for sending transition events | 690 // ordering of the surrounding blocks of code for sending transition events |
744 // are important. | 691 // are important. |
745 if (pendingPointerCaptureTarget) | 692 if (pendingPointerCaptureTarget) |
746 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); | 693 m_pointerCaptureTarget.set(pointerId, pendingPointerCaptureTarget); |
747 else | 694 else |
748 m_pointerCaptureTarget.remove(pointerId); | 695 m_pointerCaptureTarget.remove(pointerId); |
749 | 696 |
750 if (isCaptureChanged) { | 697 if (isCaptureChanged) { |
751 dispatchPointerEvent(pendingPointerCaptureTarget, | 698 dispatchPointerEvent(pendingPointerCaptureTarget, |
752 m_pointerEventFactory.createPointerCaptureEvent( | 699 m_pointerEventFactory.createPointerCaptureEvent( |
753 pointerId, EventTypeNames::gotpointercapture)); | 700 pointerEvent, EventTypeNames::gotpointercapture)); |
754 if ((pendingPointerCaptureTarget == hitTestTarget | 701 if ((pendingPointerCaptureTarget == hitTestTarget |
755 || !pendingPointerCaptureTarget) | 702 || !pendingPointerCaptureTarget) |
756 && (nodeUnderPointerAtt.target != hitTestTarget | 703 && (nodeUnderPointerAtt.target != hitTestTarget |
757 || !nodeUnderPointerAtt.hasRecievedOverEvent)) { | 704 || !nodeUnderPointerAtt.hasRecievedOverEvent)) { |
758 if (sendMouseEvent) { | 705 if (sendMouseEvent) { |
759 // Send pointer event transitions as the line after this if | 706 // Send pointer event transitions as the line after this if |
760 // block sends the mouse events | 707 // block sends the mouse events |
761 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent); | 708 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent); |
762 } | 709 } |
763 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent, | 710 sendBoundaryEvents(nullptr, hitTestTarget, pointerEvent, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 } | 747 } |
801 | 748 |
802 void PointerEventManager::elementRemoved(EventTarget* target) | 749 void PointerEventManager::elementRemoved(EventTarget* target) |
803 { | 750 { |
804 removeTargetFromPointerCapturingMapping(m_pendingPointerCaptureTarget, targe
t); | 751 removeTargetFromPointerCapturingMapping(m_pendingPointerCaptureTarget, targe
t); |
805 } | 752 } |
806 | 753 |
807 void PointerEventManager::setPointerCapture(int pointerId, EventTarget* target) | 754 void PointerEventManager::setPointerCapture(int pointerId, EventTarget* target) |
808 { | 755 { |
809 UseCounter::count(m_frame->document(), UseCounter::PointerEventSetCapture); | 756 UseCounter::count(m_frame->document(), UseCounter::PointerEventSetCapture); |
810 if (m_pointerEventFactory.isActiveButtonsState(pointerId)) { | 757 if (m_pointerEventFactory.isActiveButtonsState(pointerId)) |
811 modifyPendingPointerCapture(pointerId, target); | 758 m_pendingPointerCaptureTarget.set(pointerId, target); |
812 } | |
813 } | 759 } |
814 | 760 |
815 void PointerEventManager::releasePointerCapture(int pointerId, EventTarget* targ
et) | 761 void PointerEventManager::releasePointerCapture(int pointerId, EventTarget* targ
et) |
816 { | 762 { |
817 // Only the element that is going to get the next pointer event can release | 763 // Only the element that is going to get the next pointer event can release |
818 // the capture. Note that this might be different from | 764 // the capture. Note that this might be different from |
819 // |m_pointercaptureTarget|. |m_pointercaptureTarget| holds the element | 765 // |m_pointercaptureTarget|. |m_pointercaptureTarget| holds the element |
820 // that had the capture until now and has been receiving the pointerevents | 766 // that had the capture until now and has been receiving the pointerevents |
821 // but |m_pendingPointerCaptureTarget| indicated the element that gets the | 767 // but |m_pendingPointerCaptureTarget| indicated the element that gets the |
822 // very next pointer event. They will be the same if there was no change in | 768 // very next pointer event. They will be the same if there was no change in |
823 // capturing of a particular |pointerId|. See crbug.com/614481. | 769 // capturing of a particular |pointerId|. See crbug.com/614481. |
824 if (m_pendingPointerCaptureTarget.get(pointerId) == target) | 770 if (m_pendingPointerCaptureTarget.get(pointerId) == target) |
825 modifyPendingPointerCapture(pointerId, nullptr); | 771 releasePointerCapture(pointerId); |
826 } | 772 } |
827 | 773 |
828 void PointerEventManager::modifyPendingPointerCapture( | 774 void PointerEventManager::releasePointerCapture(int pointerId) |
829 int pointerId, EventTarget* target) | |
830 { | 775 { |
831 bool wasCaptureStationary = !getPointerCaptureState(pointerId, nullptr, null
ptr); | 776 m_pendingPointerCaptureTarget.remove(pointerId); |
832 | |
833 if (target) | |
834 m_pendingPointerCaptureTarget.set(pointerId, target); | |
835 else | |
836 m_pendingPointerCaptureTarget.remove(pointerId); | |
837 | |
838 // Only queue the processing pending pointer capture if the pending | |
839 // capture target and capture target were the same to prevent infinite | |
840 // got/lostpointercapture event sequence. | |
841 // See https://github.com/w3c/pointerevents/issues/32. | |
842 if (wasCaptureStationary) { | |
843 m_frame->document()->postTask( | |
844 BLINK_FROM_HERE, | |
845 createSameThreadTask( | |
846 &EventHandler::immediatelyProcessPendingPointerCapture, | |
847 wrapWeakPersistent(&m_frame->eventHandler()), pointerId)); | |
848 } | |
849 } | 777 } |
850 | 778 |
851 bool PointerEventManager::isActive(const int pointerId) const | 779 bool PointerEventManager::isActive(const int pointerId) const |
852 { | 780 { |
853 return m_pointerEventFactory.isActive(pointerId); | 781 return m_pointerEventFactory.isActive(pointerId); |
854 } | 782 } |
855 | 783 |
856 bool PointerEventManager::isAnyTouchActive() const | 784 bool PointerEventManager::isAnyTouchActive() const |
857 { | 785 { |
858 return m_touchEventManager.isAnyTouchActive(); | 786 return m_touchEventManager.isAnyTouchActive(); |
(...skipping 19 matching lines...) Expand all Loading... |
878 { | 806 { |
879 visitor->trace(m_frame); | 807 visitor->trace(m_frame); |
880 visitor->trace(m_nodeUnderPointer); | 808 visitor->trace(m_nodeUnderPointer); |
881 visitor->trace(m_pointerCaptureTarget); | 809 visitor->trace(m_pointerCaptureTarget); |
882 visitor->trace(m_pendingPointerCaptureTarget); | 810 visitor->trace(m_pendingPointerCaptureTarget); |
883 visitor->trace(m_touchEventManager); | 811 visitor->trace(m_touchEventManager); |
884 } | 812 } |
885 | 813 |
886 | 814 |
887 } // namespace blink | 815 } // namespace blink |
OLD | NEW |