| Index: third_party/WebKit/Source/core/input/PointerEventManager.cpp
|
| diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
|
| index 7e47ca1262db223305a146c552435bad1dd47e56..5a18188771175f635344fb342c9b6c0b0ac91bbf 100644
|
| --- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp
|
| +++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
|
| @@ -46,7 +46,7 @@ WebInputEventResult dispatchMouseEvent(
|
| {
|
| RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
|
| RefPtrWillBeRawPtr<EventTarget> relatedTarget = prpRelatedTarget;
|
| - if (target->toNode()
|
| + if (target && target->toNode()
|
| && (!checkForListener || target->hasEventListeners(mouseEventType))) {
|
| RefPtrWillBeRawPtr<Node> targetNode = target->toNode();
|
| RefPtrWillBeRawPtr<MouseEvent> event = MouseEvent::create(mouseEventType,
|
| @@ -68,6 +68,9 @@ WebInputEventResult PointerEventManager::dispatchPointerEvent(
|
| RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
|
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
|
|
|
| + if (!target)
|
| + return WebInputEventResult::NotHandled;
|
| +
|
| // Set whether node under pointer has received pointerover or not.
|
| const int pointerId = pointerEvent->pointerId();
|
| const AtomicString& eventType = pointerEvent->type();
|
| @@ -83,19 +86,6 @@ WebInputEventResult PointerEventManager::dispatchPointerEvent(
|
| }
|
| }
|
|
|
| - // TODO(crbug.com/587955): The following is a hack to work around this bug
|
| - if (pointerId == 1) {
|
| - if (eventType == EventTypeNames::pointerover) {
|
| - m_nodeUnderPointer.set(pointerId, EventTargetAttributes
|
| - (target, true));
|
| - }
|
| - if (eventType == EventTypeNames::pointerout
|
| - && m_nodeUnderPointer.get(pointerId).target == target) {
|
| - m_nodeUnderPointer.set(pointerId, EventTargetAttributes
|
| - (target, false));
|
| - }
|
| - }
|
| -
|
| if (!RuntimeEnabledFeatures::pointerEventEnabled())
|
| return WebInputEventResult::NotHandled;
|
| if (!checkForListener || target->hasEventListeners(eventType)) {
|
| @@ -113,23 +103,29 @@ PassRefPtrWillBeRawPtr<EventTarget> PointerEventManager::getEffectiveTargetForPo
|
| return target;
|
| }
|
|
|
| -// Sends node transition events (pointer|mouse)(out|leave|over|enter) to the corresponding targets
|
| -void PointerEventManager::sendNodeTransitionEvents(
|
| - PassRefPtrWillBeRawPtr<Node> prpExitedNode,
|
| - PassRefPtrWillBeRawPtr<Node> prpEnteredNode,
|
| +void PointerEventManager::sendMouseAndPossiblyPointerNodeTransitionEvents(
|
| + PassRefPtrWillBeRawPtr<Node> exitedNode,
|
| + PassRefPtrWillBeRawPtr<Node> enteredNode,
|
| const PlatformMouseEvent& mouseEvent,
|
| - PassRefPtrWillBeRawPtr<AbstractView> view)
|
| + PassRefPtrWillBeRawPtr<AbstractView> view,
|
| + bool isFrameBoundaryTransition)
|
| {
|
| - RefPtrWillBeRawPtr<Node> exitedNode = prpExitedNode;
|
| - RefPtrWillBeRawPtr<Node> enteredNode = prpEnteredNode;
|
| + // Pointer event type does not matter as it will be overridden in the sendNodeTransitionEvents
|
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
|
| m_pointerEventFactory.create(EventTypeNames::mouseout, mouseEvent,
|
| nullptr, view);
|
| - processPendingPointerCapture(pointerEvent, enteredNode, mouseEvent, true);
|
|
|
| - // Pointer event type does not matter as it will be overridden in the sendNodeTransitionEvents
|
| - sendNodeTransitionEvents(exitedNode, enteredNode, pointerEvent, mouseEvent,
|
| - true);
|
| + // TODO(crbug/545647): This state should reset with pointercancel too.
|
| + // This function also gets called for compat mouse events of touch at this
|
| + // stage. So if the event is not frame boundary transition it is only a
|
| + // compatibility mouse event and we do not need to change pointer event
|
| + // behavior regarding preventMouseEvent state in that case.
|
| + if (isFrameBoundaryTransition && pointerEvent->buttons() == 0) {
|
| + m_preventMouseEventForPointerTypeMouse = false;
|
| + }
|
| +
|
| + processCaptureAndPositionOfPointerEvent(pointerEvent, enteredNode,
|
| + exitedNode, mouseEvent, true, isFrameBoundaryTransition);
|
| }
|
|
|
| void PointerEventManager::sendNodeTransitionEvents(
|
| @@ -141,6 +137,7 @@ void PointerEventManager::sendNodeTransitionEvents(
|
| RefPtrWillBeRawPtr<EventTarget> exitedTarget = prpExitedTarget;
|
| RefPtrWillBeRawPtr<EventTarget> enteredTarget = prpEnteredTarget;
|
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
|
| +
|
| if (exitedTarget == enteredTarget)
|
| return;
|
|
|
| @@ -155,9 +152,10 @@ void PointerEventManager::sendNodeTransitionEvents(
|
|
|
| // Dispatch pointerout/mouseout events
|
| if (isInDocument(exitedTarget)) {
|
| - dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPointerTransitionEvent(
|
| - pointerEvent, EventTypeNames::pointerout, enteredTarget));
|
| - if (sendMouseEvent) {
|
| + if (!sendMouseEvent) {
|
| + dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPointerTransitionEvent(
|
| + pointerEvent, EventTypeNames::pointerout, enteredTarget));
|
| + } else {
|
| dispatchMouseEvent(exitedTarget,
|
| EventTypeNames::mouseout, mouseEvent, enteredTarget);
|
| }
|
| @@ -221,11 +219,12 @@ void PointerEventManager::sendNodeTransitionEvents(
|
|
|
| // Dispatch pointerleave/mouseleave events, in child-to-parent order.
|
| for (size_t j = 0; j < exitedAncestorIndex; j++) {
|
| - dispatchPointerEvent(exitedAncestors[j].get(),
|
| - m_pointerEventFactory.createPointerTransitionEvent(
|
| - pointerEvent, EventTypeNames::pointerleave, enteredTarget),
|
| - !exitedNodeHasCapturingAncestor);
|
| - if (sendMouseEvent) {
|
| + if (!sendMouseEvent) {
|
| + dispatchPointerEvent(exitedAncestors[j].get(),
|
| + m_pointerEventFactory.createPointerTransitionEvent(
|
| + pointerEvent, EventTypeNames::pointerleave, enteredTarget),
|
| + !exitedNodeHasCapturingAncestor);
|
| + } else {
|
| dispatchMouseEvent(exitedAncestors[j].get(),
|
| EventTypeNames::mouseleave, mouseEvent, enteredTarget,
|
| 0, !exitedNodeHasCapturingAncestor);
|
| @@ -234,9 +233,10 @@ void PointerEventManager::sendNodeTransitionEvents(
|
|
|
| // Dispatch pointerover/mouseover.
|
| if (isInDocument(enteredTarget)) {
|
| - dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPointerTransitionEvent(
|
| - pointerEvent, EventTypeNames::pointerover, exitedTarget));
|
| - if (sendMouseEvent) {
|
| + if (!sendMouseEvent) {
|
| + dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPointerTransitionEvent(
|
| + pointerEvent, EventTypeNames::pointerover, exitedTarget));
|
| + } else {
|
| dispatchMouseEvent(enteredTarget,
|
| EventTypeNames::mouseover, mouseEvent, exitedTarget);
|
| }
|
| @@ -254,11 +254,12 @@ void PointerEventManager::sendNodeTransitionEvents(
|
|
|
| // Dispatch pointerenter/mouseenter events, in parent-to-child order.
|
| for (size_t i = enteredAncestorIndex; i > 0; i--) {
|
| - dispatchPointerEvent(enteredAncestors[i-1].get(),
|
| - m_pointerEventFactory.createPointerTransitionEvent(
|
| - pointerEvent, EventTypeNames::pointerenter, exitedTarget),
|
| - !enteredNodeHasCapturingAncestor);
|
| - if (sendMouseEvent) {
|
| + if (!sendMouseEvent) {
|
| + dispatchPointerEvent(enteredAncestors[i-1].get(),
|
| + m_pointerEventFactory.createPointerTransitionEvent(
|
| + pointerEvent, EventTypeNames::pointerenter, exitedTarget),
|
| + !enteredNodeHasCapturingAncestor);
|
| + } else {
|
| dispatchMouseEvent(enteredAncestors[i-1].get(),
|
| EventTypeNames::mouseenter, mouseEvent, exitedTarget,
|
| 0, !enteredNodeHasCapturingAncestor);
|
| @@ -268,7 +269,8 @@ void PointerEventManager::sendNodeTransitionEvents(
|
|
|
| void PointerEventManager::setNodeUnderPointer(
|
| PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
|
| - PassRefPtrWillBeRawPtr<EventTarget> prpTarget)
|
| + PassRefPtrWillBeRawPtr<EventTarget> prpTarget,
|
| + bool sendEvent)
|
| {
|
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
|
| RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
|
| @@ -282,11 +284,13 @@ void PointerEventManager::setNodeUnderPointer(
|
| m_nodeUnderPointer.set(pointerEvent->pointerId(),
|
| EventTargetAttributes(target, false));
|
| }
|
| - sendNodeTransitionEvents(node.target, target, pointerEvent);
|
| + if (sendEvent)
|
| + sendNodeTransitionEvents(node.target, target, pointerEvent);
|
| } else if (target) {
|
| m_nodeUnderPointer.add(pointerEvent->pointerId(),
|
| EventTargetAttributes(target, false));
|
| - sendNodeTransitionEvents(nullptr, target, pointerEvent);
|
| + if (sendEvent)
|
| + sendNodeTransitionEvents(nullptr, target, pointerEvent);
|
| }
|
| }
|
|
|
| @@ -295,7 +299,8 @@ void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<Eve
|
| RefPtrWillBeRawPtr<EventTarget> target = prpTarget;
|
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent = m_pointerEventFactory.createPointerCancelEvent(point);
|
|
|
| - processPendingPointerCapture(pointerEvent, target);
|
| +
|
| + processCaptureAndPositionOfPointerEvent(pointerEvent, target);
|
|
|
| // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
|
| dispatchPointerEvent(
|
| @@ -320,9 +325,7 @@ WebInputEventResult PointerEventManager::sendTouchPointerEvent(
|
| pointerEventNameForTouchPointState(touchPoint.state()),
|
| touchPoint, modifiers, width, height, clientX, clientY);
|
|
|
| - processPendingPointerCapture(pointerEvent, target);
|
| -
|
| - setNodeUnderPointer(pointerEvent, target);
|
| + processCaptureAndPositionOfPointerEvent(pointerEvent, target);
|
|
|
| // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
|
| WebInputEventResult result = dispatchPointerEvent(
|
| @@ -342,18 +345,23 @@ WebInputEventResult PointerEventManager::sendMousePointerEvent(
|
| PassRefPtrWillBeRawPtr<Node> prpTarget, const AtomicString& mouseEventType,
|
| int clickCount, const PlatformMouseEvent& mouseEvent,
|
| PassRefPtrWillBeRawPtr<Node> relatedTarget,
|
| - PassRefPtrWillBeRawPtr<AbstractView> view)
|
| + PassRefPtrWillBeRawPtr<AbstractView> view,
|
| + PassRefPtrWillBeRawPtr<Node> lastNodeUnderMouse)
|
| {
|
| RefPtrWillBeRawPtr<Node> target = prpTarget;
|
| +
|
| RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
|
| m_pointerEventFactory.create(mouseEventType, mouseEvent,
|
| relatedTarget, view);
|
|
|
| - processPendingPointerCapture(pointerEvent, target, mouseEvent, true);
|
| + // This is for when the mouse is released outside of the page.
|
| + if (pointerEvent->type() == EventTypeNames::pointermove
|
| + && !pointerEvent->buttons()) {
|
| + m_preventMouseEventForPointerTypeMouse = false;
|
| + }
|
|
|
| - // TODO(crbug.com/587955): We should call setNodeUnderPointer here but it causes sending
|
| - // transition events that should be first removed from EventHandler.
|
| - // setNodeUnderPointer(pointerEvent, target);
|
| + processCaptureAndPositionOfPointerEvent(pointerEvent, target,
|
| + lastNodeUnderMouse, mouseEvent, true, true);
|
|
|
| RefPtrWillBeRawPtr<EventTarget> effectiveTarget =
|
| getEffectiveTargetForPointerEvent(target, pointerEvent->pointerId());
|
| @@ -371,8 +379,10 @@ WebInputEventResult PointerEventManager::sendMousePointerEvent(
|
| nullptr, clickCount));
|
| }
|
|
|
| - if (pointerEvent->buttons() == 0)
|
| + if (pointerEvent->buttons() == 0) {
|
| releasePointerCapture(pointerEvent->pointerId());
|
| + m_preventMouseEventForPointerTypeMouse = false;
|
| + }
|
|
|
| return result;
|
| }
|
| @@ -393,16 +403,33 @@ void PointerEventManager::clear()
|
| m_nodeUnderPointer.clear();
|
| }
|
|
|
| -void PointerEventManager::conditionallyEnableMouseEventForPointerTypeMouse(
|
| - unsigned modifiers)
|
| +void PointerEventManager::processCaptureAndPositionOfPointerEvent(
|
| + const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
|
| + const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget,
|
| + const PassRefPtrWillBeRawPtr<EventTarget> lastNodeUnderMouse,
|
| + const PlatformMouseEvent& mouseEvent,
|
| + bool sendMouseEvent, bool setPointerPosition)
|
| {
|
| -
|
| - if (MouseEvent::platformModifiersToButtons(modifiers) ==
|
| - static_cast<unsigned short>(MouseEvent::Buttons::None))
|
| - m_preventMouseEventForPointerTypeMouse = false;
|
| + RefPtrWillBeRawPtr<PointerEvent> pointerEvent = prpPointerEvent;
|
| + RefPtrWillBeRawPtr<EventTarget> hitTestTarget = prpHitTestTarget;
|
| + bool isCaptureChanged = false;
|
| +
|
| + if (setPointerPosition) {
|
| + isCaptureChanged = processPendingPointerCapture(pointerEvent,
|
| + hitTestTarget, mouseEvent, sendMouseEvent);
|
| + // If there was a change in capturing processPendingPointerCapture has
|
| + // already taken care of transition events. So we don't need to send the
|
| + // transition events here.
|
| + setNodeUnderPointer(pointerEvent, hitTestTarget, !isCaptureChanged);
|
| + }
|
| + if (sendMouseEvent && !isCaptureChanged) {
|
| + // lastNodeUnderMouse is needed here because it is still stored in EventHandler.
|
| + sendNodeTransitionEvents(lastNodeUnderMouse, hitTestTarget,
|
| + pointerEvent, mouseEvent, true);
|
| + }
|
| }
|
|
|
| -void PointerEventManager::processPendingPointerCapture(
|
| +bool PointerEventManager::processPendingPointerCapture(
|
| const PassRefPtrWillBeRawPtr<PointerEvent> prpPointerEvent,
|
| const PassRefPtrWillBeRawPtr<EventTarget> prpHitTestTarget,
|
| const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
|
| @@ -419,10 +446,20 @@ void PointerEventManager::processPendingPointerCapture(
|
| const EventTargetAttributes &nodeUnderPointerAtt =
|
| m_nodeUnderPointer.contains(pointerId)
|
| ? m_nodeUnderPointer.get(pointerId) : EventTargetAttributes();
|
| + const bool isCaptureChanged =
|
| + pointerCaptureTarget != pendingPointerCaptureTarget;
|
|
|
| - if (pointerCaptureTarget != pendingPointerCaptureTarget) {
|
| - if (pendingPointerCaptureTarget != nodeUnderPointerAtt.target
|
| + if (isCaptureChanged) {
|
| + if ((hitTestTarget != nodeUnderPointerAtt.target
|
| + || (pendingPointerCaptureTarget
|
| + && pendingPointerCaptureTarget != nodeUnderPointerAtt.target))
|
| && nodeUnderPointerAtt.hasRecievedOverEvent) {
|
| + if (sendMouseEvent) {
|
| + // Send pointer event transitions as the line after this if
|
| + // block sends the mouse events
|
| + sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr,
|
| + pointerEvent);
|
| + }
|
| sendNodeTransitionEvents(nodeUnderPointerAtt.target, nullptr,
|
| pointerEvent, mouseEvent, sendMouseEvent);
|
| }
|
| @@ -434,11 +471,9 @@ void PointerEventManager::processPendingPointerCapture(
|
| && !target->toNode()->inDocument()) {
|
| target = target->toNode()->ownerDocument();
|
| }
|
| - if (target) {
|
| - dispatchPointerEvent(target,
|
| - m_pointerEventFactory.createPointerCaptureEvent(
|
| - pointerEvent, EventTypeNames::lostpointercapture));
|
| - }
|
| + dispatchPointerEvent(target,
|
| + m_pointerEventFactory.createPointerCaptureEvent(
|
| + pointerEvent, EventTypeNames::lostpointercapture));
|
| }
|
| }
|
|
|
| @@ -451,20 +486,24 @@ void PointerEventManager::processPendingPointerCapture(
|
| else
|
| m_pointerCaptureTarget.remove(pointerId);
|
|
|
| - if (pointerCaptureTarget != pendingPointerCaptureTarget) {
|
| - if (pendingPointerCaptureTarget) {
|
| - dispatchPointerEvent(pendingPointerCaptureTarget,
|
| - m_pointerEventFactory.createPointerCaptureEvent(
|
| - pointerEvent, EventTypeNames::gotpointercapture));
|
| - }
|
| + if (isCaptureChanged) {
|
| + dispatchPointerEvent(pendingPointerCaptureTarget,
|
| + m_pointerEventFactory.createPointerCaptureEvent(
|
| + pointerEvent, EventTypeNames::gotpointercapture));
|
| if ((pendingPointerCaptureTarget == hitTestTarget
|
| || !pendingPointerCaptureTarget)
|
| && (nodeUnderPointerAtt.target != hitTestTarget
|
| || !nodeUnderPointerAtt.hasRecievedOverEvent)) {
|
| + if (sendMouseEvent) {
|
| + // Send pointer event transitions as the line after this if
|
| + // block sends the mouse events
|
| + sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent);
|
| + }
|
| sendNodeTransitionEvents(nullptr, hitTestTarget, pointerEvent,
|
| mouseEvent, sendMouseEvent);
|
| }
|
| }
|
| + return isCaptureChanged;
|
| }
|
|
|
| void PointerEventManager::removeTargetFromPointerCapturingMapping(
|
|
|