Skip to content
Permalink
Browse files
LayoutTests:
        Test for focus and blur for new text fields.

        * fast/forms/input-appearance-focus.html: Added.
        * fast/forms/input-appearance-focus-expected.txt: Added.
        * fast/forms/input-appearance-focus-expected.png: Added.
        * fast/forms/input-appearance-focus-expected.checksum: Added.

WebCore:

        Reviewed by Hyatt.

        This change will allow the new text field elements to get focus, and to respond to the focus and blur events.

        Added: fast/forms/input-appearance-focus.html

        * khtml/html/HTMLElementImpl.cpp: (WebCore::HTMLElementImpl::isFocusable):
          Removed recently added code that allowed editable elements with no parent to be focusable.
          We don't need to do this now that we try to focus the input element, instead of the inner div.
        * khtml/html/HTMLGenericFormElementImpl.cpp: (WebCore::HTMLGenericFormElementImpl::isMouseFocusable): Added case to for text fields.
        * khtml/html/HTMLInputElementImpl.cpp:
        (WebCore::HTMLInputElementImpl::focus): Added. Selects contents of text field.
        (WebCore::HTMLInputElementImpl::setSelectionStart): Added break; in switch statement.
        (WebCore::HTMLInputElementImpl::setSelectionEnd): ditto.
        (WebCore::HTMLInputElementImpl::select): ditto.
        (WebCore::HTMLInputElementImpl::setSelectionRange): ditto.
        * khtml/html/HTMLInputElementImpl.h: Added focus()
        * khtml/xml/dom_elementimpl.h: Made focus() virtual.
        * page/Frame.cpp: (Frame::setFocusNodeIfNeeded):
          Walk up the Render Tree instead of the DOM tree when trying to find a node to focus.
          This will let us choose the input node instead of one of the nodes in the shadow tree.
        * page/FrameView.cpp: (FrameView::dispatchMouseEvent): ditto.
        * rendering/RenderContainer.cpp: (WebCore::RenderContainer::destroyLeftoverChildren): Corrected misspelling.
        * rendering/RenderTextField.cpp:
        (WebCore::RenderTextField::select): Implemented.  Select contents of inner div.
        * rendering/RenderTextField.h:
        (WebCore::RenderTextField::renderName): Changed order.
        (WebCore::RenderTextField::removeLeftoverAnonymousBoxes): ditto.



Canonical link: https://commits.webkit.org/10372@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@12345 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Adele Peterson committed Jan 25, 2006
1 parent aed9a01 commit 249e5917d958d686879077317bdc7092eaef94fc
@@ -1,3 +1,12 @@
2006-01-24 Adele Peterson <adele@apple.com>

Test for focus and blur for new text fields.

* fast/forms/input-appearance-focus.html: Added.
* fast/forms/input-appearance-focus-expected.txt: Added.
* fast/forms/input-appearance-focus-expected.png: Added.
* fast/forms/input-appearance-focus-expected.checksum: Added.

2006-01-24 Darin Adler <darin@apple.com>

