| Index: sky/engine/core/page/EventHandler.cpp
|
| diff --git a/sky/engine/core/page/EventHandler.cpp b/sky/engine/core/page/EventHandler.cpp
|
| index 7998f2c99c2d5d9f08319234ec453054ae2d1836..9d5fe271b9132653fe997073ea6ee090d086be6f 100644
|
| --- a/sky/engine/core/page/EventHandler.cpp
|
| +++ b/sky/engine/core/page/EventHandler.cpp
|
| @@ -34,7 +34,6 @@
|
| #include "sky/engine/core/dom/Document.h"
|
| #include "sky/engine/core/dom/DocumentMarkerController.h"
|
| #include "sky/engine/core/dom/NodeRenderingTraversal.h"
|
| -#include "sky/engine/core/dom/TouchList.h"
|
| #include "sky/engine/core/dom/shadow/ShadowRoot.h"
|
| #include "sky/engine/core/editing/Editor.h"
|
| #include "sky/engine/core/editing/FrameSelection.h"
|
| @@ -44,7 +43,6 @@
|
| #include "sky/engine/core/events/EventPath.h"
|
| #include "sky/engine/core/events/KeyboardEvent.h"
|
| #include "sky/engine/core/events/TextEvent.h"
|
| -#include "sky/engine/core/events/TouchEvent.h"
|
| #include "sky/engine/core/fetch/ImageResource.h"
|
| #include "sky/engine/core/frame/FrameView.h"
|
| #include "sky/engine/core/frame/LocalFrame.h"
|
| @@ -64,7 +62,6 @@
|
| #include "sky/engine/core/rendering/style/RenderStyle.h"
|
| #include "sky/engine/platform/PlatformGestureEvent.h"
|
| #include "sky/engine/platform/PlatformKeyboardEvent.h"
|
| -#include "sky/engine/platform/PlatformTouchEvent.h"
|
| #include "sky/engine/platform/TraceEvent.h"
|
| #include "sky/engine/platform/WindowsKeyboardCodes.h"
|
| #include "sky/engine/platform/geometry/FloatPoint.h"
|
| @@ -140,7 +137,6 @@ EventHandler::EventHandler(LocalFrame* frame)
|
| , m_clickCount(0)
|
| , m_shouldOnlyFireDragOverEvent(false)
|
| , m_mousePositionIsUnknown(true)
|
| - , m_touchPressed(false)
|
| , m_scrollGestureHandlingNode(nullptr)
|
| , m_lastGestureScrollOverWidget(false)
|
| , m_maxMouseMovedDuration(0)
|
| @@ -173,15 +169,12 @@ void EventHandler::clear()
|
| m_mousePressed = false;
|
| m_capturesDragging = false;
|
| m_previousWheelScrolledNode = nullptr;
|
| - m_targetForTouchID.clear();
|
| - m_touchSequenceDocument.clear();
|
| m_scrollGestureHandlingNode = nullptr;
|
| m_lastGestureScrollOverWidget = false;
|
| m_previousGestureScrolledNode = nullptr;
|
| m_scrollbarHandlingScrollGesture = nullptr;
|
| m_maxMouseMovedDuration = 0;
|
| m_didStartDrag = false;
|
| - m_touchPressed = false;
|
| m_mouseDownMayStartSelect = false;
|
| m_mouseDownMayStartDrag = false;
|
| m_lastShowPressTimestamp = 0;
|
| @@ -834,23 +827,17 @@ bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults&
|
| // supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code
|
| // and LongPress is such a special scenario that it's unlikely to matter much in practice.
|
|
|
| -#if OS(ANDROID)
|
| - bool shouldLongPressSelectWord = true;
|
| -#else
|
| - bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()->touchEditingEnabled();
|
| -#endif
|
| - if (shouldLongPressSelectWord) {
|
| - IntPoint hitTestPoint = gestureEvent.position();
|
| - HitTestResult result = hitTestResultAtPoint(hitTestPoint);
|
| - Node* innerNode = result.targetNode();
|
| - if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
|
| - selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitespace);
|
| - if (m_frame->selection().isRange()) {
|
| - focusDocumentView();
|
| - return true;
|
| - }
|
| + IntPoint hitTestPoint = gestureEvent.position();
|
| + HitTestResult result = hitTestResultAtPoint(hitTestPoint);
|
| + Node* innerNode = result.targetNode();
|
| + if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
|
| + selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitespace);
|
| + if (m_frame->selection().isRange()) {
|
| + focusDocumentView();
|
| + return true;
|
| }
|
| }
|
| +
|
| return true;
|
| }
|
|
|
| @@ -1007,7 +994,7 @@ GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe
|
|
|
| HitTestRequest::HitTestRequestType EventHandler::getHitTypeForGestureType(PlatformEvent::Type type)
|
| {
|
| - HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
|
| + HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly;
|
| switch (type) {
|
| case PlatformEvent::GestureShowPress:
|
| case PlatformEvent::GestureTapUnconfirmed:
|
| @@ -1227,25 +1214,6 @@ void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setL
|
| }
|
| }
|
|
|
| -static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State 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:
|
| - // TouchStationary state is not converted to touch events, so fall through to assert.
|
| - default:
|
| - ASSERT_NOT_REACHED();
|
| - return emptyAtom;
|
| - }
|
| -}
|
| -
|
| HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
|
| {
|
| HitTestResult result(point);
|
| @@ -1261,226 +1229,6 @@ HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout
|
| return result;
|
| }
|
|
|
| -bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
|
| -{
|
| - TRACE_EVENT0("blink", "EventHandler::handleTouchEvent");
|
| -
|
| - const Vector<PlatformTouchPoint>& points = event.touchPoints();
|
| -
|
| - unsigned i;
|
| - bool freshTouchEvents = true;
|
| - bool allTouchReleased = true;
|
| - for (i = 0; i < points.size(); ++i) {
|
| - const PlatformTouchPoint& point = points[i];
|
| - if (point.state() != PlatformTouchPoint::TouchPressed)
|
| - freshTouchEvents = false;
|
| - if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
|
| - allTouchReleased = false;
|
| - }
|
| - if (freshTouchEvents) {
|
| - // 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();
|
| - }
|
| -
|
| - 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 false;
|
| - }
|
| -
|
| - // First do hit tests for any new touch points.
|
| - for (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(point.pos());
|
| - HitTestResult result;
|
| - if (!m_touchSequenceDocument) {
|
| - result = hitTestResultAtPoint(pagePoint, hitType);
|
| - } else if (m_touchSequenceDocument->frame()) {
|
| - LayoutPoint framePoint = roundedLayoutPoint(point.pos());
|
| - result = hitTestResultInFrame(m_touchSequenceDocument->frame(), framePoint, hitType);
|
| - } else
|
| - continue;
|
| -
|
| - Node* node = result.innerNode();
|
| - if (!node)
|
| - continue;
|
| -
|
| - // Touch events should not go to text nodes
|
| - if (node->isTextNode())
|
| - node = NodeRenderingTraversal::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 = computeEffectiveTouchAction(*node);
|
| - if (effectiveTouchAction != TouchActionAuto)
|
| - m_frame->page()->chrome().client().setTouchAction(effectiveTouchAction);
|
| - }
|
| - }
|
| -
|
| - m_touchPressed = !allTouchReleased;
|
| -
|
| - // If there's no document receiving touch events, then we can skip all the
|
| - // rest of this work.
|
| - if (!m_touchSequenceDocument || !m_touchSequenceDocument->frame()) {
|
| - if (allTouchReleased)
|
| - m_touchSequenceDocument.clear();
|
| - return 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.
|
| - RefPtr<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.
|
| - typedef HashMap<EventTarget*, RefPtr<TouchList> > TargetTouchesHeapMap;
|
| - TargetTouchesHeapMap touchesByTarget;
|
| -
|
| - // Array of touches per state, used to assemble the 'changedTouches' list.
|
| - typedef HashSet<RefPtr<EventTarget> > EventTargetSet;
|
| - struct {
|
| - // The touches corresponding to the particular change state this struct
|
| - // instance represents.
|
| - RefPtr<TouchList> m_touches;
|
| - // Set of targets involved in m_touches.
|
| - EventTargetSet m_targets;
|
| - } changedTouches[PlatformTouchPoint::TouchStateEnd];
|
| -
|
| - for (i = 0; i < points.size(); ++i) {
|
| - const PlatformTouchPoint& point = points[i];
|
| - PlatformTouchPoint::State pointState = point.state();
|
| - RefPtr<EventTarget> touchTarget = nullptr;
|
| -
|
| - 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());
|
| - } else {
|
| - // No hittest is performed on move or stationary, since the target
|
| - // is not allowed to change anyway.
|
| - touchTarget = m_targetForTouchID.get(point.id());
|
| - }
|
| -
|
| - LocalFrame* targetFrame = 0;
|
| - 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);
|
| -
|
| - RefPtr<Touch> touch = Touch::create(
|
| - targetFrame, touchTarget.get(), point.id(), point.screenPos(), point.pos(), point.radius(), point.rotationAngle(), point.force());
|
| -
|
| - // 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(touchTarget.get());
|
| - if (targetTouchesIterator == touchesByTarget.end()) {
|
| - touchesByTarget.set(touchTarget.get(), TouchList::create());
|
| - targetTouchesIterator = touchesByTarget.find(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 && 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(touchTarget);
|
| - }
|
| - }
|
| - if (allTouchReleased)
|
| - m_touchSequenceDocument.clear();
|
| -
|
| - // Now iterate the changedTouches list and m_targets within it, sending
|
| - // events to the targets as required.
|
| - bool swallowedEvent = false;
|
| - for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
|
| - if (!changedTouches[state].m_touches)
|
| - continue;
|
| -
|
| - const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
|
| - const EventTargetSet& targetsForState = changedTouches[state].m_targets;
|
| - for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
|
| - EventTarget* touchEventTarget = it->get();
|
| - RefPtr<TouchEvent> touchEvent = TouchEvent::create(
|
| - touches.get(), touchesByTarget.get(touchEventTarget), changedTouches[state].m_touches.get(),
|
| - stateName, touchEventTarget->toNode()->document().domWindow(),
|
| - event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.cancelable());
|
| - touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
|
| - swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
|
| - }
|
| - }
|
| -
|
| - return swallowedEvent;
|
| -}
|
| -
|
| TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2)
|
| {
|
| if (action1 == TouchActionNone || action2 == TouchActionNone)
|
|
|