[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da

tkent at chromium.org tkent at chromium.org
Wed Dec 22 17:50:32 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 053536bcf34c674c1413ede8fed4253571e57e78
Author: tkent at chromium.org <tkent at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Dec 1 04:36:46 2010 +0000

    Refactor HTMLInputElement: Move a part of HTMLInputElement::
    defaultEventHandler() to InputTypes
    https://bugs.webkit.org/show_bug.cgi?id=50097
    
    Reviewed by Darin Adler.
    
    Move all of keyboard-related event handling to InputType.
    
    No new tests because this should not change any behavior.
    
    * html/BaseButtonInputType.cpp:
    (WebCore::BaseButtonInputType::handleKeydownEvent):
    (WebCore::BaseButtonInputType::handleKeypressEvent):
    (WebCore::BaseButtonInputType::handleKeyupEvent):
    * html/BaseButtonInputType.h:
    * html/BaseCheckableInputType.cpp:
    (WebCore::BaseCheckableInputType::handleKeydownEvent):
    (WebCore::BaseCheckableInputType::handleKeypressEvent):
    * html/BaseCheckableInputType.h:
    * html/CheckboxInputType.cpp:
    (WebCore::CheckboxInputType::handleKeyupEvent):
    * html/CheckboxInputType.h:
    * html/HTMLInputElement.cpp:
    (WebCore::HTMLInputElement::defaultEventHandler):
     We remove !implicitSubmission check for callBaseClassEarly because
     implicitSubmission can not be true for keydown event and keypress
     event at this point.
    * html/InputType.cpp:
    (WebCore::InputType::shouldSubmitImplicitly):
     Returns true for a keypress event with "\r". Note that we don't overload
     this function for BUTTON, FILE, IMAGE, RESET, and SUBMIT because a
     keypress event with "\r" for these types returns from HTMLInputElement::defaultEventHandler()
     before implicit submission checking.
    (WebCore::InputType::handleKeypressEvent):
    (WebCore::InputType::handleKeyupEvent):
    * html/InputType.h:
    * html/RadioInputType.cpp:
    (WebCore::RadioInputType::handleKeydownEvent):
    (WebCore::RadioInputType::handleKeyupEvent):
    * html/RadioInputType.h:
    * html/TextFieldInputType.cpp:
    (WebCore::TextFieldInputType::shouldSubmitImplicitly):
    * html/TextFieldInputType.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73008 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 010ef93..c4ab39a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,49 @@
+2010-11-30  Kent Tamura  <tkent at chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Refactor HTMLInputElement: Move a part of HTMLInputElement::
+        defaultEventHandler() to InputTypes
+        https://bugs.webkit.org/show_bug.cgi?id=50097
+
+        Move all of keyboard-related event handling to InputType.
+
+        No new tests because this should not change any behavior.
+
+        * html/BaseButtonInputType.cpp:
+        (WebCore::BaseButtonInputType::handleKeydownEvent):
+        (WebCore::BaseButtonInputType::handleKeypressEvent):
+        (WebCore::BaseButtonInputType::handleKeyupEvent):
+        * html/BaseButtonInputType.h:
+        * html/BaseCheckableInputType.cpp:
+        (WebCore::BaseCheckableInputType::handleKeydownEvent):
+        (WebCore::BaseCheckableInputType::handleKeypressEvent):
+        * html/BaseCheckableInputType.h:
+        * html/CheckboxInputType.cpp:
+        (WebCore::CheckboxInputType::handleKeyupEvent):
+        * html/CheckboxInputType.h:
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::defaultEventHandler):
+         We remove !implicitSubmission check for callBaseClassEarly because
+         implicitSubmission can not be true for keydown event and keypress
+         event at this point.
+        * html/InputType.cpp:
+        (WebCore::InputType::shouldSubmitImplicitly):
+         Returns true for a keypress event with "\r". Note that we don't overload
+         this function for BUTTON, FILE, IMAGE, RESET, and SUBMIT because a
+         keypress event with "\r" for these types returns from HTMLInputElement::defaultEventHandler()
+         before implicit submission checking.
+        (WebCore::InputType::handleKeypressEvent):
+        (WebCore::InputType::handleKeyupEvent):
+        * html/InputType.h:
+        * html/RadioInputType.cpp:
+        (WebCore::RadioInputType::handleKeydownEvent):
+        (WebCore::RadioInputType::handleKeyupEvent):
+        * html/RadioInputType.h:
+        * html/TextFieldInputType.cpp:
+        (WebCore::TextFieldInputType::shouldSubmitImplicitly):
+        * html/TextFieldInputType.h:
+
 2010-11-30  Patrick Gansterer  <paroga at webkit.org>
 
         Reviewed by Andreas Kling.
