| Index: Source/core/html/forms/RadioInputType.cpp
|
| diff --git a/Source/core/html/forms/RadioInputType.cpp b/Source/core/html/forms/RadioInputType.cpp
|
| index 34d3df0cc960b9bba85ea7060bb3c34a4339ba1b..9731b11292cde518ac937c291681d61816058981 100644
|
| --- a/Source/core/html/forms/RadioInputType.cpp
|
| +++ b/Source/core/html/forms/RadioInputType.cpp
|
| @@ -37,9 +37,9 @@ namespace blink {
|
|
|
| namespace {
|
|
|
| -HTMLElement* nextElement(const HTMLElement& element, bool forward)
|
| +HTMLElement* nextElement(const HTMLElement& element, HTMLFormElement* stayWithin, bool forward)
|
| {
|
| - return forward ? Traversal<HTMLElement>::next(element) : Traversal<HTMLElement>::previous(element);
|
| + return forward ? Traversal<HTMLElement>::next(element, (Node* )stayWithin) : Traversal<HTMLElement>::previous(element, (Node* )stayWithin);
|
| }
|
|
|
| } // namespace
|
| @@ -71,6 +71,19 @@ void RadioInputType::handleClickEvent(MouseEvent* event)
|
| event->setDefaultHandled();
|
| }
|
|
|
| +HTMLInputElement* RadioInputType::findNextFocusableRadioButtonInGroup(HTMLInputElement* currentElement, bool forward)
|
| +{
|
| + HTMLElement* htmlElement;
|
| + for (htmlElement = nextElement(*currentElement, element().form(), forward); htmlElement; htmlElement = nextElement(*htmlElement, element().form(), forward)) {
|
| + if (!isHTMLInputElement(*htmlElement))
|
| + continue;
|
| + HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
|
| + if (element().form() == inputElement->form() && inputElement->type() == InputTypeNames::radio && inputElement->name() == element().name() && inputElement->isFocusable())
|
| + return inputElement;
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
|
| {
|
| BaseCheckableInputType::handleKeydownEvent(event);
|
| @@ -93,24 +106,23 @@ void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
|
|
|
| // We can only stay within the form's children if the form hasn't been demoted to a leaf because
|
| // of malformed HTML.
|
| - for (HTMLElement* htmlElement = nextElement(element(), forward); htmlElement; htmlElement = nextElement(*htmlElement, forward)) {
|
| - // Once we encounter a form element, we know we're through.
|
| - if (isHTMLFormElement(*htmlElement))
|
| - break;
|
| - // Look for more radio buttons.
|
| - if (!isHTMLInputElement(*htmlElement))
|
| - continue;
|
| - HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
|
| - if (inputElement->form() != element().form())
|
| - break;
|
| - if (inputElement->type() == InputTypeNames::radio && inputElement->name() == element().name() && inputElement->isFocusable()) {
|
| - RefPtrWillBeRawPtr<HTMLInputElement> protector(inputElement);
|
| - document.setFocusedElement(inputElement);
|
| - inputElement->dispatchSimulatedClick(event, SendNoEvents);
|
| - event->setDefaultHandled();
|
| - return;
|
| + HTMLInputElement* inputElement = findNextFocusableRadioButtonInGroup(toHTMLInputElement(&element()), forward);
|
| + if (!inputElement) {
|
| + // Traverse in reverse direction till last or first radio button
|
| + forward = !(forward);
|
| + HTMLInputElement* nextInputElement = findNextFocusableRadioButtonInGroup(toHTMLInputElement(&element()), forward);
|
| + while (nextInputElement) {
|
| + inputElement = nextInputElement;
|
| + nextInputElement = findNextFocusableRadioButtonInGroup(nextInputElement, forward);
|
| }
|
| }
|
| + if (inputElement) {
|
| + RefPtrWillBeRawPtr<HTMLInputElement> protector(inputElement);
|
| + document.setFocusedElement(inputElement);
|
| + inputElement->dispatchSimulatedClick(event, SendNoEvents);
|
| + event->setDefaultHandled();
|
| + return;
|
| + }
|
| }
|
|
|
| void RadioInputType::handleKeyupEvent(KeyboardEvent* event)
|
|
|