Reviewed by Eric.
@@ -0,0 +1 @@
e7fed8be71a004abd2375a8a9a3b488a
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,40 @@
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > DIV to 15 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > DIV to 15 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
layer at (0,0) size 800x600
RenderCanvas at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x576
RenderBlock (anonymous) at (0,0) size 784x18
RenderText {TEXT} at (0,0) size 755x18
text run at (0,0) width 755: "This test uses the new text field to test focus() and blur() and to make sure that onFocus and onBlur events fire correctly."
RenderBlock {P} at (0,34) size 784x18
RenderTextField {INPUT} at (0,1) size 154x17
RenderText {TEXT} at (154,0) size 4x18
text run at (154,0) width 4: " "
RenderTextField {INPUT} at (158,1) size 154x17
RenderText {TEXT} at (0,0) size 0x0
RenderBlock {DIV} at (0,68) size 784x72
RenderBR {BR} at (0,0) size 0x18
RenderText {TEXT} at (0,18) size 322x18
text run at (0,18) width 322: "Test Passed. Text field 1's onFocus event has fired."
RenderBR {BR} at (0,0) size 0x0
RenderText {TEXT} at (0,36) size 312x18
text run at (0,36) width 312: "Test Passed. Text field 1's onBlur event has fired."
RenderBR {BR} at (0,0) size 0x0
RenderText {TEXT} at (0,54) size 322x18
text run at (0,54) width 322: "Test Passed. Text field 2's onFocus event has fired."
RenderBlock {P} at (0,156) size 784x0
layer at (8,43) size 154x17
RenderBlock {DIV} at (0,0) size 154x17
RenderText {TEXT} at (2,2) size 82x13
text run at (2,2) width 82: "My Text Field 1"
layer at (166,43) size 154x17
RenderBlock {DIV} at (0,0) size 154x17
RenderText {TEXT} at (2,2) size 82x13
text run at (2,2) width 82: "My Text Field 2"
selection start: position 0 of child 0 {TEXT} of document
selection end: position 15 of child 0 {TEXT} of document
@@ -0,0 +1,11 @@
<html>
<body onload="document.getElementById('sp').focus(); document.getElementById('sp').blur(); document.getElementById('sp2').focus();">
This test uses the new text field to test focus() and blur() and to make sure that onFocus and onBlur events fire correctly.
<p>
<input type="text" id="sp" value="My Text Field 1" style="-khtml-appearance: textfield;" onfocus="document.getElementById('result').innerHTML+='<br>Test Passed. Text field 1\'s onFocus event has fired.'" onblur="document.getElementById('result').innerHTML+='<br>Test Passed. Text field 1\'s onBlur event has fired.'"></input>
<input type="text" id="sp2" value="My Text Field 2" style="-khtml-appearance: textfield;" onfocus="document.getElementById('result').innerHTML+='<br>Test Passed. Text field 2\'s onFocus event has fired.'" onblur="document.getElementById('result').innerHTML+='<br>Test Passed. Text field 2\'s onBlur event has fired.'"></input>

<div id="result"></div>
</p>
</body>
</html>
@@ -1,3 +1,34 @@
2006-01-24 Adele Peterson <adele@apple.com>

Reviewed by Hyatt.

This change will allow the new text field elements to get focus, and to respond to the focus and blur events.

Added: fast/forms/input-appearance-focus.html

* khtml/html/HTMLElementImpl.cpp: (WebCore::HTMLElementImpl::isFocusable):
Removed recently added code that allowed editable elements with no parent to be focusable.
We don't need to do this now that we try to focus the input element, instead of the inner div.
* khtml/html/HTMLGenericFormElementImpl.cpp: (WebCore::HTMLGenericFormElementImpl::isMouseFocusable): Added case to for text fields.
* khtml/html/HTMLInputElementImpl.cpp:
(WebCore::HTMLInputElementImpl::focus): Added. Selects contents of text field.
(WebCore::HTMLInputElementImpl::setSelectionStart): Added break; in switch statement.
(WebCore::HTMLInputElementImpl::setSelectionEnd): ditto.
(WebCore::HTMLInputElementImpl::select): ditto.
(WebCore::HTMLInputElementImpl::setSelectionRange): ditto.
* khtml/html/HTMLInputElementImpl.h: Added focus()
* khtml/xml/dom_elementimpl.h: Made focus() virtual.
* page/Frame.cpp: (Frame::setFocusNodeIfNeeded):
Walk up the Render Tree instead of the DOM tree when trying to find a node to focus.
This will let us choose the input node instead of one of the nodes in the shadow tree.
* page/FrameView.cpp: (FrameView::dispatchMouseEvent): ditto.
* rendering/RenderContainer.cpp: (WebCore::RenderContainer::destroyLeftoverChildren): Corrected misspelling.
* rendering/RenderTextField.cpp:
(WebCore::RenderTextField::select): Implemented. Select contents of inner div.
* rendering/RenderTextField.h:
(WebCore::RenderTextField::renderName): Changed order.
(WebCore::RenderTextField::removeLeftoverAnonymousBoxes): ditto.

2006-01-24 Darin Adler <darin@apple.com>

