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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 , m_mouseDownWasInSubframe(false) | 215 , m_mouseDownWasInSubframe(false) |
216 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire
d) | 216 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire
d) |
217 , m_svgPan(false) | 217 , m_svgPan(false) |
218 , m_resizeScrollableArea(0) | 218 , m_resizeScrollableArea(0) |
219 , m_eventHandlerWillResetCapturingMouseEventsNode(0) | 219 , m_eventHandlerWillResetCapturingMouseEventsNode(0) |
220 , m_clickCount(0) | 220 , m_clickCount(0) |
221 , m_shouldOnlyFireDragOverEvent(false) | 221 , m_shouldOnlyFireDragOverEvent(false) |
222 , m_mousePositionIsUnknown(true) | 222 , m_mousePositionIsUnknown(true) |
223 , m_mouseDownTimestamp(0) | 223 , m_mouseDownTimestamp(0) |
224 , m_widgetIsLatched(false) | 224 , m_widgetIsLatched(false) |
225 , m_originatingTouchPointTargetKey(0) | |
226 , m_touchPressed(false) | 225 , m_touchPressed(false) |
227 , m_scrollGestureHandlingNode(nullptr) | 226 , m_scrollGestureHandlingNode(nullptr) |
228 , m_lastHitTestResultOverWidget(false) | 227 , m_lastHitTestResultOverWidget(false) |
229 , m_maxMouseMovedDuration(0) | 228 , m_maxMouseMovedDuration(0) |
230 , m_baseEventType(PlatformEvent::NoType) | 229 , m_baseEventType(PlatformEvent::NoType) |
231 , m_didStartDrag(false) | 230 , m_didStartDrag(false) |
232 , m_longTapShouldInvokeContextMenu(false) | 231 , m_longTapShouldInvokeContextMenu(false) |
233 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) | 232 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) |
234 , m_lastShowPressTimestamp(0) | 233 , m_lastShowPressTimestamp(0) |
235 { | 234 { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 m_mousePositionIsUnknown = true; | 270 m_mousePositionIsUnknown = true; |
272 m_lastKnownMousePosition = IntPoint(); | 271 m_lastKnownMousePosition = IntPoint(); |
273 m_lastKnownMouseGlobalPosition = IntPoint(); | 272 m_lastKnownMouseGlobalPosition = IntPoint(); |
274 m_lastMouseDownUserGestureToken.clear(); | 273 m_lastMouseDownUserGestureToken.clear(); |
275 m_mousePressNode = nullptr; | 274 m_mousePressNode = nullptr; |
276 m_mousePressed = false; | 275 m_mousePressed = false; |
277 m_capturesDragging = false; | 276 m_capturesDragging = false; |
278 m_capturingMouseEventsNode = nullptr; | 277 m_capturingMouseEventsNode = nullptr; |
279 m_latchedWheelEventNode = nullptr; | 278 m_latchedWheelEventNode = nullptr; |
280 m_previousWheelScrolledNode = nullptr; | 279 m_previousWheelScrolledNode = nullptr; |
281 m_originatingTouchPointTargets.clear(); | 280 m_targetForTouchID.clear(); |
282 m_originatingTouchPointDocument.clear(); | 281 m_touchSequenceDocument.clear(); |
283 m_originatingTouchPointTargetKey = 0; | |
284 m_scrollGestureHandlingNode = nullptr; | 282 m_scrollGestureHandlingNode = nullptr; |
285 m_lastHitTestResultOverWidget = false; | 283 m_lastHitTestResultOverWidget = false; |
286 m_previousGestureScrolledNode = nullptr; | 284 m_previousGestureScrolledNode = nullptr; |
287 m_scrollbarHandlingScrollGesture = nullptr; | 285 m_scrollbarHandlingScrollGesture = nullptr; |
288 m_maxMouseMovedDuration = 0; | 286 m_maxMouseMovedDuration = 0; |
289 m_baseEventType = PlatformEvent::NoType; | 287 m_baseEventType = PlatformEvent::NoType; |
290 m_didStartDrag = false; | 288 m_didStartDrag = false; |
291 m_touchPressed = false; | 289 m_touchPressed = false; |
292 m_mouseDownMayStartSelect = false; | 290 m_mouseDownMayStartSelect = false; |
293 m_mouseDownMayStartDrag = false; | 291 m_mouseDownMayStartDrag = false; |
(...skipping 3136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3430 return result; | 3428 return result; |
3431 } | 3429 } |
3432 frame->contentRenderer()->hitTest(HitTestRequest(hitType), result); | 3430 frame->contentRenderer()->hitTest(HitTestRequest(hitType), result); |
3433 return result; | 3431 return result; |
3434 } | 3432 } |
3435 | 3433 |
3436 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) | 3434 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) |
3437 { | 3435 { |
3438 TRACE_EVENT0("webkit", "EventHandler::handleTouchEvent"); | 3436 TRACE_EVENT0("webkit", "EventHandler::handleTouchEvent"); |
3439 | 3437 |
3440 // First build up the lists to use for the 'touches', 'targetTouches' and 'c
hangedTouches' attributes | |
3441 // in the JS event. See http://www.sitepen.com/blog/2008/07/10/touching-and-
gesturing-on-the-iphone/ | |
3442 // for an overview of how these lists fit together. | |
3443 | |
3444 // Holds the complete set of touches on the screen and will be used as the '
touches' list in the JS event. | |
3445 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create(); | |
3446 | |
3447 // A different view on the 'touches' list above, filtered and grouped by eve
nt target. Used for the | |
3448 // 'targetTouches' list in the JS event. | |
3449 typedef WillBeHeapHashMap<EventTarget*, RefPtrWillBeMember<TouchList> > Targ
etTouchesHeapMap; | |
3450 TargetTouchesHeapMap touchesByTarget; | |
3451 | |
3452 // Array of touches per state, used to assemble the 'changedTouches' list in
the JS event. | |
3453 typedef HashSet<RefPtr<EventTarget> > EventTargetSet; | |
3454 struct { | |
3455 // The touches corresponding to the particular change state this struct
instance represents. | |
3456 RefPtrWillBeMember<TouchList> m_touches; | |
3457 // Set of targets involved in m_touches. | |
3458 EventTargetSet m_targets; | |
3459 } changedTouches[PlatformTouchPoint::TouchStateEnd]; | |
3460 | |
3461 const Vector<PlatformTouchPoint>& points = event.touchPoints(); | 3438 const Vector<PlatformTouchPoint>& points = event.touchPoints(); |
3462 | 3439 |
3463 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); | 3440 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); |
3464 | 3441 |
3465 unsigned i; | 3442 unsigned i; |
3466 bool freshTouchEvents = true; | 3443 bool freshTouchEvents = true; |
3467 bool allTouchReleased = true; | 3444 bool allTouchReleased = true; |
3468 for (i = 0; i < points.size(); ++i) { | 3445 for (i = 0; i < points.size(); ++i) { |
3469 const PlatformTouchPoint& point = points[i]; | 3446 const PlatformTouchPoint& point = points[i]; |
3470 if (point.state() != PlatformTouchPoint::TouchPressed) | 3447 if (point.state() != PlatformTouchPoint::TouchPressed) |
3471 freshTouchEvents = false; | 3448 freshTouchEvents = false; |
3472 if (point.state() != PlatformTouchPoint::TouchReleased && point.state()
!= PlatformTouchPoint::TouchCancelled) | 3449 if (point.state() != PlatformTouchPoint::TouchReleased && point.state()
!= PlatformTouchPoint::TouchCancelled) |
3473 allTouchReleased = false; | 3450 allTouchReleased = false; |
3474 } | 3451 } |
| 3452 if (freshTouchEvents) { |
| 3453 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should |
| 3454 // have cleared the active document when we saw the last release. But we |
| 3455 // have some tests that violate this, ClusterFuzz could trigger it, and |
| 3456 // there may be cases where the browser doesn't reliably release all |
| 3457 // touches. http://crbug.com/345372 tracks this. |
| 3458 m_touchSequenceDocument.clear(); |
| 3459 } |
3475 | 3460 |
| 3461 // First do hit tests for any new touch points. |
3476 for (i = 0; i < points.size(); ++i) { | 3462 for (i = 0; i < points.size(); ++i) { |
3477 const PlatformTouchPoint& point = points[i]; | 3463 const PlatformTouchPoint& point = points[i]; |
3478 PlatformTouchPoint::State pointState = point.state(); | |
3479 LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos()
); | 3464 LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos()
); |
3480 | 3465 |
3481 // Gesture events trigger the active state, not touch events, | 3466 // Touch events implicitly capture to the touched node, and don't change |
3482 // so touch event hit tests can always be read only. | 3467 // active/hover states themselves (Gesture events do). So we only need |
3483 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent
| HitTestRequest::ReadOnly; | 3468 // to hit-test on touchstart, and it can be read-only. |
3484 // The HitTestRequest types used for mouse events map quite adequately | 3469 if (point.state() == PlatformTouchPoint::TouchPressed) { |
3485 // to touch events. Note that in addition to meaning that the hit test | 3470 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv
ent | HitTestRequest::ReadOnly | HitTestRequest::Active; |
3486 // should affect the active state of the current node if necessary, | |
3487 // HitTestRequest::Active signifies that the hit test is taking place | |
3488 // with the mouse (or finger in this case) being pressed. | |
3489 switch (pointState) { | |
3490 case PlatformTouchPoint::TouchPressed: | |
3491 hitType |= HitTestRequest::Active; | |
3492 break; | |
3493 case PlatformTouchPoint::TouchMoved: | |
3494 hitType |= HitTestRequest::Active | HitTestRequest::Move; | |
3495 break; | |
3496 case PlatformTouchPoint::TouchReleased: | |
3497 case PlatformTouchPoint::TouchCancelled: | |
3498 hitType |= HitTestRequest::Release; | |
3499 break; | |
3500 case PlatformTouchPoint::TouchStationary: | |
3501 hitType |= HitTestRequest::Active; | |
3502 break; | |
3503 default: | |
3504 ASSERT_NOT_REACHED(); | |
3505 break; | |
3506 } | |
3507 | |
3508 // Increment the platform touch id by 1 to avoid storing a key of 0 in t
he hashmap. | |
3509 unsigned touchPointTargetKey = point.id() + 1; | |
3510 RefPtr<EventTarget> touchTarget; | |
3511 if (pointState == PlatformTouchPoint::TouchPressed) { | |
3512 HitTestResult result; | 3471 HitTestResult result; |
3513 if (freshTouchEvents) { | 3472 if (!m_touchSequenceDocument) { |
3514 result = hitTestResultAtPoint(pagePoint, hitType); | 3473 result = hitTestResultAtPoint(pagePoint, hitType); |
3515 m_originatingTouchPointTargetKey = touchPointTargetKey; | 3474 } else if (m_touchSequenceDocument->frame()) { |
3516 } else if (m_originatingTouchPointDocument.get() && m_originatingTou
chPointDocument->frame()) { | 3475 LayoutPoint pagePointInOriginatingDocument = documentPointForWin
dowPoint(m_touchSequenceDocument->frame(), point.pos()); |
3517 LayoutPoint pagePointInOriginatingDocument = documentPointForWin
dowPoint(m_originatingTouchPointDocument->frame(), point.pos()); | 3476 result = hitTestResultInFrame(m_touchSequenceDocument->frame(),
pagePointInOriginatingDocument, hitType); |
3518 result = hitTestResultInFrame(m_originatingTouchPointDocument->f
rame(), pagePointInOriginatingDocument, hitType); | |
3519 } else | 3477 } else |
3520 continue; | 3478 continue; |
3521 | 3479 |
3522 Node* node = result.innerNode(); | 3480 Node* node = result.innerNode(); |
3523 if (!node) | 3481 if (!node) |
3524 continue; | 3482 continue; |
3525 | 3483 |
3526 // Touch events should not go to text nodes | 3484 // Touch events should not go to text nodes |
3527 if (node->isTextNode()) | 3485 if (node->isTextNode()) |
3528 node = NodeRenderingTraversal::parent(node); | 3486 node = NodeRenderingTraversal::parent(node); |
3529 | 3487 |
3530 Document& doc = node->document(); | 3488 if (!m_touchSequenceDocument) { |
3531 // Record the originating touch document even if it does not have a
touch listener. | 3489 // Keep track of which document should receive all touch events |
3532 if (freshTouchEvents) { | 3490 // in the active sequence. This must be a single document to |
3533 m_originatingTouchPointDocument = &doc; | 3491 // ensure we don't leak Nodes between documents. |
3534 freshTouchEvents = false; | 3492 m_touchSequenceDocument = &(result.innerNode()->document()); |
3535 } | 3493 } |
3536 if (!doc.hasTouchEventHandlers()) | 3494 |
3537 continue; | 3495 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id()) |
3538 m_originatingTouchPointTargets.set(touchPointTargetKey, node); | 3496 // since we shouldn't get a touchstart for a touch that's already |
3539 touchTarget = node; | 3497 // down. However EventSender allows this to be violated and there's |
| 3498 // some tests that take advantage of it. There may also be edge |
| 3499 // cases in the browser where this happens. |
| 3500 // See http://crbug.com/345372. |
| 3501 m_targetForTouchID.set(point.id(), node); |
3540 | 3502 |
3541 TouchAction effectiveTouchAction = computeEffectiveTouchAction(pageP
oint); | 3503 TouchAction effectiveTouchAction = computeEffectiveTouchAction(pageP
oint); |
3542 if (effectiveTouchAction != TouchActionAuto) | 3504 if (effectiveTouchAction != TouchActionAuto) |
3543 m_frame->page()->chrome().client().setTouchAction(effectiveTouch
Action); | 3505 m_frame->page()->chrome().client().setTouchAction(effectiveTouch
Action); |
| 3506 } |
| 3507 } |
3544 | 3508 |
3545 } else if (pointState == PlatformTouchPoint::TouchReleased || pointState
== PlatformTouchPoint::TouchCancelled) { | 3509 m_touchPressed = !allTouchReleased; |
3546 // The target should be the original target for this touch, so get i
t from the hashmap. As it's a release or cancel | |
3547 // we also remove it from the map. | |
3548 touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKe
y); | |
3549 } else | |
3550 // No hittest is performed on move or stationary, since the target i
s not allowed to change anyway. | |
3551 touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey
); | |
3552 | 3510 |
3553 if (!touchTarget.get()) | 3511 // If there's no document receiving touch events, or no handlers on the |
3554 continue; | 3512 // document set to receive the events, then we can skip all the rest of |
3555 Document& doc = touchTarget->toNode()->document(); | 3513 // this work. |
3556 if (!doc.hasTouchEventHandlers()) | 3514 if (!m_touchSequenceDocument || !m_touchSequenceDocument->hasTouchEventHandl
ers() || !m_touchSequenceDocument->frame()) { |
3557 continue; | 3515 if (allTouchReleased) |
3558 LocalFrame* targetFrame = doc.frame(); | 3516 m_touchSequenceDocument.clear(); |
3559 if (!targetFrame) | 3517 return false; |
3560 continue; | 3518 } |
| 3519 |
| 3520 // Build up the lists to use for the 'touches', 'targetTouches' and |
| 3521 // 'changedTouches' attributes in the JS event. See |
| 3522 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these |
| 3523 // lists fit together. |
| 3524 |
| 3525 // Holds the complete set of touches on the screen. |
| 3526 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create(); |
| 3527 |
| 3528 // A different view on the 'touches' list above, filtered and grouped by |
| 3529 // event target. Used for the 'targetTouches' list in the JS event. |
| 3530 typedef WillBeHeapHashMap<EventTarget*, RefPtrWillBeMember<TouchList> > Targ
etTouchesHeapMap; |
| 3531 TargetTouchesHeapMap touchesByTarget; |
| 3532 |
| 3533 // Array of touches per state, used to assemble the 'changedTouches' list. |
| 3534 typedef HashSet<RefPtr<EventTarget> > EventTargetSet; |
| 3535 struct { |
| 3536 // The touches corresponding to the particular change state this struct |
| 3537 // instance represents. |
| 3538 RefPtrWillBeMember<TouchList> m_touches; |
| 3539 // Set of targets involved in m_touches. |
| 3540 EventTargetSet m_targets; |
| 3541 } changedTouches[PlatformTouchPoint::TouchStateEnd]; |
| 3542 |
| 3543 for (i = 0; i < points.size(); ++i) { |
| 3544 const PlatformTouchPoint& point = points[i]; |
| 3545 LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos()
); |
| 3546 PlatformTouchPoint::State pointState = point.state(); |
| 3547 RefPtr<EventTarget> touchTarget; |
| 3548 |
| 3549 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla
tformTouchPoint::TouchCancelled) { |
| 3550 // The target should be the original target for this touch, so get |
| 3551 // it from the hashmap. As it's a release or cancel we also remove |
| 3552 // it from the map. |
| 3553 touchTarget = m_targetForTouchID.take(point.id()); |
| 3554 } else { |
| 3555 // No hittest is performed on move or stationary, since the target |
| 3556 // is not allowed to change anyway. |
| 3557 touchTarget = m_targetForTouchID.get(point.id()); |
| 3558 } |
| 3559 |
| 3560 LocalFrame* targetFrame; |
| 3561 bool knownTarget; |
| 3562 if (touchTarget) { |
| 3563 Document& doc = touchTarget->toNode()->document(); |
| 3564 ASSERT(&doc == m_touchSequenceDocument.get()); |
| 3565 targetFrame = doc.frame(); |
| 3566 knownTarget = true; |
| 3567 } else { |
| 3568 // If we don't have a target registered for the point it means we've |
| 3569 // missed our opportunity to do a hit test for it (due to some |
| 3570 // optimization that prevented blink from ever seeing the |
| 3571 // touchstart), or that the touch started outside the active touch |
| 3572 // sequence document. We should still include the touch in the |
| 3573 // Touches list reported to the application (eg. so it can |
| 3574 // differentiate between a one and two finger gesture), but we won't |
| 3575 // actually dispatch any events for it. Set the target to the |
| 3576 // Document so that there's some valid node here. Perhaps this |
| 3577 // should really be DOMWindow, but in all other cases the target of |
| 3578 // a Touch is a Node so using the window could be a breaking change. |
| 3579 // Since we know there was no handler invoked, the specific target |
| 3580 // should be completely irrelevant to the application. |
| 3581 touchTarget = m_touchSequenceDocument; |
| 3582 targetFrame = m_touchSequenceDocument->frame(); |
| 3583 knownTarget = false; |
| 3584 } |
| 3585 ASSERT(targetFrame); |
3561 | 3586 |
3562 if (m_frame != targetFrame) { | 3587 if (m_frame != targetFrame) { |
3563 // pagePoint should always be relative to the target elements contai
ning frame. | 3588 // pagePoint should always be relative to the target elements |
| 3589 // containing frame. |
3564 pagePoint = documentPointForWindowPoint(targetFrame, point.pos()); | 3590 pagePoint = documentPointForWindowPoint(targetFrame, point.pos()); |
3565 } | 3591 } |
3566 | 3592 |
3567 float scaleFactor = targetFrame->pageZoomFactor(); | 3593 float scaleFactor = targetFrame->pageZoomFactor(); |
3568 | 3594 |
3569 int adjustedPageX = lroundf(pagePoint.x() / scaleFactor); | 3595 int adjustedPageX = lroundf(pagePoint.x() / scaleFactor); |
3570 int adjustedPageY = lroundf(pagePoint.y() / scaleFactor); | 3596 int adjustedPageY = lroundf(pagePoint.y() / scaleFactor); |
3571 int adjustedRadiusX = lroundf(point.radiusX() / scaleFactor); | 3597 int adjustedRadiusX = lroundf(point.radiusX() / scaleFactor); |
3572 int adjustedRadiusY = lroundf(point.radiusY() / scaleFactor); | 3598 int adjustedRadiusY = lroundf(point.radiusY() / scaleFactor); |
3573 | 3599 |
3574 RefPtrWillBeRawPtr<Touch> touch = Touch::create(targetFrame, touchTarget
.get(), point.id(), | 3600 RefPtrWillBeRawPtr<Touch> touch = Touch::create(targetFrame, touchTarget
.get(), point.id(), |
3575 point.screenPos().x(), point.screenP
os().y(), | 3601 point.screenPos().x(), point.screenP
os().y(), |
3576 adjustedPageX, adjustedPageY, | 3602 adjustedPageX, adjustedPageY, |
3577 adjustedRadiusX, adjustedRadiusY, | 3603 adjustedRadiusX, adjustedRadiusY, |
3578 point.rotationAngle(), point.force()
); | 3604 point.rotationAngle(), point.force()
); |
3579 | 3605 |
3580 // Ensure this target's touch list exists, even if it ends up empty, so
it can always be passed to TouchEvent::Create below. | 3606 // Ensure this target's touch list exists, even if it ends up empty, so |
| 3607 // it can always be passed to TouchEvent::Create below. |
3581 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f
ind(touchTarget.get()); | 3608 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f
ind(touchTarget.get()); |
3582 if (targetTouchesIterator == touchesByTarget.end()) { | 3609 if (targetTouchesIterator == touchesByTarget.end()) { |
3583 touchesByTarget.set(touchTarget.get(), TouchList::create()); | 3610 touchesByTarget.set(touchTarget.get(), TouchList::create()); |
3584 targetTouchesIterator = touchesByTarget.find(touchTarget.get()); | 3611 targetTouchesIterator = touchesByTarget.find(touchTarget.get()); |
3585 } | 3612 } |
3586 | 3613 |
3587 // touches and targetTouches should only contain information about touch
es still on the screen, so if this point is | 3614 // touches and targetTouches should only contain information about |
3588 // released or cancelled it will only appear in the changedTouches list. | 3615 // touches still on the screen, so if this point is released or |
| 3616 // cancelled it will only appear in the changedTouches list. |
3589 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla
tformTouchPoint::TouchCancelled) { | 3617 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla
tformTouchPoint::TouchCancelled) { |
3590 touches->append(touch); | 3618 touches->append(touch); |
3591 targetTouchesIterator->value->append(touch); | 3619 targetTouchesIterator->value->append(touch); |
3592 } | 3620 } |
3593 | 3621 |
3594 // Now build up the correct list for changedTouches. | 3622 // Now build up the correct list for changedTouches. |
3595 // Note that any touches that are in the TouchStationary state (e.g. if | 3623 // Note that any touches that are in the TouchStationary state (e.g. if |
3596 // the user had several points touched but did not move them all) should | 3624 // the user had several points touched but did not move them all) should |
3597 // never be in the changedTouches list so we do not handle them explicit
ly here. | 3625 // never be in the changedTouches list so we do not handle them |
3598 // See https://bugs.webkit.org/show_bug.cgi?id=37609 for further discuss
ion | 3626 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609 |
3599 // about the TouchStationary state. | 3627 // for further discussion about the TouchStationary state. |
3600 if (pointState != PlatformTouchPoint::TouchStationary) { | 3628 if (pointState != PlatformTouchPoint::TouchStationary && knownTarget) { |
3601 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd); | 3629 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd); |
3602 if (!changedTouches[pointState].m_touches) | 3630 if (!changedTouches[pointState].m_touches) |
3603 changedTouches[pointState].m_touches = TouchList::create(); | 3631 changedTouches[pointState].m_touches = TouchList::create(); |
3604 changedTouches[pointState].m_touches->append(touch); | 3632 changedTouches[pointState].m_touches->append(touch); |
3605 changedTouches[pointState].m_targets.add(touchTarget); | 3633 changedTouches[pointState].m_targets.add(touchTarget); |
3606 } | 3634 } |
3607 } | 3635 } |
3608 m_touchPressed = touches->length() > 0; | |
3609 if (allTouchReleased) | 3636 if (allTouchReleased) |
3610 m_originatingTouchPointDocument.clear(); | 3637 m_touchSequenceDocument.clear(); |
3611 | 3638 |
3612 // Now iterate the changedTouches list and m_targets within it, sending even
ts to the targets as required. | 3639 // Now iterate the changedTouches list and m_targets within it, sending |
| 3640 // events to the targets as required. |
3613 bool swallowedEvent = false; | 3641 bool swallowedEvent = false; |
3614 RefPtrWillBeRawPtr<TouchList> emptyList = TouchList::create(); | 3642 RefPtrWillBeRawPtr<TouchList> emptyList = TouchList::create(); |
3615 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state
) { | 3643 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state
) { |
3616 if (!changedTouches[state].m_touches) | 3644 if (!changedTouches[state].m_touches) |
3617 continue; | 3645 continue; |
3618 | 3646 |
3619 // When sending a touch cancel event, use empty touches and targetTouche
s lists. | |
3620 bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled); | |
3621 RefPtrWillBeRawPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emp
tyList : touches); | |
3622 const AtomicString& stateName(eventNameForTouchPointState(static_cast<Pl
atformTouchPoint::State>(state))); | 3647 const AtomicString& stateName(eventNameForTouchPointState(static_cast<Pl
atformTouchPoint::State>(state))); |
3623 const EventTargetSet& targetsForState = changedTouches[state].m_targets; | 3648 const EventTargetSet& targetsForState = changedTouches[state].m_targets; |
3624 | |
3625 for (EventTargetSet::const_iterator it = targetsForState.begin(); it !=
targetsForState.end(); ++it) { | 3649 for (EventTargetSet::const_iterator it = targetsForState.begin(); it !=
targetsForState.end(); ++it) { |
3626 EventTarget* touchEventTarget = it->get(); | 3650 EventTarget* touchEventTarget = it->get(); |
3627 RefPtrWillBeRawPtr<TouchList> targetTouches(isTouchCancelEvent ? emp
tyList.get() : touchesByTarget.get(touchEventTarget)); | 3651 RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create( |
3628 ASSERT(targetTouches); | 3652 touches.get(), touchesByTarget.get(touchEventTarget), changedTou
ches[state].m_touches.get(), |
3629 | 3653 stateName, touchEventTarget->toNode()->document().domWindow(), |
3630 RefPtrWillBeRawPtr<TouchEvent> touchEvent = | 3654 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(), e
vent.metaKey(), event.cancelable()); |
3631 TouchEvent::create(effectiveTouches.get(), targetTouches.get(),
changedTouches[state].m_touches.get(), | |
3632 stateName, touchEventTarget->toNode()->document().domWindow(
), | |
3633 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(
), event.metaKey(), event.cancelable()); | |
3634 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get()); | 3655 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get()); |
3635 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() ||
touchEvent->defaultHandled(); | 3656 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() ||
touchEvent->defaultHandled(); |
3636 } | 3657 } |
3637 } | 3658 } |
3638 | 3659 |
3639 return swallowedEvent; | 3660 return swallowedEvent; |
3640 } | 3661 } |
3641 | 3662 |
3642 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction
action2) | 3663 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction
action2) |
3643 { | 3664 { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3763 unsigned EventHandler::accessKeyModifiers() | 3784 unsigned EventHandler::accessKeyModifiers() |
3764 { | 3785 { |
3765 #if OS(MACOSX) | 3786 #if OS(MACOSX) |
3766 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; | 3787 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; |
3767 #else | 3788 #else |
3768 return PlatformEvent::AltKey; | 3789 return PlatformEvent::AltKey; |
3769 #endif | 3790 #endif |
3770 } | 3791 } |
3771 | 3792 |
3772 } // namespace WebCore | 3793 } // namespace WebCore |
OLD | NEW |