diff --git a/WebCore/html/BaseButtonInputType.cpp b/WebCore/html/BaseButtonInputType.cpp
index fd6a8ff..0ba1d89 100644
--- a/WebCore/html/BaseButtonInputType.cpp
+++ b/WebCore/html/BaseButtonInputType.cpp
@@ -32,6 +32,7 @@
 #include "BaseButtonInputType.h"
 
 #include "HTMLInputElement.h"
+#include "KeyboardEvent.h"
 #include "RenderButton.h"
 
 namespace WebCore {
@@ -42,6 +43,43 @@ bool BaseButtonInputType::appendFormData(FormDataList&, bool) const
     return false;
 }
 
+bool BaseButtonInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+    const String& key = event->keyIdentifier();
+    if (key == "U+0020") {
+        element()->setActive(true, true);
+        // No setDefaultHandled(), because IE dispatches a keypress in this case
+        // and the caller will only dispatch a keypress if we don't call setDefaultHandled().
+    }
+    return false;
+}
+
+bool BaseButtonInputType::handleKeypressEvent(KeyboardEvent* event)
+{
+    int charCode = event->charCode();
+    if (charCode == '\r') {
+        element()->dispatchSimulatedClick(event);
+        event->setDefaultHandled();
+        return true;
+    }
+    if (charCode == ' ') {
+        // Prevent scrolling down the page.
+        event->setDefaultHandled();
+        return true;
+    }
+    return false;
+}
+
+bool BaseButtonInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+    const String& key = event->keyIdentifier();
+    if (key != "U+0020")
+        return false;
+    // Simulate mouse click for spacebar for button types.
+    dispatchSimulatedClickIfActive(event);
+    return true;
+}
+
 RenderObject* BaseButtonInputType::createRenderer(RenderArena* arena, RenderStyle*) const
 {
     return new (arena) RenderButton(element());
diff --git a/WebCore/html/BaseButtonInputType.h b/WebCore/html/BaseButtonInputType.h
index e7f683b..59e28bf 100644
--- a/WebCore/html/BaseButtonInputType.h
+++ b/WebCore/html/BaseButtonInputType.h
@@ -42,6 +42,9 @@ protected:
 
 private:
     virtual bool appendFormData(FormDataList&, bool) const;
+    virtual bool handleKeydownEvent(KeyboardEvent*);
+    virtual bool handleKeypressEvent(KeyboardEvent*);
+    virtual bool handleKeyupEvent(KeyboardEvent*);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
 };
 
diff --git a/WebCore/html/BaseCheckableInputType.cpp b/WebCore/html/BaseCheckableInputType.cpp
index 009e8e4..940acf4 100644
--- a/WebCore/html/BaseCheckableInputType.cpp
+++ b/WebCore/html/BaseCheckableInputType.cpp
@@ -34,6 +34,7 @@
 #include "FormDataList.h"
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
+#include "KeyboardEvent.h"
 #include "RegularExpression.h"
 
 namespace WebCore {
@@ -57,4 +58,25 @@ bool BaseCheckableInputType::appendFormData(FormDataList& encoding, bool) const
     return true;
 }
 
+bool BaseCheckableInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+    const String& key = event->keyIdentifier();
+    if (key == "U+0020") {
+        element()->setActive(true, true);
+        // No setDefaultHandled(), because IE dispatches a keypress in this case
+        // and the caller will only dispatch a keypress if we don't call setDefaultHandled().
+    }
+    return false;
+}
+
+bool BaseCheckableInputType::handleKeypressEvent(KeyboardEvent* event)
+{
+    if (event->charCode() == ' ') {
+        // Prevent scrolling down the page.
+        event->setDefaultHandled();
+        return true;
+    }
+    return false;
+}
+
 } // namespace WebCore
