| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |