This source file includes following definitions.
- create
- formControlType
- valueMissing
- valueMissingText
- handleClickEvent
- handleKeydownEvent
- handleKeyupEvent
- isKeyboardFocusable
- shouldSendChangeEventAfterCheckedChanged
- willDispatchClick
- didDispatchClick
- isRadioButton
- supportsIndeterminateAppearance
#include "config.h"
#include "core/html/forms/RadioInputType.h"
#include "HTMLNames.h"
#include "InputTypeNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
#include "core/html/HTMLInputElement.h"
#include "core/page/SpatialNavigation.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
using namespace HTMLNames;
PassRefPtr<InputType> RadioInputType::create(HTMLInputElement& element)
{
return adoptRef(new RadioInputType(element));
}
const AtomicString& RadioInputType::formControlType() const
{
return InputTypeNames::radio;
}
bool RadioInputType::valueMissing(const String&) const
{
return element().isInRequiredRadioButtonGroup() && !element().checkedRadioButtonForGroup();
}
String RadioInputType::valueMissingText() const
{
return locale().queryString(blink::WebLocalizedString::ValidationValueMissingForRadio);
}
void RadioInputType::handleClickEvent(MouseEvent* event)
{
event->setDefaultHandled();
}
void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
{
BaseCheckableInputType::handleKeydownEvent(event);
if (event->defaultHandled())
return;
const String& key = event->keyIdentifier();
if (key != "Up" && key != "Down" && key != "Left" && key != "Right")
return;
Document& document = element().document();
if (isSpatialNavigationEnabled(document.frame()))
return;
bool forward = (key == "Down" || key == "Right");
HTMLElement* htmlElement = &element();
while ((htmlElement = (forward ? Traversal<HTMLElement>::next(*htmlElement) : Traversal<HTMLElement>::previous(*htmlElement)))) {
if (isHTMLFormElement(*htmlElement))
break;
if (!isHTMLInputElement(*htmlElement))
continue;
HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
if (inputElement->form() != element().form())
break;
if (inputElement->isRadioButton() && inputElement->name() == element().name() && inputElement->isFocusable()) {
RefPtr<HTMLInputElement> protector(inputElement);
document.setFocusedElement(inputElement);
inputElement->dispatchSimulatedClick(event, SendNoEvents);
event->setDefaultHandled();
return;
}
}
}
void RadioInputType::handleKeyupEvent(KeyboardEvent* event)
{
const String& key = event->keyIdentifier();
if (key != "U+0020")
return;
if (element().checked())
return;
dispatchSimulatedClickIfActive(event);
}
bool RadioInputType::isKeyboardFocusable() const
{
if (!InputType::isKeyboardFocusable())
return false;
if (isSpatialNavigationEnabled(element().document().frame()))
return true;
Element* currentFocusedElement = element().document().focusedElement();
if (isHTMLInputElement(currentFocusedElement)) {
HTMLInputElement& focusedInput = toHTMLInputElement(*currentFocusedElement);
if (focusedInput.isRadioButton() && focusedInput.form() == element().form() && focusedInput.name() == element().name())
return false;
}
return element().checked() || !element().checkedRadioButtonForGroup();
}
bool RadioInputType::shouldSendChangeEventAfterCheckedChanged()
{
return element().checked();
}
PassOwnPtr<ClickHandlingState> RadioInputType::willDispatchClick()
{
OwnPtr<ClickHandlingState> state = adoptPtr(new ClickHandlingState);
state->checked = element().checked();
state->checkedRadioButton = element().checkedRadioButtonForGroup();
element().setChecked(true, DispatchChangeEvent);
return state.release();
}
void RadioInputType::didDispatchClick(Event* event, const ClickHandlingState& state)
{
if (event->defaultPrevented() || event->defaultHandled()) {
HTMLInputElement* checkedRadioButton = state.checkedRadioButton.get();
if (checkedRadioButton
&& checkedRadioButton->isRadioButton()
&& checkedRadioButton->form() == element().form()
&& checkedRadioButton->name() == element().name()) {
checkedRadioButton->setChecked(true);
}
}
event->setDefaultHandled();
}
bool RadioInputType::isRadioButton() const
{
return true;
}
bool RadioInputType::supportsIndeterminateAppearance() const
{
return false;
}
}