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;