Chromium Code Reviews| Index: third_party/WebKit/Source/core/input/EventHandler.cpp |
| diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp |
| index 762216c4c403531efb91c1f103f96da81ce4f2b9..5c4a3d80ae387891d95f25fcfc8d6a99d5098469 100644 |
| --- a/third_party/WebKit/Source/core/input/EventHandler.cpp |
| +++ b/third_party/WebKit/Source/core/input/EventHandler.cpp |
| @@ -56,6 +56,7 @@ |
| #include "core/frame/LocalFrame.h" |
| #include "core/frame/Settings.h" |
| #include "core/frame/VisualViewport.h" |
| +#include "core/html/HTMLCanvasElement.h" |
| #include "core/html/HTMLDialogElement.h" |
| #include "core/html/HTMLFrameElementBase.h" |
| #include "core/html/HTMLFrameSetElement.h" |
| @@ -365,6 +366,7 @@ DEFINE_TRACE(EventHandler) |
| visitor->trace(m_previousWheelScrolledNode); |
| visitor->trace(m_scrollbarHandlingScrollGesture); |
| visitor->trace(m_targetForTouchID); |
| + visitor->trace(m_regionForTouchID); |
| visitor->trace(m_touchSequenceDocument); |
| visitor->trace(m_scrollGestureHandlingNode); |
| visitor->trace(m_previousGestureScrolledNode); |
| @@ -1383,6 +1385,14 @@ WebInputEventResult EventHandler::handleMouseReleaseEvent(const PlatformMouseEve |
| if (Node* clickTargetNode = mev.innerNode()->commonAncestor( |
| *m_clickNode, parentForClickEvent)) { |
| + if (isHTMLCanvasElement(clickTargetNode)) { |
| + LayoutPoint documentPoint = contentPointFromRootFrame(m_frame, mouseEvent.position()); |
| + std::pair<Element*, String> regionInfo = toHTMLCanvasElement(clickTargetNode)->getControlAndIdIfHitRegionExists(documentPoint); |
| + if (regionInfo.first) |
| + clickTargetNode = regionInfo.first; |
| + const_cast<PlatformMouseEvent&>(mouseEvent).setRegion(regionInfo.second); |
|
Rick Byers
2016/02/23 20:26:08
It's unfortunate to need to rely on a const_cast h
zino
2016/03/08 12:33:48
I couldn't find the part that you mentioned "That
Rick Byers
2016/03/08 15:57:34
This code:
return MouseEventWithHitTestResults(
Rick Byers
2016/03/10 21:36:28
This looks really great now, thanks! I love how y
|
| + } |
| + |
| // Dispatch mouseup directly w/o calling updateMouseEventTargetNode |
| // because the mouseup dispatch above has already updated it |
| // correctly. Moreover, clickTargetNode is different from |
| @@ -1649,6 +1659,14 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo |
| m_lastScrollbarUnderMouse = nullptr; |
| } |
| + if (isHTMLCanvasElement(m_nodeUnderMouse)) { |
| + LayoutPoint documentPoint = contentPointFromRootFrame(m_frame, mouseEvent.position()); |
| + std::pair<Element*, String> regionInfo = toHTMLCanvasElement(m_nodeUnderMouse)->getControlAndIdIfHitRegionExists(documentPoint); |
| + if (regionInfo.first) |
| + m_nodeUnderMouse = regionInfo.first; |
| + const_cast<PlatformMouseEvent&>(mouseEvent).setRegion(regionInfo.second); |
| + } |
| + |
| if (lastNodeUnderMouse != m_nodeUnderMouse) |
| sendNodeTransitionEvents(lastNodeUnderMouse.get(), m_nodeUnderMouse.get(), mouseEvent); |
| } |
| @@ -3850,7 +3868,8 @@ WebInputEventResult EventHandler::dispatchTouchEvents(const PlatformTouchEvent& |
| touchInfo.adjustedPagePoint, |
| touchInfo.adjustedRadius, |
| point.rotationAngle(), |
| - point.force()); |
| + point.force(), |
| + touchInfo.region); |
| // Ensure this target's touch list exists, even if it ends up empty, so |
| // it can always be passed to TouchEvent::Create below. |
| @@ -3977,6 +3996,13 @@ WebInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEvent& eve |
| if (!node) |
| continue; |
| + if (isHTMLCanvasElement(node)) { |
| + std::pair<Element*, String> regionInfo = toHTMLCanvasElement(node)->getControlAndIdIfHitRegionExists(result.pointInInnerNodeFrame()); |
| + if (regionInfo.first) |
| + node = regionInfo.first; |
| + m_regionForTouchID.set(point.id(), regionInfo.second); |
| + } |
| + |
| // Touch events should not go to text nodes |
| if (node->isTextNode()) |
| node = FlatTreeTraversal::parent(*node); |
| @@ -4023,16 +4049,19 @@ WebInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEvent& eve |
| const PlatformTouchPoint& point = points[i]; |
| PlatformTouchPoint::State pointState = point.state(); |
| RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr; |
| + String regionID; |
| 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. |
| touchTarget = m_targetForTouchID.take(point.id()); |
| + regionID = m_regionForTouchID.take(point.id()); |
| } else { |
| // No hittest is performed on move or stationary, since the target |
| // is not allowed to change anyway. |
| touchTarget = m_targetForTouchID.get(point.id()); |
| + regionID = m_regionForTouchID.get(point.id()); |
| } |
| LocalFrame* targetFrame = nullptr; |
| @@ -4078,6 +4107,7 @@ WebInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEvent& eve |
| touchInfo.adjustedRadius = point.radius().scaledBy(scaleFactor); |
| touchInfo.knownTarget = knownTarget; |
| touchInfo.consumed = false; |
| + touchInfo.region = regionID; |
| } |
| if (!m_inPointerCanceledState) { |