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 25 matching lines...) Expand all Loading... |
36 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
37 #include "core/dom/TouchList.h" | 37 #include "core/dom/TouchList.h" |
38 #include "core/dom/shadow/ComposedTreeTraversal.h" | 38 #include "core/dom/shadow/ComposedTreeTraversal.h" |
39 #include "core/dom/shadow/ShadowRoot.h" | 39 #include "core/dom/shadow/ShadowRoot.h" |
40 #include "core/editing/Editor.h" | 40 #include "core/editing/Editor.h" |
41 #include "core/editing/FrameSelection.h" | 41 #include "core/editing/FrameSelection.h" |
42 #include "core/editing/SelectionController.h" | 42 #include "core/editing/SelectionController.h" |
43 #include "core/events/EventPath.h" | 43 #include "core/events/EventPath.h" |
44 #include "core/events/KeyboardEvent.h" | 44 #include "core/events/KeyboardEvent.h" |
45 #include "core/events/MouseEvent.h" | 45 #include "core/events/MouseEvent.h" |
| 46 #include "core/events/PointerEvent.h" |
46 #include "core/events/TextEvent.h" | 47 #include "core/events/TextEvent.h" |
47 #include "core/events/TouchEvent.h" | 48 #include "core/events/TouchEvent.h" |
48 #include "core/events/WheelEvent.h" | 49 #include "core/events/WheelEvent.h" |
49 #include "core/fetch/ImageResource.h" | 50 #include "core/fetch/ImageResource.h" |
50 #include "core/frame/EventHandlerRegistry.h" | 51 #include "core/frame/EventHandlerRegistry.h" |
51 #include "core/frame/FrameHost.h" | 52 #include "core/frame/FrameHost.h" |
52 #include "core/frame/FrameView.h" | 53 #include "core/frame/FrameView.h" |
53 #include "core/frame/LocalFrame.h" | 54 #include "core/frame/LocalFrame.h" |
54 #include "core/frame/PinchViewport.h" | 55 #include "core/frame/PinchViewport.h" |
55 #include "core/frame/Settings.h" | 56 #include "core/frame/Settings.h" |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 m_previousWheelScrolledNode = nullptr; | 308 m_previousWheelScrolledNode = nullptr; |
308 m_targetForTouchID.clear(); | 309 m_targetForTouchID.clear(); |
309 m_touchSequenceDocument.clear(); | 310 m_touchSequenceDocument.clear(); |
310 m_touchSequenceUserGestureToken.clear(); | 311 m_touchSequenceUserGestureToken.clear(); |
311 m_scrollGestureHandlingNode = nullptr; | 312 m_scrollGestureHandlingNode = nullptr; |
312 m_lastGestureScrollOverWidget = false; | 313 m_lastGestureScrollOverWidget = false; |
313 m_previousGestureScrolledNode = nullptr; | 314 m_previousGestureScrolledNode = nullptr; |
314 m_scrollbarHandlingScrollGesture = nullptr; | 315 m_scrollbarHandlingScrollGesture = nullptr; |
315 m_maxMouseMovedDuration = 0; | 316 m_maxMouseMovedDuration = 0; |
316 m_touchPressed = false; | 317 m_touchPressed = false; |
| 318 m_pointerIdManager.clear(); |
317 m_mouseDownMayStartDrag = false; | 319 m_mouseDownMayStartDrag = false; |
318 m_lastShowPressTimestamp = 0; | 320 m_lastShowPressTimestamp = 0; |
319 m_lastDeferredTapElement = nullptr; | 321 m_lastDeferredTapElement = nullptr; |
320 m_eventHandlerWillResetCapturingMouseEventsNode = false; | 322 m_eventHandlerWillResetCapturingMouseEventsNode = false; |
321 m_mouseDownMayStartAutoscroll = false; | 323 m_mouseDownMayStartAutoscroll = false; |
322 m_svgPan = false; | 324 m_svgPan = false; |
323 m_mouseDownPos = IntPoint(); | 325 m_mouseDownPos = IntPoint(); |
324 m_mouseDownTimestamp = 0; | 326 m_mouseDownTimestamp = 0; |
325 m_longTapShouldInvokeContextMenu = false; | 327 m_longTapShouldInvokeContextMenu = false; |
326 m_dragStartPos = LayoutPoint(); | 328 m_dragStartPos = LayoutPoint(); |
(...skipping 3045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3372 m_lastScrollbarUnderMouse->mouseExited(); | 3374 m_lastScrollbarUnderMouse->mouseExited(); |
3373 | 3375 |
3374 // Send mouse entered if we're setting a new scrollbar. | 3376 // Send mouse entered if we're setting a new scrollbar. |
3375 if (scrollbar && setLast) | 3377 if (scrollbar && setLast) |
3376 scrollbar->mouseEntered(); | 3378 scrollbar->mouseEntered(); |
3377 | 3379 |
3378 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; | 3380 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; |
3379 } | 3381 } |
3380 } | 3382 } |
3381 | 3383 |
3382 static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State
state) | 3384 static const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::
State state) |
3383 { | 3385 { |
3384 switch (state) { | 3386 switch (state) { |
3385 case PlatformTouchPoint::TouchReleased: | 3387 case PlatformTouchPoint::TouchReleased: |
3386 return EventTypeNames::touchend; | 3388 return EventTypeNames::touchend; |
3387 case PlatformTouchPoint::TouchCancelled: | 3389 case PlatformTouchPoint::TouchCancelled: |
3388 return EventTypeNames::touchcancel; | 3390 return EventTypeNames::touchcancel; |
3389 case PlatformTouchPoint::TouchPressed: | 3391 case PlatformTouchPoint::TouchPressed: |
3390 return EventTypeNames::touchstart; | 3392 return EventTypeNames::touchstart; |
3391 case PlatformTouchPoint::TouchMoved: | 3393 case PlatformTouchPoint::TouchMoved: |
3392 return EventTypeNames::touchmove; | 3394 return EventTypeNames::touchmove; |
3393 case PlatformTouchPoint::TouchStationary: | 3395 case PlatformTouchPoint::TouchStationary: |
3394 // TouchStationary state is not converted to touch events, so fall throu
gh to assert. | 3396 // Fall through to default |
3395 default: | 3397 default: |
3396 ASSERT_NOT_REACHED(); | 3398 ASSERT_NOT_REACHED(); |
3397 return emptyAtom; | 3399 return emptyAtom; |
| 3400 } |
| 3401 } |
| 3402 |
| 3403 static const AtomicString& pointerEventNameForTouchPointState(PlatformTouchPoint
::State state) |
| 3404 { |
| 3405 switch (state) { |
| 3406 case PlatformTouchPoint::TouchReleased: |
| 3407 return EventTypeNames::pointerup; |
| 3408 case PlatformTouchPoint::TouchCancelled: |
| 3409 return EventTypeNames::pointercancel; |
| 3410 case PlatformTouchPoint::TouchPressed: |
| 3411 return EventTypeNames::pointerdown; |
| 3412 case PlatformTouchPoint::TouchMoved: |
| 3413 return EventTypeNames::pointermove; |
| 3414 case PlatformTouchPoint::TouchStationary: |
| 3415 // Fall through to default |
| 3416 default: |
| 3417 ASSERT_NOT_REACHED(); |
| 3418 return emptyAtom; |
3398 } | 3419 } |
3399 } | 3420 } |
3400 | 3421 |
3401 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout
Point& point, HitTestRequest::HitTestRequestType hitType) | 3422 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout
Point& point, HitTestRequest::HitTestRequestType hitType) |
3402 { | 3423 { |
3403 HitTestResult result(HitTestRequest(hitType), point); | 3424 HitTestResult result(HitTestRequest(hitType), point); |
3404 | 3425 |
3405 if (!frame || !frame->contentLayoutObject()) | 3426 if (!frame || !frame->contentLayoutObject()) |
3406 return result; | 3427 return result; |
3407 if (frame->view()) { | 3428 if (frame->view()) { |
3408 IntRect rect = frame->view()->visibleContentRect(IncludeScrollbars); | 3429 IntRect rect = frame->view()->visibleContentRect(IncludeScrollbars); |
3409 if (!rect.contains(roundedIntPoint(point))) | 3430 if (!rect.contains(roundedIntPoint(point))) |
3410 return result; | 3431 return result; |
3411 } | 3432 } |
3412 frame->contentLayoutObject()->hitTest(result); | 3433 frame->contentLayoutObject()->hitTest(result); |
3413 return result; | 3434 return result; |
3414 } | 3435 } |
3415 | 3436 |
| 3437 void EventHandler::dispatchPointerEventsForTouchEvent(const PlatformTouchEvent&
event, Vector<TouchInfo>& touchInfos) |
| 3438 { |
| 3439 const String& PointerTypeStrForTouch("touch"); |
| 3440 |
| 3441 // Iterate through the touch points, sending PointerEvents to the targets as
required. |
| 3442 for (unsigned i = 0; i < touchInfos.size(); ++i) { |
| 3443 TouchInfo& touchInfo = touchInfos[i]; |
| 3444 const PlatformTouchPoint& point = touchInfo.point; |
| 3445 const unsigned& pointerId = point.id(); |
| 3446 const PlatformTouchPoint::State pointState = point.state(); |
| 3447 |
| 3448 if (pointState == PlatformTouchPoint::TouchStationary) |
| 3449 continue; |
| 3450 bool pointerReleasedOrCancelled = |
| 3451 pointState == PlatformTouchPoint::TouchReleased || pointState == Pla
tformTouchPoint::TouchCancelled; |
| 3452 const AtomicString& eventName(pointerEventNameForTouchPointState(pointSt
ate)); |
| 3453 |
| 3454 if (pointState == PlatformTouchPoint::TouchPressed) |
| 3455 m_pointerIdManager.add(PointerIdManager::PointerTypeTouch, pointerId
); |
| 3456 |
| 3457 bool isEnterOrLeave = false; |
| 3458 |
| 3459 PointerEventInit pointerEventInit; |
| 3460 pointerEventInit.setPointerId(pointerId); |
| 3461 pointerEventInit.setWidth(touchInfo.adjustedRadius.width()); |
| 3462 pointerEventInit.setHeight(touchInfo.adjustedRadius.height()); |
| 3463 pointerEventInit.setPressure(point.force()); |
| 3464 pointerEventInit.setPointerType(PointerTypeStrForTouch); |
| 3465 pointerEventInit.setIsPrimary(m_pointerIdManager.isPrimary(PointerIdMana
ger::PointerTypeTouch, pointerId)); |
| 3466 pointerEventInit.setScreenX(point.screenPos().x()); |
| 3467 pointerEventInit.setScreenY(point.screenPos().y()); |
| 3468 pointerEventInit.setClientX(touchInfo.adjustedPagePoint.x()); |
| 3469 pointerEventInit.setClientY(touchInfo.adjustedPagePoint.y()); |
| 3470 pointerEventInit.setButton(0); |
| 3471 pointerEventInit.setButtons(pointerReleasedOrCancelled ? 0 : 1); |
| 3472 |
| 3473 pointerEventInit.setCtrlKey(event.ctrlKey()); |
| 3474 pointerEventInit.setShiftKey(event.shiftKey()); |
| 3475 pointerEventInit.setAltKey(event.altKey()); |
| 3476 pointerEventInit.setMetaKey(event.metaKey()); |
| 3477 |
| 3478 pointerEventInit.setBubbles(!isEnterOrLeave); |
| 3479 pointerEventInit.setCancelable(!isEnterOrLeave && pointState != Platform
TouchPoint::TouchCancelled); |
| 3480 |
| 3481 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = PointerEvent::create(eve
ntName, pointerEventInit); |
| 3482 touchInfo.touchTarget->toNode()->dispatchPointerEvent(pointerEvent.get()
); |
| 3483 touchInfo.consumed = pointerEvent->defaultPrevented() || pointerEvent->d
efaultHandled(); |
| 3484 |
| 3485 // Remove the released/cancelled id at the end to correctly determine pr
imary id above. |
| 3486 if (pointerReleasedOrCancelled) |
| 3487 m_pointerIdManager.remove(PointerIdManager::PointerTypeTouch, pointe
rId); |
| 3488 } |
| 3489 } |
| 3490 |
| 3491 bool EventHandler::dispatchTouchEvents(const PlatformTouchEvent& event, |
| 3492 Vector<TouchInfo>& touchInfos, bool freshTouchEvents, bool allTouchReleased) |
| 3493 { |
| 3494 bool swallowedEvent = false; |
| 3495 |
| 3496 // Build up the lists to use for the 'touches', 'targetTouches' and |
| 3497 // 'changedTouches' attributes in the JS event. See |
| 3498 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these |
| 3499 // lists fit together. |
| 3500 |
| 3501 // Holds the complete set of touches on the screen. |
| 3502 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create(); |
| 3503 |
| 3504 // A different view on the 'touches' list above, filtered and grouped by |
| 3505 // event target. Used for the 'targetTouches' list in the JS event. |
| 3506 using TargetTouchesHeapMap = WillBeHeapHashMap<EventTarget*, RefPtrWillBeMem
ber<TouchList>>; |
| 3507 TargetTouchesHeapMap touchesByTarget; |
| 3508 |
| 3509 // Array of touches per state, used to assemble the 'changedTouches' list. |
| 3510 using EventTargetSet = WillBeHeapHashSet<RefPtrWillBeMember<EventTarget>>; |
| 3511 struct { |
| 3512 // The touches corresponding to the particular change state this struct |
| 3513 // instance represents. |
| 3514 RefPtrWillBeMember<TouchList> m_touches; |
| 3515 // Set of targets involved in m_touches. |
| 3516 EventTargetSet m_targets; |
| 3517 } changedTouches[PlatformTouchPoint::TouchStateEnd]; |
| 3518 |
| 3519 for (unsigned i = 0; i < touchInfos.size(); ++i) { |
| 3520 const TouchInfo& touchInfo = touchInfos[i]; |
| 3521 const PlatformTouchPoint& point = touchInfo.point; |
| 3522 PlatformTouchPoint::State pointState = point.state(); |
| 3523 |
| 3524 if (touchInfo.consumed) |
| 3525 continue; |
| 3526 |
| 3527 RefPtrWillBeRawPtr<Touch> touch = Touch::create( |
| 3528 touchInfo.targetFrame, |
| 3529 touchInfo.touchTarget, |
| 3530 point.id(), |
| 3531 point.screenPos(), |
| 3532 touchInfo.adjustedPagePoint, |
| 3533 touchInfo.adjustedRadius, |
| 3534 point.rotationAngle(), |
| 3535 point.force()); |
| 3536 |
| 3537 // Ensure this target's touch list exists, even if it ends up empty, so |
| 3538 // it can always be passed to TouchEvent::Create below. |
| 3539 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f
ind(touchInfo.touchTarget); |
| 3540 if (targetTouchesIterator == touchesByTarget.end()) { |
| 3541 touchesByTarget.set(touchInfo.touchTarget, TouchList::create()); |
| 3542 targetTouchesIterator = touchesByTarget.find(touchInfo.touchTarget); |
| 3543 } |
| 3544 |
| 3545 // touches and targetTouches should only contain information about |
| 3546 // touches still on the screen, so if this point is released or |
| 3547 // cancelled it will only appear in the changedTouches list. |
| 3548 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla
tformTouchPoint::TouchCancelled) { |
| 3549 touches->append(touch); |
| 3550 targetTouchesIterator->value->append(touch); |
| 3551 } |
| 3552 |
| 3553 // Now build up the correct list for changedTouches. |
| 3554 // Note that any touches that are in the TouchStationary state (e.g. if |
| 3555 // the user had several points touched but did not move them all) should |
| 3556 // never be in the changedTouches list so we do not handle them |
| 3557 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609 |
| 3558 // for further discussion about the TouchStationary state. |
| 3559 if (pointState != PlatformTouchPoint::TouchStationary && touchInfo.known
Target) { |
| 3560 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd); |
| 3561 if (!changedTouches[pointState].m_touches) |
| 3562 changedTouches[pointState].m_touches = TouchList::create(); |
| 3563 changedTouches[pointState].m_touches->append(touch); |
| 3564 changedTouches[pointState].m_targets.add(touchInfo.touchTarget); |
| 3565 } |
| 3566 } |
| 3567 if (allTouchReleased) { |
| 3568 m_touchSequenceDocument.clear(); |
| 3569 m_touchSequenceUserGestureToken.clear(); |
| 3570 } |
| 3571 |
| 3572 // Now iterate through the changedTouches list and m_targets within it, send
ing |
| 3573 // TouchEvents to the targets as required. |
| 3574 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state
) { |
| 3575 if (!changedTouches[state].m_touches) |
| 3576 continue; |
| 3577 |
| 3578 const AtomicString& eventName(touchEventNameForTouchPointState(static_ca
st<PlatformTouchPoint::State>(state))); |
| 3579 const EventTargetSet& targetsForState = changedTouches[state].m_targets; |
| 3580 for (const RefPtrWillBeMember<EventTarget>& eventTarget : targetsForStat
e) { |
| 3581 EventTarget* touchEventTarget = eventTarget.get(); |
| 3582 RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create( |
| 3583 touches.get(), touchesByTarget.get(touchEventTarget), changedTou
ches[state].m_touches.get(), |
| 3584 eventName, touchEventTarget->toNode()->document().domWindow(), |
| 3585 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey
(), event.cancelable(), event.causesScrollingIfUncanceled(), event.timestamp()); |
| 3586 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get()); |
| 3587 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() ||
touchEvent->defaultHandled(); |
| 3588 } |
| 3589 } |
| 3590 |
| 3591 return swallowedEvent; |
| 3592 } |
| 3593 |
3416 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) | 3594 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) |
3417 { | 3595 { |
3418 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); | 3596 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); |
3419 | 3597 |
3420 const Vector<PlatformTouchPoint>& points = event.touchPoints(); | 3598 const Vector<PlatformTouchPoint>& points = event.touchPoints(); |
3421 | 3599 |
3422 unsigned i; | |
3423 bool freshTouchEvents = true; | 3600 bool freshTouchEvents = true; |
3424 bool allTouchReleased = true; | 3601 bool allTouchReleased = true; |
3425 for (i = 0; i < points.size(); ++i) { | 3602 for (unsigned i = 0; i < points.size(); ++i) { |
3426 const PlatformTouchPoint& point = points[i]; | 3603 const PlatformTouchPoint& point = points[i]; |
| 3604 |
3427 if (point.state() != PlatformTouchPoint::TouchPressed) | 3605 if (point.state() != PlatformTouchPoint::TouchPressed) |
3428 freshTouchEvents = false; | 3606 freshTouchEvents = false; |
3429 if (point.state() != PlatformTouchPoint::TouchReleased && point.state()
!= PlatformTouchPoint::TouchCancelled) | 3607 if (point.state() != PlatformTouchPoint::TouchReleased && point.state()
!= PlatformTouchPoint::TouchCancelled) |
3430 allTouchReleased = false; | 3608 allTouchReleased = false; |
3431 } | 3609 } |
3432 if (freshTouchEvents) { | 3610 if (freshTouchEvents) { |
3433 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should | 3611 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should |
3434 // have cleared the active document when we saw the last release. But we | 3612 // have cleared the active document when we saw the last release. But we |
3435 // have some tests that violate this, ClusterFuzz could trigger it, and | 3613 // have some tests that violate this, ClusterFuzz could trigger it, and |
3436 // there may be cases where the browser doesn't reliably release all | 3614 // there may be cases where the browser doesn't reliably release all |
(...skipping 12 matching lines...) Expand all Loading... |
3449 m_touchSequenceUserGestureToken = gestureIndicator->currentToken(); | 3627 m_touchSequenceUserGestureToken = gestureIndicator->currentToken(); |
3450 | 3628 |
3451 ASSERT(m_frame->view()); | 3629 ASSERT(m_frame->view()); |
3452 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc
hSequenceDocument->frame()->view())) { | 3630 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc
hSequenceDocument->frame()->view())) { |
3453 // If the active touch document has no frame or view, it's probably bein
g destroyed | 3631 // If the active touch document has no frame or view, it's probably bein
g destroyed |
3454 // so we can't dispatch events. | 3632 // so we can't dispatch events. |
3455 return false; | 3633 return false; |
3456 } | 3634 } |
3457 | 3635 |
3458 // First do hit tests for any new touch points. | 3636 // First do hit tests for any new touch points. |
3459 for (i = 0; i < points.size(); ++i) { | 3637 for (unsigned i = 0; i < points.size(); ++i) { |
3460 const PlatformTouchPoint& point = points[i]; | 3638 const PlatformTouchPoint& point = points[i]; |
3461 | 3639 |
3462 // Touch events implicitly capture to the touched node, and don't change | 3640 // Touch events implicitly capture to the touched node, and don't change |
3463 // active/hover states themselves (Gesture events do). So we only need | 3641 // active/hover states themselves (Gesture events do). So we only need |
3464 // to hit-test on touchstart, and it can be read-only. | 3642 // to hit-test on touchstart, and it can be read-only. |
3465 if (point.state() == PlatformTouchPoint::TouchPressed) { | 3643 if (point.state() == PlatformTouchPoint::TouchPressed) { |
3466 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv
ent | HitTestRequest::ReadOnly | HitTestRequest::Active; | 3644 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv
ent | HitTestRequest::ReadOnly | HitTestRequest::Active; |
3467 LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->rootFram
eToContents(point.pos())); | 3645 LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->rootFram
eToContents(point.pos())); |
3468 HitTestResult result; | 3646 HitTestResult result; |
3469 if (!m_touchSequenceDocument) { | 3647 if (!m_touchSequenceDocument) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3511 // document set to receive the events, then we can skip all the rest of | 3689 // document set to receive the events, then we can skip all the rest of |
3512 // this work. | 3690 // this work. |
3513 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !m_
touchSequenceDocument->frameHost()->eventHandlerRegistry().hasEventHandlers(Even
tHandlerRegistry::TouchEvent) || !m_touchSequenceDocument->frame()) { | 3691 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !m_
touchSequenceDocument->frameHost()->eventHandlerRegistry().hasEventHandlers(Even
tHandlerRegistry::TouchEvent) || !m_touchSequenceDocument->frame()) { |
3514 if (allTouchReleased) { | 3692 if (allTouchReleased) { |
3515 m_touchSequenceDocument.clear(); | 3693 m_touchSequenceDocument.clear(); |
3516 m_touchSequenceUserGestureToken.clear(); | 3694 m_touchSequenceUserGestureToken.clear(); |
3517 } | 3695 } |
3518 return false; | 3696 return false; |
3519 } | 3697 } |
3520 | 3698 |
3521 // Build up the lists to use for the 'touches', 'targetTouches' and | 3699 // Compute and store the common info used by both PointerEvent and TouchEven
t. |
3522 // 'changedTouches' attributes in the JS event. See | 3700 Vector<TouchInfo> touchInfos(points.size()); |
3523 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these | |
3524 // lists fit together. | |
3525 | 3701 |
3526 // Holds the complete set of touches on the screen. | 3702 for (unsigned i = 0; i < points.size(); ++i) { |
3527 RefPtrWillBeRawPtr<TouchList> touches = TouchList::create(); | |
3528 | |
3529 // A different view on the 'touches' list above, filtered and grouped by | |
3530 // event target. Used for the 'targetTouches' list in the JS event. | |
3531 using TargetTouchesHeapMap = WillBeHeapHashMap<EventTarget*, RefPtrWillBeMem
ber<TouchList>>; | |
3532 TargetTouchesHeapMap touchesByTarget; | |
3533 | |
3534 // Array of touches per state, used to assemble the 'changedTouches' list. | |
3535 using EventTargetSet = WillBeHeapHashSet<RefPtrWillBeMember<EventTarget>>; | |
3536 struct { | |
3537 // The touches corresponding to the particular change state this struct | |
3538 // instance represents. | |
3539 RefPtrWillBeMember<TouchList> m_touches; | |
3540 // Set of targets involved in m_touches. | |
3541 EventTargetSet m_targets; | |
3542 } changedTouches[PlatformTouchPoint::TouchStateEnd]; | |
3543 | |
3544 for (i = 0; i < points.size(); ++i) { | |
3545 const PlatformTouchPoint& point = points[i]; | 3703 const PlatformTouchPoint& point = points[i]; |
3546 PlatformTouchPoint::State pointState = point.state(); | 3704 PlatformTouchPoint::State pointState = point.state(); |
3547 RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr; | 3705 RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr; |
3548 | 3706 |
3549 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla
tformTouchPoint::TouchCancelled) { | 3707 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla
tformTouchPoint::TouchCancelled) { |
3550 // The target should be the original target for this touch, so get | 3708 // 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 | 3709 // it from the hashmap. As it's a release or cancel we also remove |
3552 // it from the map. | 3710 // it from the map. |
3553 touchTarget = m_targetForTouchID.take(point.id()); | 3711 touchTarget = m_targetForTouchID.take(point.id()); |
3554 } else { | 3712 } else { |
(...skipping 28 matching lines...) Expand all Loading... |
3583 // a Touch is a Node so using the window could be a breaking change. | 3741 // a Touch is a Node so using the window could be a breaking change. |
3584 // Since we know there was no handler invoked, the specific target | 3742 // Since we know there was no handler invoked, the specific target |
3585 // should be completely irrelevant to the application. | 3743 // should be completely irrelevant to the application. |
3586 touchTarget = m_touchSequenceDocument; | 3744 touchTarget = m_touchSequenceDocument; |
3587 targetFrame = m_touchSequenceDocument->frame(); | 3745 targetFrame = m_touchSequenceDocument->frame(); |
3588 } | 3746 } |
3589 ASSERT(targetFrame); | 3747 ASSERT(targetFrame); |
3590 | 3748 |
3591 // pagePoint should always be in the target element's document coordinat
es. | 3749 // pagePoint should always be in the target element's document coordinat
es. |
3592 FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(point.po
s()); | 3750 FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(point.po
s()); |
3593 | |
3594 float scaleFactor = 1.0f / targetFrame->pageZoomFactor(); | 3751 float scaleFactor = 1.0f / targetFrame->pageZoomFactor(); |
3595 | 3752 |
3596 FloatPoint adjustedPagePoint = pagePoint.scaledBy(scaleFactor); | 3753 TouchInfo& touchInfo = touchInfos[i]; |
3597 FloatSize adjustedRadius = point.radius().scaledBy(scaleFactor); | 3754 touchInfo.point = point; |
3598 | 3755 touchInfo.touchTarget = touchTarget.get(); |
3599 RefPtrWillBeRawPtr<Touch> touch = Touch::create( | 3756 touchInfo.targetFrame = targetFrame; |
3600 targetFrame, touchTarget.get(), point.id(), point.screenPos(), adjus
tedPagePoint, adjustedRadius, point.rotationAngle(), point.force()); | 3757 touchInfo.adjustedPagePoint = pagePoint.scaledBy(scaleFactor); |
3601 | 3758 touchInfo.adjustedRadius = point.radius().scaledBy(scaleFactor); |
3602 // Ensure this target's touch list exists, even if it ends up empty, so | 3759 touchInfo.knownTarget = knownTarget; |
3603 // it can always be passed to TouchEvent::Create below. | 3760 touchInfo.consumed = false; |
3604 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f
ind(touchTarget.get()); | |
3605 if (targetTouchesIterator == touchesByTarget.end()) { | |
3606 touchesByTarget.set(touchTarget.get(), TouchList::create()); | |
3607 targetTouchesIterator = touchesByTarget.find(touchTarget.get()); | |
3608 } | |
3609 | |
3610 // touches and targetTouches should only contain information about | |
3611 // touches still on the screen, so if this point is released or | |
3612 // cancelled it will only appear in the changedTouches list. | |
3613 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla
tformTouchPoint::TouchCancelled) { | |
3614 touches->append(touch); | |
3615 targetTouchesIterator->value->append(touch); | |
3616 } | |
3617 | |
3618 // Now build up the correct list for changedTouches. | |
3619 // Note that any touches that are in the TouchStationary state (e.g. if | |
3620 // the user had several points touched but did not move them all) should | |
3621 // never be in the changedTouches list so we do not handle them | |
3622 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609 | |
3623 // for further discussion about the TouchStationary state. | |
3624 if (pointState != PlatformTouchPoint::TouchStationary && knownTarget) { | |
3625 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd); | |
3626 if (!changedTouches[pointState].m_touches) | |
3627 changedTouches[pointState].m_touches = TouchList::create(); | |
3628 changedTouches[pointState].m_touches->append(touch); | |
3629 changedTouches[pointState].m_targets.add(touchTarget); | |
3630 } | |
3631 } | |
3632 if (allTouchReleased) { | |
3633 m_touchSequenceDocument.clear(); | |
3634 m_touchSequenceUserGestureToken.clear(); | |
3635 } | 3761 } |
3636 | 3762 |
3637 // Now iterate the changedTouches list and m_targets within it, sending | 3763 if (RuntimeEnabledFeatures::pointerEventEnabled()) { |
3638 // events to the targets as required. | 3764 dispatchPointerEventsForTouchEvent(event, touchInfos); |
3639 bool swallowedEvent = false; | 3765 // TODO(mustaq): This needs attention. |
3640 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state
) { | 3766 // From CL discussion: The disposition of any pointer events affects onl
y the generation of |
3641 if (!changedTouches[state].m_touches) | 3767 // touch events. If pointer events were handled (and hence no touch even
ts generated) that is |
3642 continue; | 3768 // still equivalent to the touch events going unhandled because pointer
event handler don't |
3643 | 3769 // block scroll gesture generation. |
3644 const AtomicString& stateName(eventNameForTouchPointState(static_cast<Pl
atformTouchPoint::State>(state))); | |
3645 const EventTargetSet& targetsForState = changedTouches[state].m_targets; | |
3646 for (const RefPtrWillBeMember<EventTarget>& eventTarget : targetsForStat
e) { | |
3647 EventTarget* touchEventTarget = eventTarget.get(); | |
3648 RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create( | |
3649 touches.get(), touchesByTarget.get(touchEventTarget), changedTou
ches[state].m_touches.get(), | |
3650 stateName, touchEventTarget->toNode()->document().domWindow(), | |
3651 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey
(), event.cancelable(), event.causesScrollingIfUncanceled(), event.timestamp()); | |
3652 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get()); | |
3653 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() ||
touchEvent->defaultHandled(); | |
3654 } | |
3655 } | 3770 } |
3656 | 3771 |
3657 return swallowedEvent; | 3772 return dispatchTouchEvents(event, touchInfos, freshTouchEvents, allTouchRele
ased); |
3658 } | 3773 } |
3659 | 3774 |
3660 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction
action2) | 3775 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction
action2) |
3661 { | 3776 { |
3662 if (action1 == TouchActionNone || action2 == TouchActionNone) | 3777 if (action1 == TouchActionNone || action2 == TouchActionNone) |
3663 return TouchActionNone; | 3778 return TouchActionNone; |
3664 if (action1 == TouchActionAuto) | 3779 if (action1 == TouchActionAuto) |
3665 return action2; | 3780 return action2; |
3666 if (action2 == TouchActionAuto) | 3781 if (action2 == TouchActionAuto) |
3667 return action1; | 3782 return action1; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3761 unsigned EventHandler::accessKeyModifiers() | 3876 unsigned EventHandler::accessKeyModifiers() |
3762 { | 3877 { |
3763 #if OS(MACOSX) | 3878 #if OS(MACOSX) |
3764 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; | 3879 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; |
3765 #else | 3880 #else |
3766 return PlatformEvent::AltKey; | 3881 return PlatformEvent::AltKey; |
3767 #endif | 3882 #endif |
3768 } | 3883 } |
3769 | 3884 |
3770 } // namespace blink | 3885 } // namespace blink |
OLD | NEW |