Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Unified Diff: third_party/WebKit/Source/core/input/EventHandler.cpp

Issue 1670073004: Send node transition events for touch events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing the comment Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 762216c4c403531efb91c1f103f96da81ce4f2b9..57f4577d006af7968a2fafe51d970e616881287c 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -110,41 +110,6 @@ bool hasTouchHandlers(const EventHandlerRegistry& registry)
|| registry.hasEventHandlers(EventHandlerRegistry::TouchEventPassive);
}
-WebInputEventResult mergeEventResult(WebInputEventResult responseA, WebInputEventResult responseB)
-{
- // The ordering of the enumeration is specific. There are times that
- // multiple events fire and we need to combine them into a single
- // result code. The enumeration is based on the level of consumption that
- // is most significant. The enumeration is ordered with smaller specified
- // numbers first. Examples of merged results are:
- // (HandledApplication, HandledSystem) -> HandledSystem
- // (NotHandled, HandledApplication) -> HandledApplication
- static_assert(static_cast<int>(WebInputEventResult::NotHandled) == 0, "WebInputEventResult not ordered");
- static_assert(static_cast<int>(WebInputEventResult::HandledSuppressed) < static_cast<int>(WebInputEventResult::HandledApplication), "WebInputEventResult not ordered");
- static_assert(static_cast<int>(WebInputEventResult::HandledApplication) < static_cast<int>(WebInputEventResult::HandledSystem), "WebInputEventResult not ordered");
- return static_cast<WebInputEventResult>(max(static_cast<int>(responseA), static_cast<int>(responseB)));
-}
-
-WebInputEventResult eventToEventResult(PassRefPtrWillBeRawPtr<Event> event, bool res)
-{
- if (event->defaultPrevented())
- return WebInputEventResult::HandledApplication;
- if (event->defaultHandled())
- return WebInputEventResult::HandledSystem;
-
- // TODO(dtapuska): There are cases in the code where dispatchEvent
- // returns false (indicated handled) but event is not marked
- // as default handled or default prevented. crbug.com/560355
- if (!res)
- return WebInputEventResult::HandledSuppressed;
- return WebInputEventResult::NotHandled;
-}
-
-bool isNodeInDocument(Node* n)
-{
- return n && n->inDocument();
-}
-
const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::State state)
{
switch (state) {
@@ -164,46 +129,6 @@ const AtomicString& touchEventNameForTouchPointState(PlatformTouchPoint::State s
}
}
-const AtomicString& pointerEventNameForTouchPointState(PlatformTouchPoint::State state)
-{
- switch (state) {
- case PlatformTouchPoint::TouchReleased:
- return EventTypeNames::pointerup;
- case PlatformTouchPoint::TouchCancelled:
- return EventTypeNames::pointercancel;
- case PlatformTouchPoint::TouchPressed:
- return EventTypeNames::pointerdown;
- case PlatformTouchPoint::TouchMoved:
- return EventTypeNames::pointermove;
- case PlatformTouchPoint::TouchStationary:
- // Fall through to default
- default:
- ASSERT_NOT_REACHED();
- return emptyAtom;
- }
-}
-
-const AtomicString& pointerEventNameForMouseEventName(const AtomicString& mouseEventName)
-{
-#define RETURN_CORRESPONDING_PE_NAME(eventSuffix) \
- if (mouseEventName == EventTypeNames::mouse##eventSuffix) {\
- return EventTypeNames::pointer##eventSuffix;\
- }
-
- RETURN_CORRESPONDING_PE_NAME(down);
- RETURN_CORRESPONDING_PE_NAME(enter);
- RETURN_CORRESPONDING_PE_NAME(leave);
- RETURN_CORRESPONDING_PE_NAME(move);
- RETURN_CORRESPONDING_PE_NAME(out);
- RETURN_CORRESPONDING_PE_NAME(over);
- RETURN_CORRESPONDING_PE_NAME(up);
-
-#undef RETURN_CORRESPONDING_PE_NAME
-
- ASSERT_NOT_REACHED();
- return emptyAtom;
-}
-
} // namespace
using namespace HTMLNames;
@@ -333,7 +258,6 @@ EventHandler::EventHandler(LocalFrame* frame)
, m_mousePositionIsUnknown(true)
, m_mouseDownTimestamp(0)
, m_touchPressed(false)
- , m_preventMouseEventForPointerTypeMouse(false)
, m_inPointerCanceledState(false)
, m_scrollGestureHandlingNode(nullptr)
, m_lastGestureScrollOverWidget(false)
@@ -370,6 +294,7 @@ DEFINE_TRACE(EventHandler)
visitor->trace(m_previousGestureScrolledNode);
visitor->trace(m_lastDeferredTapElement);
visitor->trace(m_selectionController);
+ visitor->trace(m_pointerEventManager);
#endif
}
@@ -411,7 +336,6 @@ void EventHandler::clear()
m_scrollbarHandlingScrollGesture = nullptr;
m_touchPressed = false;
m_pointerEventManager.clear();
- m_preventMouseEventForPointerTypeMouse = false;
m_inPointerCanceledState = false;
m_mouseDownMayStartDrag = false;
m_lastShowPressTimestamp = 0;
@@ -427,6 +351,38 @@ void EventHandler::clear()
m_mouseDown = PlatformMouseEvent();
}
+WebInputEventResult EventHandler::mergeEventResult(
+ WebInputEventResult resultA, WebInputEventResult resultB)
+{
+ // The ordering of the enumeration is specific. There are times that
+ // multiple events fire and we need to combine them into a single
+ // result code. The enumeration is based on the level of consumption that
+ // is most significant. The enumeration is ordered with smaller specified
+ // numbers first. Examples of merged results are:
+ // (HandledApplication, HandledSystem) -> HandledSystem
+ // (NotHandled, HandledApplication) -> HandledApplication
+ static_assert(static_cast<int>(WebInputEventResult::NotHandled) == 0, "WebInputEventResult not ordered");
+ static_assert(static_cast<int>(WebInputEventResult::HandledSuppressed) < static_cast<int>(WebInputEventResult::HandledApplication), "WebInputEventResult not ordered");
+ static_assert(static_cast<int>(WebInputEventResult::HandledApplication) < static_cast<int>(WebInputEventResult::HandledSystem), "WebInputEventResult not ordered");
+ return static_cast<WebInputEventResult>(max(static_cast<int>(resultA), static_cast<int>(resultB)));
+}
+
+WebInputEventResult EventHandler::eventToEventResult(
+ PassRefPtrWillBeRawPtr<Event> event, bool result)
+{
+ if (event->defaultPrevented())
+ return WebInputEventResult::HandledApplication;
+ if (event->defaultHandled())
+ return WebInputEventResult::HandledSystem;
+
+ // TODO(dtapuska): There are cases in the code where dispatchEvent
+ // returns false (indicated handled) but event is not marked
+ // as default handled or default prevented. crbug.com/560355
+ if (!result)
+ return WebInputEventResult::HandledSuppressed;
+ return WebInputEventResult::NotHandled;
+}
+
void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
{
if (nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get())) {
@@ -1150,7 +1106,8 @@ WebInputEventResult EventHandler::handleMouseMoveEvent(const PlatformMouseEvent&
{
TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent");
- conditionallyEnableMouseEventForPointerTypeMouse(event);
+ m_pointerEventManager.conditionallyEnableMouseEventForPointerTypeMouse(
+ event.modifiers());
RefPtrWillBeRawPtr<FrameView> protector(m_frame->view());
@@ -1179,7 +1136,8 @@ void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event)
{
TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent");
- conditionallyEnableMouseEventForPointerTypeMouse(event);
+ m_pointerEventManager.conditionallyEnableMouseEventForPointerTypeMouse(
+ event.modifiers());
RefPtrWillBeRawPtr<FrameView> protector(m_frame->view());
handleMouseMoveOrLeaveEvent(event, 0, false, true);
@@ -1363,7 +1321,8 @@ WebInputEventResult EventHandler::handleMouseReleaseEvent(const PlatformMouseEve
WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(EventTypeNames::mouseup, mev.innerNode(), m_clickCount, mouseEvent);
// TODO(crbug/545647): This state should reset with pointercancel too.
- m_preventMouseEventForPointerTypeMouse = false;
+ m_pointerEventManager.conditionallyEnableMouseEventForPointerTypeMouse(
+ PlatformEvent::NoModifiers);
bool contextMenuEvent = mouseEvent.button() == RightButton;
#if OS(MACOSX)
@@ -1649,108 +1608,8 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
m_lastScrollbarUnderMouse = nullptr;
}
- if (lastNodeUnderMouse != m_nodeUnderMouse)
- sendNodeTransitionEvents(lastNodeUnderMouse.get(), m_nodeUnderMouse.get(), mouseEvent);
-}
-
-WebInputEventResult EventHandler::dispatchPointerEvent(EventTarget* target, PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent)
-{
- if (!RuntimeEnabledFeatures::pointerEventEnabled())
- return WebInputEventResult::NotHandled;
-
- bool dispatchResult = target->dispatchEvent(pointerEvent.get());
- return eventToEventResult(pointerEvent, dispatchResult);
-}
-
-void EventHandler::sendNodeTransitionEvents(Node* exitedNode, Node* enteredNode,
- const PlatformMouseEvent& mouseEvent)
-{
- ASSERT(exitedNode != enteredNode);
-
- // Dispatch pointerout/mouseout events
- if (isNodeInDocument(exitedNode)) {
- sendPointerAndMouseTransitionEvents(exitedNode, EventTypeNames::mouseout, mouseEvent, enteredNode, false);
- }
-
- // A note on mouseenter and mouseleave: These are non-bubbling events, and they are dispatched if there
- // is a capturing event handler on an ancestor or a normal event handler on the element itself. This special
- // handling is necessary to avoid O(n^2) capturing event handler checks.
- //
- // Note, however, that this optimization can possibly cause some unanswered/missing/redundant mouseenter or
- // mouseleave events in certain contrived eventhandling scenarios, e.g., when:
- // - the mouseleave handler for a node sets the only capturing-mouseleave-listener in its ancestor, or
- // - DOM mods in any mouseenter/mouseleave handler changes the common ancestor of exited & entered nodes, etc.
- // We think the spec specifies a "frozen" state to avoid such corner cases (check the discussion on "candidate event
- // listeners" at http://www.w3.org/TR/uievents), but our code below preserves one such behavior from past only to
- // match Firefox and IE behavior.
- //
- // TODO(mustaq): Confirm spec conformance, double-check with other browsers.
-
- // Create lists of all exited/entered ancestors, locate the common ancestor & capturing listeners.
- WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors;
- WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors;
- if (isNodeInDocument(exitedNode)) {
- exitedNode->updateDistribution();
- for (Node* node = exitedNode; node; node = FlatTreeTraversal::parent(*node)) {
- exitedAncestors.append(node);
- }
- }
- if (isNodeInDocument(enteredNode)) {
- enteredNode->updateDistribution();
- for (Node* node = enteredNode; node; node = FlatTreeTraversal::parent(*node)) {
- enteredAncestors.append(node);
- }
- }
-
- size_t numExitedAncestors = exitedAncestors.size();
- size_t numEnteredAncestors = enteredAncestors.size();
-
- size_t exitedAncestorIndex = numExitedAncestors;
- size_t enteredAncestorIndex = numEnteredAncestors;
- for (size_t j = 0; j < numExitedAncestors; j++) {
- for (size_t i = 0; i < numEnteredAncestors; i++) {
- if (exitedAncestors[j] == enteredAncestors[i]) {
- exitedAncestorIndex = j;
- enteredAncestorIndex = i;
- break;
- }
- }
- if (exitedAncestorIndex < numExitedAncestors)
- break;
- }
-
- bool exitedNodeHasCapturingAncestor = false;
- for (size_t j = 0; j < numExitedAncestors; j++) {
- if (exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::mouseleave)
- || (RuntimeEnabledFeatures::pointerEventEnabled()
- && exitedAncestors[j]->hasCapturingEventListeners(EventTypeNames::pointerleave)))
- exitedNodeHasCapturingAncestor = true;
- }
-
- // Dispatch pointerleave/mouseleave events, in child-to-parent order.
- for (size_t j = 0; j < exitedAncestorIndex; j++) {
- sendPointerAndMouseTransitionEvents(exitedAncestors[j].get(), EventTypeNames::mouseleave, mouseEvent, enteredNode, !exitedNodeHasCapturingAncestor);
- }
-
- // Dispatch pointerover/mouseover.
- if (isNodeInDocument(enteredNode)) {
- sendPointerAndMouseTransitionEvents(enteredNode, EventTypeNames::mouseover, mouseEvent, exitedNode, false);
- }
-
- // Defer locating capturing pointeenter/mouseenter listener until /after/ dispatching the leave events because
- // the leave handlers might set a capturing enter handler.
- bool enteredNodeHasCapturingAncestor = false;
- for (size_t i = 0; i < numEnteredAncestors; i++) {
- if (enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::mouseenter)
- || (RuntimeEnabledFeatures::pointerEventEnabled()
- && enteredAncestors[i]->hasCapturingEventListeners(EventTypeNames::pointerenter)))
- enteredNodeHasCapturingAncestor = true;
- }
-
- // Dispatch pointerenter/mouseenter events, in parent-to-child order.
- for (size_t i = enteredAncestorIndex; i > 0; i--) {
- sendPointerAndMouseTransitionEvents(enteredAncestors[i-1].get(), EventTypeNames::mouseenter, mouseEvent, exitedNode, !enteredNodeHasCapturingAncestor);
- }
+ m_pointerEventManager.sendNodeTransitionEvents(lastNodeUnderMouse,
+ m_nodeUnderMouse, mouseEvent, m_frame->document()->domWindow());
}
WebInputEventResult EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent)
@@ -1764,38 +1623,6 @@ WebInputEventResult EventHandler::dispatchMouseEvent(const AtomicString& eventTy
return eventToEventResult(event, dispatchResult);
}
-EventTarget* EventHandler::getEffectiveTargetForPointerEvent(
- EventTarget* target, PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent)
-{
- EventTarget* capturingNode = m_pointerEventManager.getCapturingNode(pointerEvent.get());
- if (capturingNode)
- target = capturingNode;
- return target;
-}
-
-void EventHandler::sendPointerAndMouseTransitionEvents(Node* target, const AtomicString& mouseEventType,
- const PlatformMouseEvent& mouseEvent, Node* relatedTarget, bool checkForListener)
-{
- ASSERT(mouseEventType == EventTypeNames::mouseenter
- || mouseEventType == EventTypeNames::mouseleave
- || mouseEventType == EventTypeNames::mouseover
- || mouseEventType == EventTypeNames::mouseout);
-
- AtomicString pointerEventType = pointerEventNameForMouseEventName(mouseEventType);
- RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.create(pointerEventType,
- mouseEvent, relatedTarget, m_frame->document()->domWindow());
-
- // Suppress these events if the target is not the capturing element
- if (target != getEffectiveTargetForPointerEvent(target, pointerEvent))
- return;
-
- if (!checkForListener || target->hasEventListeners(pointerEventType))
- dispatchPointerEvent(target, pointerEvent);
-
- if (!checkForListener || target->hasEventListeners(mouseEventType))
- target->dispatchMouseEvent(mouseEvent, mouseEventType, 0, relatedTarget);
-}
-
// TODO(mustaq): Make PE drive ME dispatch & bookkeeping in EventHandler.
WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const AtomicString& mouseEventType, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent)
{
@@ -1807,28 +1634,9 @@ WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const Ato
if (!m_nodeUnderMouse)
return WebInputEventResult::NotHandled;
- AtomicString pointerEventType = pointerEventNameForMouseEventName(mouseEventType);
- unsigned short pointerButtonsPressed = MouseEvent::platformModifiersToButtons(mouseEvent.modifiers());
-
- // Make sure chorded buttons fire pointermove instead of pointerup/pointerdown.
- if ((pointerEventType == EventTypeNames::pointerdown && (pointerButtonsPressed & ~MouseEvent::buttonToButtons(mouseEvent.button())) != 0)
- || (pointerEventType == EventTypeNames::pointerup && pointerButtonsPressed != 0))
- pointerEventType = EventTypeNames::pointermove;
-
- RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.create(pointerEventType,
- mouseEvent, nullptr, m_frame->document()->domWindow());
-
- EventTarget* target = getEffectiveTargetForPointerEvent(m_nodeUnderMouse.get(), pointerEvent);
- WebInputEventResult result = dispatchPointerEvent(target, pointerEvent);
-
- if (result != WebInputEventResult::NotHandled && pointerEventType == EventTypeNames::pointerdown)
- m_preventMouseEventForPointerTypeMouse = true;
-
- if (!m_preventMouseEventForPointerTypeMouse) {
- RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(mouseEventType, m_nodeUnderMouse->document().domWindow(), mouseEvent, clickCount, nullptr);
- bool dispatchResult = target->dispatchEvent(event);
- result = mergeEventResult(result, eventToEventResult(event, dispatchResult));
- }
+ WebInputEventResult result = m_pointerEventManager.sendMousePointerEvent(
+ m_nodeUnderMouse, mouseEventType, clickCount, mouseEvent, nullptr,
+ m_frame->document()->domWindow());
return result;
}
@@ -3743,29 +3551,18 @@ void EventHandler::dispatchPointerEvents(const PlatformTouchEvent& event,
for (unsigned i = 0; i < touchInfos.size(); ++i) {
TouchInfo& touchInfo = touchInfos[i];
const PlatformTouchPoint& touchPoint = touchInfo.point;
- const PlatformTouchPoint::State pointState = touchPoint.state();
- if (pointState == PlatformTouchPoint::TouchStationary || !touchInfo.knownTarget)
+ if (touchPoint.state() == PlatformTouchPoint::TouchStationary
+ || !touchInfo.knownTarget)
continue;
- bool pointerReleasedOrCancelled = pointState == PlatformTouchPoint::TouchReleased
- || pointState == PlatformTouchPoint::TouchCancelled;
-
- RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.create(
- pointerEventNameForTouchPointState(pointState),
- touchPoint, event.modifiers(),
+ WebInputEventResult result =
+ m_pointerEventManager.sendTouchPointerEvent(
+ touchInfo.touchTarget, touchPoint, event.modifiers(),
touchInfo.adjustedRadius.width(), touchInfo.adjustedRadius.height(),
touchInfo.adjustedPagePoint.x(), touchInfo.adjustedPagePoint.y());
-
- // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
- touchInfo.touchTarget->dispatchEvent(pointerEvent.get());
-
- touchInfo.consumed = pointerEvent->defaultPrevented() || pointerEvent->defaultHandled();
-
- // Remove the released/cancelled id at the end to correctly determine primary id above.
- if (pointerReleasedOrCancelled)
- m_pointerEventManager.remove(pointerEvent);
+ touchInfo.consumed = result != WebInputEventResult::NotHandled;
}
}
@@ -3783,12 +3580,9 @@ void EventHandler::sendPointerCancels(WillBeHeapVector<TouchInfo>& touchInfos)
|| pointState == PlatformTouchPoint::TouchCancelled)
continue;
- RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventManager.createPointerCancel(point);
-
- // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
- touchInfo.touchTarget->dispatchEvent(pointerEvent.get());
-
- m_pointerEventManager.remove(pointerEvent);
+ m_pointerEventManager.sendTouchCancelPointerEvent(
+ touchInfo.touchTarget,
+ point);
}
}
@@ -4116,12 +3910,6 @@ void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
m_lastKnownMouseGlobalPosition = event.globalPosition();
}
-void EventHandler::conditionallyEnableMouseEventForPointerTypeMouse(const PlatformMouseEvent& event)
-{
- if (event.button() == NoButton)
- m_preventMouseEventForPointerTypeMouse = false;
-}
-
WebInputEventResult EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe)
{
selectionController().passMousePressEventToSubframe(mev);
« no previous file with comments | « third_party/WebKit/Source/core/input/EventHandler.h ('k') | third_party/WebKit/Source/core/input/PointerEventManager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698