2009-03-10 Simon Fraser <simon.fraser@apple.com>
Reviewed by Darin Adler
https://bugs.webkit.org/show_bug.cgi?id=24503
Fix hit testing of absolutely positioned single line text controls by
ensuring that we set result.innerNode() correctly. If the hit node is
a descendant of the inner text element or if it is the <input> itself,
then we say we hit the innerTextElement.
Rename hitInnerTextBlock() to hitInnerTextElement() to match the
'innerTextElement' terminology used elsewhere.
Assert that if renderer()->hitTest() returns false, no-one set
result.innerNode().
Test: fast/forms/search-abs-pos-cancel-button.html
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::hitTestContents):
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::hitInnerTextElement):
* rendering/RenderTextControl.h:
* rendering/RenderTextControlMultiLine.cpp:
(WebCore::RenderTextControlMultiLine::nodeAtPoint):
* rendering/RenderTextControlSingleLine.cpp:
(WebCore::RenderTextControlSingleLine::nodeAtPoint):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@41576 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index ca885f8..0e84aaf 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -270,12 +270,14 @@
if (!RenderTextControl::nodeAtPoint(request, result, xPos, yPos, tx, ty, hitTestAction))
return false;
- if (result.innerNode() != node() && result.innerNode() != innerTextElement())
- return false;
+ // If we hit a node inside the inner text element, say that we hit that element,
+ // and if we hit our node (e.g. we're over the border or padding), also say that we hit the
+ // inner text element so that it gains focus.
+ if (result.innerNode()->isDescendantOf(innerTextElement()) || result.innerNode() == node())
+ hitInnerTextElement(result, xPos, yPos, tx, ty);
- hitInnerTextBlock(result, xPos, yPos, tx, ty);
-
- if (!m_innerBlock)
+ // If we're not a search field, or we already found the results or cancel buttons, we're done.
+ if (!m_innerBlock || result.innerNode() == m_resultsButton || result.innerNode() == m_cancelButton)
return true;
Node* innerNode = 0;