Bug 1100535 - Do not assume that the radio required status changed when the attribute changes. r=smaug

--HG--
extra : rebase_source : 5f6b36ba8a05507638d5ab4513864a308fa939c7
This commit is contained in:
Giovanni Sferro 2014-11-27 17:40:00 -08:00
parent 77d8eb386f
commit 8f2d0cf2db
8 changed files with 55 additions and 28 deletions

View File

@ -8376,13 +8376,11 @@ nsDocument::GetRequiredRadioCount(const nsAString& aName) const
}
void
nsDocument::RadioRequiredChanged(const nsAString& aName, nsIFormControl* aRadio)
nsDocument::RadioRequiredWillChange(const nsAString& aName, bool aRequiredAdded)
{
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
NS_ASSERTION(element, "radio controls have to be content elements");
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
if (aRequiredAdded) {
radioGroup->mRequiredRadioCount++;
} else {
NS_ASSERTION(radioGroup->mRequiredRadioCount != 0,

View File

@ -930,8 +930,8 @@ public:
virtual void RemoveFromRadioGroup(const nsAString& aName,
nsIFormControl* aRadio) MOZ_OVERRIDE;
virtual uint32_t GetRequiredRadioCount(const nsAString& aName) const MOZ_OVERRIDE;
virtual void RadioRequiredChanged(const nsAString& aName,
nsIFormControl* aRadio) MOZ_OVERRIDE;
virtual void RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) MOZ_OVERRIDE;
virtual bool GetValueMissingState(const nsAString& aName) const MOZ_OVERRIDE;
virtual void SetValueMissingState(const nsAString& aName, bool aValue) MOZ_OVERRIDE;

View File

@ -2196,13 +2196,10 @@ HTMLFormElement::GetRequiredRadioCount(const nsAString& aName) const
}
void
HTMLFormElement::RadioRequiredChanged(const nsAString& aName,
nsIFormControl* aRadio)
HTMLFormElement::RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded)
{
nsCOMPtr<nsIContent> element = do_QueryInterface(aRadio);
NS_ASSERTION(element, "radio controls have to be content elements!");
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::required)) {
if (aRequiredAdded) {
mRequiredRadioButtonCounts.Put(aName,
mRequiredRadioButtonCounts.Get(aName)+1);
} else {

View File

@ -76,8 +76,8 @@ public:
void AddToRadioGroup(const nsAString& aName, nsIFormControl* aRadio) MOZ_OVERRIDE;
void RemoveFromRadioGroup(const nsAString& aName, nsIFormControl* aRadio) MOZ_OVERRIDE;
virtual uint32_t GetRequiredRadioCount(const nsAString& aName) const MOZ_OVERRIDE;
virtual void RadioRequiredChanged(const nsAString& aName,
nsIFormControl* aRadio) MOZ_OVERRIDE;
virtual void RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) MOZ_OVERRIDE;
virtual bool GetValueMissingState(const nsAString& aName) const MOZ_OVERRIDE;
virtual void SetValueMissingState(const nsAString& aName, bool aValue) MOZ_OVERRIDE;

View File

@ -1332,6 +1332,16 @@ HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir,
nsGkAtoms::_auto, eIgnoreCase)) {
SetDirectionIfAuto(false, aNotify);
} else if (mType == NS_FORM_INPUT_RADIO && aName == nsGkAtoms::required) {
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
if (container &&
((aValue && !HasAttr(aNameSpaceID, aName)) ||
(!aValue && HasAttr(aNameSpaceID, aName)))) {
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
container->RadioRequiredWillChange(name, !!aValue);
}
}
}
@ -1405,16 +1415,6 @@ HTMLInputElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
}
}
if (mType == NS_FORM_INPUT_RADIO && aName == nsGkAtoms::required) {
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
if (container) {
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
container->RadioRequiredChanged(name, this);
}
}
if (aName == nsGkAtoms::required || aName == nsGkAtoms::disabled ||
aName == nsGkAtoms::readonly) {
UpdateValueMissingValidityState();

View File

@ -18,8 +18,8 @@ class HTMLInputElement;
}
#define NS_IRADIOGROUPCONTAINER_IID \
{ 0x22924a01, 0x4360, 0x401b, \
{ 0xb1, 0xd1, 0x56, 0x8d, 0xf5, 0xa3, 0xda, 0x71 } }
{ 0x800320a0, 0x733f, 0x11e4, \
{ 0x82, 0xf8, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }
/**
* A container that has multiple radio groups in it, defined by name.
@ -91,8 +91,8 @@ public:
virtual void RemoveFromRadioGroup(const nsAString& aName, nsIFormControl* aRadio) = 0;
virtual uint32_t GetRequiredRadioCount(const nsAString& aName) const = 0;
virtual void RadioRequiredChanged(const nsAString& aName,
nsIFormControl* aRadio) = 0;
virtual void RadioRequiredWillChange(const nsAString& aName,
bool aRequiredAdded) = 0;
virtual bool GetValueMissingState(const nsAString& aName) const = 0;
virtual void SetValueMissingState(const nsAString& aName, bool aValue) = 0;
};

View File

@ -6,6 +6,7 @@ support-files =
[test_bug1039548.html]
[test_button_attributes_reflection.html]
[test_input_radio_radiogroup.html]
[test_input_radio_required.html]
[test_change_event.html]
skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_datalist_element.html]

View File

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id={BUGNUMBER}
-->
<head>
<title>Test for Bug 1100535</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1100535">Mozilla Bug 1100535</a>
<p id="display"></p>
<div id="content" style="display: none">
<form>
<input type="radio" name="a">
</form>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var input = document.querySelector("input");
input.setAttribute("required", "x");
input.setAttribute("required", "y");
is(document.forms[0].checkValidity(), false);
input.required = false;
is(document.forms[0].checkValidity(), true);
</script>
</pre>
</body>
</html>