Chromium Code Reviews| 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..1f753a81285f1d230c043157f63b46935b949e34 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); |
|
mustaq
2016/02/11 19:11:31
I added it before chorded button support, should h
Navid Zolghadr
2016/02/11 19:17:24
I will file a bug for that one and fix that in ano
|
| 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.get(), 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); |