Skip to content
Permalink
Browse files
LayoutTests:
        Reviewed by Darin.

        Test for http://bugs.webkit.org/show_bug.cgi?id=12517
        <rdar://problem/4971227> REGRESSION: Tab order incorrect when input
        inside frame/iframe gets initial focus (12517)

        * fast/events/frame-programmatic-focus-expected.txt: Added.
        * fast/events/frame-programmatic-focus.html: Added.
        * fast/forms/focus2-expected.txt: Updated results to now-correct
        behavior.

WebCore:

        Reviewed by Darin.

        Fix http://bugs.webkit.org/show_bug.cgi?id=12517
        <rdar://problem/4971227> REGRESSION: Tab order incorrect when input
        inside frame/iframe gets initial focus (12517)

        Test: fast/events/frame-programmatic-focus.html

        * dom/Element.cpp:
        (WebCore::Element::focus): Call FocusController::setFocusedNode to set
        the focus for the whole page.
        * html/HTMLInputElement.cpp:
        (WebCore::HTMLInputElement::focus): Ditto.
        * html/HTMLTextAreaElement.cpp:
        (WebCore::HTMLTextAreaElement::focus): Ditto.
        * page/EventHandler.cpp:
        (WebCore::EventHandler::handleTextInputEvent): Send the textInput
        event to the same target that was sent the keypress event before it.
        * page/FocusController.cpp:
        (WebCore::FocusController::advanceFocus): Added a FIXME.
        (WebCore::FocusController::setFocusedNode): Added. Sets the focused
        node for a whole page.
        * page/FocusController.h: Added declaration.
        * platform/cf/RetainPtr.h: Removed unused pointer_cast functions.



Canonical link: https://commits.webkit.org/16511@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@19636 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
aroben committed Feb 15, 2007
1 parent d3ffb5b commit 47868a26f881bd59acdf8a40f413905b731cc333
Showing 12 changed files with 153 additions and 23 deletions.
@@ -1,3 +1,16 @@
2007-02-14 Adam Roben <aroben@apple.com>

Reviewed by Darin.

Test for http://bugs.webkit.org/show_bug.cgi?id=12517
<rdar://problem/4971227> REGRESSION: Tab order incorrect when input
inside frame/iframe gets initial focus (12517)

* fast/events/frame-programmatic-focus-expected.txt: Added.
* fast/events/frame-programmatic-focus.html: Added.
* fast/forms/focus2-expected.txt: Updated results to now-correct
behavior.

2007-02-14 Justin Garcia <justin.garcia@apple.com>

Reviewed by adele
@@ -0,0 +1,13 @@

This page tests that frames receive focus events when one of their child elements is programmatically focused, and receive blur events when an element not in that frame is programmatically focused.

<input> focused
<input> blurred
main frame blurred
iframe focused
<input> in iframe focused
<input> in frame blurred
iframe blurred
main frame focused
<input> focused

@@ -0,0 +1,43 @@
<html>
<head>
<script>
function log(msg) {
document.getElementById('log').appendChild(document.createTextNode(msg + '\n'));
}

function test() {
if (window.layoutTestController) {
layoutTestController.dumpAsText();
}

window.onfocus = function() { log('main frame focused'); }
window.onblur = function() { log('main frame blurred'); }

var input = document.getElementsByTagName('input')[0];
input.onfocus = function() { log('<input> focused'); }
input.onblur = function() { log ('<input> blurred'); }

var w = document.getElementById('frame').contentWindow;
w.onfocus = function() { log('iframe focused'); }
w.onblur = function() { log('iframe blurred'); }

var inputInIframe = w.document.getElementsByTagName('input')[0];
inputInIframe.onfocus = function() { log('<input> in iframe focused'); }
inputInIframe.onblur = function() { log ('<input> in frame blurred'); }

input.focus();
inputInIframe.focus();
input.focus();
}
</script>
</head>
<body onload="test()">
<input>
<iframe id="frame" src="data:text/html,<input>" style="width: 100px; height: 100px; margin: 0px; border: 2px solid black;"></iframe>
<p>This page tests that frames receive focus events when one of their child
elements is programmatically focused, and receive blur events when an
element not in that frame is programmatically focused.</p>

<pre id="log"></pre>
</body>
</html>
@@ -49,8 +49,6 @@ blur event: [to] ANCHOR
IFRAME DOCUMENT:
focus event: [to] BUTTON
keypress event: [to] BUTTON
focus event: [to] BUTTON
keypress event: [to] BUTTON
blur event: [to] BUTTON
focus event: [to] CHECKBOX
keypress event: [to] CHECKBOX
@@ -86,4 +84,7 @@ focus event: [to] TEXTAREA
keypress event: [to] TEXTAREA
blur event: [to] TEXTAREA
focus event: [to] DIV
keypress event: [to] DIV
blur event: [to] DIV
focus event: [to] ANCHOR

@@ -1,3 +1,30 @@
2007-02-14 Adam Roben <aroben@apple.com>

Reviewed by Darin.

Fix http://bugs.webkit.org/show_bug.cgi?id=12517
<rdar://problem/4971227> REGRESSION: Tab order incorrect when input
inside frame/iframe gets initial focus (12517)

Test: fast/events/frame-programmatic-focus.html

