mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 635008 (3/4) - Keep track of the validity state of radio groups. r=bz a=hardblocker
This commit is contained in:
parent
1c0e6ffecf
commit
729c57b0b5
@ -502,6 +502,7 @@ struct nsRadioGroupStruct
|
|||||||
{
|
{
|
||||||
nsRadioGroupStruct()
|
nsRadioGroupStruct()
|
||||||
: mRequiredRadioCount(0)
|
: mRequiredRadioCount(0)
|
||||||
|
, mGroupSuffersFromValueMissing(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -510,6 +511,7 @@ struct nsRadioGroupStruct
|
|||||||
nsCOMPtr<nsIDOMHTMLInputElement> mSelectedRadioButton;
|
nsCOMPtr<nsIDOMHTMLInputElement> mSelectedRadioButton;
|
||||||
nsCOMArray<nsIFormControl> mRadioButtons;
|
nsCOMArray<nsIFormControl> mRadioButtons;
|
||||||
PRUint32 mRequiredRadioCount;
|
PRUint32 mRequiredRadioCount;
|
||||||
|
bool mGroupSuffersFromValueMissing;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -6806,6 +6808,34 @@ nsDocument::RadioRequiredChanged(const nsAString& aName, nsIFormControl* aRadio)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsDocument::GetValueMissingState(const nsAString& aName) const
|
||||||
|
{
|
||||||
|
nsRadioGroupStruct* radioGroup = nsnull;
|
||||||
|
// TODO: we should call GetRadioGroup here (and make it const) but for that
|
||||||
|
// we would need to have an explicit CreateRadioGroup() instead of create
|
||||||
|
// one when GetRadioGroup is called. See bug 636123.
|
||||||
|
nsAutoString tmKey(aName);
|
||||||
|
if (IsHTML())
|
||||||
|
ToLowerCase(tmKey); //should case-insensitive.
|
||||||
|
mRadioGroups.Get(tmKey, &radioGroup);
|
||||||
|
|
||||||
|
return radioGroup && radioGroup->mGroupSuffersFromValueMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDocument::SetValueMissingState(const nsAString& aName, bool aValue)
|
||||||
|
{
|
||||||
|
nsRadioGroupStruct* radioGroup = nsnull;
|
||||||
|
GetRadioGroup(aName, &radioGroup);
|
||||||
|
|
||||||
|
if (!radioGroup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
radioGroup->mGroupSuffersFromValueMissing = aValue;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
||||||
{
|
{
|
||||||
|
@ -793,6 +793,8 @@ public:
|
|||||||
virtual PRUint32 GetRequiredRadioCount(const nsAString& aName) const;
|
virtual PRUint32 GetRequiredRadioCount(const nsAString& aName) const;
|
||||||
virtual void RadioRequiredChanged(const nsAString& aName,
|
virtual void RadioRequiredChanged(const nsAString& aName,
|
||||||
nsIFormControl* aRadio);
|
nsIFormControl* aRadio);
|
||||||
|
virtual bool GetValueMissingState(const nsAString& aName) const;
|
||||||
|
virtual void SetValueMissingState(const nsAString& aName, bool aValue);
|
||||||
|
|
||||||
// for radio group
|
// for radio group
|
||||||
nsresult GetRadioGroup(const nsAString& aName,
|
nsresult GetRadioGroup(const nsAString& aName,
|
||||||
|
@ -138,8 +138,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIRadioGroupContainer,
|
|||||||
NS_IRADIOGROUPCONTAINER_IID)
|
NS_IRADIOGROUPCONTAINER_IID)
|
||||||
|
|
||||||
#define NS_IRADIOGROUPCONTAINER_MOZILLA_2_0_BRANCH_IID \
|
#define NS_IRADIOGROUPCONTAINER_MOZILLA_2_0_BRANCH_IID \
|
||||||
{ 0xdb6419eb, 0xff3d, 0x4bce, \
|
{ 0xaa9ec446, 0xcdc7, 0x4030, \
|
||||||
{ 0x9e, 0x4d, 0x47, 0x8c, 0x43, 0xb8, 0x1a, 0x10 } }
|
{ 0xab, 0x02, 0xda, 0x44, 0xee, 0xb1, 0x80, 0x0a } }
|
||||||
|
|
||||||
class nsIRadioGroupContainer_MOZILLA_2_0_BRANCH : public nsIRadioGroupContainer
|
class nsIRadioGroupContainer_MOZILLA_2_0_BRANCH : public nsIRadioGroupContainer
|
||||||
{
|
{
|
||||||
@ -149,6 +149,8 @@ public:
|
|||||||
virtual PRUint32 GetRequiredRadioCount(const nsAString& aName) const = 0;
|
virtual PRUint32 GetRequiredRadioCount(const nsAString& aName) const = 0;
|
||||||
virtual void RadioRequiredChanged(const nsAString& aName,
|
virtual void RadioRequiredChanged(const nsAString& aName,
|
||||||
nsIFormControl* aRadio) = 0;
|
nsIFormControl* aRadio) = 0;
|
||||||
|
virtual bool GetValueMissingState(const nsAString& aName) const = 0;
|
||||||
|
virtual void SetValueMissingState(const nsAString& aName, bool aValue) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIRadioGroupContainer_MOZILLA_2_0_BRANCH,
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIRadioGroupContainer_MOZILLA_2_0_BRANCH,
|
||||||
|
@ -297,6 +297,8 @@ nsHTMLFormElement::Init()
|
|||||||
NS_ERROR_OUT_OF_MEMORY);
|
NS_ERROR_OUT_OF_MEMORY);
|
||||||
NS_ENSURE_TRUE(mRequiredRadioButtonCounts.Init(4),
|
NS_ENSURE_TRUE(mRequiredRadioButtonCounts.Init(4),
|
||||||
NS_ERROR_OUT_OF_MEMORY);
|
NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
NS_ENSURE_TRUE(mValueMissingRadioGroups.Init(4),
|
||||||
|
NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -1179,15 +1181,7 @@ nsHTMLFormElement::AddElement(nsGenericHTMLFormElement* aChild,
|
|||||||
AssertDocumentOrder(controlList, this);
|
AssertDocumentOrder(controlList, this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
|
||||||
// Notify the radio button it's been added to a group
|
|
||||||
//
|
|
||||||
PRInt32 type = aChild->GetType();
|
PRInt32 type = aChild->GetType();
|
||||||
if (type == NS_FORM_INPUT_RADIO) {
|
|
||||||
nsRefPtr<nsHTMLInputElement> radio =
|
|
||||||
static_cast<nsHTMLInputElement*>(aChild);
|
|
||||||
radio->AddedToRadioGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// If it is a password control, and the password manager has not yet been
|
// If it is a password control, and the password manager has not yet been
|
||||||
@ -1265,6 +1259,15 @@ nsHTMLFormElement::AddElement(nsGenericHTMLFormElement* aChild,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify the radio button it's been added to a group
|
||||||
|
// This has to be done _after_ UpdateValidity() call to prevent the element
|
||||||
|
// being count twice.
|
||||||
|
if (type == NS_FORM_INPUT_RADIO) {
|
||||||
|
nsRefPtr<nsHTMLInputElement> radio =
|
||||||
|
static_cast<nsHTMLInputElement*>(aChild);
|
||||||
|
radio->AddedToRadioGroup();
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2185,6 +2188,18 @@ nsHTMLFormElement::RadioRequiredChanged(const nsAString& aName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsHTMLFormElement::GetValueMissingState(const nsAString& aName) const
|
||||||
|
{
|
||||||
|
return mValueMissingRadioGroups.Get(aName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsHTMLFormElement::SetValueMissingState(const nsAString& aName, bool aValue)
|
||||||
|
{
|
||||||
|
mValueMissingRadioGroups.Put(aName, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// nsFormControlList implementation, this could go away if there were
|
// nsFormControlList implementation, this could go away if there were
|
||||||
|
@ -153,6 +153,8 @@ public:
|
|||||||
virtual PRUint32 GetRequiredRadioCount(const nsAString& aName) const;
|
virtual PRUint32 GetRequiredRadioCount(const nsAString& aName) const;
|
||||||
virtual void RadioRequiredChanged(const nsAString& aName,
|
virtual void RadioRequiredChanged(const nsAString& aName,
|
||||||
nsIFormControl* aRadio);
|
nsIFormControl* aRadio);
|
||||||
|
virtual bool GetValueMissingState(const nsAString& aName) const;
|
||||||
|
virtual void SetValueMissingState(const nsAString& aName, bool aValue);
|
||||||
|
|
||||||
// nsIContent
|
// nsIContent
|
||||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||||
@ -418,6 +420,8 @@ protected:
|
|||||||
nsInterfaceHashtable<nsStringCaseInsensitiveHashKey,nsIDOMHTMLInputElement> mSelectedRadioButtons;
|
nsInterfaceHashtable<nsStringCaseInsensitiveHashKey,nsIDOMHTMLInputElement> mSelectedRadioButtons;
|
||||||
/** The number of required radio button of each group */
|
/** The number of required radio button of each group */
|
||||||
nsDataHashtable<nsStringCaseInsensitiveHashKey,PRUint32> mRequiredRadioButtonCounts;
|
nsDataHashtable<nsStringCaseInsensitiveHashKey,PRUint32> mRequiredRadioButtonCounts;
|
||||||
|
/** The value missing state of each group */
|
||||||
|
nsDataHashtable<nsStringCaseInsensitiveHashKey,bool> mValueMissingRadioGroups;
|
||||||
/** Whether we are currently processing a submit event or not */
|
/** Whether we are currently processing a submit event or not */
|
||||||
PRPackedBool mGeneratingSubmit;
|
PRPackedBool mGeneratingSubmit;
|
||||||
/** Whether we are currently processing a reset event or not */
|
/** Whether we are currently processing a reset event or not */
|
||||||
|
@ -814,6 +814,9 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||||||
mType == NS_FORM_INPUT_RADIO &&
|
mType == NS_FORM_INPUT_RADIO &&
|
||||||
(mForm || !(GET_BOOLBIT(mBitField, BF_PARSER_CREATING)))) {
|
(mForm || !(GET_BOOLBIT(mBitField, BF_PARSER_CREATING)))) {
|
||||||
AddedToRadioGroup();
|
AddedToRadioGroup();
|
||||||
|
UpdateValueMissingValidityStateForRadio(false);
|
||||||
|
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID |
|
||||||
|
NS_EVENT_STATE_REQUIRED | NS_EVENT_STATE_OPTIONAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If @value is changed and BF_VALUE_CHANGED is false, @value is the value
|
// If @value is changed and BF_VALUE_CHANGED is false, @value is the value
|
||||||
@ -3494,6 +3497,13 @@ nsHTMLInputElement::AddedToRadioGroup()
|
|||||||
nsAutoString name;
|
nsAutoString name;
|
||||||
if (GetNameIfExists(name)) {
|
if (GetNameIfExists(name)) {
|
||||||
container->AddToRadioGroup(name, static_cast<nsIFormControl*>(this));
|
container->AddToRadioGroup(name, static_cast<nsIFormControl*>(this));
|
||||||
|
|
||||||
|
// We initialize the validity of the element to the validity of the group
|
||||||
|
// because we assume UpdateValueMissingState() will be called after.
|
||||||
|
nsCOMPtr<nsIRadioGroupContainer_MOZILLA_2_0_BRANCH> container2 =
|
||||||
|
do_QueryInterface(container);
|
||||||
|
SetValidityState(VALIDITY_STATE_VALUE_MISSING,
|
||||||
|
container2->GetValueMissingState(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3927,10 +3937,11 @@ nsHTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
|
|||||||
nsCOMPtr<nsIRadioGroupContainer_MOZILLA_2_0_BRANCH> container =
|
nsCOMPtr<nsIRadioGroupContainer_MOZILLA_2_0_BRANCH> container =
|
||||||
do_QueryInterface(c);
|
do_QueryInterface(c);
|
||||||
nsAutoString name;
|
nsAutoString name;
|
||||||
|
GetNameIfExists(name);
|
||||||
|
|
||||||
// If the current radio is required and not ignored, we can assume the entire
|
// If the current radio is required and not ignored, we can assume the entire
|
||||||
// group is required.
|
// group is required.
|
||||||
if (!required && container && GetNameIfExists(name)) {
|
if (!required && container && !name.IsEmpty()) {
|
||||||
required = (aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required))
|
required = (aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required))
|
||||||
? container->GetRequiredRadioCount(name) - 1
|
? container->GetRequiredRadioCount(name) - 1
|
||||||
: container->GetRequiredRadioCount(name);
|
: container->GetRequiredRadioCount(name);
|
||||||
@ -3938,6 +3949,10 @@ nsHTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
|
|||||||
|
|
||||||
valueMissing = required && !selected;
|
valueMissing = required && !selected;
|
||||||
|
|
||||||
|
if (container && !name.IsEmpty()) {
|
||||||
|
if (container->GetValueMissingState(name) != valueMissing) {
|
||||||
|
container->SetValueMissingState(name, valueMissing);
|
||||||
|
|
||||||
SetValidityState(VALIDITY_STATE_VALUE_MISSING, valueMissing);
|
SetValidityState(VALIDITY_STATE_VALUE_MISSING, valueMissing);
|
||||||
|
|
||||||
nsCOMPtr<nsIRadioVisitor> visitor =
|
nsCOMPtr<nsIRadioVisitor> visitor =
|
||||||
@ -3945,6 +3960,10 @@ nsHTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
|
|||||||
notify);
|
notify);
|
||||||
VisitGroup(visitor, notify);
|
VisitGroup(visitor, notify);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SetValidityState(VALIDITY_STATE_VALUE_MISSING, valueMissing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHTMLInputElement::UpdateValueMissingValidityState()
|
nsHTMLInputElement::UpdateValueMissingValidityState()
|
||||||
|
Loading…
Reference in New Issue
Block a user