| 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 27 matching lines...) Expand all Loading... |
| 38 #include "core/dom/TouchList.h" | 38 #include "core/dom/TouchList.h" |
| 39 #include "core/dom/shadow/ComposedTreeTraversal.h" | 39 #include "core/dom/shadow/ComposedTreeTraversal.h" |
| 40 #include "core/dom/shadow/ShadowRoot.h" | 40 #include "core/dom/shadow/ShadowRoot.h" |
| 41 #include "core/editing/Editor.h" | 41 #include "core/editing/Editor.h" |
| 42 #include "core/editing/FrameSelection.h" | 42 #include "core/editing/FrameSelection.h" |
| 43 #include "core/editing/htmlediting.h" | 43 #include "core/editing/htmlediting.h" |
| 44 #include "core/editing/iterators/TextIterator.h" | 44 #include "core/editing/iterators/TextIterator.h" |
| 45 #include "core/events/EventPath.h" | 45 #include "core/events/EventPath.h" |
| 46 #include "core/events/KeyboardEvent.h" | 46 #include "core/events/KeyboardEvent.h" |
| 47 #include "core/events/MouseEvent.h" | 47 #include "core/events/MouseEvent.h" |
| 48 #include "core/events/PointerEvent.h" |
| 48 #include "core/events/TextEvent.h" | 49 #include "core/events/TextEvent.h" |
| 49 #include "core/events/TouchEvent.h" | 50 #include "core/events/TouchEvent.h" |
| 50 #include "core/events/WheelEvent.h" | 51 #include "core/events/WheelEvent.h" |
| 51 #include "core/fetch/ImageResource.h" | 52 #include "core/fetch/ImageResource.h" |
| 52 #include "core/frame/EventHandlerRegistry.h" | 53 #include "core/frame/EventHandlerRegistry.h" |
| 53 #include "core/frame/FrameHost.h" | 54 #include "core/frame/FrameHost.h" |
| 54 #include "core/frame/FrameView.h" | 55 #include "core/frame/FrameView.h" |
| 55 #include "core/frame/LocalFrame.h" | 56 #include "core/frame/LocalFrame.h" |
| 56 #include "core/frame/PinchViewport.h" | 57 #include "core/frame/PinchViewport.h" |
| 57 #include "core/frame/Settings.h" | 58 #include "core/frame/Settings.h" |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire
d) | 230 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire
d) |
| 230 , m_svgPan(false) | 231 , m_svgPan(false) |
| 231 , m_resizeScrollableArea(nullptr) | 232 , m_resizeScrollableArea(nullptr) |
| 232 , m_eventHandlerWillResetCapturingMouseEventsNode(0) | 233 , m_eventHandlerWillResetCapturingMouseEventsNode(0) |
| 233 , m_clickCount(0) | 234 , m_clickCount(0) |
| 234 , m_shouldOnlyFireDragOverEvent(false) | 235 , m_shouldOnlyFireDragOverEvent(false) |
| 235 , m_mousePositionIsUnknown(true) | 236 , m_mousePositionIsUnknown(true) |
| 236 , m_mouseDownTimestamp(0) | 237 , m_mouseDownTimestamp(0) |
| 237 , m_widgetIsLatched(false) | 238 , m_widgetIsLatched(false) |
| 238 , m_touchPressed(false) | 239 , m_touchPressed(false) |
| 240 , m_primaryPointerId(0) |
| 239 , m_scrollGestureHandlingNode(nullptr) | 241 , m_scrollGestureHandlingNode(nullptr) |
| 240 , m_lastGestureScrollOverWidget(false) | 242 , m_lastGestureScrollOverWidget(false) |
| 241 , m_maxMouseMovedDuration(0) | 243 , m_maxMouseMovedDuration(0) |
| 242 , m_longTapShouldInvokeContextMenu(false) | 244 , m_longTapShouldInvokeContextMenu(false) |
| 243 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) | 245 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) |
| 244 , m_lastShowPressTimestamp(0) | 246 , m_lastShowPressTimestamp(0) |
| 245 , m_deltaConsumedForScrollSequence(false) | 247 , m_deltaConsumedForScrollSequence(false) |
| 246 { | 248 { |
| 247 } | 249 } |
| 248 | 250 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 m_previousWheelScrolledNode = nullptr; | 311 m_previousWheelScrolledNode = nullptr; |
| 310 m_targetForTouchID.clear(); | 312 m_targetForTouchID.clear(); |
| 311 m_touchSequenceDocument.clear(); | 313 m_touchSequenceDocument.clear(); |
| 312 m_touchSequenceUserGestureToken.clear(); | 314 m_touchSequenceUserGestureToken.clear(); |
| 313 m_scrollGestureHandlingNode = nullptr; | 315 m_scrollGestureHandlingNode = nullptr; |
| 314 m_lastGestureScrollOverWidget = false; | 316 m_lastGestureScrollOverWidget = false; |
| 315 m_previousGestureScrolledNode = nullptr; | 317 m_previousGestureScrolledNode = nullptr; |
| 316 m_scrollbarHandlingScrollGesture = nullptr; | 318 m_scrollbarHandlingScrollGesture = nullptr; |
| 317 m_maxMouseMovedDuration = 0; | 319 m_maxMouseMovedDuration = 0; |
| 318 m_touchPressed = false; | 320 m_touchPressed = false; |
| 321 m_primaryPointerId = 0; |
| 319 m_mouseDownMayStartSelect = false; | 322 m_mouseDownMayStartSelect = false; |
| 320 m_mouseDownMayStartDrag = false; | 323 m_mouseDownMayStartDrag = false; |
| 321 m_lastShowPressTimestamp = 0; | 324 m_lastShowPressTimestamp = 0; |
| 322 m_lastDeferredTapElement = nullptr; | 325 m_lastDeferredTapElement = nullptr; |
| 323 m_eventHandlerWillResetCapturingMouseEventsNode = false; | 326 m_eventHandlerWillResetCapturingMouseEventsNode = false; |
| 324 m_mouseDownWasSingleClickInSelection = false; | 327 m_mouseDownWasSingleClickInSelection = false; |
| 325 m_selectionInitiationState = HaveNotStartedSelection; | 328 m_selectionInitiationState = HaveNotStartedSelection; |
| 326 m_mouseDownMayStartAutoscroll = false; | 329 m_mouseDownMayStartAutoscroll = false; |
| 327 m_svgPan = false; | 330 m_svgPan = false; |
| 328 m_mouseDownPos = IntPoint(); | 331 m_mouseDownPos = IntPoint(); |
| (...skipping 3441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3770 m_lastScrollbarUnderMouse->mouseExited(); | 3773 m_lastScrollbarUnderMouse->mouseExited(); |
| 3771 | 3774 |
| 3772 // Send mouse entered if we're setting a new scrollbar. | 3775 // Send mouse entered if we're setting a new scrollbar. |
| 3773 if (scrollbar && setLast) | 3776 if (scrollbar && setLast) |
| 3774 scrollbar->mouseEntered(); | 3777 scrollbar->mouseEntered(); |
| 3775 | 3778 |
| 3776 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; | 3779 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; |
| 3777 } | 3780 } |
| 3778 } | 3781 } |
| 3779 | 3782 |
| 3780 static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State
state) | 3783 static const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::
State state) |
| 3781 { | 3784 { |
| 3782 switch (state) { | 3785 switch (state) { |
| 3783 case PlatformTouchPoint::TouchReleased: | 3786 case PlatformTouchPoint::TouchReleased: |
| 3784 return EventTypeNames::touchend; | 3787 return EventTypeNames::touchend; |
| 3785 case PlatformTouchPoint::TouchCancelled: | 3788 case PlatformTouchPoint::TouchCancelled: |
| 3786 return EventTypeNames::touchcancel; | 3789 return EventTypeNames::touchcancel; |
| 3787 case PlatformTouchPoint::TouchPressed: | 3790 case PlatformTouchPoint::TouchPressed: |
| 3788 return EventTypeNames::touchstart; | 3791 return EventTypeNames::touchstart; |
| 3789 case PlatformTouchPoint::TouchMoved: | 3792 case PlatformTouchPoint::TouchMoved: |
| 3790 return EventTypeNames::touchmove; | 3793 return EventTypeNames::touchmove; |
| 3791 case PlatformTouchPoint::TouchStationary: | 3794 case PlatformTouchPoint::TouchStationary: |
| 3792 // TouchStationary state is not converted to touch events, so fall throu
gh to assert. | 3795 // TouchStationary state is not converted to touch events, so fall throu
gh to assert. |
| 3793 default: | 3796 default: |
| 3794 ASSERT_NOT_REACHED(); | 3797 ASSERT_NOT_REACHED(); |
| 3795 return emptyAtom; | 3798 return emptyAtom; |
| 3796 } | 3799 } |
| 3797 } | 3800 } |
| 3798 | 3801 |
| 3802 static const AtomicString& pointerEventNameForTouchPointState(PlatformTouchPoint
::State state) |
| 3803 { |
| 3804 switch (state) { |
| 3805 case PlatformTouchPoint::TouchReleased: |
| 3806 return EventTypeNames::pointerup; |
| 3807 case PlatformTouchPoint::TouchCancelled: |
| 3808 return EventTypeNames::pointercancel; |
| 3809 case PlatformTouchPoint::TouchPressed: |
| 3810 return EventTypeNames::pointerdown; |
| 3811 case PlatformTouchPoint::TouchMoved: |
| 3812 return EventTypeNames::pointermove; |
| 3813 case PlatformTouchPoint::TouchStationary: |
| 3814 // TouchStationary state is not converted to touch events, so fall throu
gh to assert. |
| 3815 default: |
| 3816 ASSERT_NOT_REACHED(); |
| 3817 return emptyAtom; |
| 3818 } |
| 3819 } |
| 3820 |
| 3799 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout
Point& point, HitTestRequest::HitTestRequestType hitType) | 3821 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout
Point& point, HitTestRequest::HitTestRequestType hitType) |
| 3800 { | 3822 { |
| 3801 HitTestResult result(HitTestRequest(hitType), point); | 3823 HitTestResult result(HitTestRequest(hitType), point); |
| 3802 | 3824 |
| 3803 if (!frame || !frame->contentLayoutObject()) | 3825 if (!frame || !frame->contentLayoutObject()) |
| 3804 return result; | 3826 return result; |
| 3805 if (frame->view()) { | 3827 if (frame->view()) { |
| 3806 IntRect rect = frame->view()->visibleContentRect(IncludeScrollbars); | 3828 IntRect rect = frame->view()->visibleContentRect(IncludeScrollbars); |
| 3807 if (!rect.contains(roundedIntPoint(point))) | 3829 if (!rect.contains(roundedIntPoint(point))) |
| 3808 return result; | 3830 return result; |
| 3809 } | 3831 } |
| 3810 frame->contentLayoutObject()->hitTest(result); | 3832 frame->contentLayoutObject()->hitTest(result); |
| 3811 return result; | 3833 return result; |
| 3812 } | 3834 } |
| 3813 | 3835 |
| 3814 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) | 3836 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) |
| 3815 { | 3837 { |
| 3816 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); | 3838 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); |
| 3817 | 3839 |
| 3818 const Vector<PlatformTouchPoint>& points = event.touchPoints(); | 3840 const Vector<PlatformTouchPoint>& points = event.touchPoints(); |
| 3819 | 3841 |
| 3820 unsigned i; | |
| 3821 bool freshTouchEvents = true; | 3842 bool freshTouchEvents = true; |
| 3822 bool allTouchReleased = true; | 3843 bool allTouchReleased = true; |
| 3823 for (i = 0; i < points.size(); ++i) { | 3844 for (unsigned i = 0; i < points.size(); ++i) { |
| 3824 const PlatformTouchPoint& point = points[i]; | 3845 const PlatformTouchPoint& point = points[i]; |
| 3825 if (point.state() != PlatformTouchPoint::TouchPressed) | 3846 if (point.state() != PlatformTouchPoint::TouchPressed) |
| 3826 freshTouchEvents = false; | 3847 freshTouchEvents = false; |
| 3827 if (point.state() != PlatformTouchPoint::TouchReleased && point.state()
!= PlatformTouchPoint::TouchCancelled) | 3848 if (point.state() != PlatformTouchPoint::TouchReleased && point.state()
!= PlatformTouchPoint::TouchCancelled) |
| 3828 allTouchReleased = false; | 3849 allTouchReleased = false; |
| 3829 } | 3850 } |
| 3830 if (freshTouchEvents) { | 3851 if (freshTouchEvents) { |
| 3831 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should | 3852 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should |
| 3832 // have cleared the active document when we saw the last release. But we | 3853 // have cleared the active document when we saw the last release. But we |
| 3833 // have some tests that violate this, ClusterFuzz could trigger it, and | 3854 // have some tests that violate this, ClusterFuzz could trigger it, and |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3847 m_touchSequenceUserGestureToken = gestureIndicator->currentToken(); | 3868 m_touchSequenceUserGestureToken = gestureIndicator->currentToken(); |
| 3848 | 3869 |
| 3849 ASSERT(m_frame->view()); | 3870 ASSERT(m_frame->view()); |
| 3850 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc
hSequenceDocument->frame()->view())) { | 3871 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc
hSequenceDocument->frame()->view())) { |
| 3851 // If the active touch document has no frame or view, it's probably bein
g destroyed | 3872 // If the active touch document has no frame or view, it's probably bein
g destroyed |
| 3852 // so we can't dispatch events. | 3873 // so we can't dispatch events. |
| 3853 return false; | 3874 return false; |
| 3854 } | 3875 } |
| 3855 | 3876 |
| 3856 // First do hit tests for any new touch points. | 3877 // First do hit tests for any new touch points. |
| 3857 for (i = 0; i < points.size(); ++i) { | 3878 for (unsigned i = 0; i < points.size(); ++i) { |
| 3858 const PlatformTouchPoint& point = points[i]; | 3879 const PlatformTouchPoint& point = points[i]; |
| 3859 | 3880 |
| 3860 // Touch events implicitly capture to the touched node, and don't change | 3881 // Touch events implicitly capture to the touched node, and don't change |
| 3861 // active/hover states themselves (Gesture events do). So we only need | 3882 // active/hover states themselves (Gesture events do). So we only need |
| 3862 // to hit-test on touchstart, and it can be read-only. | 3883 // to hit-test on touchstart, and it can be read-only. |
| 3863 if (point.state() == PlatformTouchPoint::TouchPressed) { | 3884 if (point.state() == PlatformTouchPoint::TouchPressed) { |
| 3864 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv
ent | HitTestRequest::ReadOnly | HitTestRequest::Active; | 3885 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv
ent | HitTestRequest::ReadOnly | HitTestRequest::Active; |
| 3865 LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->rootFram
eToContents(point.pos())); | 3886 LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->rootFram
eToContents(point.pos())); |
| 3866 HitTestResult result; | 3887 HitTestResult result; |
| 3867 if (!m_touchSequenceDocument) { | 3888 if (!m_touchSequenceDocument) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3882 node = ComposedTreeTraversal::parent(*node); | 3903 node = ComposedTreeTraversal::parent(*node); |
| 3883 | 3904 |
| 3884 if (!m_touchSequenceDocument) { | 3905 if (!m_touchSequenceDocument) { |
| 3885 // Keep track of which document should receive all touch events | 3906 // Keep track of which document should receive all touch events |
| 3886 // in the active sequence. This must be a single document to | 3907 // in the active sequence. This must be a single document to |
| 3887 // ensure we don't leak Nodes between documents. | 3908 // ensure we don't leak Nodes between documents. |
| 3888 m_touchSequenceDocument = &(result.innerNode()->document()); | 3909 m_touchSequenceDocument = &(result.innerNode()->document()); |
| 3889 ASSERT(m_touchSequenceDocument->frame()->view()); | 3910 ASSERT(m_touchSequenceDocument->frame()->view()); |
| 3890 } | 3911 } |
| 3891 | 3912 |
| 3913 // If it is the first TouchPressed we have seen so far, we will cons
ider it primary. |
| 3914 if (!m_primaryPointerId) |
| 3915 m_primaryPointerId = point.id(); |
| 3916 |
| 3892 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id()) | 3917 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id()) |
| 3893 // since we shouldn't get a touchstart for a touch that's already | 3918 // since we shouldn't get a touchstart for a touch that's already |
| 3894 // down. However EventSender allows this to be violated and there's | 3919 // down. However EventSender allows this to be violated and there's |
| 3895 // some tests that take advantage of it. There may also be edge | 3920 // some tests that take advantage of it. There may also be edge |
| 3896 // cases in the browser where this happens. | 3921 // cases in the browser where this happens. |
| 3897 // See http://crbug.com/345372. | 3922 // See http://crbug.com/345372. |
| 3898 m_targetForTouchID.set(point.id(), node); | 3923 m_targetForTouchID.set(point.id(), node); |
| 3899 | 3924 |
| 3900 TouchAction effectiveTouchAction = computeEffectiveTouchAction(*node
); | 3925 TouchAction effectiveTouchAction = computeEffectiveTouchAction(*node
); |
| 3901 if (effectiveTouchAction != TouchActionAuto) | 3926 if (effectiveTouchAction != TouchActionAuto) |
| 3902 m_frame->page()->chromeClient().setTouchAction(effectiveTouchAct
ion); | 3927 m_frame->page()->chromeClient().setTouchAction(effectiveTouchAct
ion); |
| 3903 } | 3928 } |
| 3904 } | 3929 } |
| 3905 | 3930 |
| 3906 m_touchPressed = !allTouchReleased; | 3931 m_touchPressed = !allTouchReleased; |
| 3907 | 3932 |
| 3933 unsigned lastPrimaryPointerId = m_primaryPointerId; |
| 3934 if (allTouchReleased) |
| 3935 m_primaryPointerId = 0; |
| 3936 |
| 3908 // If there's no document receiving touch events, or no handlers on the | 3937 // If there's no document receiving touch events, or no handlers on the |
| 3909 // document set to receive the events, then we can skip all the rest of | 3938 // document set to receive the events, then we can skip all the rest of |
| 3910 // this work. | 3939 // this work. |
| 3911 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !m_
touchSequenceDocument->frameHost()->eventHandlerRegistry().hasEventHandlers(Even
tHandlerRegistry::TouchEvent) || !m_touchSequenceDocument->frame()) { | 3940 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !m_
touchSequenceDocument->frameHost()->eventHandlerRegistry().hasEventHandlers(Even
tHandlerRegistry::TouchEvent) || !m_touchSequenceDocument->frame()) { |
| 3912 if (allTouchReleased) { | 3941 if (allTouchReleased) { |
| 3913 m_touchSequenceDocument.clear(); | 3942 m_touchSequenceDocument.clear(); |
| 3914 m_touchSequenceUserGestureToken.clear(); | 3943 m_touchSequenceUserGestureToken.clear(); |
| 3915 } | 3944 } |
| 3916 return false; | 3945 return false; |
| 3917 } | 3946 } |
| 3918 | 3947 |
| 3919 // Build up the lists to use for the 'touches', 'targetTouches' and | 3948 // Compute and store the common info used by both PointerEvent and TouchEven
t. |
| 3920 // 'changedTouches' attributes in the JS event. See | 3949 using TouchInfo = struct { |
| 3921 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these | 3950 EventTarget* touchTarget; |
| 3922 // lists fit together. | 3951 LocalFrame* targetFrame; |
| 3952 FloatPoint adjustedPagePoint; |
| 3953 FloatSize adjustedRadius; |
| 3954 bool knownTarget; |
| 3955 bool consumed; |
| 3956 }; |
| 3957 Vector<TouchInfo> touchInfos(points.size()); |
| 3923 | 3958 |
| 3924 // Holds the complete set of touches on the screen. | 3959 for (unsigned i = 0; i < points.size(); ++i) { |
| 3925 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create(); | |
| 3926 | |
| 3927 // A different view on the 'touches' list above, filtered and grouped by | |
| 3928 // event target. Used for the 'targetTouches' list in the JS event. | |
| 3929 using TargetTouchesHeapMap = WillBeHeapHashMap<EventTarget*, RefPtrWillBeMem
ber<TouchList>>; | |
| 3930 TargetTouchesHeapMap touchesByTarget; | |
| 3931 | |
| 3932 // Array of touches per state, used to assemble the 'changedTouches' list. | |
| 3933 using EventTargetSet = WillBeHeapHashSet<RefPtrWillBeMember<EventTarget>>; | |
| 3934 struct { | |
| 3935 // The touches corresponding to the particular change state this struct | |
| 3936 // instance represents. | |
| 3937 RefPtrWillBeMember<TouchList> m_touches; | |
| 3938 // Set of targets involved in m_touches. | |
| 3939 EventTargetSet m_targets; | |
| 3940 } changedTouches[PlatformTouchPoint::TouchStateEnd]; | |
| 3941 | |
| 3942 for (i = 0; i < points.size(); ++i) { | |
| 3943 const PlatformTouchPoint& point = points[i]; | 3960 const PlatformTouchPoint& point = points[i]; |
| 3944 PlatformTouchPoint::State pointState = point.state(); | 3961 PlatformTouchPoint::State pointState = point.state(); |
| 3945 RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr; | 3962 RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr; |
| 3946 | 3963 |
| 3947 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla
tformTouchPoint::TouchCancelled) { | 3964 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla
tformTouchPoint::TouchCancelled) { |
| 3948 // The target should be the original target for this touch, so get | 3965 // The target should be the original target for this touch, so get |
| 3949 // it from the hashmap. As it's a release or cancel we also remove | 3966 // it from the hashmap. As it's a release or cancel we also remove |
| 3950 // it from the map. | 3967 // it from the map. |
| 3951 touchTarget = m_targetForTouchID.take(point.id()); | 3968 touchTarget = m_targetForTouchID.take(point.id()); |
| 3952 } else { | 3969 } else { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3981 // a Touch is a Node so using the window could be a breaking change. | 3998 // a Touch is a Node so using the window could be a breaking change. |
| 3982 // Since we know there was no handler invoked, the specific target | 3999 // Since we know there was no handler invoked, the specific target |
| 3983 // should be completely irrelevant to the application. | 4000 // should be completely irrelevant to the application. |
| 3984 touchTarget = m_touchSequenceDocument; | 4001 touchTarget = m_touchSequenceDocument; |
| 3985 targetFrame = m_touchSequenceDocument->frame(); | 4002 targetFrame = m_touchSequenceDocument->frame(); |
| 3986 } | 4003 } |
| 3987 ASSERT(targetFrame); | 4004 ASSERT(targetFrame); |
| 3988 | 4005 |
| 3989 // pagePoint should always be in the target element's document coordinat
es. | 4006 // pagePoint should always be in the target element's document coordinat
es. |
| 3990 FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(point.po
s()); | 4007 FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(point.po
s()); |
| 3991 | |
| 3992 float scaleFactor = 1.0f / targetFrame->pageZoomFactor(); | 4008 float scaleFactor = 1.0f / targetFrame->pageZoomFactor(); |
| 3993 | 4009 |
| 3994 FloatPoint adjustedPagePoint = pagePoint.scaledBy(scaleFactor); | 4010 FloatPoint adjustedPagePoint = pagePoint.scaledBy(scaleFactor); |
| 3995 FloatSize adjustedRadius = point.radius().scaledBy(scaleFactor); | 4011 FloatSize adjustedRadius = point.radius().scaledBy(scaleFactor); |
| 3996 | 4012 |
| 4013 TouchInfo& touchInfo = touchInfos[i]; |
| 4014 touchInfo.touchTarget = touchTarget.get(); |
| 4015 touchInfo.targetFrame = targetFrame; |
| 4016 touchInfo.adjustedPagePoint = adjustedPagePoint; |
| 4017 touchInfo.adjustedRadius = adjustedRadius; |
| 4018 touchInfo.knownTarget = knownTarget; |
| 4019 touchInfo.consumed = false; |
| 4020 } |
| 4021 |
| 4022 if (RuntimeEnabledFeatures::pointerEventEnabled()) { |
| 4023 // Iterate through the touch points, sending PointerEvents to the target
s as required. |
| 4024 for (unsigned i = 0; i < points.size(); ++i) { |
| 4025 const PlatformTouchPoint& point = points[i]; |
| 4026 TouchInfo& touchInfo = touchInfos[i]; |
| 4027 |
| 4028 const PlatformTouchPoint::State pointState = point.state(); |
| 4029 const AtomicString& eventName(pointerEventNameForTouchPointState(poi
ntState)); |
| 4030 |
| 4031 bool isEnterOrLeave = false; |
| 4032 bool isCancelable = !(isEnterOrLeave || pointState == PlatformTouchP
oint::TouchCancelled); |
| 4033 bool isBubbling = !isEnterOrLeave; |
| 4034 |
| 4035 PointerEventInit pointerEventInit; |
| 4036 pointerEventInit.setPointerId(point.id()); |
| 4037 pointerEventInit.setWidth(touchInfo.adjustedRadius.width()); |
| 4038 pointerEventInit.setHeight(touchInfo.adjustedRadius.height()); |
| 4039 pointerEventInit.setPressure(point.force()); |
| 4040 pointerEventInit.setTiltX(0.0); |
| 4041 pointerEventInit.setTiltY(0.0); |
| 4042 pointerEventInit.setPointerType(eventName); |
| 4043 pointerEventInit.setIsPrimary(lastPrimaryPointerId == point.id()); /
/ TODO(mustaq): Fix. |
| 4044 |
| 4045 pointerEventInit.setScreenX(point.screenPos().x()); |
| 4046 pointerEventInit.setScreenY(point.screenPos().y()); |
| 4047 pointerEventInit.setClientX(0); |
| 4048 pointerEventInit.setClientY(0); |
| 4049 pointerEventInit.setMovementX(0); |
| 4050 pointerEventInit.setMovementY(0); |
| 4051 pointerEventInit.setButton(0); |
| 4052 pointerEventInit.setButtons(0); |
| 4053 pointerEventInit.setRelatedTarget(nullptr); |
| 4054 |
| 4055 pointerEventInit.setCtrlKey(event.ctrlKey()); |
| 4056 pointerEventInit.setShiftKey(event.shiftKey()); |
| 4057 pointerEventInit.setAltKey(event.altKey()); |
| 4058 pointerEventInit.setMetaKey(event.metaKey()); |
| 4059 |
| 4060 pointerEventInit.setBubbles(isBubbling); |
| 4061 pointerEventInit.setCancelable(isCancelable); |
| 4062 |
| 4063 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = PointerEvent::create
(eventName, pointerEventInit); |
| 4064 touchInfo.touchTarget->toNode()->dispatchPointerEvent(pointerEvent.g
et()); |
| 4065 touchInfo.consumed = pointerEvent->defaultPrevented() || pointerEven
t->defaultHandled(); |
| 4066 } |
| 4067 } |
| 4068 |
| 4069 bool swallowedEvent = false; |
| 4070 |
| 4071 // Build up the lists to use for the 'touches', 'targetTouches' and |
| 4072 // 'changedTouches' attributes in the JS event. See |
| 4073 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these |
| 4074 // lists fit together. |
| 4075 |
| 4076 // Holds the complete set of touches on the screen. |
| 4077 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create(); |
| 4078 |
| 4079 // A different view on the 'touches' list above, filtered and grouped by |
| 4080 // event target. Used for the 'targetTouches' list in the JS event. |
| 4081 using TargetTouchesHeapMap = WillBeHeapHashMap<EventTarget*, RefPtrWillBeMem
ber<TouchList>>; |
| 4082 TargetTouchesHeapMap touchesByTarget; |
| 4083 |
| 4084 // Array of touches per state, used to assemble the 'changedTouches' list. |
| 4085 using EventTargetSet = WillBeHeapHashSet<RefPtrWillBeMember<EventTarget>>; |
| 4086 struct { |
| 4087 // The touches corresponding to the particular change state this struct |
| 4088 // instance represents. |
| 4089 RefPtrWillBeMember<TouchList> m_touches; |
| 4090 // Set of targets involved in m_touches. |
| 4091 EventTargetSet m_targets; |
| 4092 } changedTouches[PlatformTouchPoint::TouchStateEnd]; |
| 4093 |
| 4094 for (unsigned i = 0; i < points.size(); ++i) { |
| 4095 const PlatformTouchPoint& point = points[i]; |
| 4096 const TouchInfo& touchInfo = touchInfos[i]; |
| 4097 PlatformTouchPoint::State pointState = point.state(); |
| 4098 |
| 4099 if (touchInfo.consumed) |
| 4100 continue; |
| 4101 |
| 3997 RefPtrWillBeRawPtr<Touch> touch = Touch::create( | 4102 RefPtrWillBeRawPtr<Touch> touch = Touch::create( |
| 3998 targetFrame, touchTarget.get(), point.id(), point.screenPos(), adjus
tedPagePoint, adjustedRadius, point.rotationAngle(), point.force()); | 4103 touchInfo.targetFrame, |
| 4104 touchInfo.touchTarget, |
| 4105 point.id(), |
| 4106 point.screenPos(), |
| 4107 touchInfo.adjustedPagePoint, |
| 4108 touchInfo.adjustedRadius, |
| 4109 point.rotationAngle(), |
| 4110 point.force()); |
| 3999 | 4111 |
| 4000 // Ensure this target's touch list exists, even if it ends up empty, so | 4112 // Ensure this target's touch list exists, even if it ends up empty, so |
| 4001 // it can always be passed to TouchEvent::Create below. | 4113 // it can always be passed to TouchEvent::Create below. |
| 4002 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f
ind(touchTarget.get()); | 4114 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f
ind(touchInfo.touchTarget); |
| 4003 if (targetTouchesIterator == touchesByTarget.end()) { | 4115 if (targetTouchesIterator == touchesByTarget.end()) { |
| 4004 touchesByTarget.set(touchTarget.get(), TouchList::create()); | 4116 touchesByTarget.set(touchInfo.touchTarget, TouchList::create()); |
| 4005 targetTouchesIterator = touchesByTarget.find(touchTarget.get()); | 4117 targetTouchesIterator = touchesByTarget.find(touchInfo.touchTarget); |
| 4006 } | 4118 } |
| 4007 | 4119 |
| 4008 // touches and targetTouches should only contain information about | 4120 // touches and targetTouches should only contain information about |
| 4009 // touches still on the screen, so if this point is released or | 4121 // touches still on the screen, so if this point is released or |
| 4010 // cancelled it will only appear in the changedTouches list. | 4122 // cancelled it will only appear in the changedTouches list. |
| 4011 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla
tformTouchPoint::TouchCancelled) { | 4123 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla
tformTouchPoint::TouchCancelled) { |
| 4012 touches->append(touch); | 4124 touches->append(touch); |
| 4013 targetTouchesIterator->value->append(touch); | 4125 targetTouchesIterator->value->append(touch); |
| 4014 } | 4126 } |
| 4015 | 4127 |
| 4016 // Now build up the correct list for changedTouches. | 4128 // Now build up the correct list for changedTouches. |
| 4017 // Note that any touches that are in the TouchStationary state (e.g. if | 4129 // Note that any touches that are in the TouchStationary state (e.g. if |
| 4018 // the user had several points touched but did not move them all) should | 4130 // the user had several points touched but did not move them all) should |
| 4019 // never be in the changedTouches list so we do not handle them | 4131 // never be in the changedTouches list so we do not handle them |
| 4020 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609 | 4132 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609 |
| 4021 // for further discussion about the TouchStationary state. | 4133 // for further discussion about the TouchStationary state. |
| 4022 if (pointState != PlatformTouchPoint::TouchStationary && knownTarget) { | 4134 if (pointState != PlatformTouchPoint::TouchStationary && touchInfo.known
Target) { |
| 4023 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd); | 4135 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd); |
| 4024 if (!changedTouches[pointState].m_touches) | 4136 if (!changedTouches[pointState].m_touches) |
| 4025 changedTouches[pointState].m_touches = TouchList::create(); | 4137 changedTouches[pointState].m_touches = TouchList::create(); |
| 4026 changedTouches[pointState].m_touches->append(touch); | 4138 changedTouches[pointState].m_touches->append(touch); |
| 4027 changedTouches[pointState].m_targets.add(touchTarget); | 4139 changedTouches[pointState].m_targets.add(touchInfo.touchTarget); |
| 4028 } | 4140 } |
| 4029 } | 4141 } |
| 4030 if (allTouchReleased) { | 4142 if (allTouchReleased) { |
| 4031 m_touchSequenceDocument.clear(); | 4143 m_touchSequenceDocument.clear(); |
| 4032 m_touchSequenceUserGestureToken.clear(); | 4144 m_touchSequenceUserGestureToken.clear(); |
| 4033 } | 4145 } |
| 4034 | 4146 |
| 4035 // Now iterate the changedTouches list and m_targets within it, sending | 4147 // Now iterate through the changedTouches list and m_targets within it, send
ing |
| 4036 // events to the targets as required. | 4148 // TouchEvents to the targets as required. |
| 4037 bool swallowedEvent = false; | |
| 4038 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state
) { | 4149 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state
) { |
| 4039 if (!changedTouches[state].m_touches) | 4150 if (!changedTouches[state].m_touches) |
| 4040 continue; | 4151 continue; |
| 4041 | 4152 |
| 4042 const AtomicString& stateName(eventNameForTouchPointState(static_cast<Pl
atformTouchPoint::State>(state))); | 4153 const AtomicString& eventName(touchEventNameForTouchPointState(static_ca
st<PlatformTouchPoint::State>(state))); |
| 4043 const EventTargetSet& targetsForState = changedTouches[state].m_targets; | 4154 const EventTargetSet& targetsForState = changedTouches[state].m_targets; |
| 4044 for (const RefPtrWillBeMember<EventTarget>& eventTarget : targetsForStat
e) { | 4155 for (const RefPtrWillBeMember<EventTarget>& eventTarget : targetsForStat
e) { |
| 4045 EventTarget* touchEventTarget = eventTarget.get(); | 4156 EventTarget* touchEventTarget = eventTarget.get(); |
| 4046 RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create( | 4157 RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create( |
| 4047 touches.get(), touchesByTarget.get(touchEventTarget), changedTou
ches[state].m_touches.get(), | 4158 touches.get(), touchesByTarget.get(touchEventTarget), changedTou
ches[state].m_touches.get(), |
| 4048 stateName, touchEventTarget->toNode()->document().domWindow(), | 4159 eventName, touchEventTarget->toNode()->document().domWindow(), |
| 4049 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey
(), event.cancelable(), event.causesScrollingIfUncanceled(), event.timestamp()); | 4160 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey
(), event.cancelable(), event.causesScrollingIfUncanceled(), event.timestamp()); |
| 4050 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get()); | 4161 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get()); |
| 4051 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() ||
touchEvent->defaultHandled(); | 4162 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() ||
touchEvent->defaultHandled(); |
| 4052 } | 4163 } |
| 4053 } | 4164 } |
| 4054 | 4165 |
| 4055 return swallowedEvent; | 4166 return swallowedEvent; |
| 4056 } | 4167 } |
| 4057 | 4168 |
| 4058 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction
action2) | 4169 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction
action2) |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4170 unsigned EventHandler::accessKeyModifiers() | 4281 unsigned EventHandler::accessKeyModifiers() |
| 4171 { | 4282 { |
| 4172 #if OS(MACOSX) | 4283 #if OS(MACOSX) |
| 4173 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; | 4284 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; |
| 4174 #else | 4285 #else |
| 4175 return PlatformEvent::AltKey; | 4286 return PlatformEvent::AltKey; |
| 4176 #endif | 4287 #endif |
| 4177 } | 4288 } |
| 4178 | 4289 |
| 4179 } // namespace blink | 4290 } // namespace blink |
| OLD | NEW |