Reviewed by Eric.
@@ -1245,7 +1245,6 @@
93D1FEF6067EBF89009CE68A /* KWQFoundationExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = KWQFoundationExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
93E62D980985F41600E1B5E3 /* SystemTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SystemTime.cpp; path = platform/mac/SystemTime.cpp; sourceTree = "<group>"; };
93E62D990985F41600E1B5E3 /* SystemTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SystemTime.h; path = platform/SystemTime.h; sourceTree = "<group>"; };
93ECDB7E03ABE65B008635CE /* KWQColorData.gperf */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = KWQColorData.gperf; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
93F19B1908245E59001E9ABC /* Info.plist */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
93F19B1A08245E5A001E9ABC /* WebCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WebCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
93F1D31A0558CC5C00821BC0 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = /usr/lib/libicucore.dylib; sourceTree = "<absolute>"; };
@@ -450,9 +450,7 @@ void HTMLElementImpl::addHTMLAlignment(MappedAttributeImpl* attr)

bool HTMLElementImpl::isFocusable() const
{
// Added the check for !parent() so shadow elements, like those in engine-based textfields, can get focus.
// We may reevaluate this when we resolve outstanding focus issues with these shadow elements.
return isContentEditable() && ((parent() && !parent()->isContentEditable()) || !parent());
return isContentEditable() && parent() && !parent()->isContentEditable();
}

bool HTMLElementImpl::isContentEditable() const
@@ -217,10 +217,12 @@ bool HTMLGenericFormElementImpl::isKeyboardFocusable() const
bool HTMLGenericFormElementImpl::isMouseFocusable() const
{
if (isFocusable()) {
if (renderer()->isWidget()) {
if (renderer()->style()->appearance() == TextFieldAppearance)
return true;
else if (renderer()->isWidget()) {
return static_cast<RenderWidget*>(renderer())->widget() &&
(static_cast<RenderWidget*>(renderer())->widget()->focusPolicy() & QWidget::ClickFocus);
}
}
// For <input type=image> and <button>, we will assume no mouse focusability. This is
// consistent with OS X behavior for buttons.
return false;
@@ -32,6 +32,7 @@
#include "FormDataList.h"

#include "cssproperties.h"
#include "Frame.h"
#include "render_form.h"
#include "render_button.h"
#include "RenderTextField.h"
@@ -127,6 +128,23 @@ bool HTMLInputElementImpl::isKeyboardFocusable() const
return true;
}

void HTMLInputElementImpl::focus()
{
if ((m_type == TEXT) || (m_type == PASSWORD) && renderer()->style()->appearance() == TextFieldAppearance) {
DocumentImpl* doc = getDocument();
if (doc) {
doc->updateLayout();
if (isFocusable()) {
doc->setFocusNode(this);
select();
doc->frame()->revealSelection();
}
}
} else
HTMLGenericFormElementImpl::focus();

}

void HTMLInputElementImpl::setType(const DOMString& t)
{
if (t.isEmpty()) {
@@ -323,8 +341,10 @@ void HTMLInputElementImpl::setSelectionStart(int start)
switch (m_type) {
case PASSWORD:
case TEXT:
if (renderer()->style()->appearance() == TextFieldAppearance)
if (renderer()->style()->appearance() == TextFieldAppearance) {
static_cast<RenderTextField *>(renderer())->setSelectionStart(start);
break;
}
// Fall through for text fields that don't specify appearance
case SEARCH:
static_cast<RenderLineEdit *>(renderer())->setSelectionStart(start);
@@ -342,8 +362,10 @@ void HTMLInputElementImpl::setSelectionEnd(int end)
switch (m_type) {
case PASSWORD:
case TEXT:
if (renderer()->style()->appearance() == TextFieldAppearance)
if (renderer()->style()->appearance() == TextFieldAppearance) {
static_cast<RenderTextField *>(renderer())->setSelectionEnd(end);
break;
}
// Fall through for text fields that don't specify appearance
case SEARCH:
static_cast<RenderLineEdit *>(renderer())->setSelectionEnd(end);
@@ -364,8 +386,10 @@ void HTMLInputElementImpl::select( )
break;
case PASSWORD:
case TEXT:
if (renderer()->style()->appearance() == TextFieldAppearance)
if (renderer()->style()->appearance() == TextFieldAppearance) {
static_cast<RenderTextField *>(renderer())->select();
break;
}
// Fall through for text fields that don't specify appearance
case SEARCH:
static_cast<RenderLineEdit*>(renderer())->select();
@@ -391,8 +415,10 @@ void HTMLInputElementImpl::setSelectionRange(int start, int end)
switch (m_type) {
case PASSWORD:
case TEXT:
if (renderer()->style()->appearance() == TextFieldAppearance)
if (renderer()->style()->appearance() == TextFieldAppearance) {
static_cast<RenderTextField *>(renderer())->setSelectionRange(start, end);
break;
}
// Fall through for text fields that don't specify appearance
case SEARCH:
static_cast<RenderLineEdit *>(renderer())->setSelectionRange(start, end);
@@ -74,6 +74,7 @@ class HTMLInputElementImpl : public HTMLGenericFormElementImpl

virtual bool isKeyboardFocusable() const;
virtual bool isEnumeratable() const { return inputType() != IMAGE; }
virtual void focus();

virtual const AtomicString& name() const;

@@ -263,7 +263,7 @@ class ElementImpl : public ContainerNodeImpl

virtual bool isURLAttribute(AttributeImpl *attr) const;

void focus();
virtual void focus();
void blur();

#ifndef NDEBUG
@@ -1447,14 +1447,21 @@ void Frame::setFocusNodeIfNeeded()
NodeImpl *target = startNode ? startNode->rootEditableElement() : 0;

if (target) {
for ( ; target; target = target->parentNode()) {
RenderObject* renderer = target->renderer();

// Walk up the render tree to search for a node to focus.
// Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
while (renderer) {
// We don't want to set focus on a subframe when selecting in a parent frame,
// so add the !isFrameElement check here. There's probably a better way to make this
// work in the long term, but this is the safest fix at this time.
if (target->isMouseFocusable() && !::isFrameElement(target)) {
if (target && target->isMouseFocusable() && !::isFrameElement(target)) {
document()->setFocusNode(target);
return;
}
renderer = renderer->parent();
if (renderer)
target = renderer->element();
}
document()->setFocusNode(0);
}
@@ -1086,7 +1086,16 @@ bool FrameView::dispatchMouseEvent(const AtomicString &eventType, NodeImpl *targ
// is expected by some sites that rely on onChange handlers running
// from form fields before the button click is processed.
NodeImpl* node = targetNode;
for ( ; node && !node->isFocusable(); node = node->parentNode());
RenderObject* renderer = node->renderer();

// Walk up the render tree to search for a node to focus.
// Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
while (renderer) {
node = renderer->element();
if (node && node->isFocusable())
break;
renderer = renderer->parent();
}
// If focus shift is blocked, we eat the event. Note we should never clear swallowEvent
// if the page already set it (e.g., by canceling default behavior).
if (node && node->isMouseFocusable()) {
@@ -65,7 +65,7 @@ void RenderContainer::destroyLeftoverChildren()
if (m_first->isListMarker())
m_first->remove(); // List markers are owned by their enclosing list and so don't get destroyed by this container.
else {
// Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based textfields.
// Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
if (m_first->element())
m_first->element()->setRenderer(0);
m_first->destroy();
@@ -19,17 +19,18 @@
*/

