| Index: third_party/WebKit/Source/core/input/EventHandler.cpp
|
| diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
|
| index 5f643cf8b2ad4e8a6e7efcf500ca41fed94410ee..dbc20349449fedba842cf2c85959f0cd7ceda670 100644
|
| --- a/third_party/WebKit/Source/core/input/EventHandler.cpp
|
| +++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
|
| @@ -59,7 +59,6 @@
|
| #include "core/frame/TopControls.h"
|
| #include "core/frame/UseCounter.h"
|
| #include "core/frame/VisualViewport.h"
|
| -#include "core/html/HTMLCanvasElement.h"
|
| #include "core/html/HTMLDialogElement.h"
|
| #include "core/html/HTMLFrameElementBase.h"
|
| #include "core/html/HTMLFrameSetElement.h"
|
| @@ -89,7 +88,6 @@
|
| #include "core/paint/PaintLayer.h"
|
| #include "core/style/ComputedStyle.h"
|
| #include "core/svg/SVGDocumentExtensions.h"
|
| -#include "platform/Histogram.h"
|
| #include "platform/PlatformGestureEvent.h"
|
| #include "platform/PlatformKeyboardEvent.h"
|
| #include "platform/PlatformTouchEvent.h"
|
| @@ -111,33 +109,6 @@ namespace blink {
|
|
|
| namespace {
|
|
|
| -bool hasTouchHandlers(const EventHandlerRegistry& registry)
|
| -{
|
| - return registry.hasEventHandlers(EventHandlerRegistry::TouchStartOrMoveEventBlocking)
|
| - || registry.hasEventHandlers(EventHandlerRegistry::TouchStartOrMoveEventPassive)
|
| - || registry.hasEventHandlers(EventHandlerRegistry::TouchEndOrCancelEventBlocking)
|
| - || registry.hasEventHandlers(EventHandlerRegistry::TouchEndOrCancelEventPassive);
|
| -}
|
| -
|
| -const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::TouchState state)
|
| -{
|
| - switch (state) {
|
| - case PlatformTouchPoint::TouchReleased:
|
| - return EventTypeNames::touchend;
|
| - case PlatformTouchPoint::TouchCancelled:
|
| - return EventTypeNames::touchcancel;
|
| - case PlatformTouchPoint::TouchPressed:
|
| - return EventTypeNames::touchstart;
|
| - case PlatformTouchPoint::TouchMoved:
|
| - return EventTypeNames::touchmove;
|
| - case PlatformTouchPoint::TouchStationary:
|
| - // Fall through to default
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return emptyAtom;
|
| - }
|
| -}
|
| -
|
| // Convert |event->deltaMode()| to scroll granularity and output as |granularity|.
|
| bool wheelGranularityToScrollGranularity(const WheelEvent* event, ScrollGranularity* granularity)
|
| {
|
| @@ -211,59 +182,6 @@ void recomputeScrollChain(const LocalFrame& frame, const Node& startNode,
|
| scrollChain.push_front(DOMNodeIds::idForNode(frame.document()->scrollingElement()));
|
| }
|
|
|
| -// These offsets change indicies into the ListenerHistogram
|
| -// enumeration. The addition of a series of offsets then
|
| -// produces the resulting ListenerHistogram value.
|
| -const size_t kTouchTargetHistogramRootScrollerOffset = 4;
|
| -const size_t kTouchTargetHistogramScrollableDocumentOffset = 2;
|
| -const size_t kTouchTargetHistogramHandledOffset = 1;
|
| -
|
| -enum TouchTargetAndDispatchResultType {
|
| - NonRootScrollerNonScrollableNotHandled, // Non-root-scroller, non-scrollable document, not handled.
|
| - NonRootScrollerNonScrollableHandled, // Non-root-scroller, non-scrollable document, handled application.
|
| - NonRootScrollerScrollableDocumentNotHandled, // Non-root-scroller, scrollable document, not handled.
|
| - NonRootScrollerScrollableDocumentHandled, // Non-root-scroller, scrollable document, handled application.
|
| - RootScrollerNonScrollableNotHandled, // Root-scroller, non-scrollable document, not handled.
|
| - RootScrollerNonScrollableHandled, // Root-scroller, non-scrollable document, handled.
|
| - RootScrollerScrollableDocumentNotHandled, // Root-scroller, scrollable document, not handled.
|
| - RootScrollerScrollableDocumentHandled, // Root-scroller, scrollable document, handled.
|
| - TouchTargetAndDispatchResultTypeMax,
|
| -};
|
| -
|
| -TouchTargetAndDispatchResultType toTouchTargetHistogramValue(EventTarget* eventTarget, DispatchEventResult dispatchResult)
|
| -{
|
| - int result = 0;
|
| - Document* document = nullptr;
|
| -
|
| - if (const LocalDOMWindow* domWindow = eventTarget->toLocalDOMWindow()) {
|
| - // Treat the window as a root scroller as well.
|
| - document = domWindow->document();
|
| - result += kTouchTargetHistogramRootScrollerOffset;
|
| - } else if (Node* node = eventTarget->toNode()) {
|
| - // Report if the target node is the document or body.
|
| - if (node->isDocumentNode() || static_cast<Node*>(node->document().documentElement()) == node || static_cast<Node*>(node->document().body()) == node) {
|
| - result += kTouchTargetHistogramRootScrollerOffset;
|
| - }
|
| - document = &node->document();
|
| - }
|
| -
|
| - if (document) {
|
| - FrameView* view = document->view();
|
| - if (view && view->isScrollable())
|
| - result += kTouchTargetHistogramScrollableDocumentOffset;
|
| - }
|
| -
|
| - if (dispatchResult != DispatchEventResult::NotCanceled)
|
| - result += kTouchTargetHistogramHandledOffset;
|
| - return static_cast<TouchTargetAndDispatchResultType>(result);
|
| -}
|
| -
|
| -enum TouchEventDispatchResultType {
|
| - UnhandledTouches, // Unhandled touch events.
|
| - HandledTouches, // Handled touch events.
|
| - TouchEventDispatchResultTypeMax,
|
| -};
|
| -
|
| } // namespace
|
|
|
| using namespace HTMLNames;
|
| @@ -335,14 +253,13 @@ EventHandler::EventHandler(LocalFrame* frame)
|
| , m_shouldOnlyFireDragOverEvent(false)
|
| , m_mousePositionIsUnknown(true)
|
| , m_mouseDownTimestamp(0)
|
| - , m_touchPressed(false)
|
| + , m_pointerEventManager(frame)
|
| , m_scrollGestureHandlingNode(nullptr)
|
| , m_lastGestureScrollOverWidget(false)
|
| , m_longTapShouldInvokeContextMenu(false)
|
| , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
|
| , m_lastShowPressTimestamp(0)
|
| , m_deltaConsumedForScrollSequence(false)
|
| - , m_waitingForFirstTouchMove(false)
|
| {
|
| }
|
|
|
| @@ -364,8 +281,6 @@ DEFINE_TRACE(EventHandler)
|
| visitor->trace(m_dragTarget);
|
| visitor->trace(m_frameSetBeingResized);
|
| visitor->trace(m_scrollbarHandlingScrollGesture);
|
| - visitor->trace(m_targetForTouchID);
|
| - visitor->trace(m_touchSequenceDocument);
|
| visitor->trace(m_scrollGestureHandlingNode);
|
| visitor->trace(m_previousGestureScrolledNode);
|
| visitor->trace(m_lastDeferredTapElement);
|
| @@ -402,13 +317,9 @@ void EventHandler::clear()
|
| m_mousePressed = false;
|
| m_capturesDragging = false;
|
| m_capturingMouseEventsNode = nullptr;
|
| - m_targetForTouchID.clear();
|
| - m_touchSequenceDocument.clear();
|
| - m_touchSequenceUserGestureToken.clear();
|
| clearGestureScrollState();
|
| m_lastGestureScrollOverWidget = false;
|
| m_scrollbarHandlingScrollGesture = nullptr;
|
| - m_touchPressed = false;
|
| m_pointerEventManager.clear();
|
| m_mouseDownMayStartDrag = false;
|
| m_lastShowPressTimestamp = 0;
|
| @@ -1362,7 +1273,7 @@ WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMous
|
| }
|
|
|
| // Treat any mouse move events as readonly if the user is currently touching the screen.
|
| - if (m_touchPressed)
|
| + if (m_pointerEventManager.isAnyTouchActive())
|
| hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
|
| HitTestRequest request(hitType);
|
| MouseEventWithHitTestResults mev = MouseEventWithHitTestResults(mouseEvent, HitTestResult(request, LayoutPoint()));
|
| @@ -3724,384 +3635,11 @@ HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout
|
| return result;
|
| }
|
|
|
| -void EventHandler::dispatchPointerEvents(const PlatformTouchEvent& event,
|
| - HeapVector<TouchInfo>& touchInfos)
|
| -{
|
| - if (!RuntimeEnabledFeatures::pointerEventEnabled())
|
| - return;
|
| -
|
| - // Iterate through the touch points, sending PointerEvents to the targets as required.
|
| - for (unsigned i = 0; i < touchInfos.size(); ++i) {
|
| - TouchInfo& touchInfo = touchInfos[i];
|
| - const PlatformTouchPoint& touchPoint = touchInfo.point;
|
| -
|
| -
|
| - if (touchPoint.state() == PlatformTouchPoint::TouchStationary
|
| - || !touchInfo.knownTarget)
|
| - continue;
|
| -
|
| - WebInputEventResult result =
|
| - m_pointerEventManager.sendTouchPointerEvent(
|
| - touchInfo.touchTarget, touchPoint, event.getModifiers(),
|
| - touchInfo.adjustedRadius.width(), touchInfo.adjustedRadius.height(),
|
| - touchInfo.adjustedPagePoint.x(), touchInfo.adjustedPagePoint.y());
|
| - touchInfo.consumed = result != WebInputEventResult::NotHandled;
|
| - }
|
| -}
|
| -
|
| -namespace {
|
| -
|
| -// Defining this class type local to dispatchTouchEvents() and annotating
|
| -// it with STACK_ALLOCATED(), runs into MSVC(VS 2013)'s C4822 warning
|
| -// that the local class doesn't provide a local definition for 'operator new'.
|
| -// Which it intentionally doesn't and shouldn't.
|
| -//
|
| -// Work around such toolchain bugginess by lifting out the type, thereby
|
| -// taking it out of C4822's reach.
|
| -class ChangedTouches final {
|
| - STACK_ALLOCATED();
|
| -public:
|
| - // The touches corresponding to the particular change state this struct
|
| - // instance represents.
|
| - Member<TouchList> m_touches;
|
| -
|
| - using EventTargetSet = HeapHashSet<Member<EventTarget>>;
|
| - // Set of targets involved in m_touches.
|
| - EventTargetSet m_targets;
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -WebInputEventResult EventHandler::dispatchTouchEvents(const PlatformTouchEvent& event,
|
| - HeapVector<TouchInfo>& touchInfos, bool allTouchReleased)
|
| -{
|
| - bool touchStartOrFirstTouchMove = false;
|
| - if (event.type() == PlatformEvent::TouchStart) {
|
| - m_waitingForFirstTouchMove = true;
|
| - touchStartOrFirstTouchMove = true;
|
| - } else if (event.type() == PlatformEvent::TouchMove) {
|
| - touchStartOrFirstTouchMove = m_waitingForFirstTouchMove;
|
| - m_waitingForFirstTouchMove = false;
|
| - }
|
| -
|
| - // Build up the lists to use for the 'touches', 'targetTouches' and
|
| - // 'changedTouches' attributes in the JS event. See
|
| - // http://www.w3.org/TR/touch-events/#touchevent-interface for how these
|
| - // lists fit together.
|
| -
|
| - // Holds the complete set of touches on the screen.
|
| - TouchList* touches = TouchList::create();
|
| -
|
| - // A different view on the 'touches' list above, filtered and grouped by
|
| - // event target. Used for the 'targetTouches' list in the JS event.
|
| - using TargetTouchesHeapMap = HeapHashMap<EventTarget*, Member<TouchList>>;
|
| - TargetTouchesHeapMap touchesByTarget;
|
| -
|
| - // Array of touches per state, used to assemble the 'changedTouches' list.
|
| - ChangedTouches changedTouches[PlatformTouchPoint::TouchStateEnd];
|
| -
|
| - for (unsigned i = 0; i < touchInfos.size(); ++i) {
|
| - const TouchInfo& touchInfo = touchInfos[i];
|
| - const PlatformTouchPoint& point = touchInfo.point;
|
| - PlatformTouchPoint::TouchState pointState = point.state();
|
| -
|
| - if (touchInfo.consumed)
|
| - continue;
|
| -
|
| - Touch* touch = Touch::create(
|
| - touchInfo.targetFrame.get(),
|
| - touchInfo.touchTarget.get(),
|
| - point.id(),
|
| - point.screenPos(),
|
| - touchInfo.adjustedPagePoint,
|
| - touchInfo.adjustedRadius,
|
| - point.rotationAngle(),
|
| - point.force(),
|
| - touchInfo.region);
|
| -
|
| - // Ensure this target's touch list exists, even if it ends up empty, so
|
| - // it can always be passed to TouchEvent::Create below.
|
| - TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.find(touchInfo.touchTarget.get());
|
| - if (targetTouchesIterator == touchesByTarget.end()) {
|
| - touchesByTarget.set(touchInfo.touchTarget.get(), TouchList::create());
|
| - targetTouchesIterator = touchesByTarget.find(touchInfo.touchTarget.get());
|
| - }
|
| -
|
| - // touches and targetTouches should only contain information about
|
| - // touches still on the screen, so if this point is released or
|
| - // cancelled it will only appear in the changedTouches list.
|
| - if (pointState != PlatformTouchPoint::TouchReleased && pointState != PlatformTouchPoint::TouchCancelled) {
|
| - touches->append(touch);
|
| - targetTouchesIterator->value->append(touch);
|
| - }
|
| -
|
| - // Now build up the correct list for changedTouches.
|
| - // Note that any touches that are in the TouchStationary state (e.g. if
|
| - // the user had several points touched but did not move them all) should
|
| - // never be in the changedTouches list so we do not handle them
|
| - // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609
|
| - // for further discussion about the TouchStationary state.
|
| - if (pointState != PlatformTouchPoint::TouchStationary && touchInfo.knownTarget) {
|
| - ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
|
| - if (!changedTouches[pointState].m_touches)
|
| - changedTouches[pointState].m_touches = TouchList::create();
|
| - changedTouches[pointState].m_touches->append(touch);
|
| - changedTouches[pointState].m_targets.add(touchInfo.touchTarget);
|
| - }
|
| - }
|
| - if (allTouchReleased) {
|
| - m_touchSequenceDocument.clear();
|
| - m_touchSequenceUserGestureToken.clear();
|
| - }
|
| -
|
| - WebInputEventResult eventResult = WebInputEventResult::NotHandled;
|
| -
|
| - // Now iterate through the changedTouches list and m_targets within it, sending
|
| - // TouchEvents to the targets as required.
|
| - for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
|
| - if (!changedTouches[state].m_touches)
|
| - continue;
|
| -
|
| - const AtomicString& eventName(touchEventNameForTouchPointState(static_cast<PlatformTouchPoint::TouchState>(state)));
|
| - for (const auto& eventTarget : changedTouches[state].m_targets) {
|
| - EventTarget* touchEventTarget = eventTarget;
|
| - TouchEvent* touchEvent = TouchEvent::create(
|
| - touches, touchesByTarget.get(touchEventTarget), changedTouches[state].m_touches.get(),
|
| - eventName, touchEventTarget->toNode()->document().domWindow(),
|
| - event.getModifiers(), event.cancelable(), event.causesScrollingIfUncanceled(), event.timestamp());
|
| -
|
| - DispatchEventResult domDispatchResult = touchEventTarget->dispatchEvent(touchEvent);
|
| -
|
| - // Only report for top level documents with a single touch on
|
| - // touch-start or the first touch-move.
|
| - if (touchStartOrFirstTouchMove && touchInfos.size() == 1 && event.cancelable() && !m_frame->document()->ownerElement()) {
|
| - DEFINE_STATIC_LOCAL(EnumerationHistogram, rootDocumentListenerHistogram, ("Event.Touch.TargetAndDispatchResult", TouchTargetAndDispatchResultTypeMax));
|
| - rootDocumentListenerHistogram.count(toTouchTargetHistogramValue(eventTarget, domDispatchResult));
|
| -
|
| - // Count the handled touch starts and first touch moves before and after the page is fully loaded respectively.
|
| - if (m_frame->document()->isLoadCompleted()) {
|
| - DEFINE_STATIC_LOCAL(EnumerationHistogram, touchDispositionsAfterPageLoadHistogram, ("Event.Touch.TouchDispositionsAfterPageLoad", TouchEventDispatchResultTypeMax));
|
| - touchDispositionsAfterPageLoadHistogram.count((domDispatchResult != DispatchEventResult::NotCanceled) ? HandledTouches : UnhandledTouches);
|
| - } else {
|
| - DEFINE_STATIC_LOCAL(EnumerationHistogram, touchDispositionsBeforePageLoadHistogram, ("Event.Touch.TouchDispositionsBeforePageLoad", TouchEventDispatchResultTypeMax));
|
| - touchDispositionsBeforePageLoadHistogram.count((domDispatchResult != DispatchEventResult::NotCanceled) ? HandledTouches : UnhandledTouches);
|
| - }
|
| - }
|
| - eventResult = mergeEventResult(eventResult, toWebInputEventResult(domDispatchResult));
|
| - }
|
| - }
|
| - return eventResult;
|
| -}
|
| -
|
| WebInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
|
| {
|
| TRACE_EVENT0("blink", "EventHandler::handleTouchEvent");
|
|
|
| - if (event.type() == PlatformEvent::TouchScrollStarted) {
|
| - m_pointerEventManager.blockTouchPointers();
|
| - return WebInputEventResult::HandledSystem;
|
| - }
|
| -
|
| - const Vector<PlatformTouchPoint>& points = event.touchPoints();
|
| -
|
| - bool newTouchSequence = true;
|
| - bool allTouchReleased = true;
|
| - for (unsigned i = 0; i < points.size(); ++i) {
|
| - const PlatformTouchPoint& point = points[i];
|
| -
|
| - if (point.state() != PlatformTouchPoint::TouchPressed)
|
| - newTouchSequence = false;
|
| - if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
|
| - allTouchReleased = false;
|
| - }
|
| -
|
| - if (newTouchSequence) {
|
| - // Ideally we'd ASSERT !m_touchSequenceDocument here since we should
|
| - // have cleared the active document when we saw the last release. But we
|
| - // have some tests that violate this, ClusterFuzz could trigger it, and
|
| - // there may be cases where the browser doesn't reliably release all
|
| - // touches. http://crbug.com/345372 tracks this.
|
| - m_touchSequenceDocument.clear();
|
| - m_touchSequenceUserGestureToken.clear();
|
| - m_pointerEventManager.unblockTouchPointers();
|
| - }
|
| -
|
| - ASSERT(m_frame->view());
|
| - if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touchSequenceDocument->frame()->view())) {
|
| - // If the active touch document has no frame or view, it's probably being destroyed
|
| - // so we can't dispatch events.
|
| - return WebInputEventResult::NotHandled;
|
| - }
|
| -
|
| - // First do hit tests for any new touch points.
|
| - for (unsigned i = 0; i < points.size(); ++i) {
|
| - const PlatformTouchPoint& point = points[i];
|
| -
|
| - // Touch events implicitly capture to the touched node, and don't change
|
| - // active/hover states themselves (Gesture events do). So we only need
|
| - // to hit-test on touchstart, and it can be read-only.
|
| - if (point.state() == PlatformTouchPoint::TouchPressed) {
|
| - HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | HitTestRequest::ReadOnly | HitTestRequest::Active;
|
| - LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->rootFrameToContents(point.pos()));
|
| - HitTestResult result;
|
| - if (!m_touchSequenceDocument) {
|
| - result = hitTestResultAtPoint(pagePoint, hitType);
|
| - } else if (m_touchSequenceDocument->frame()) {
|
| - LayoutPoint framePoint = roundedLayoutPoint(m_touchSequenceDocument->frame()->view()->rootFrameToContents(point.pos()));
|
| - result = hitTestResultInFrame(m_touchSequenceDocument->frame(), framePoint, hitType);
|
| - } else {
|
| - continue;
|
| - }
|
| -
|
| - Node* node = result.innerNode();
|
| - if (!node)
|
| - continue;
|
| -
|
| - if (isHTMLCanvasElement(node)) {
|
| - std::pair<Element*, String> regionInfo = toHTMLCanvasElement(node)->getControlAndIdIfHitRegionExists(result.pointInInnerNodeFrame());
|
| - if (regionInfo.first)
|
| - node = regionInfo.first;
|
| - m_regionForTouchID.set(point.id(), regionInfo.second);
|
| - }
|
| -
|
| - // Touch events should not go to text nodes
|
| - if (node->isTextNode())
|
| - node = FlatTreeTraversal::parent(*node);
|
| -
|
| - if (!m_touchSequenceDocument) {
|
| - // Keep track of which document should receive all touch events
|
| - // in the active sequence. This must be a single document to
|
| - // ensure we don't leak Nodes between documents.
|
| - m_touchSequenceDocument = &(result.innerNode()->document());
|
| - ASSERT(m_touchSequenceDocument->frame()->view());
|
| - }
|
| -
|
| - // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id())
|
| - // since we shouldn't get a touchstart for a touch that's already
|
| - // down. However EventSender allows this to be violated and there's
|
| - // some tests that take advantage of it. There may also be edge
|
| - // cases in the browser where this happens.
|
| - // See http://crbug.com/345372.
|
| - m_targetForTouchID.set(point.id(), node);
|
| -
|
| - TouchAction effectiveTouchAction = TouchActionUtil::computeEffectiveTouchAction(*node);
|
| - if (effectiveTouchAction != TouchActionAuto)
|
| - m_frame->page()->chromeClient().setTouchAction(effectiveTouchAction);
|
| - }
|
| - }
|
| -
|
| - m_touchPressed = !allTouchReleased;
|
| -
|
| - // If there's no document receiving touch events, or no handlers on the
|
| - // document set to receive the events, then we can skip all the rest of
|
| - // this work.
|
| - if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !hasTouchHandlers(m_touchSequenceDocument->frameHost()->eventHandlerRegistry()) || !m_touchSequenceDocument->frame()) {
|
| - if (allTouchReleased) {
|
| - m_touchSequenceDocument.clear();
|
| - m_touchSequenceUserGestureToken.clear();
|
| - }
|
| - return WebInputEventResult::NotHandled;
|
| - }
|
| -
|
| - // Whether a touch should be considered a "user gesture" or not is a tricky question.
|
| - // https://docs.google.com/document/d/1oF1T3O7_E4t1PYHV6gyCwHxOi3ystm0eSL5xZu7nvOg/edit#
|
| - // TODO(rbyers): Disable user gesture in some cases but retain logging for now (crbug.com/582140).
|
| - OwnPtr<UserGestureIndicator> gestureIndicator;
|
| - if (event.touchPoints().size() == 1
|
| - && event.touchPoints()[0].state() == PlatformTouchPoint::TouchReleased
|
| - && !event.causesScrollingIfUncanceled()) {
|
| - // This is a touchend corresponding to a tap, definitely a user gesture. So don't supply
|
| - // a UserGestureUtilizedCallback.
|
| - gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessingUserGesture));
|
| - } else {
|
| - // This is some other touch event that perhaps shouldn't be considered a user gesture. So
|
| - // use a UserGestureUtilizedCallback to get metrics / deprecation warnings.
|
| - if (m_touchSequenceUserGestureToken)
|
| - gestureIndicator = adoptPtr(new UserGestureIndicator(m_touchSequenceUserGestureToken.release(), &m_touchSequenceDocument->frame()->eventHandler()));
|
| - else
|
| - gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessingUserGesture, &m_touchSequenceDocument->frame()->eventHandler()));
|
| - m_touchSequenceUserGestureToken = UserGestureIndicator::currentToken();
|
| - }
|
| -
|
| - // Compute and store the common info used by both PointerEvent and TouchEvent.
|
| - HeapVector<TouchInfo> touchInfos(points.size());
|
| -
|
| - for (unsigned i = 0; i < points.size(); ++i) {
|
| - const PlatformTouchPoint& point = points[i];
|
| - PlatformTouchPoint::TouchState pointState = point.state();
|
| - EventTarget* touchTarget = nullptr;
|
| - String regionID;
|
| -
|
| - if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) {
|
| - // The target should be the original target for this touch, so get
|
| - // it from the hashmap. As it's a release or cancel we also remove
|
| - // it from the map.
|
| - touchTarget = m_targetForTouchID.take(point.id());
|
| - regionID = m_regionForTouchID.take(point.id());
|
| - } else {
|
| - // No hittest is performed on move or stationary, since the target
|
| - // is not allowed to change anyway.
|
| - touchTarget = m_targetForTouchID.get(point.id());
|
| - regionID = m_regionForTouchID.get(point.id());
|
| - }
|
| -
|
| - LocalFrame* targetFrame = nullptr;
|
| - bool knownTarget = false;
|
| - if (touchTarget) {
|
| - Document& doc = touchTarget->toNode()->document();
|
| - // If the target node has moved to a new document while it was being touched,
|
| - // we can't send events to the new document because that could leak nodes
|
| - // from one document to another. See http://crbug.com/394339.
|
| - if (&doc == m_touchSequenceDocument.get()) {
|
| - targetFrame = doc.frame();
|
| - knownTarget = true;
|
| - }
|
| - }
|
| - if (!knownTarget) {
|
| - // If we don't have a target registered for the point it means we've
|
| - // missed our opportunity to do a hit test for it (due to some
|
| - // optimization that prevented blink from ever seeing the
|
| - // touchstart), or that the touch started outside the active touch
|
| - // sequence document. We should still include the touch in the
|
| - // Touches list reported to the application (eg. so it can
|
| - // differentiate between a one and two finger gesture), but we won't
|
| - // actually dispatch any events for it. Set the target to the
|
| - // Document so that there's some valid node here. Perhaps this
|
| - // should really be LocalDOMWindow, but in all other cases the target of
|
| - // a Touch is a Node so using the window could be a breaking change.
|
| - // Since we know there was no handler invoked, the specific target
|
| - // should be completely irrelevant to the application.
|
| - touchTarget = m_touchSequenceDocument;
|
| - targetFrame = m_touchSequenceDocument->frame();
|
| - }
|
| - ASSERT(targetFrame);
|
| -
|
| - // pagePoint should always be in the target element's document coordinates.
|
| - FloatPoint pagePoint = targetFrame->view()->rootFrameToContents(point.pos());
|
| - float scaleFactor = 1.0f / targetFrame->pageZoomFactor();
|
| -
|
| - TouchInfo& touchInfo = touchInfos[i];
|
| - touchInfo.point = point;
|
| - touchInfo.touchTarget = touchTarget;
|
| - touchInfo.targetFrame = targetFrame;
|
| - touchInfo.adjustedPagePoint = pagePoint.scaledBy(scaleFactor);
|
| - touchInfo.adjustedRadius = point.radius().scaledBy(scaleFactor);
|
| - touchInfo.knownTarget = knownTarget;
|
| - touchInfo.consumed = false;
|
| - touchInfo.region = regionID;
|
| - }
|
| -
|
| - dispatchPointerEvents(event, touchInfos);
|
| - // Note that the disposition of any pointer events affects only the generation of touch
|
| - // events. If all pointer events were handled (and hence no touch events were fired), that
|
| - // is still equivalent to the touch events going unhandled because pointer event handler
|
| - // don't block scroll gesture generation.
|
| -
|
| - // TODO(crbug.com/507408): If PE handlers always call preventDefault, we won't see TEs until after
|
| - // scrolling starts because the scrolling would suppress upcoming PEs. This sudden "break" in TE
|
| - // suppression can make the visible TEs inconsistent (e.g. touchmove without a touchstart).
|
| -
|
| - return dispatchTouchEvents(event, touchInfos, allTouchReleased);
|
| + return m_pointerEventManager.handleTouchEvents(event);
|
| }
|
|
|
| void EventHandler::userGestureUtilized()
|
|
|