Index: Source/core/page/EventHandler.cpp |
diff --git a/Source/core/page/EventHandler.cpp b/Source/core/page/EventHandler.cpp |
index e0301a0034d9d5e7edd6564342e4facd19597c63..50c94d0a972a7a2f8609f54e7e3a7cf78a22119b 100644 |
--- a/Source/core/page/EventHandler.cpp |
+++ b/Source/core/page/EventHandler.cpp |
@@ -2225,6 +2225,30 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv |
m_previousWheelScrolledNode = stopNode; |
} |
+bool EventHandler::hasScrollableAncestor(const Node* node) const |
+{ |
+ RenderObject* renderer = node->renderer(); |
+ while (node && !renderer) { |
+ node = node->parentElement(); |
+ renderer = node ? node->renderer() : 0; |
+ } |
+ |
+ if (renderer && renderer->isBox()) { |
+ RenderBox* box = toRenderBox(renderer); |
+ if (box->canBeScrolledAndHasScrollableArea()) |
+ return true; |
+ } |
+ |
+ if (renderer && renderer->enclosingScrollableBox()) |
+ return true; |
+ |
+ LocalFrame* parent = m_frame->tree().parent(); |
+ if (!parent) |
+ return false; |
+ |
+ return parent->eventHandler().hasScrollableAncestor(m_frame->ownerElement()); |
+} |
+ |
bool EventHandler::handleGestureShowPress() |
{ |
m_lastShowPressTimestamp = WTF::currentTime(); |
@@ -2249,36 +2273,9 @@ bool EventHandler::handleGestureShowPress() |
bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) |
{ |
IntPoint adjustedPoint = gestureEvent.position(); |
- RefPtr<LocalFrame> subframe = nullptr; |
- switch (gestureEvent.type()) { |
- case PlatformEvent::GestureScrollBegin: |
- case PlatformEvent::GestureScrollUpdate: |
- case PlatformEvent::GestureScrollUpdateWithoutPropagation: |
- case PlatformEvent::GestureScrollEnd: |
- case PlatformEvent::GestureFlingStart: |
- // Handle directly in main frame |
- break; |
- |
- case PlatformEvent::GestureTap: |
- case PlatformEvent::GestureTapUnconfirmed: |
- case PlatformEvent::GestureTapDown: |
- case PlatformEvent::GestureShowPress: |
- case PlatformEvent::GestureTapDownCancel: |
- case PlatformEvent::GestureTwoFingerTap: |
- case PlatformEvent::GestureLongPress: |
- case PlatformEvent::GestureLongTap: |
- case PlatformEvent::GesturePinchBegin: |
- case PlatformEvent::GesturePinchEnd: |
- case PlatformEvent::GesturePinchUpdate: |
- adjustGesturePosition(gestureEvent, adjustedPoint); |
- subframe = getSubFrameForGestureEvent(adjustedPoint, gestureEvent); |
- if (subframe) |
- return subframe->eventHandler().handleGestureEvent(gestureEvent); |
- break; |
- |
- default: |
- ASSERT_NOT_REACHED(); |
- } |
+ RefPtr<LocalFrame> subframe = frameForGestureEvent(gestureEvent, adjustedPoint); |
+ if (subframe != m_frame) |
+ return subframe->eventHandler().handleGestureEvent(gestureEvent); |
Node* eventTarget = 0; |
Scrollbar* scrollbar = 0; |
@@ -2655,13 +2652,44 @@ bool EventHandler::sendScrollEventToView(const PlatformGestureEvent& gestureEven |
return scrolledFrame; |
} |
-LocalFrame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent& gestureEvent) |
+LocalFrame* EventHandler::frameForGestureEvent(const PlatformGestureEvent& gestureEvent, IntPoint& adjustedPoint) |
{ |
- PlatformMouseEvent mouseDown(touchAdjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, 1, |
- gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp()); |
- HitTestRequest request(HitTestRequest::ReadOnly); |
- MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDown); |
- return subframeForHitTestResult(mev); |
+ switch (gestureEvent.type()) { |
+ case PlatformEvent::GestureScrollBegin: |
+ case PlatformEvent::GestureScrollUpdate: |
+ case PlatformEvent::GestureScrollUpdateWithoutPropagation: |
+ case PlatformEvent::GestureScrollEnd: |
+ case PlatformEvent::GestureFlingStart: |
+ // Handle in current frame |
+ break; |
+ |
+ case PlatformEvent::GestureTap: |
+ case PlatformEvent::GestureTapUnconfirmed: |
+ case PlatformEvent::GestureTapDown: |
+ case PlatformEvent::GestureShowPress: |
+ case PlatformEvent::GestureTapDownCancel: |
+ case PlatformEvent::GestureTwoFingerTap: |
+ case PlatformEvent::GestureLongPress: |
+ case PlatformEvent::GestureLongTap: |
+ case PlatformEvent::GesturePinchBegin: |
+ case PlatformEvent::GesturePinchEnd: |
+ case PlatformEvent::GesturePinchUpdate: { |
+ adjustGesturePosition(gestureEvent, adjustedPoint); |
+ PlatformMouseEvent mouseDown(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, 1, |
+ gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp()); |
+ HitTestRequest request(HitTestRequest::ReadOnly); |
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDown); |
+ RefPtr<LocalFrame> subframe = subframeForHitTestResult(mev); |
+ if (subframe) |
+ return subframe->eventHandler().frameForGestureEvent(gestureEvent, adjustedPoint); |
+ break; |
+ } |
+ |
+ default: |
+ ASSERT_NOT_REACHED(); |
+ } |
+ |
+ return m_frame; |
} |
void EventHandler::clearGestureScrollNodes() |