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

Unified Diff: sky/engine/core/frame/NewEventHandler.cpp

Issue 823873004: Add basic PointerEvent support in NewEventHandler (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Actually add NewEventHandler Created 5 years, 11 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: sky/engine/core/frame/NewEventHandler.cpp
diff --git a/sky/engine/core/frame/NewEventHandler.cpp b/sky/engine/core/frame/NewEventHandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8195b85884e90a0ee8185b5bfd1fa3cdd0843b2b
--- /dev/null
+++ b/sky/engine/core/frame/NewEventHandler.cpp
@@ -0,0 +1,151 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sky/engine/config.h"
+#include "sky/engine/core/frame/NewEventHandler.h"
+
+#include "sky/engine/core/dom/Document.h"
+#include "sky/engine/core/dom/NodeRenderingTraversal.h"
+#include "sky/engine/core/dom/TouchList.h"
+#include "sky/engine/core/editing/Editor.h"
+#include "sky/engine/core/editing/FrameSelection.h"
+#include "sky/engine/core/editing/htmlediting.h"
+#include "sky/engine/core/events/PointerEvent.h"
+#include "sky/engine/core/frame/LocalFrame.h"
+#include "sky/engine/core/frame/FrameView.h"
+#include "sky/engine/core/page/EventWithHitTestResults.h"
+#include "sky/engine/core/rendering/RenderObject.h"
+#include "sky/engine/core/rendering/RenderView.h"
+#include "sky/engine/platform/geometry/FloatPoint.h"
+#include "sky/engine/public/platform/WebInputEvent.h"
+
+namespace blink {
+
+static VisiblePosition visiblePositionForHitTestResult(const HitTestResult& hitTestResult)
+{
+ Node* innerNode = hitTestResult.innerNode();
+ VisiblePosition position(innerNode->renderer()->positionForPoint(hitTestResult.localPoint()));
+ if (!position.isNull())
+ return position;
+ return VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOWNSTREAM);
+}
+
+static LayoutPoint positionForEvent(const WebPointerEvent& event)
+{
+ return roundedLayoutPoint(FloatPoint(event.x, event.y));
+}
+
+NewEventHandler::NewEventHandler(LocalFrame* frame)
+ : m_frame(frame)
+{
+}
+
+NewEventHandler::~NewEventHandler()
+{
+}
+
+Node* NewEventHandler::targetForHitTestResult(const HitTestResult& hitTestResult)
esprehn 2015/01/20 18:14:33 This can really be far more specific, we can fix i
abarth-chromium 2015/01/20 18:26:54 You're saying we can change the return type to Con
esprehn 2015/01/21 02:47:51 Yes.
+{
+ Node* node = hitTestResult.innerNode();
+ if (!node)
+ return m_frame->document();
+ if (node->isTextNode())
+ return NodeRenderingTraversal::parent(node);
+ return node;
+}
+
+HitTestResult NewEventHandler::performHitTest(const LayoutPoint& point)
+{
+ HitTestResult result(point);
+ if (!m_frame->contentRenderer() || (m_frame->view() && !m_frame->view()->visibleContentRect().contains(roundedIntPoint(point))))
esprehn 2015/01/20 18:14:33 view() and RenderView (contentRenderer) should liv
abarth-chromium 2015/01/20 18:26:54 Ok. I cargo culted this from the old code. Will
abarth-chromium 2015/01/20 21:37:55 Done.
+ return result;
+ m_frame->contentRenderer()->hitTest(HitTestRequest(HitTestRequest::ReadOnly), result);
esprehn 2015/01/20 18:14:33 Why doesn't hitTest() should do the above contains
abarth-chromium 2015/01/20 18:26:54 It looks like it doesn't do this because it's not
esprehn 2015/01/21 02:47:51 RenderView::hitTest is special, it's not a virtual
abarth-chromium 2015/01/21 07:03:26 Ah! Will do.
+ return result;
+}
+
+bool NewEventHandler::dispatchPointerEvent(Node* target, const WebPointerEvent& event)
+{
+ RefPtr<PointerEvent> pointerEvent = PointerEvent::create(event);
+ // TODO(abarth): Keep track of how many pointers are targeting the same node
+ // and only mark the first one as primary.
+ pointerEvent->setPrimary(true);
+ return target->dispatchEvent(pointerEvent.release());
+}
+
+bool NewEventHandler::dispatchClickEvent(Node* capturingTarget, const WebPointerEvent& event)
+{
+ ASSERT(event.type == WebInputEvent::PointerUp);
+ HitTestResult hitTestResult = performHitTest(positionForEvent(event));
+ Node* releaseTarget = targetForHitTestResult(hitTestResult);
+ Node* clickTarget = NodeRenderingTraversal::commonAncestor(*releaseTarget, *capturingTarget);
+ if (!clickTarget)
+ return true;
+ // TODO(abarth): Make a proper gesture event that includes information from the event.
+ return clickTarget->dispatchEvent(Event::createCancelableBubble(EventTypeNames::click));
+}
+
+void NewEventHandler::updateSelectionForPointerDown(const HitTestResult& hitTestResult, const WebPointerEvent& event)
+{
+ Node* innerNode = hitTestResult.innerNode();
+ if (!innerNode->renderer())
+ return;
+ if (Position::nodeIsUserSelectNone(innerNode))
+ return;
+ if (!innerNode->dispatchEvent(Event::createCancelableBubble(EventTypeNames::selectstart)))
+ return;
+ VisiblePosition position = visiblePositionForHitTestResult(hitTestResult);
+ m_frame->selection().setNonDirectionalSelectionIfNeeded(VisibleSelection(position), CharacterGranularity);
+}
+
+bool NewEventHandler::handlePointerEvent(const WebPointerEvent& event)
+{
+ if (event.type == WebInputEvent::PointerDown)
+ return handlePointerDownEvent(event);
+ if (event.type == WebInputEvent::PointerUp)
+ return handlePointerUpEvent(event);
+ if (event.type == WebInputEvent::PointerMove)
esprehn 2015/01/20 18:14:32 switch() then the compiler will shout if you miss
abarth-chromium 2015/01/20 18:26:54 Here |type| comes from the base class WebInputEven
esprehn 2015/01/21 02:47:51 There's no default cases in this function though,
abarth-chromium 2015/01/21 07:03:26 I can do that, but if we don't use |default| the s
+ return handlePointerMoveEvent(event);
+ ASSERT(event.type == WebInputEvent::PointerCancel);
+ return handlePointerCancelEvent(event);
+}
+
+bool NewEventHandler::handlePointerDownEvent(const WebPointerEvent& event)
+{
+ ASSERT(!m_targetForPointer.contains(event.pointer));
+ HitTestResult hitTestResult = performHitTest(positionForEvent(event));
+ RefPtr<Node> target = targetForHitTestResult(hitTestResult);
+ m_targetForPointer.set(event.pointer, target);
+ bool eventSwallowed = !dispatchPointerEvent(target.get(), event);
+ // TODO(abarth): Set the target for the pointer to something determined when
+ // dispatching the event.
+ updateSelectionForPointerDown(hitTestResult, event);
+ return eventSwallowed;
+}
+
+bool NewEventHandler::handlePointerUpEvent(const WebPointerEvent& event)
+{
+ RefPtr<Node> target = m_targetForPointer.take(event.pointer);
+ if (!target)
+ return false;
+ bool eventSwallowed = !dispatchPointerEvent(target.get(), event);
+ // When the user releases the primary pointer, we need to dispatch a tap
+ // event to the common ancestor for where the pointer went down and where
+ // it came up.
+ eventSwallowed |= !dispatchClickEvent(target.get(), event);
esprehn 2015/01/20 18:14:33 I find |= really hard to catch when reading the co
abarth-chromium 2015/01/20 18:26:54 Sure!
esprehn 2015/01/21 02:47:51 Follow up cl.
+ return eventSwallowed;
+}
+
+bool NewEventHandler::handlePointerMoveEvent(const WebPointerEvent& event)
+{
+ RefPtr<Node> target = m_targetForPointer.get(event.pointer);
+ return target && dispatchPointerEvent(target.get(), event);
+}
+
+bool NewEventHandler::handlePointerCancelEvent(const WebPointerEvent& event)
+{
+ RefPtr<Node> target = m_targetForPointer.take(event.pointer);
+ return target && dispatchPointerEvent(target.get(), event);
+}
+
+}

Powered by Google App Engine
This is Rietveld 408576698