Chromium Code Reviews| Index: Source/web/WebViewImpl.cpp |
| diff --git a/Source/web/WebViewImpl.cpp b/Source/web/WebViewImpl.cpp |
| index 2e8c4489c508032ec429afa3104707b1ace80892..e85d36a856625109af2387528bc23f8a48a9ac8b 100644 |
| --- a/Source/web/WebViewImpl.cpp |
| +++ b/Source/web/WebViewImpl.cpp |
| @@ -1168,6 +1168,22 @@ void WebViewImpl::computeScaleAndScrollForBlockRect(const WebPoint& hitPoint, co |
| scroll = clampOffsetAtScale(scroll, scale); |
| } |
| +static Node* findCursorDefiningAncestor(Node* node, LocalFrame* frame) |
| +{ |
| + // Go up the tree to find the node that defines a mouse cursor style |
| + while (node) { |
| + // If the current node has an attached renderer, check the cursor. Otherwise, go up. |
|
Rick Byers
2014/07/24 18:29:36
I'd omit this comment - the code says this very cl
mustaq
2014/07/29 18:34:50
Done.
|
| + if (node->renderer()) { |
| + ECursor cursor = node->renderer()->style()->cursor(); |
| + if (cursor != CURSOR_AUTO || frame->eventHandler().useHandCursor(node, node->isLink())) |
|
Rick Byers
2014/07/24 18:29:36
I don't think this is right. If a node explicitly
mustaq
2014/07/29 18:34:50
After some experiment based on yours, it seems tha
mustaq
2014/08/08 18:24:53
After fixing the test failures caused by changes i
|
| + break; |
| + } |
| + node = node->parentNode(); |
| + } |
| + |
| + return node; |
| +} |
| + |
| static bool invokesHandCursor(Node* node, LocalFrame* frame) |
| { |
| if (!node || !node->renderer()) |
| @@ -1185,28 +1201,31 @@ Node* WebViewImpl::bestTapNode(const PlatformGestureEvent& tapEvent) |
| if (!m_page || !m_page->mainFrame()) |
| return 0; |
| - Node* bestTouchNode = 0; |
| - |
| // FIXME: Rely on earlier hit test instead of hit testing again. |
| - GestureEventWithHitTestResults targetedEvent = m_page->deprecatedLocalMainFrame()->eventHandler().targetGestureEvent(tapEvent, true); |
| - bestTouchNode = targetedEvent.hitTestResult().targetNode(); |
| + GestureEventWithHitTestResults targetedEvent = |
| + m_page->deprecatedLocalMainFrame()->eventHandler().targetGestureEvent(tapEvent, true); |
| + Node* bestTouchNode = targetedEvent.hitTestResult().targetNode(); |
| // We might hit something like an image map that has no renderer on it |
| // Walk up the tree until we have a node with an attached renderer |
| while (bestTouchNode && !bestTouchNode->renderer()) |
| bestTouchNode = bestTouchNode->parentNode(); |
| - // Check if we're in the subtree of a node with a hand cursor |
| - // this is the heuristic we use to determine if we show a highlight on tap |
| - while (bestTouchNode && !invokesHandCursor(bestTouchNode, m_page->deprecatedLocalMainFrame())) |
| - bestTouchNode = bestTouchNode->parentNode(); |
| - |
| - if (!bestTouchNode) |
| + Node* cursorDefiningAncestor = |
| + findCursorDefiningAncestor(bestTouchNode, m_page->deprecatedLocalMainFrame()); |
| + // We show a highlight on tap only when the current node shows a hand cursor |
| + if (!cursorDefiningAncestor || !invokesHandCursor(cursorDefiningAncestor, m_page->deprecatedLocalMainFrame())) { |
| return 0; |
| + } |
| - // We should pick the largest enclosing node with hand cursor set. |
| - while (bestTouchNode->parentNode() && invokesHandCursor(bestTouchNode->parentNode(), toLocalFrame(m_page->mainFrame()))) |
| - bestTouchNode = bestTouchNode->parentNode(); |
| + // We should pick the largest enclosing node with hand cursor set. We do this by first jumping |
| + // up to cursorDefiningAncestor (which is already known to have hand cursor set). Then we locate |
| + // the next cursor-defining ancestor up in the the tree and repeat the jumps as long as the node |
| + // has hand cursor set. |
| + do { |
| + bestTouchNode = cursorDefiningAncestor; |
| + cursorDefiningAncestor = findCursorDefiningAncestor(bestTouchNode->parentNode(), m_page->deprecatedLocalMainFrame()); |
| + } while (cursorDefiningAncestor && invokesHandCursor(cursorDefiningAncestor, m_page->deprecatedLocalMainFrame())); |
| return bestTouchNode; |
| } |