Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: Source/core/html/forms/RadioInputType.cpp

Issue 546753002: Fix to Handle downkey event on last and first radio button of a radio button list (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: After Updating branch Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/html/forms/RadioInputType.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 19 matching lines...) Expand all
30 #include "core/events/MouseEvent.h" 30 #include "core/events/MouseEvent.h"
31 #include "core/html/HTMLInputElement.h" 31 #include "core/html/HTMLInputElement.h"
32 #include "core/page/SpatialNavigation.h" 32 #include "core/page/SpatialNavigation.h"
33 #include "platform/text/PlatformLocale.h" 33 #include "platform/text/PlatformLocale.h"
34 #include "wtf/PassOwnPtr.h" 34 #include "wtf/PassOwnPtr.h"
35 35
36 namespace blink { 36 namespace blink {
37 37
38 namespace { 38 namespace {
39 39
40 HTMLElement* nextElement(const HTMLElement& element, bool forward) 40 HTMLElement* nextElement(const HTMLElement& element, HTMLFormElement* stayWithin , bool forward)
41 { 41 {
42 return forward ? Traversal<HTMLElement>::next(element) : Traversal<HTMLEleme nt>::previous(element); 42 return forward ? Traversal<HTMLElement>::next(element, (Node* )stayWithin) : Traversal<HTMLElement>::previous(element, (Node* )stayWithin);
43 } 43 }
44 44
45 } // namespace 45 } // namespace
46 46
47 using namespace HTMLNames; 47 using namespace HTMLNames;
48 48
49 PassRefPtrWillBeRawPtr<InputType> RadioInputType::create(HTMLInputElement& eleme nt) 49 PassRefPtrWillBeRawPtr<InputType> RadioInputType::create(HTMLInputElement& eleme nt)
50 { 50 {
51 return adoptRefWillBeNoop(new RadioInputType(element)); 51 return adoptRefWillBeNoop(new RadioInputType(element));
52 } 52 }
(...skipping 11 matching lines...) Expand all
64 String RadioInputType::valueMissingText() const 64 String RadioInputType::valueMissingText() const
65 { 65 {
66 return locale().queryString(blink::WebLocalizedString::ValidationValueMissin gForRadio); 66 return locale().queryString(blink::WebLocalizedString::ValidationValueMissin gForRadio);
67 } 67 }
68 68
69 void RadioInputType::handleClickEvent(MouseEvent* event) 69 void RadioInputType::handleClickEvent(MouseEvent* event)
70 { 70 {
71 event->setDefaultHandled(); 71 event->setDefaultHandled();
72 } 72 }
73 73
74 HTMLInputElement* RadioInputType::findNextFocusableRadioButtonInGroup(HTMLInputE lement* currentElement, bool forward)
75 {
76 HTMLElement* htmlElement;
77 for (htmlElement = nextElement(*currentElement, element().form(), forward); htmlElement; htmlElement = nextElement(*htmlElement, element().form(), forward)) {
78 if (!isHTMLInputElement(*htmlElement))
79 continue;
80 HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
81 if (element().form() == inputElement->form() && inputElement->type() == InputTypeNames::radio && inputElement->name() == element().name() && inputElemen t->isFocusable())
82 return inputElement;
83 }
84 return nullptr;
85 }
86
74 void RadioInputType::handleKeydownEvent(KeyboardEvent* event) 87 void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
75 { 88 {
76 BaseCheckableInputType::handleKeydownEvent(event); 89 BaseCheckableInputType::handleKeydownEvent(event);
77 if (event->defaultHandled()) 90 if (event->defaultHandled())
78 return; 91 return;
79 const String& key = event->keyIdentifier(); 92 const String& key = event->keyIdentifier();
80 if (key != "Up" && key != "Down" && key != "Left" && key != "Right") 93 if (key != "Up" && key != "Down" && key != "Left" && key != "Right")
81 return; 94 return;
82 95
83 // Left and up mean "previous radio button". 96 // Left and up mean "previous radio button".
84 // Right and down mean "next radio button". 97 // Right and down mean "next radio button".
85 // Tested in WinIE, and even for RTL, left still means previous radio button 98 // Tested in WinIE, and even for RTL, left still means previous radio button
86 // (and so moves to the right). Seems strange, but we'll match it. However, 99 // (and so moves to the right). Seems strange, but we'll match it. However,
87 // when using Spatial Navigation, we need to be able to navigate without 100 // when using Spatial Navigation, we need to be able to navigate without
88 // changing the selection. 101 // changing the selection.
89 Document& document = element().document(); 102 Document& document = element().document();
90 if (isSpatialNavigationEnabled(document.frame())) 103 if (isSpatialNavigationEnabled(document.frame()))
91 return; 104 return;
92 bool forward = (key == "Down" || key == "Right"); 105 bool forward = (key == "Down" || key == "Right");
93 106
94 // We can only stay within the form's children if the form hasn't been demot ed to a leaf because 107 // We can only stay within the form's children if the form hasn't been demot ed to a leaf because
95 // of malformed HTML. 108 // of malformed HTML.
96 for (HTMLElement* htmlElement = nextElement(element(), forward); htmlElement ; htmlElement = nextElement(*htmlElement, forward)) { 109 HTMLInputElement* inputElement = findNextFocusableRadioButtonInGroup(toHTMLI nputElement(&element()), forward);
97 // Once we encounter a form element, we know we're through. 110 if (!inputElement) {
98 if (isHTMLFormElement(*htmlElement)) 111 // Traverse in reverse direction till last or first radio button
99 break; 112 forward = !(forward);
100 // Look for more radio buttons. 113 HTMLInputElement* nextInputElement = findNextFocusableRadioButtonInGroup (toHTMLInputElement(&element()), forward);
101 if (!isHTMLInputElement(*htmlElement)) 114 while (nextInputElement) {
102 continue; 115 inputElement = nextInputElement;
103 HTMLInputElement* inputElement = toHTMLInputElement(htmlElement); 116 nextInputElement = findNextFocusableRadioButtonInGroup(nextInputElem ent, forward);
104 if (inputElement->form() != element().form())
105 break;
106 if (inputElement->type() == InputTypeNames::radio && inputElement->name( ) == element().name() && inputElement->isFocusable()) {
107 RefPtrWillBeRawPtr<HTMLInputElement> protector(inputElement);
108 document.setFocusedElement(inputElement);
109 inputElement->dispatchSimulatedClick(event, SendNoEvents);
110 event->setDefaultHandled();
111 return;
112 } 117 }
113 } 118 }
119 if (inputElement) {
120 RefPtrWillBeRawPtr<HTMLInputElement> protector(inputElement);
121 document.setFocusedElement(inputElement);
122 inputElement->dispatchSimulatedClick(event, SendNoEvents);
123 event->setDefaultHandled();
124 return;
125 }
114 } 126 }
115 127
116 void RadioInputType::handleKeyupEvent(KeyboardEvent* event) 128 void RadioInputType::handleKeyupEvent(KeyboardEvent* event)
117 { 129 {
118 const String& key = event->keyIdentifier(); 130 const String& key = event->keyIdentifier();
119 if (key != "U+0020") 131 if (key != "U+0020")
120 return; 132 return;
121 // If an unselected radio is tabbed into (because the entire group has nothi ng 133 // If an unselected radio is tabbed into (because the entire group has nothi ng
122 // checked, or because of some explicit .focus() call), then allow space to check it. 134 // checked, or because of some explicit .focus() call), then allow space to check it.
123 if (element().checked()) 135 if (element().checked())
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 // The work we did in willDispatchClick was default handling. 201 // The work we did in willDispatchClick was default handling.
190 event->setDefaultHandled(); 202 event->setDefaultHandled();
191 } 203 }
192 204
193 bool RadioInputType::shouldAppearIndeterminate() const 205 bool RadioInputType::shouldAppearIndeterminate() const
194 { 206 {
195 return !element().checkedRadioButtonForGroup(); 207 return !element().checkedRadioButtonForGroup();
196 } 208 }
197 209
198 } // namespace blink 210 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/html/forms/RadioInputType.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698