Diff
Modified: branches/chromium/1025/LayoutTests/fast/forms/ValidityState-valueMissing-radio-expected.txt (111481 => 111482)
--- branches/chromium/1025/LayoutTests/fast/forms/ValidityState-valueMissing-radio-expected.txt 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/LayoutTests/fast/forms/ValidityState-valueMissing-radio-expected.txt 2012-03-21 02:00:19 UTC (rev 111482)
@@ -6,8 +6,8 @@
Without form element
No checked button:
PASS inputs[0].validity.valueMissing is true
-PASS inputs[1].validity.valueMissing is true
-PASS inputs[2].validity.valueMissing is true
+PASS inputs[1].validity.valueMissing is false
+PASS inputs[2].validity.valueMissing is false
The second button has been checked:
PASS inputs[0].validity.valueMissing is false
PASS inputs[1].validity.valueMissing is false
@@ -20,12 +20,11 @@
PASS inputs[0].validity.valueMissing is false
PASS inputs[1].validity.valueMissing is false
PASS inputs[2].validity.valueMissing is false
-
With form element
No checked button:
PASS inputs[0].validity.valueMissing is true
-PASS inputs[1].validity.valueMissing is true
-PASS inputs[2].validity.valueMissing is true
+PASS inputs[1].validity.valueMissing is false
+PASS inputs[2].validity.valueMissing is false
The first button has been checked:
PASS inputs[0].validity.valueMissing is false
PASS inputs[1].validity.valueMissing is false
@@ -38,13 +37,6 @@
PASS inputs[0].validity.valueMissing is false
PASS inputs[1].validity.valueMissing is false
PASS inputs[2].validity.valueMissing is false
-
-Not in a radio button group
-PASS requiredButton.validity.valueMissing is false
-PASS requiredButton.validity.valueMissing is true
-PASS button.validity.valueMissing is true
-PASS button.validity.valueMissing is false
-PASS requiredButton.validity.valueMissing is false
PASS successfullyParsed is true
TEST COMPLETE
Deleted: branches/chromium/1025/LayoutTests/fast/forms/radio/radio-live-validation-style-expected.txt (111481 => 111482)
--- branches/chromium/1025/LayoutTests/fast/forms/radio/radio-live-validation-style-expected.txt 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/LayoutTests/fast/forms/radio/radio-live-validation-style-expected.txt 2012-03-21 02:00:19 UTC (rev 111482)
@@ -1,45 +0,0 @@
-Check if :valid/:invalid CSS pseudo selectors are lively applied
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Removing a checked radio button from a required radio button group by a DOM tree mutation:
-PASS backgroundOf($("radio1")) is validColor
-PASS parent.removeChild($("radio2")); backgroundOf($("radio1")) is invalidColor
-
-Removing a checked radio button from a required radio button group by name attribute change:
-PASS $("radio2").name = "group2"; backgroundOf($("radio1")) is invalidColor
-
-Removing a checked radio button from a required radio button group by type change:
-PASS $("radio2").type = "text"; backgroundOf($("radio1")) is invalidColor
-
-Make a radio button group required by required attribute change:
-PASS backgroundOf($("radio1")) is validColor
-PASS backgroundOf($("radio2")) is validColor
-PASS $("radio1").required = true; backgroundOf($("radio1")) is invalidColor
-PASS backgroundOf($("radio2")) is invalidColor
-
-Make a radio button group not required by required attribute change:
-PASS backgroundOf($("radio1")) is invalidColor
-PASS backgroundOf($("radio2")) is invalidColor
-PASS $("radio1").required = false; backgroundOf($("radio1")) is validColor
-PASS backgroundOf($("radio2")) is validColor
-
-Removing one of multiple required attributes:
-PASS backgroundOf($("radio1")) is invalidColor
-PASS backgroundOf($("radio2")) is invalidColor
-PASS $("radio1").required = false; backgroundOf($("radio1")) is invalidColor
-PASS backgroundOf($("radio2")) is invalidColor
-
-Adding a radio button with the required attribute to a radio button group:
-PASS backgroundOf($("radio1")) is validColor
-PASS parent.appendChild(requiredRadioButton); backgroundOf($("radio1")) is invalidColor
-PASS backgroundOf(requiredRadioButton) is invalidColor
-
-Removing a radio button with the required attribute from a radio button group:
-PASS parent.removeChild(requiredRadioButton); backgroundOf($("radio1")) is validColor
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
Deleted: branches/chromium/1025/LayoutTests/fast/forms/radio/radio-live-validation-style.html (111481 => 111482)
--- branches/chromium/1025/LayoutTests/fast/forms/radio/radio-live-validation-style.html 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/LayoutTests/fast/forms/radio/radio-live-validation-style.html 2012-03-21 02:00:19 UTC (rev 111482)
@@ -1,94 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script src=""
-<style>
-:invalid { background: rgb(255, 0, 0); }
-:valid { background: rgb(0, 0, 255); }
-</style>
-</head>
-<body>
-<script>
-description('Check if :valid/:invalid CSS pseudo selectors are lively applied');
-
-function $(id) {
- return document.getElementById(id);
-}
-
-function backgroundOf(element) {
- return document.defaultView.getComputedStyle(element, null).getPropertyValue('background-color');
-}
-
-var invalidColor = 'rgb(255, 0, 0)';
-var validColor = 'rgb(0, 0, 255)';
-
-var parent = document.createElement('div');
-document.body.appendChild(parent);
-
-debug('Removing a checked radio button from a required radio button group by a DOM tree mutation:');
-parent.innerHTML = '<input type=radio name=group1 required id=radio1>' +
- '<input type=radio name=group1 checked id=radio2>';
-shouldBe('backgroundOf($("radio1"))', 'validColor');
-shouldBe('parent.removeChild($("radio2")); backgroundOf($("radio1"))', 'invalidColor');
-debug('');
-
-debug('Removing a checked radio button from a required radio button group by name attribute change:');
-parent.innerHTML = '<input type=radio name=group1 required id=radio1>' +
- '<input type=radio name=group1 checked id=radio2>';
-shouldBe('$("radio2").name = "group2"; backgroundOf($("radio1"))', 'invalidColor');
-debug('');
-
-debug('Removing a checked radio button from a required radio button group by type change:');
-parent.innerHTML = '<input type=radio name=group1 required id=radio1>' +
- '<input type=radio name=group1 checked id=radio2>';
-shouldBe('$("radio2").type = "text"; backgroundOf($("radio1"))', 'invalidColor');
-debug('');
-
-debug('Make a radio button group required by required attribute change:');
-parent.innerHTML = '<input type=radio name=group1 id=radio1>' +
- '<input type=radio name=group1 id=radio2>';
-shouldBe('backgroundOf($("radio1"))', 'validColor');
-shouldBe('backgroundOf($("radio2"))', 'validColor');
-shouldBe('$("radio1").required = true; backgroundOf($("radio1"))', 'invalidColor');
-shouldBe('backgroundOf($("radio2"))', 'invalidColor');
-debug('');
-
-debug('Make a radio button group not required by required attribute change:');
-parent.innerHTML = '<input type=radio required name=group1 id=radio1>' +
- '<input type=radio name=group1 id=radio2>';
-shouldBe('backgroundOf($("radio1"))', 'invalidColor');
-shouldBe('backgroundOf($("radio2"))', 'invalidColor');
-shouldBe('$("radio1").required = false; backgroundOf($("radio1"))', 'validColor');
-shouldBe('backgroundOf($("radio2"))', 'validColor');
-debug('');
-
-
-debug('Removing one of multiple required attributes:');
-parent.innerHTML = '<input type=radio required name=group1 id=radio1>' +
- '<input type=radio required name=group1 id=radio2>';
-shouldBe('backgroundOf($("radio1"))', 'invalidColor');
-shouldBe('backgroundOf($("radio2"))', 'invalidColor');
-shouldBe('$("radio1").required = false; backgroundOf($("radio1"))', 'invalidColor');
-shouldBe('backgroundOf($("radio2"))', 'invalidColor');
-debug('');
-
-debug('Adding a radio button with the required attribute to a radio button group:');
-parent.innerHTML = '<input type=radio name=group1 id=radio1>';
-shouldBe('backgroundOf($("radio1"))', 'validColor');
-var requiredRadioButton = document.createElement('input');
-requiredRadioButton.type = 'radio';
-requiredRadioButton.name = 'group1';
-requiredRadioButton.required = true;
-shouldBe('parent.appendChild(requiredRadioButton); backgroundOf($("radio1"))', 'invalidColor');
-shouldBe('backgroundOf(requiredRadioButton)', 'invalidColor');
-debug('');
-
-debug('Removing a radio button with the required attribute from a radio button group:');
-shouldBe('parent.removeChild(requiredRadioButton); backgroundOf($("radio1"))', 'validColor');
-debug('');
-
-parent.innerHTML = '';
-</script>
-<script src=""
-</body>
-</html>
Modified: branches/chromium/1025/LayoutTests/fast/forms/script-tests/ValidityState-valueMissing-radio.js (111481 => 111482)
--- branches/chromium/1025/LayoutTests/fast/forms/script-tests/ValidityState-valueMissing-radio.js 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/LayoutTests/fast/forms/script-tests/ValidityState-valueMissing-radio.js 2012-03-21 02:00:19 UTC (rev 111482)
@@ -10,8 +10,11 @@
var inputs = document.getElementsByName('victim');
debug('No checked button:');
shouldBeTrue('inputs[0].validity.valueMissing');
-shouldBeTrue('inputs[1].validity.valueMissing');
-shouldBeTrue('inputs[2].validity.valueMissing');
+// The following result should be false because the element does not have
+// "required". It conforms to HTML5, and this behavior has no practical
+// problems.
+shouldBeFalse('inputs[1].validity.valueMissing');
+shouldBeFalse('inputs[2].validity.valueMissing');
debug('The second button has been checked:');
inputs[1].checked = true;
shouldBeFalse('inputs[0].validity.valueMissing');
@@ -28,7 +31,6 @@
shouldBeFalse('inputs[1].validity.valueMissing');
shouldBeFalse('inputs[2].validity.valueMissing');
-debug('');
debug('With form element');
parent.innerHTML = '<form>'
+ '<input name=victim type=radio required>'
@@ -38,8 +40,9 @@
inputs = document.getElementsByName('victim');
debug('No checked button:');
shouldBeTrue('inputs[0].validity.valueMissing');
-shouldBeTrue('inputs[1].validity.valueMissing');
-shouldBeTrue('inputs[2].validity.valueMissing');
+// The following result should be false.
+shouldBeFalse('inputs[1].validity.valueMissing');
+shouldBeFalse('inputs[2].validity.valueMissing');
debug('The first button has been checked:');
inputs[0].checked = true;
shouldBeFalse('inputs[0].validity.valueMissing');
@@ -55,22 +58,3 @@
shouldBeFalse('inputs[0].validity.valueMissing');
shouldBeFalse('inputs[1].validity.valueMissing');
shouldBeFalse('inputs[2].validity.valueMissing');
-
-debug('');
-debug('Not in a radio button group');
-var requiredButton = document.createElement('input');
-requiredButton.type = 'radio';
-requiredButton.name = 'victim';
-requiredButton.required = true;
-shouldBeFalse('requiredButton.validity.valueMissing');
-
-parent.innerHTML = '<input name=victim type=radio required><input name=victim type=radio>';
-requiredButton = document.getElementsByName('victim')[0];
-var button = document.getElementsByName('victim')[1];
-shouldBeTrue('requiredButton.validity.valueMissing');
-shouldBeTrue('button.validity.valueMissing');
-parent.removeChild(button);
-shouldBeFalse('button.validity.valueMissing');
-parent.removeChild(requiredButton);
-shouldBeFalse('requiredButton.validity.valueMissing');
-
Deleted: branches/chromium/1025/LayoutTests/perf/adding-radio-buttons-expected.txt (111481 => 111482)
--- branches/chromium/1025/LayoutTests/perf/adding-radio-buttons-expected.txt 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/LayoutTests/perf/adding-radio-buttons-expected.txt 2012-03-21 02:00:19 UTC (rev 111482)
@@ -1,3 +0,0 @@
-Tests that adding a radio button to a radio button group is constant in the number of radio buttons.
-PASS
-
Deleted: branches/chromium/1025/LayoutTests/perf/adding-radio-buttons.html (111481 => 111482)
--- branches/chromium/1025/LayoutTests/perf/adding-radio-buttons.html 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/LayoutTests/perf/adding-radio-buttons.html 2012-03-21 02:00:19 UTC (rev 111482)
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<script src=""
-<script>
-var parentForm = null;
-
-function setup(magnitude) {
- if (parentForm)
- document.body.removeChild(parentForm);
- parentForm = document.createElement('form');
- document.body.appendChild(parentForm);
- for (var i = 0; i < magnitude; ++i) {
- var radio = document.createElement('input');
- radio.type = 'radio';
- radio.name = 'group1';
- radio.checked = true;
- parentForm.appendChild(radio);
- }
- parentForm.offsetLeft;
-}
-
-function test(magnitude) {
- var radio = document.createElement('input');
- radio.type = 'radio';
- radio.name = 'group1';
- radio.checked = true;
- parentForm.appendChild(radio);
- radio.offsetLeft;
- parentForm.removeChild(radio);
-}
-
-Magnitude.description("Tests that adding a radio button to a radio button group is constant in the number of radio buttons.");
-Magnitude.run(setup, test, Magnitude.CONSTANT);
-</script>
-</body>
-</html>
Modified: branches/chromium/1025/Source/WebCore/dom/CheckedRadioButtons.cpp (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/dom/CheckedRadioButtons.cpp 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/dom/CheckedRadioButtons.cpp 2012-03-21 02:00:19 UTC (rev 111482)
@@ -22,244 +22,65 @@
#include "CheckedRadioButtons.h"
#include "HTMLInputElement.h"
-#include <wtf/HashSet.h>
namespace WebCore {
-class RadioButtonGroup {
-public:
- static PassOwnPtr<RadioButtonGroup> create();
- bool isEmpty() const { return m_members.isEmpty(); }
- bool isRequired() const { return m_requiredCount; }
- HTMLInputElement* checkedButton() const { return m_checkedButton; }
- void add(HTMLInputElement*);
- void updateCheckedState(HTMLInputElement*);
- void requiredAttributeChanged(HTMLInputElement*);
- void remove(HTMLInputElement*);
-
-private:
- RadioButtonGroup();
- void setNeedsValidityCheckForAllButtons();
- bool isValid() const;
- void setCheckedButton(HTMLInputElement*);
-
- HashSet<HTMLInputElement*> m_members;
- HTMLInputElement* m_checkedButton;
- size_t m_requiredCount;
-};
-
-RadioButtonGroup::RadioButtonGroup()
- : m_checkedButton(0)
- , m_requiredCount(0)
-{
-}
-
-PassOwnPtr<RadioButtonGroup> RadioButtonGroup::create()
-{
- return adoptPtr(new RadioButtonGroup);
-}
-
-inline bool RadioButtonGroup::isValid() const
-{
- return !isRequired() || m_checkedButton;
-}
-
-void RadioButtonGroup::setCheckedButton(HTMLInputElement* button)
-{
- HTMLInputElement* oldCheckedButton = m_checkedButton;
- if (oldCheckedButton == button)
- return;
- m_checkedButton = button;
- if (oldCheckedButton)
- oldCheckedButton->setChecked(false);
-}
-
-void RadioButtonGroup::add(HTMLInputElement* button)
-{
- ASSERT(button->isRadioButton());
- if (!m_members.add(button).second)
- return;
- bool groupWasValid = isValid();
- if (button->required())
- ++m_requiredCount;
- if (button->checked())
- setCheckedButton(button);
-
- bool groupIsValid = isValid();
- if (groupWasValid != groupIsValid)
- setNeedsValidityCheckForAllButtons();
- else if (!groupIsValid) {
- // A radio button not in a group is always valid. We need to make it
- // invalid only if the group is invalid.
- button->setNeedsValidityCheck();
- }
-}
-
-void RadioButtonGroup::updateCheckedState(HTMLInputElement* button)
-{
- ASSERT(button->isRadioButton());
- ASSERT(m_members.contains(button));
- bool wasValid = isValid();
- if (button->checked())
- setCheckedButton(button);
- else {
- if (m_checkedButton == button)
- m_checkedButton = 0;
- }
- if (wasValid != isValid())
- setNeedsValidityCheckForAllButtons();
-}
-
-void RadioButtonGroup::requiredAttributeChanged(HTMLInputElement* button)
-{
- ASSERT(button->isRadioButton());
- ASSERT(m_members.contains(button));
- bool wasValid = isValid();
- if (button->required())
- ++m_requiredCount;
- else {
- ASSERT(m_requiredCount);
- --m_requiredCount;
- }
- if (wasValid != isValid())
- setNeedsValidityCheckForAllButtons();
-}
-
-void RadioButtonGroup::remove(HTMLInputElement* button)
-{
- ASSERT(button->isRadioButton());
- HashSet<HTMLInputElement*>::iterator it = m_members.find(button);
- if (it == m_members.end())
- return;
- bool wasValid = isValid();
- m_members.remove(it);
- if (button->required()) {
- ASSERT(m_requiredCount);
- --m_requiredCount;
- }
- if (m_checkedButton == button)
- m_checkedButton = 0;
-
- if (m_members.isEmpty()) {
- ASSERT(!m_requiredCount);
- ASSERT(!m_checkedButton);
- } else if (wasValid != isValid())
- setNeedsValidityCheckForAllButtons();
- if (!wasValid) {
- // A radio button not in a group is always valid. We need to make it
- // valid only if the group was invalid.
- button->setNeedsValidityCheck();
- }
-}
-
-void RadioButtonGroup::setNeedsValidityCheckForAllButtons()
-{
- typedef HashSet<HTMLInputElement*>::const_iterator Iterator;
- Iterator end = m_members.end();
- for (Iterator it = m_members.begin(); it != end; ++it) {
- HTMLInputElement* button = *it;
- ASSERT(button->isRadioButton());
- button->setNeedsValidityCheck();
- }
-}
-
-// ----------------------------------------------------------------
-
static inline bool shouldMakeRadioGroup(HTMLInputElement* element)
{
return element->isRadioButton() && !element->name().isEmpty() && element->inDocument();
}
-// Explicity define empty constructor and destructor in order to prevent the
-// compiler from generating them as inlines. So we don't need to to define
-// RadioButtonGroup in the header.
-CheckedRadioButtons::CheckedRadioButtons()
-{
-}
-
-CheckedRadioButtons::~CheckedRadioButtons()
-{
-}
-
void CheckedRadioButtons::addButton(HTMLInputElement* element)
{
if (!shouldMakeRadioGroup(element))
return;
- if (!m_nameToGroupMap)
- m_nameToGroupMap = adoptPtr(new NameToGroupMap);
+ // We only track checked buttons.
+ if (!element->checked())
+ return;
- OwnPtr<RadioButtonGroup>& group = m_nameToGroupMap->add(element->name().impl(), PassOwnPtr<RadioButtonGroup>()).first->second;
- if (!group)
- group = RadioButtonGroup::create();
- group->add(element);
-}
+ if (!m_nameToCheckedRadioButtonMap)
+ m_nameToCheckedRadioButtonMap = adoptPtr(new NameToInputMap);
-void CheckedRadioButtons::updateCheckedState(HTMLInputElement* element)
-{
- if (!shouldMakeRadioGroup(element))
+ pair<NameToInputMap::iterator, bool> result = m_nameToCheckedRadioButtonMap->add(element->name().impl(), element);
+ if (result.second)
return;
- ASSERT(m_nameToGroupMap);
- if (!m_nameToGroupMap)
+
+ HTMLInputElement* oldCheckedButton = result.first->second;
+ if (oldCheckedButton == element)
return;
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
- ASSERT(group);
- group->updateCheckedState(element);
-}
-void CheckedRadioButtons::requiredAttributeChanged(HTMLInputElement* element)
-{
- if (!shouldMakeRadioGroup(element))
- return;
- ASSERT(m_nameToGroupMap);
- if (!m_nameToGroupMap)
- return;
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
- ASSERT(group);
- group->requiredAttributeChanged(element);
+ result.first->second = element;
+ oldCheckedButton->setChecked(false);
}
HTMLInputElement* CheckedRadioButtons::checkedButtonForGroup(const AtomicString& name) const
{
- if (!m_nameToGroupMap)
+ if (!m_nameToCheckedRadioButtonMap)
return 0;
- m_nameToGroupMap->checkConsistency();
- RadioButtonGroup* group = m_nameToGroupMap->get(name.impl());
- return group ? group->checkedButton() : 0;
-}
-bool CheckedRadioButtons::isInRequiredGroup(HTMLInputElement* element) const
-{
- ASSERT(element->isRadioButton());
- if (!element->inDocument())
- return false;
- if (!m_nameToGroupMap)
- return false;
-
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
- return group && group->isRequired();
+ m_nameToCheckedRadioButtonMap->checkConsistency();
+
+ return m_nameToCheckedRadioButtonMap->get(name.impl());
}
void CheckedRadioButtons::removeButton(HTMLInputElement* element)
{
- if (!shouldMakeRadioGroup(element))
+ if (element->name().isEmpty() || !m_nameToCheckedRadioButtonMap)
return;
- if (!m_nameToGroupMap)
- return;
+
+ m_nameToCheckedRadioButtonMap->checkConsistency();
- m_nameToGroupMap->checkConsistency();
- NameToGroupMap::iterator it = m_nameToGroupMap->find(element->name().impl());
- if (it == m_nameToGroupMap->end())
+ NameToInputMap::iterator it = m_nameToCheckedRadioButtonMap->find(element->name().impl());
+ if (it == m_nameToCheckedRadioButtonMap->end() || it->second != element)
return;
- it->second->remove(element);
- if (it->second->isEmpty()) {
- // FIXME: We may skip deallocating the empty RadioButtonGroup for
- // performance improvement. If we do so, we need to change the key type
- // of m_nameToGroupMap from AtomicStringImpl* to RefPtr<AtomicStringImpl>.
- m_nameToGroupMap->remove(it);
- if (m_nameToGroupMap->isEmpty())
- m_nameToGroupMap.clear();
- }
+
+ ASSERT(element->shouldAppearChecked());
+ ASSERT(element->isRadioButton());
+
+ m_nameToCheckedRadioButtonMap->remove(it);
+ if (m_nameToCheckedRadioButtonMap->isEmpty())
+ m_nameToCheckedRadioButtonMap.clear();
}
} // namespace
Modified: branches/chromium/1025/Source/WebCore/dom/CheckedRadioButtons.h (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/dom/CheckedRadioButtons.h 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/dom/CheckedRadioButtons.h 2012-03-21 02:00:19 UTC (rev 111482)
@@ -28,24 +28,16 @@
namespace WebCore {
class HTMLInputElement;
-class RadioButtonGroup;
-// FIXME: Rename the class. The class was a simple map from a name to a checked
-// radio button. It manages RadioButtonGroup objects now.
class CheckedRadioButtons {
public:
- CheckedRadioButtons();
- ~CheckedRadioButtons();
void addButton(HTMLInputElement*);
- void updateCheckedState(HTMLInputElement*);
- void requiredAttributeChanged(HTMLInputElement*);
void removeButton(HTMLInputElement*);
HTMLInputElement* checkedButtonForGroup(const AtomicString& groupName) const;
- bool isInRequiredGroup(HTMLInputElement*) const;
private:
- typedef HashMap<AtomicStringImpl*, OwnPtr<RadioButtonGroup> > NameToGroupMap;
- OwnPtr<NameToGroupMap> m_nameToGroupMap;
+ typedef HashMap<AtomicStringImpl*, HTMLInputElement*> NameToInputMap;
+ OwnPtr<NameToInputMap> m_nameToCheckedRadioButtonMap;
};
} // namespace WebCore
Modified: branches/chromium/1025/Source/WebCore/html/CheckboxInputType.cpp (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/CheckboxInputType.cpp 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/CheckboxInputType.cpp 2012-03-21 02:00:19 UTC (rev 111482)
@@ -51,7 +51,7 @@
bool CheckboxInputType::valueMissing(const String&) const
{
- return element()->required() && !element()->checked();
+ return !element()->checked();
}
String CheckboxInputType::valueMissingText() const
Modified: branches/chromium/1025/Source/WebCore/html/FileInputType.cpp (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/FileInputType.cpp 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/FileInputType.cpp 2012-03-21 02:00:19 UTC (rev 111482)
@@ -129,7 +129,7 @@
bool FileInputType::valueMissing(const String& value) const
{
- return element()->required() && value.isEmpty();
+ return value.isEmpty();
}
String FileInputType::valueMissingText() const
Modified: branches/chromium/1025/Source/WebCore/html/HTMLFormControlElement.cpp (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/HTMLFormControlElement.cpp 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/HTMLFormControlElement.cpp 2012-03-21 02:00:19 UTC (rev 111482)
@@ -122,21 +122,15 @@
} else if (attr->name() == requiredAttr) {
bool oldRequired = m_required;
m_required = !attr->isNull();
- if (oldRequired != m_required)
- requiredAttributeChanged();
+ if (oldRequired != m_required) {
+ setNeedsValidityCheck();
+ setNeedsStyleRecalc(); // Updates for :required :optional classes.
+ }
} else
HTMLElement::parseMappedAttribute(attr);
setNeedsWillValidateCheck();
}
-void HTMLFormControlElement::requiredAttributeChanged()
-{
- setNeedsValidityCheck();
- // Style recalculation is needed because style selectors may include
- // :required and :optional pseudo-classes.
- setNeedsStyleRecalc();
-}
-
static bool shouldAutofocus(HTMLFormControlElement* element)
{
if (!element->autofocus())
Modified: branches/chromium/1025/Source/WebCore/html/HTMLFormControlElement.h (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/HTMLFormControlElement.h 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/HTMLFormControlElement.h 2012-03-21 02:00:19 UTC (rev 111482)
@@ -115,7 +115,6 @@
HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
virtual void parseMappedAttribute(Attribute*);
- virtual void requiredAttributeChanged();
virtual void attach();
virtual void insertedIntoTree(bool deep);
virtual void removedFromTree(bool deep);
Modified: branches/chromium/1025/Source/WebCore/html/HTMLInputElement.cpp (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/HTMLInputElement.cpp 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/HTMLInputElement.cpp 2012-03-21 02:00:19 UTC (rev 111482)
@@ -178,6 +178,38 @@
return HTMLTextFormControlElement::shouldAutocomplete();
}
+void HTMLInputElement::updateCheckedRadioButtons()
+{
+ checkedRadioButtons().addButton(this);
+
+ if (form()) {
+ const Vector<FormAssociatedElement*>& controls = form()->associatedElements();
+ for (unsigned i = 0; i < controls.size(); ++i) {
+ if (!controls[i]->isFormControlElement())
+ continue;
+ HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(controls[i]);
+ if (control->name() != name())
+ continue;
+ if (control->type() != type())
+ continue;
+ control->setNeedsValidityCheck();
+ }
+ } else {
+ typedef Document::FormElementListHashSet::const_iterator Iterator;
+ Iterator end = document()->formElements()->end();
+ for (Iterator it = document()->formElements()->begin(); it != end; ++it) {
+ HTMLFormControlElementWithState* control = *it;
+ if (control->formControlName() != name())
+ continue;
+ if (control->formControlType() != type())
+ continue;
+ if (control->form())
+ continue;
+ control->setNeedsValidityCheck();
+ }
+ }
+}
+
bool HTMLInputElement::isValidValue(const String& value) const
{
if (!m_inputType->canSetStringValue()) {
@@ -200,6 +232,8 @@
bool HTMLInputElement::valueMissing(const String& value) const
{
+ if (!isRequiredFormControl() || readOnly() || disabled())
+ return false;
return m_inputType->valueMissing(value);
}
@@ -918,11 +952,13 @@
if (checked() == nowChecked)
return;
+ checkedRadioButtons().removeButton(this);
+
m_reflectsCheckedAttribute = false;
m_isChecked = nowChecked;
setNeedsStyleRecalc();
if (isRadioButton())
- checkedRadioButtons().updateCheckedState(this);
+ updateCheckedRadioButtons();
if (renderer() && renderer()->style()->hasAppearance())
renderer()->theme()->stateChanged(renderer(), CheckedState);
setNeedsValidityCheck();
@@ -1513,12 +1549,6 @@
return m_inputType->supportsValidation() && HTMLTextFormControlElement::recalcWillValidate();
}
-void HTMLInputElement::requiredAttributeChanged()
-{
- HTMLTextFormControlElement::requiredAttributeChanged();
- checkedRadioButtons().requiredAttributeChanged(this);
-}
-
#if ENABLE(INPUT_COLOR)
void HTMLInputElement::selectColorInColorChooser(const Color& color)
{
Modified: branches/chromium/1025/Source/WebCore/html/HTMLInputElement.h (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/HTMLInputElement.h 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/HTMLInputElement.h 2012-03-21 02:00:19 UTC (rev 111482)
@@ -321,7 +321,6 @@
virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
virtual bool isRequiredFormControl() const;
virtual bool recalcWillValidate() const;
- virtual void requiredAttributeChanged() OVERRIDE;
void updateType();
Modified: branches/chromium/1025/Source/WebCore/html/RadioInputType.cpp (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/RadioInputType.cpp 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/RadioInputType.cpp 2012-03-21 02:00:19 UTC (rev 111482)
@@ -48,7 +48,7 @@
bool RadioInputType::valueMissing(const String&) const
{
- return element()->checkedRadioButtons().isInRequiredGroup(element()) && !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
+ return !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
}
String RadioInputType::valueMissingText() const
@@ -133,6 +133,12 @@
return element()->checked() || !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
}
+void RadioInputType::attach()
+{
+ InputType::attach();
+ element()->updateCheckedRadioButtons();
+}
+
bool RadioInputType::shouldSendChangeEventAfterCheckedChanged()
{
// Don't send a change event for a radio button that's getting unchecked.
Modified: branches/chromium/1025/Source/WebCore/html/RadioInputType.h (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/RadioInputType.h 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/RadioInputType.h 2012-03-21 02:00:19 UTC (rev 111482)
@@ -48,6 +48,7 @@
virtual void handleKeydownEvent(KeyboardEvent*) OVERRIDE;
virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
+ virtual void attach() OVERRIDE;
virtual bool shouldSendChangeEventAfterCheckedChanged() OVERRIDE;
virtual PassOwnPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
virtual void didDispatchClick(Event*, const ClickHandlingState&) OVERRIDE;
Modified: branches/chromium/1025/Source/WebCore/html/TextFieldInputType.cpp (111481 => 111482)
--- branches/chromium/1025/Source/WebCore/html/TextFieldInputType.cpp 2012-03-21 01:29:28 UTC (rev 111481)
+++ branches/chromium/1025/Source/WebCore/html/TextFieldInputType.cpp 2012-03-21 02:00:19 UTC (rev 111482)
@@ -69,7 +69,7 @@
bool TextFieldInputType::valueMissing(const String& value) const
{
- return element()->required() && value.isEmpty();
+ return value.isEmpty();
}
bool TextFieldInputType::canSetSuggestedValue()