diff --git a/WebCore/html/BaseCheckableInputType.h b/WebCore/html/BaseCheckableInputType.h
index 02edf29..8cb95cf 100644
--- a/WebCore/html/BaseCheckableInputType.h
+++ b/WebCore/html/BaseCheckableInputType.h
@@ -39,11 +39,13 @@ namespace WebCore {
 class BaseCheckableInputType : public InputType {
 protected:
     BaseCheckableInputType(HTMLInputElement* element) : InputType(element) { }
+    virtual bool handleKeydownEvent(KeyboardEvent*);
 
 private:
     virtual bool saveFormControlState(String&) const;
     virtual void restoreFormControlState(const String&) const;
     virtual bool appendFormData(FormDataList&, bool) const;
+    virtual bool handleKeypressEvent(KeyboardEvent*);
 };
 
 } // namespace WebCore
diff --git a/WebCore/html/CheckboxInputType.cpp b/WebCore/html/CheckboxInputType.cpp
index 5e015e4..cd171c1 100644
--- a/WebCore/html/CheckboxInputType.cpp
+++ b/WebCore/html/CheckboxInputType.cpp
@@ -32,6 +32,7 @@
 #include "CheckboxInputType.h"
 
 #include "HTMLInputElement.h"
+#include "KeyboardEvent.h"
 #include "LocalizedStrings.h"
 #include <wtf/PassOwnPtr.h>
 
@@ -57,4 +58,13 @@ String CheckboxInputType::valueMissingText() const
     return validationMessageValueMissingForCheckboxText();
 }
 
+bool CheckboxInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+    const String& key = event->keyIdentifier();
+    if (key != "U+0020")
+        return false;
+    dispatchSimulatedClickIfActive(event);
+    return true;
+}
+
 } // namespace WebCore
diff --git a/WebCore/html/CheckboxInputType.h b/WebCore/html/CheckboxInputType.h
index a4c419d..e66ab15 100644
--- a/WebCore/html/CheckboxInputType.h
+++ b/WebCore/html/CheckboxInputType.h
@@ -44,6 +44,7 @@ private:
     virtual const AtomicString& formControlType() const;
     virtual bool valueMissing(const String&) const;
     virtual String valueMissingText() const;
+    virtual bool handleKeyupEvent(KeyboardEvent*);
 };
 
 } // namespace WebCore
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index e474773..263a057 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -1292,11 +1292,6 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
     // FIXME: It would be better to refactor this for the different types of input element.
     // Having them all in one giant function makes this hard to read, and almost all the handling is type-specific.
 
-    bool implicitSubmission = false;
-
-    if (isTextField() && evt->type() == eventNames().textInputEvent && evt->isTextEvent() && static_cast<TextEvent*>(evt)->data() == "\n")
-        implicitSubmission = true;
-
     if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt)))
         return;
 
@@ -1305,8 +1300,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
 
     // Call the base event handler before any of our own event handling for almost all events in text fields.
     // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
