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

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

Issue 2255323004: Create MouseEventManager and EventHandlingUtil (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebasing Created 4 years, 3 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/PointerEventManager.cpp
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
index 6eced7f17500571408547a5e1b34d499bca80180..18f769bc12a1f7a230b1a72564ee5d278e417746 100644
--- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
@@ -11,6 +11,8 @@
#include "core/frame/UseCounter.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/input/EventHandler.h"
+#include "core/input/EventHandlingUtil.h"
+#include "core/input/MouseEventManager.h"
#include "core/input/TouchActionUtil.h"
#include "core/layout/HitTestCanvasResult.h"
#include "core/page/ChromeClient.h"
@@ -47,88 +49,59 @@ bool isInDocument(EventTarget* n)
return n && n->toNode() && n->toNode()->isConnected();
}
-WebInputEventResult dispatchMouseEvent(
- EventTarget* target,
- const AtomicString& mouseEventType,
- const PlatformMouseEvent& mouseEvent,
- EventTarget* relatedTarget,
- int detail = 0,
- bool checkForListener = false)
-{
- if (target && target->toNode()
- && (!checkForListener || target->hasEventListeners(mouseEventType))) {
- Node* targetNode = target->toNode();
- MouseEvent* event = MouseEvent::create(mouseEventType,
- targetNode->document().domWindow(), mouseEvent, detail,
- relatedTarget ? relatedTarget->toNode() : nullptr);
- DispatchEventResult dispatchResult = target->dispatchEvent(event);
- return EventHandler::toWebInputEventResult(dispatchResult);
- }
- return WebInputEventResult::NotHandled;
+} // namespace
+
+PointerEventManager::PointerEventBoundaryEventDispatcher::PointerEventBoundaryEventDispatcher(
+ PointerEventManager* pointerEventManager,
+ PointerEvent* pointerEvent)
+ : m_pointerEventManager(pointerEventManager)
+ , m_pointerEvent(pointerEvent)
+{
}
-PlatformMouseEvent mouseEventWithRegion(Node* node, const PlatformMouseEvent& mouseEvent)
+void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchOut(
+ EventTarget* target, EventTarget* relatedTarget)
{
- if (!node->isElementNode())
- return mouseEvent;
+ dispatch(target, relatedTarget, EventTypeNames::pointerout, false);
+}
- Element* element = toElement(node);
- if (!element->isInCanvasSubtree())
- return mouseEvent;
+void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchOver(
+ EventTarget* target, EventTarget* relatedTarget)
+{
+ dispatch(target, relatedTarget, EventTypeNames::pointerover, false);
+}
- HTMLCanvasElement* canvas = Traversal<HTMLCanvasElement>::firstAncestorOrSelf(*element);
- // In this case, the event target is canvas and mouse rerouting doesn't happen.
- if (canvas == element)
- return mouseEvent;
- String region = canvas->getIdFromControl(element);
- PlatformMouseEvent newMouseEvent = mouseEvent;
- newMouseEvent.setRegion(region);
- return newMouseEvent;
+void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchLeave(
+ EventTarget* target, EventTarget* relatedTarget, bool checkForListener)
+{
+ dispatch(target, relatedTarget, EventTypeNames::pointerleave, checkForListener);
}
-void buildAncestorChain(
- EventTarget* target,
- HeapVector<Member<Node>, 20>* ancestors)
+void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatchEnter(
+ EventTarget* target, EventTarget* relatedTarget, bool checkForListener)
{
- if (!isInDocument(target))
- return;
- Node* targetNode = target->toNode();
- DCHECK(targetNode);
- targetNode->updateDistribution();
- // Index 0 element in the ancestors arrays will be the corresponding
- // target. So the root of their document will be their last element.
- for (Node* node = targetNode; node; node = FlatTreeTraversal::parent(*node))
- ancestors->append(node);
-}
-
-void buildAncestorChainsAndFindCommonAncestors(
- EventTarget* exitedTarget, EventTarget* enteredTarget,
- HeapVector<Member<Node>, 20>* exitedAncestorsOut,
- HeapVector<Member<Node>, 20>* enteredAncestorsOut,
- size_t* exitedAncestorsCommonParentIndexOut,
- size_t* enteredAncestorsCommonParentIndexOut)
-{
- DCHECK(exitedAncestorsOut);
- DCHECK(enteredAncestorsOut);
- DCHECK(exitedAncestorsCommonParentIndexOut);
- DCHECK(enteredAncestorsCommonParentIndexOut);
-
- buildAncestorChain(exitedTarget, exitedAncestorsOut);
- buildAncestorChain(enteredTarget, enteredAncestorsOut);
-
- *exitedAncestorsCommonParentIndexOut = exitedAncestorsOut->size();
- *enteredAncestorsCommonParentIndexOut = enteredAncestorsOut->size();
- while (*exitedAncestorsCommonParentIndexOut > 0
- && *enteredAncestorsCommonParentIndexOut > 0) {
- if ((*exitedAncestorsOut)[(*exitedAncestorsCommonParentIndexOut)-1]
- != (*enteredAncestorsOut)[(*enteredAncestorsCommonParentIndexOut)-1])
- break;
- (*exitedAncestorsCommonParentIndexOut)--;
- (*enteredAncestorsCommonParentIndexOut)--;
- }
+ dispatch(target, relatedTarget, EventTypeNames::pointerenter, checkForListener);
}
-} // namespace
+AtomicString PointerEventManager::PointerEventBoundaryEventDispatcher::getLeaveEvent()
+{
+ return EventTypeNames::pointerleave;
+}
+
+AtomicString PointerEventManager::PointerEventBoundaryEventDispatcher::getEnterEvent()
+{
+ return EventTypeNames::pointerenter;
+}
+
+void PointerEventManager::PointerEventBoundaryEventDispatcher::dispatch(
+ EventTarget* target, EventTarget* relatedTarget, const AtomicString& type,
+ bool checkForListener)
+{
+ m_pointerEventManager->dispatchPointerEvent(target,
+ m_pointerEventManager->m_pointerEventFactory.createPointerBoundaryEvent(
+ m_pointerEvent, type, relatedTarget),
+ checkForListener);
+}
WebInputEventResult PointerEventManager::dispatchPointerEvent(
EventTarget* target,
@@ -161,7 +134,7 @@ WebInputEventResult PointerEventManager::dispatchPointerEvent(
UseCounter::count(m_frame->document(), UseCounter::PointerEventDispatchPointerDown);
DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent);
- return EventHandler::toWebInputEventResult(dispatchResult);
+ return EventHandlingUtil::toWebInputEventResult(dispatchResult);
}
return WebInputEventResult::NotHandled;
}
@@ -205,109 +178,10 @@ void PointerEventManager::sendMouseAndPossiblyPointerBoundaryEvents(
void PointerEventManager::sendBoundaryEvents(
EventTarget* exitedTarget,
EventTarget* enteredTarget,
- PointerEvent* pointerEvent,
- const PlatformMouseEvent& mouseEvent, bool sendMouseEvent)
+ PointerEvent* pointerEvent)
{
- if (exitedTarget == enteredTarget)
- return;
-
- // Dispatch pointerout/mouseout events
- if (isInDocument(exitedTarget)) {
- if (!sendMouseEvent) {
- dispatchPointerEvent(exitedTarget, m_pointerEventFactory.createPointerBoundaryEvent(
- pointerEvent, EventTypeNames::pointerout, enteredTarget));
- } else {
- dispatchMouseEvent(exitedTarget,
- EventTypeNames::mouseout,
- mouseEventWithRegion(exitedTarget->toNode(), mouseEvent),
- enteredTarget);
- }
- }
-
- // Create lists of all exited/entered ancestors, locate the common ancestor
- // Based on httparchive, in more than 97% cases the depth of DOM is less
- // than 20.
- HeapVector<Member<Node>, 20> exitedAncestors;
- HeapVector<Member<Node>, 20> enteredAncestors;
- size_t exitedAncestorsCommonParentIndex = 0;
- size_t enteredAncestorsCommonParentIndex = 0;
-
- // 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.
-
- buildAncestorChainsAndFindCommonAncestors(
- exitedTarget, enteredTarget,
- &exitedAncestors, &enteredAncestors,
- &exitedAncestorsCommonParentIndex, &enteredAncestorsCommonParentIndex);
-
- bool exitedNodeHasCapturingAncestor = false;
- for (size_t j = 0; j < exitedAncestors.size(); 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 < exitedAncestorsCommonParentIndex; j++) {
- if (!sendMouseEvent) {
- dispatchPointerEvent(exitedAncestors[j].get(),
- m_pointerEventFactory.createPointerBoundaryEvent(
- pointerEvent, EventTypeNames::pointerleave, enteredTarget),
- !exitedNodeHasCapturingAncestor);
- } else {
- dispatchMouseEvent(exitedAncestors[j].get(),
- EventTypeNames::mouseleave,
- mouseEventWithRegion(exitedTarget->toNode(), mouseEvent),
- enteredTarget, 0, !exitedNodeHasCapturingAncestor);
- }
- }
-
- // Dispatch pointerover/mouseover.
- if (isInDocument(enteredTarget)) {
- if (!sendMouseEvent) {
- dispatchPointerEvent(enteredTarget, m_pointerEventFactory.createPointerBoundaryEvent(
- pointerEvent, EventTypeNames::pointerover, exitedTarget));
- } else {
- dispatchMouseEvent(enteredTarget,
- EventTypeNames::mouseover, mouseEvent, exitedTarget);
- }
- }
-
- // 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 < enteredAncestors.size(); 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 = enteredAncestorsCommonParentIndex; i > 0; i--) {
- if (!sendMouseEvent) {
- dispatchPointerEvent(enteredAncestors[i-1].get(),
- m_pointerEventFactory.createPointerBoundaryEvent(
- pointerEvent, EventTypeNames::pointerenter, exitedTarget),
- !enteredNodeHasCapturingAncestor);
- } else {
- dispatchMouseEvent(enteredAncestors[i-1].get(),
- EventTypeNames::mouseenter, mouseEvent, exitedTarget,
- 0, !enteredNodeHasCapturingAncestor);
- }
- }
+ PointerEventBoundaryEventDispatcher boundaryEventDispatcher(this, pointerEvent);
+ boundaryEventDispatcher.sendBoundaryEvents(exitedTarget, enteredTarget);
}
void PointerEventManager::setNodeUnderPointer(
@@ -380,7 +254,7 @@ WebInputEventResult PointerEventManager::handleTouchEvents(
if (event.type() == PlatformEvent::TouchScrollStarted) {
blockTouchPointers();
- m_touchEventManager.setTouchScrollStarted();
+ m_touchEventManager->setTouchScrollStarted();
return WebInputEventResult::HandledSystem;
}
@@ -397,7 +271,7 @@ WebInputEventResult PointerEventManager::handleTouchEvents(
dispatchTouchPointerEvents(event, touchInfos);
- return m_touchEventManager.handleTouchEvent(event, touchInfos);
+ return m_touchEventManager->handleTouchEvent(event, touchInfos);
}
void PointerEventManager::dispatchTouchPointerEvents(
@@ -577,9 +451,9 @@ WebInputEventResult PointerEventManager::sendMousePointerEvent(
}
}
}
- result = EventHandler::mergeEventResult(result,
- dispatchMouseEvent(mouseTarget, mouseEventType, mouseEvent,
- nullptr, clickCount));
+ result = EventHandlingUtil::mergeEventResult(result,
+ m_mouseEventManager->dispatchMouseEvent(mouseTarget, mouseEventType,
+ mouseEvent, nullptr, clickCount));
}
if (pointerEvent->type() == EventTypeNames::pointerup
@@ -598,22 +472,20 @@ WebInputEventResult PointerEventManager::sendMousePointerEvent(
return result;
}
-PointerEventManager::PointerEventManager(LocalFrame* frame)
-: m_frame(frame)
-, m_touchEventManager(frame)
+PointerEventManager::PointerEventManager(LocalFrame* frame,
+ MouseEventManager* mouseEventManager)
+ : m_frame(frame)
+ , m_touchEventManager(new TouchEventManager(frame))
+ , m_mouseEventManager(mouseEventManager)
{
clear();
}
-PointerEventManager::~PointerEventManager()
-{
-}
-
void PointerEventManager::clear()
{
for (auto& entry : m_preventMouseEventForPointerType)
entry = false;
- m_touchEventManager.clear();
+ m_touchEventManager->clear();
m_inCanceledStateForPointerTypeTouch = false;
m_pointerEventFactory.clear();
m_touchIdsForCanceledPointerdowns.clear();
@@ -659,8 +531,8 @@ EventTarget* PointerEventManager::processCaptureAndPositionOfPointerEvent(
}
if (sendMouseEvent) {
// lastNodeUnderMouse is needed here because it is still stored in EventHandler.
- sendBoundaryEvents(lastNodeUnderMouse, hitTestTarget,
- pointerEvent, mouseEvent, true);
+ m_mouseEventManager->sendBoundaryEvents(lastNodeUnderMouse,
+ hitTestTarget, mouseEvent);
}
return hitTestTarget;
}
@@ -783,7 +655,7 @@ bool PointerEventManager::isActive(const int pointerId) const
bool PointerEventManager::isAnyTouchActive() const
{
- return m_touchEventManager.isAnyTouchActive();
+ return m_touchEventManager->isAnyTouchActive();
}
bool PointerEventManager::primaryPointerdownCanceled(uint32_t uniqueTouchEventId)
@@ -814,6 +686,7 @@ DEFINE_TRACE(PointerEventManager)
visitor->trace(m_pointerCaptureTarget);
visitor->trace(m_pendingPointerCaptureTarget);
visitor->trace(m_touchEventManager);
+ visitor->trace(m_mouseEventManager);
}
« no previous file with comments | « third_party/WebKit/Source/core/input/PointerEventManager.h ('k') | third_party/WebKit/Source/core/input/ScrollManager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698