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

Unified Diff: third_party/WebKit/Source/core/events/PointerEventManager.cpp

Issue 1670073004: Send node transition events for touch events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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/events/PointerEventManager.cpp
diff --git a/third_party/WebKit/Source/core/events/PointerEventManager.cpp b/third_party/WebKit/Source/core/events/PointerEventManager.cpp
index 3b6414415c80268e86bd483b1aa5feb68b7f78e5..89daa2c60da882dfe17112cb77dc5cf16b5689d8 100644
--- a/third_party/WebKit/Source/core/events/PointerEventManager.cpp
+++ b/third_party/WebKit/Source/core/events/PointerEventManager.cpp
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "core/events/PointerEventManager.h"
+#include "core/dom/shadow/ComposedTreeTraversal.h"
namespace blink {
@@ -26,6 +27,37 @@ const char* pointerTypeNameForWebPointPointerType(WebPointerProperties::PointerT
return "";
}
+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;
+ }
+}
+
+bool isInDocument(EventTarget *n)
+{
+ return n && n->toNode() && n->toNode()->inDocument();
+}
+
+void sendPointerEventToTarget(EventTarget *target,
+ PassRefPtrWillBeRawPtr<PointerEvent> pointerevent)
+{
+ if (isInDocument(target))
+ target->dispatchEvent(pointerevent);
+}
+
} // namespace
const PointerEventManager::MappedId PointerEventManager::s_invalidId = 0;
@@ -89,7 +121,8 @@ PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(const AtomicStr
return PointerEvent::create(type, pointerEventInit);
}
-PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(const AtomicString& type,
+PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(
+ const AtomicString& type,
const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers,
const double width, const double height,
const double clientX, const double clientY)
@@ -126,8 +159,152 @@ PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(const AtomicStr
return PointerEvent::create(type, pointerEventInit);
}
+PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(
+ PassRefPtrWillBeRawPtr<PointerEvent> pointerevent,
+ const AtomicString& type,
+ PassRefPtrWillBeRawPtr<EventTarget> relatedTarget)
+{
+ PointerEventInit pointerEventInit;
+
+ pointerEventInit.setPointerId(pointerevent->pointerId());
+ pointerEventInit.setPointerType(pointerevent->pointerType());
+ pointerEventInit.setIsPrimary(pointerevent->isPrimary());
+ pointerEventInit.setWidth(pointerevent->width());
+ pointerEventInit.setHeight(pointerevent->height());
+ pointerEventInit.setTiltX(pointerevent->tiltX());
+ pointerEventInit.setTiltY(pointerevent->tiltY());
+ pointerEventInit.setScreenX(pointerevent->screenX());
+ pointerEventInit.setScreenY(pointerevent->screenY());
+ pointerEventInit.setClientX(pointerevent->clientX());
+ pointerEventInit.setClientY(pointerevent->clientY());
+ pointerEventInit.setButton(pointerevent->button());
+ pointerEventInit.setButtons(pointerevent->buttons());
+ pointerEventInit.setPressure(pointerevent->pressure());
-PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::createPointerCancel(const PlatformTouchPoint& touchPoint)
+ pointerEventInit.setBubbles(type != EventTypeNames::pointerenter
+ && type != EventTypeNames::pointerleave);
+ pointerEventInit.setCancelable(type != EventTypeNames::pointerenter
+ && type != EventTypeNames::pointerleave
+ && type != EventTypeNames::pointercancel);
+
+ return PointerEvent::create(type, pointerEventInit);
+}
+
+void PointerEventManager::sendNodeTransitionEvents(
mustaq 2016/02/08 17:01:34 This duplication looks bad. All you need here is a
Navid Zolghadr 2016/02/10 16:25:29 Done.
+ EventTarget* exitedTarget, EventTarget* enteredTarget,
+ PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent)
+{
+ if (exitedTarget == enteredTarget)
+ return;
+
+ if (!RuntimeEnabledFeatures::pointerEventEnabled())
+ return;
+
+ // Create lists of all exited/entered ancestors, locate the common ancestor
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors;
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors;
+ if (isInDocument(exitedTarget)) {
+ Node* exitedNode = exitedTarget->toNode();
+ exitedNode->updateDistribution();
+ for (Node* node = exitedNode; node; node = ComposedTreeTraversal::parent(*node))
+ exitedAncestors.append(node);
+ }
+ if (isInDocument(enteredTarget)) {
+ Node* enteredNode = enteredTarget->toNode();
+ enteredNode->updateDistribution();
+ for (Node* node = enteredNode; node; node = ComposedTreeTraversal::parent(*node))
+ enteredAncestors.append(node);
+ }
+
+ size_t exitedAncestorIndex = exitedAncestors.size();
+ size_t enteredAncestorIndex = enteredAncestors.size();
+ if (!exitedAncestors.isEmpty() && !enteredAncestors.isEmpty()) {
+ for (size_t i = exitedAncestors.size(), j = enteredAncestors.size(); i>0 && j>0; j--, i--) {
+ if (exitedAncestors[i-1] == enteredAncestors[j-1]) {
+ exitedAncestorIndex = i-1;
+ enteredAncestorIndex = j-1;
+ } else {
+ break;
+ }
+ }
+ }
+
+ // Dispatch pointerout
+ sendPointerEventToTarget(exitedTarget,
+ create(pointerEvent, EventTypeNames::pointerout, enteredTarget));
+
+ // Dispatch pointerleave events, in child-to-parent order
+ for (size_t i = 0; i < exitedAncestorIndex; i++) {
+ sendPointerEventToTarget(exitedAncestors[i].get(),
+ create(pointerEvent, EventTypeNames::pointerleave, enteredTarget));
+ }
+
+ // Dispatch pointerover
+ sendPointerEventToTarget(enteredTarget,
+ create(pointerEvent, EventTypeNames::pointerover, exitedTarget));
+
+ // Dispatch pointerenter events, in parent-to-child order.
+ for (size_t j = enteredAncestorIndex; j > 0; j--) {
+ sendPointerEventToTarget(enteredAncestors[j-1].get(),
+ create(pointerEvent, EventTypeNames::pointerenter, exitedTarget));
+ }
+}
+
+void PointerEventManager::setNodeUnderPointer(
+ PassRefPtrWillBeRawPtr<PointerEvent> pointerevent, EventTarget* target)
+{
+ if (m_nodeUnderPointer.contains(pointerevent->pointerId())) {
+ sendNodeTransitionEvents(m_nodeUnderPointer.get(
+ pointerevent->pointerId()), target, pointerevent);
+ if (!target)
+ m_nodeUnderPointer.remove(pointerevent->pointerId());
+ else
+ m_nodeUnderPointer.set(pointerevent->pointerId(), target);
+ } else if (target) {
+ sendNodeTransitionEvents(nullptr, target, pointerevent);
+ m_nodeUnderPointer.add(pointerevent->pointerId(), target);
+ }
+}
+
+void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<EventTarget> target,
+ const PlatformTouchPoint& point)
+{
+ RefPtrWillBeRawPtr<PointerEvent> pointerEvent =
+ createPointerCancel(point);
+
+ // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
+ target->dispatchEvent(pointerEvent.get());
+
+ remove(pointerEvent);
+ setNodeUnderPointer(pointerEvent, nullptr);
+}
+
+bool PointerEventManager::sendTouchPointerEvent(
+ PassRefPtrWillBeRawPtr<EventTarget> target,
+ const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers,
+ const double width, const double height,
+ const double clientX, const double clientY)
+{
+ RefPtrWillBeRawPtr<PointerEvent> pointerEvent = create(
+ pointerEventNameForTouchPointState(touchPoint.state()),
+ touchPoint, modifiers, width, height, clientX, clientY);
+
+ setNodeUnderPointer(pointerEvent, target);
+
+ // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing vs pointer event capturing
+ target->dispatchEvent(pointerEvent.get());
+
+ if (touchPoint.state() == PlatformTouchPoint::TouchReleased
+ || touchPoint.state() == PlatformTouchPoint::TouchCancelled) {
+ remove(pointerEvent);
+ setNodeUnderPointer(pointerEvent, nullptr);
+ }
+
+ return pointerEvent->defaultPrevented() || pointerEvent->defaultHandled();
+}
+
+PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::createPointerCancel(
+ const PlatformTouchPoint& touchPoint)
{
PointerEventInit pointerEventInit;
@@ -149,6 +326,11 @@ PointerEventManager::~PointerEventManager()
clear();
}
+DEFINE_TRACE(PointerEventManager)
+{
+ visitor->trace(m_nodeUnderPointer);
+}
+
void PointerEventManager::clear()
{
for (int type = 0; type <= toInt(WebPointerProperties::PointerType::LastEntry); type++) {
@@ -157,6 +339,7 @@ void PointerEventManager::clear()
}
m_idMapping.clear();
m_idReverseMapping.clear();
+ m_nodeUnderPointer.clear();
// Always add mouse pointer in initialization and never remove it.
// No need to add it to m_idMapping as it is not going to be used with the existing APIs

Powered by Google App Engine
This is Rietveld 408576698