Index: Source/core/page/EventHandler.cpp |
diff --git a/Source/core/page/EventHandler.cpp b/Source/core/page/EventHandler.cpp |
index 80ec34a263280ef5c0ca41ef5bdebec929461e9c..a5e2a885a6bd8d8d1ebbd03917c4d2cc6bb09571 100644 |
--- a/Source/core/page/EventHandler.cpp |
+++ b/Source/core/page/EventHandler.cpp |
@@ -60,6 +60,7 @@ |
#include "core/page/AutoscrollController.h" |
#include "core/page/BackForwardClient.h" |
#include "core/page/Chrome.h" |
+#include "core/page/ChromeClient.h" |
#include "core/page/DragController.h" |
#include "core/page/DragState.h" |
#include "core/page/EditorClient.h" |
@@ -85,6 +86,7 @@ |
#include "core/rendering/RenderView.h" |
#include "core/rendering/RenderWidget.h" |
#include "core/rendering/style/CursorList.h" |
+#include "core/rendering/style/RenderStyle.h" |
#include "core/svg/SVGDocument.h" |
#include "core/svg/SVGElementInstance.h" |
#include "core/svg/SVGUseElement.h" |
@@ -3616,6 +3618,12 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) |
continue; |
m_originatingTouchPointTargets.set(touchPointTargetKey, node); |
touchTarget = node; |
+ |
+ // FIXME(rbyers): Should really be doing a second hit test that ignores inline elements - crbug.com/319479. |
+ TouchAction effectiveTouchAction = computeEffectiveTouchAction(node); |
+ if (effectiveTouchAction != TouchActionAuto) |
+ m_frame->page()->chrome().client().setTouchAction(effectiveTouchAction); |
+ |
} else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) { |
// The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel |
// we also remove it from the map. |
@@ -3827,6 +3835,39 @@ bool EventHandler::handleWheelEventAsEmulatedGesture(const PlatformWheelEvent& e |
return true; |
} |
+TouchAction EventHandler::computeEffectiveTouchAction(Node* node) |
+{ |
+ // Optimization to minimize risk of this new feature (behavior should be identical |
+ // since there's no way to get non-default touch-action values). |
+ if (!RuntimeEnabledFeatures::cssTouchActionEnabled()) |
+ return TouchActionAuto; |
+ |
+ // Start by permitting all actions, then walk the block level elements from |
+ // the target node up to the nearest scrollable ancestor and exclude any |
+ // prohibited actions. For now this is trivial, but when we add more types |
+ // of actions it'll get a little more complex. |
+ TouchAction effectiveTouchAction = TouchActionAuto; |
+ |
+ while (node) { |
+ // The spec says only block and SVG elements get touch-action. |
+ // FIXME(rbyers): Add correct support for SVG, crbug.com/247396. |
+ if (node->isBlockFlowElement()) { |
+ if (RenderObject* renderer = node->renderer()) { |
esprehn
2013/11/21 16:26:29
This loop checks for renderer() repeatedly (isBloc
Rick Byers
2013/11/21 22:09:29
Thanks. I could have sworn I've seen situations w
|
+ TouchAction action = renderer->style()->touchAction(); |
+ if (action == TouchActionNone) |
+ effectiveTouchAction = action; |
+ } |
+ } |
+ |
+ // If we've reached an ancestor that supports a touch action, search no further. |
+ if (node->renderBox() && node->renderBox()->scrollsOverflow()) |
+ break; |
+ |
+ node = node->parentNode(); |
esprehn
2013/11/21 16:26:29
This doesn't appear correct, Shadow DOM means pare
Rick Byers
2013/11/21 22:09:29
Yes, thank you! I've fixed this to traverse up th
|
+ } |
+ return effectiveTouchAction; |
+} |
+ |
void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event) |
{ |
m_mousePositionIsUnknown = false; |