#include "config.h"
#include "DocumentImpl.h"
#include "RenderTextField.h"

#include "DocumentImpl.h"
#include "Frame.h"
#include "RenderText.h"
#include "htmlnames.h"
#include "HTMLInputElementImpl.h"

using namespace DOM;
using namespace HTMLNames;

namespace WebCore {

using namespace HTMLNames;

RenderTextField::RenderTextField(NodeImpl* node)
:RenderBlock(node)
{
@@ -147,7 +148,9 @@ void RenderTextField::setSelectionEnd(int end)

void RenderTextField::select()
{
// FIXME: Implement this.
DocumentImpl* doc = document();
if (doc && m_div)
doc->frame()->selectContentsOfNode(m_div.get());
}

void RenderTextField::setSelectionRange(int start, int end)
@@ -29,22 +29,20 @@ namespace WebCore
class RenderTextField : public RenderBlock
{
public:
RenderTextField(DOM::NodeImpl* node);
RenderTextField(NodeImpl* node);
virtual ~RenderTextField();

virtual const char *renderName() const { return "RenderTextField"; }
virtual void removeLeftoverAnonymousBoxes() {};

virtual void setStyle(RenderStyle* style);
RenderStyle* createDivStyle(RenderStyle* startStyle);
virtual void updateFromElement();

virtual const char *renderName() const { return "RenderTextField"; }

RenderStyle* createDivStyle(RenderStyle* startStyle);

int selectionStart();
int selectionEnd();
void setSelectionStart(int);
void setSelectionEnd(int);

void setSelectionEnd(int);
void select();
void setSelectionRange(int, int);

0 comments on commit 249e591

Please sign in to comment.