* dom/Element.cpp:
(WebCore::Element::focus): Call FocusController::setFocusedNode to set
the focus for the whole page.
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::focus): Ditto.
* html/HTMLTextAreaElement.cpp:
(WebCore::HTMLTextAreaElement::focus): Ditto.
* page/EventHandler.cpp:
(WebCore::EventHandler::handleTextInputEvent): Send the textInput
event to the same target that was sent the keypress event before it.
* page/FocusController.cpp:
(WebCore::FocusController::advanceFocus): Added a FIXME.
(WebCore::FocusController::setFocusedNode): Added. Sets the focused
node for a whole page.
* page/FocusController.h: Added declaration.
* platform/cf/RetainPtr.h: Removed unused pointer_cast functions.

2007-02-14 Justin Garcia <justin.garcia@apple.com>

Reviewed by adele
@@ -30,10 +30,12 @@
#include "Document.h"
#include "Editor.h"
#include "ExceptionCode.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameView.h"
#include "HTMLNames.h"
#include "NamedAttrMap.h"
#include "Page.h"
#include "RenderBlock.h"
#include "SelectionController.h"
#include "TextIterator.h"
@@ -871,9 +873,10 @@ void Element::focus()
doc->updateLayout();

if (!supportsFocus())
return;

doc->setFocusedNode(this);
return;

if (Page* page = doc->page())
page->focusController()->setFocusedNode(this);

if (!isFocusable()) {
setNeedsFocusAppearanceUpdate(true);
@@ -33,6 +33,7 @@
#include "Event.h"
#include "EventHandler.h"
#include "EventNames.h"
#include "FocusController.h"
#include "FormDataList.h"
#include "Frame.h"
#include "HTMLFormElement.h"
@@ -41,6 +42,7 @@
#include "KeyboardEvent.h"
#include "LocalizedStrings.h"
#include "MouseEvent.h"
#include "Page.h"
#include "RenderButton.h"
#include "RenderFileUploadControl.h"
#include "RenderImage.h"
@@ -189,7 +191,8 @@ void HTMLInputElement::focus()
doc->updateLayout();
if (!supportsFocus())
return;
doc->setFocusedNode(this);
if (Page* page = doc->page())
page->focusController()->setFocusedNode(this);
// FIXME: Should isFocusable do the updateLayout?
if (!isFocusable()) {
setNeedsFocusAppearanceUpdate(true);
@@ -31,9 +31,11 @@
#include "Document.h"
#include "Event.h"
#include "EventNames.h"
#include "FocusController.h"
#include "FormDataList.h"
#include "Frame.h"
#include "HTMLNames.h"
#include "Page.h"
#include "RenderStyle.h"
#include "RenderTextControl.h"
#include "Selection.h"
@@ -206,7 +208,8 @@ void HTMLTextAreaElement::focus()
doc->updateLayout();
if (!supportsFocus())
return;
doc->setFocusedNode(this);
if (Page* page = doc->page())
page->focusController()->setFocusedNode(this);
// FIXME: Should isFocusable do the updateLayout?
if (!isFocusable()) {
setNeedsFocusAppearanceUpdate(true);
@@ -1359,7 +1359,11 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
{
if (!m_frame)
return false;
EventTargetNode* target = eventTargetNodeForDocument(m_frame->document());
EventTarget* target;
if (underlyingEvent)
target = underlyingEvent->target();
else
target = eventTargetNodeForDocument(m_frame->document());
if (!target)
return false;
RefPtr<TextEvent> event = new TextEvent(m_frame->domWindow(), text);
@@ -189,6 +189,10 @@ bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* even
setFocusedFrame(owner->contentFrame());
return true;
}

// FIXME: It would be nice to just be able to call setFocusedNode(node) here, but we can't do
// that because some elements (e.g. HTMLInputElement and HTMLTextAreaElement) do extra work in
// their focus() methods.

Document* newDocument = node->document();

@@ -203,4 +207,32 @@ bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* even
return true;
}

bool FocusController::setFocusedNode(Node* node)
{
RefPtr<Frame> oldFocusedFrame = focusedFrame();
RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;

if (!node) {
if (oldDocument)
oldDocument->setFocusedNode(0);
return true;
}

RefPtr<Document> newDocument = node ? node->document() : 0;
RefPtr<Frame> newFocusedFrame = newDocument ? newDocument->frame() : 0;

if (newDocument && newDocument->focusedNode() == node)
return true;

if (oldDocument && oldDocument != newDocument)
oldDocument->setFocusedNode(0);

setFocusedFrame(newFocusedFrame);

if (newDocument)
newDocument->setFocusedNode(node);

return true;
}

} // namespace WebCore
@@ -34,6 +34,7 @@ namespace WebCore {

class Frame;
class KeyboardEvent;
class Node;
class Page;

class FocusController {
@@ -46,6 +47,8 @@ namespace WebCore {

bool advanceFocus(KeyboardEvent*);
bool advanceFocus(FocusDirection, KeyboardEvent*);

bool setFocusedNode(Node*);

private:
Page* m_page;
@@ -192,21 +192,6 @@ namespace WebCore {
{
return a != b.get();
}

template <typename T, typename U> inline RetainPtr<T> static_pointer_cast(const RetainPtr<U>& p)
{
return RetainPtr<T>(static_cast<typename RetainPtr<T>::PtrType>(p.get()));
}

template <typename T, typename U> inline RetainPtr<T> const_pointer_cast(const RetainPtr<U>& p)
{
return RetainPtr<T>(const_cast<typename RetainPtr<T>::PtrType>(p.get()));
}

template <typename T> inline typename RemovePointer<T>::type getPtr(const RetainPtr<T>& p)
{
return p.get();
}

}

0 comments on commit 47868a2

Please sign in to comment.