Chromium Code Reviews| 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); |
| +} |
| + |
| +} |