-    bool callBaseClassEarly = isTextField() && !implicitSubmission
-        && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
+    bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
     if (callBaseClassEarly) {
         HTMLFormControlElementWithState::defaultEventHandler(evt);
         if (evt->defaultHandled())
@@ -1322,180 +1316,13 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
 
     // Use key press event here since sending simulated mouse events
     // on key down blocks the proper sending of the key press event.
-    if (evt->type() == eventNames().keypressEvent && evt->isKeyboardEvent()) {
-        bool clickElement = false;
-
-        int charCode = static_cast<KeyboardEvent*>(evt)->charCode();
-
-        if (charCode == '\r') {
-            switch (deprecatedInputType()) {
-            case CHECKBOX:
-            case COLOR:
-            case DATE:
-            case DATETIME:
-            case DATETIMELOCAL:
-            case EMAIL:
-            case HIDDEN:
-            case ISINDEX:
-            case MONTH:
-            case NUMBER:
-            case PASSWORD:
-            case RADIO:
-            case RANGE:
-            case SEARCH:
-            case TELEPHONE:
-            case TEXT:
-            case TIME:
-            case URL:
-            case WEEK:
-                // Simulate mouse click on the default form button for enter for these types of elements.
-                implicitSubmission = true;
-                break;
-            case BUTTON:
-            case FILE:
-            case IMAGE:
-            case RESET:
-            case SUBMIT:
-                // Simulate mouse click for enter for these types of elements.
-                clickElement = true;
-                break;
-            }
-        } else if (charCode == ' ') {
-            switch (deprecatedInputType()) {
-            case BUTTON:
-            case CHECKBOX:
-            case FILE:
-            case IMAGE:
-            case RESET:
-            case SUBMIT:
-            case RADIO:
-                // Prevent scrolling down the page.
-                evt->setDefaultHandled();
-                return;
-            default:
-                break;
-            }
-        }
-
-        if (clickElement) {
-            dispatchSimulatedClick(evt);
-            evt->setDefaultHandled();
-            return;
-        }
-    }
-
-    if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent()) {
-        const String& key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
-
-        if (key == "U+0020") {
-            switch (deprecatedInputType()) {
-            case BUTTON:
-            case CHECKBOX:
-            case FILE:
-            case IMAGE:
-            case RESET:
-            case SUBMIT:
-            case RADIO:
-                setActive(true, true);
-                // No setDefaultHandled(), because IE dispatches a keypress in this case
-                // and the caller will only dispatch a keypress if we don't call setDefaultHandled.
-                return;
-            default:
-                break;
-            }
-        }
-
-        if (deprecatedInputType() == RADIO && (key == "Up" || key == "Down" || key == "Left" || key == "Right")) {
-            // Left and up mean "previous radio button".
-            // Right and down mean "next radio button".
-            // Tested in WinIE, and even for RTL, left still means previous radio button (and so moves
-            // to the right).  Seems strange, but we'll match it.
-            // However, when using Spatial Navigation, we need to be able to navigate without changing the selection.
-            if (!isSpatialNavigationEnabled(document()->frame())) {
-                bool forward = (key == "Down" || key == "Right");
-
-                // We can only stay within the form's children if the form hasn't been demoted to a leaf because
-                // of malformed HTML.
-                Node* n = this;
-                while ((n = (forward ? n->traverseNextNode() : n->traversePreviousNode()))) {
-                    // Once we encounter a form element, we know we're through.
-                    if (n->hasTagName(formTag))
-                        break;
-
-                    // Look for more radio buttons.
-                    if (n->hasTagName(inputTag)) {
-                        HTMLInputElement* elt = static_cast<HTMLInputElement*>(n);
-                        if (elt->form() != form())
-                            break;
-                        if (n->hasTagName(inputTag)) {
-                            HTMLInputElement* inputElt = static_cast<HTMLInputElement*>(n);
-                            if (inputElt->deprecatedInputType() == RADIO && inputElt->name() == name() && inputElt->isFocusable()) {
-                                inputElt->setChecked(true);
-                                document()->setFocusedNode(inputElt);
-                                inputElt->dispatchSimulatedClick(evt, false, false);
-                                evt->setDefaultHandled();
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    if (evt->type() == eventNames().keyupEvent && evt->isKeyboardEvent()) {
-        bool clickElement = false;
-
-        const String& key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
-
-        if (key == "U+0020") {
-            switch (deprecatedInputType()) {
-            case BUTTON:
-            case CHECKBOX:
-            case FILE:
-            case IMAGE:
-            case RESET:
-            case SUBMIT:
-                // Simulate mouse click for spacebar for these types of elements.
-                // The AppKit already does this for some, but not all, of them.
-                clickElement = true;
-                break;
-            case RADIO:
-                // If an unselected radio is tabbed into (because the entire group has nothing
-                // checked, or because of some explicit .focus() call), then allow space to check it.
-                if (!checked())
-                    clickElement = true;
-                break;
-            case COLOR:
-            case DATE:
-            case DATETIME:
-            case DATETIMELOCAL:
-            case EMAIL:
-            case HIDDEN:
-            case ISINDEX:
-            case MONTH:
-            case NUMBER:
-            case PASSWORD:
-            case RANGE:
-            case SEARCH:
-            case TELEPHONE:
-            case TEXT:
-            case TIME:
-            case URL:
-            case WEEK:
-                break;
-            }
-        }
+    if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent && m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt)))
+        return;
 
-        if (clickElement) {
-            if (active())
-                dispatchSimulatedClick(evt);
-            evt->setDefaultHandled();
-            return;
-        }        
-    }
+    if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent && m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt)))
+        return;
 
-    if (implicitSubmission) {
+    if (m_inputType->shouldSubmitImplicitly(evt)) {
         if (isSearchField()) {
             addSearchResult();
             onSearch();
diff --git a/WebCore/html/InputType.cpp b/WebCore/html/InputType.cpp
index f298932..8a7a979 100644
--- a/WebCore/html/InputType.cpp
+++ b/WebCore/html/InputType.cpp
@@ -41,6 +41,7 @@
 #include "HiddenInputType.h"
 #include "ImageInputType.h"
 #include "IsIndexInputType.h"
+#include "KeyboardEvent.h"
 #include "LocalizedStrings.h"
 #include "MonthInputType.h"
 #include "NumberInputType.h"
@@ -305,6 +306,21 @@ bool InputType::handleKeydownEvent(KeyboardEvent*)
     return false;
 }
 
+bool InputType::handleKeypressEvent(KeyboardEvent*)
+{
+    return false;
+}
+
+bool InputType::handleKeyupEvent(KeyboardEvent*)
+{
+    return false;
+}
+
+bool InputType::shouldSubmitImplicitly(Event* event)
+{
+    return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
+}
+
 RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
 {
     return RenderObject::createObject(element(), style);
@@ -334,6 +350,12 @@ String InputType::serialize(double) const
     return String();
 }
 
+void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
+{
+    if (element()->active())
+        element()->dispatchSimulatedClick(event);
+    event->setDefaultHandled();
+}
 
 namespace InputTypeNames {
 
diff --git a/WebCore/html/InputType.h b/WebCore/html/InputType.h
index 500ccb3..f275ae8 100644
--- a/WebCore/html/InputType.h
+++ b/WebCore/html/InputType.h
@@ -112,6 +112,10 @@ public:
     virtual bool handleClickEvent(MouseEvent*);
     virtual bool handleDOMActivateEvent(Event*);
     virtual bool handleKeydownEvent(KeyboardEvent*);
+    virtual bool handleKeypressEvent(KeyboardEvent*);
+    virtual bool handleKeyupEvent(KeyboardEvent*);
+    // A helper for event handlers.
+    virtual bool shouldSubmitImplicitly(Event*);
 
     // Miscellaneous functions
 
@@ -139,6 +143,7 @@ public:
 protected:
     InputType(HTMLInputElement* element) : m_element(element) { }
     HTMLInputElement* element() const { return m_element; }
+    void dispatchSimulatedClickIfActive(KeyboardEvent*) const;
     // We can't make this a static const data member because VC++ doesn't like it.
     static double defaultStepBase() { return 0.0; }
 
diff --git a/WebCore/html/RadioInputType.cpp b/WebCore/html/RadioInputType.cpp
index f59cf78..4c459be 100644
--- a/WebCore/html/RadioInputType.cpp
+++ b/WebCore/html/RadioInputType.cpp
@@ -1,43 +1,41 @@
 /*
+ * Copyright (C) 2005 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Google Inc. All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
  *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "config.h"
 #include "RadioInputType.h"
 
+#include "Frame.h"
 #include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "KeyboardEvent.h"
 #include "LocalizedStrings.h"
 #include "MouseEvent.h"
+#include "Settings.h"
+#include "SpatialNavigation.h"
 #include <wtf/PassOwnPtr.h>
 
 namespace WebCore {
 
+using namespace HTMLNames;
+
 PassOwnPtr<InputType> RadioInputType::create(HTMLInputElement* element)
 {
     return adoptPtr(new RadioInputType(element));
@@ -64,4 +62,59 @@ bool RadioInputType::handleClickEvent(MouseEvent* event)
     return true;
 }
 
+bool RadioInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+    if (BaseCheckableInputType::handleKeydownEvent(event))
+        return true;
+    const String& key = event->keyIdentifier();
+    if (key != "Up" && key != "Down" && key != "Left" && key != "Right")
+        return false;
+
+    // Left and up mean "previous radio button".
+    // Right and down mean "next radio button".
+    // Tested in WinIE, and even for RTL, left still means previous radio button (and so moves
+    // to the right).  Seems strange, but we'll match it.
+    // However, when using Spatial Navigation, we need to be able to navigate without changing the selection.
+    Document* document = element()->document();
+    if (isSpatialNavigationEnabled(document->frame()))
+        return false;
+    bool forward = (key == "Down" || key == "Right");
+
+    // We can only stay within the form's children if the form hasn't been demoted to a leaf because
+    // of malformed HTML.
+    Node* node = element();
+    while ((node = (forward ? node->traverseNextNode() : node->traversePreviousNode()))) {
+        // Once we encounter a form element, we know we're through.
+        if (node->hasTagName(formTag))
+            break;
+        // Look for more radio buttons.
+        if (!node->hasTagName(inputTag))
+            continue;
+        HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node);
+        if (inputElement->form() != element()->form())
+            break;
+        if (inputElement->isRadioButton() && inputElement->name() == element()->name() && inputElement->isFocusable()) {
+            inputElement->setChecked(true);
+            document->setFocusedNode(inputElement);
+            inputElement->dispatchSimulatedClick(event, false, false);
+            event->setDefaultHandled();
+            return true;
+        }
+    }
+    return false;
+}
+
+bool RadioInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+    const String& key = event->keyIdentifier();
+    if (key != "U+0020")
+        return false;
+    // If an unselected radio is tabbed into (because the entire group has nothing
+    // checked, or because of some explicit .focus() call), then allow space to check it.
+    if (element()->checked())
+        return false;
+    dispatchSimulatedClickIfActive(event);
+    return true;
+}
+
 } // namespace WebCore
diff --git a/WebCore/html/RadioInputType.h b/WebCore/html/RadioInputType.h
index 27ae75e..62becf6 100644
--- a/WebCore/html/RadioInputType.h
+++ b/WebCore/html/RadioInputType.h
@@ -45,6 +45,8 @@ private:
     virtual bool valueMissing(const String&) const;
     virtual String valueMissingText() const;
     virtual bool handleClickEvent(MouseEvent*);
+    virtual bool handleKeydownEvent(KeyboardEvent*);
+    virtual bool handleKeyupEvent(KeyboardEvent*);
 };
 
 } // namespace WebCore
diff --git a/WebCore/html/TextFieldInputType.cpp b/WebCore/html/TextFieldInputType.cpp
index d93f972..8b74359 100644
--- a/WebCore/html/TextFieldInputType.cpp
+++ b/WebCore/html/TextFieldInputType.cpp
@@ -35,6 +35,7 @@
 #include "HTMLInputElement.h"
 #include "KeyboardEvent.h"
 #include "RenderTextControlSingleLine.h"
+#include "TextEvent.h"
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -75,6 +76,11 @@ bool TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent* event)
     return true;
 }
 
+bool TextFieldInputType::shouldSubmitImplicitly(Event* event)
+{
+    return (event->type() == eventNames().textInputEvent && event->isTextEvent() && static_cast<TextEvent*>(event)->data() == "\n") || InputType::shouldSubmitImplicitly(event);
+}
+
 RenderObject* TextFieldInputType::createRenderer(RenderArena* arena, RenderStyle*) const
 {
     return new (arena) RenderTextControlSingleLine(element(), element()->placeholderShouldBeVisible());
diff --git a/WebCore/html/TextFieldInputType.h b/WebCore/html/TextFieldInputType.h
index 50418aa..07f06e9 100644
--- a/WebCore/html/TextFieldInputType.h
+++ b/WebCore/html/TextFieldInputType.h
@@ -44,6 +44,7 @@ protected:
     virtual bool valueMissing(const String&) const;
     virtual bool handleKeydownEvent(KeyboardEvent*);
     bool handleKeydownEventForSpinButton(KeyboardEvent*);
+    virtual bool shouldSubmitImplicitly(Event*);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
 };
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list