Bug 641720 - Make nsHTMLInputElement::GetRadioGroupContainer saner. r=sicking,bz

This commit is contained in:
Mounir Lamouri 2011-05-04 14:45:47 +02:00
Родитель 75fc1888ff
Коммит ad4633017a
2 изменённых файлов: 103 добавлений и 124 удалений

Просмотреть файл

@ -909,12 +909,13 @@ nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
}
if (mType == NS_FORM_INPUT_RADIO && aName == nsGkAtoms::required) {
nsCOMPtr<nsIRadioGroupContainer> c = GetRadioGroupContainer();
nsIRadioGroupContainer* c = GetRadioGroupContainer();
nsCOMPtr<nsIRadioGroupContainer_MOZILLA_2_0_BRANCH> container =
do_QueryInterface(c);
nsAutoString name;
if (container && GetNameIfExists(name)) {
if (container) {
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
container->RadioRequiredChanged(name, this);
}
}
@ -1576,13 +1577,12 @@ nsHTMLInputElement::DoSetChecked(PRBool aChecked, PRBool aNotify,
if (aChecked) {
rv = RadioSetChecked(aNotify);
} else {
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (container) {
nsAutoString name;
if (GetNameIfExists(name)) {
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
container->SetCurrentRadioButton(name, nsnull);
}
}
// SetCheckedInternal is going to ask all radios to update their
// validity state. We have to be sure the radio group container knows
// the currently selected radio.
@ -1618,9 +1618,10 @@ nsHTMLInputElement::RadioSetChecked(PRBool aNotify)
//
// Let the group know that we are now the One True Radio Button
//
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (container) {
nsAutoString name;
if (container && GetNameIfExists(name)) {
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
rv = container->SetCurrentRadioButton(name, this);
}
@ -1634,35 +1635,40 @@ nsHTMLInputElement::RadioSetChecked(PRBool aNotify)
return rv;
}
/* virtual */ already_AddRefed<nsIRadioGroupContainer>
nsHTMLInputElement::GetRadioGroupContainer()
nsIRadioGroupContainer*
nsHTMLInputElement::GetRadioGroupContainer() const
{
nsIRadioGroupContainer* retval = nsnull;
NS_ASSERTION(mType == NS_FORM_INPUT_RADIO,
"GetRadioGroupContainer should only be called when type='radio'");
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
if (name.IsEmpty()) {
return nsnull;
}
if (mForm) {
CallQueryInterface(mForm, &retval);
} else {
nsIDocument* currentDoc = GetCurrentDoc();
if (currentDoc) {
CallQueryInterface(currentDoc, &retval);
return mForm;
}
}
return retval;
nsIDocument* doc = GetCurrentDoc();
nsCOMPtr<nsIRadioGroupContainer> group = do_QueryInterface(doc);
return group.get();
}
already_AddRefed<nsIDOMHTMLInputElement>
nsHTMLInputElement::GetSelectedRadioButton()
{
nsIDOMHTMLInputElement* selected;
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (!container) {
return nsnull;
}
nsAutoString name;
if (!GetNameIfExists(name)) {
return nsnull;
}
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
container->GetCurrentRadioButton(name, &selected);
return selected;
@ -2279,10 +2285,10 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
case NS_VK_DOWN:
case NS_VK_RIGHT:
// Arrow key pressed, focus+select prev/next radio button
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (container) {
nsAutoString name;
if (GetNameIfExists(name)) {
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
container->GetNextRadioButton(name, isMovingBack, this,
getter_AddRefs(selectedRadioButton));
@ -2307,7 +2313,6 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
}
}
}
}
/*
* For some input types, if the user hits enter, the form is submitted.
@ -3406,7 +3411,7 @@ nsHTMLInputElement::AddedToRadioGroup()
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
if (container) {
nsAutoString name;
if (GetNameIfExists(name)) {
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
container->AddToRadioGroup(name, static_cast<nsIFormControl*>(this));
// We initialize the validity of the element to the validity of the group
@ -3416,59 +3421,30 @@ nsHTMLInputElement::AddedToRadioGroup()
SetValidityState(VALIDITY_STATE_VALUE_MISSING,
container2->GetValueMissingState(name));
}
}
}
void
nsHTMLInputElement::WillRemoveFromRadioGroup()
{
//
// If the input element is not in a form and
// not in a document, we just need to return.
//
if (!mForm && !(IsInDoc() && GetParent())) {
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (!container) {
return;
}
//
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
// If this button was checked, we need to notify the group that there is no
// longer a selected radio button
//
nsAutoString name;
PRBool gotName = PR_FALSE;
if (GetChecked()) {
if (!gotName) {
if (!GetNameIfExists(name)) {
// If the name doesn't exist, nothing is going to happen anyway
return;
}
gotName = PR_TRUE;
}
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
if (container) {
container->SetCurrentRadioButton(name, nsnull);
}
}
//
// Remove this radio from its group in the container
//
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
if (container) {
if (!gotName) {
if (!GetNameIfExists(name)) {
// If the name doesn't exist, nothing is going to happen anyway
return;
}
gotName = PR_TRUE;
}
// Remove this radio from its group in the container.
// We need to call UpdateValueMissingValidityStateForRadio before to make sure
// the group validity is updated (with this element being ignored).
UpdateValueMissingValidityStateForRadio(true);
container->RemoveFromRadioGroup(name,
static_cast<nsIFormControl*>(this));
}
container->RemoveFromRadioGroup(name, static_cast<nsIFormControl*>(this));
}
PRBool
@ -3529,13 +3505,15 @@ nsHTMLInputElement::IsHTMLFocusable(PRBool aWithMouse, PRBool *aIsFocusable, PRI
// Current radio button is not selected.
// But make it tabbable if nothing in group is selected.
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
nsAutoString name;
if (!container || !GetNameIfExists(name)) {
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (!container) {
*aIsFocusable = defaultFocusable;
return PR_FALSE;
}
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
nsCOMPtr<nsIDOMHTMLInputElement> currentRadio;
container->GetCurrentRadioButton(name, getter_AddRefs(currentRadio));
if (currentRadio) {
@ -3548,19 +3526,15 @@ nsHTMLInputElement::IsHTMLFocusable(PRBool aWithMouse, PRBool *aIsFocusable, PRI
nsresult
nsHTMLInputElement::VisitGroup(nsIRadioVisitor* aVisitor, PRBool aFlushContent)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (container) {
nsAutoString name;
if (GetNameIfExists(name)) {
rv = container->WalkRadioGroup(name, aVisitor, aFlushContent);
} else {
aVisitor->Visit(this);
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
return container->WalkRadioGroup(name, aVisitor, aFlushContent);
}
} else {
aVisitor->Visit(this);
}
return rv;
return NS_OK;
}
nsHTMLInputElement::ValueModeType
@ -3839,15 +3813,21 @@ nsHTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
: HasAttr(kNameSpaceID_None, nsGkAtoms::required);
bool valueMissing = false;
nsCOMPtr<nsIRadioGroupContainer> c = GetRadioGroupContainer();
nsIRadioGroupContainer* c = GetRadioGroupContainer();
nsCOMPtr<nsIRadioGroupContainer_MOZILLA_2_0_BRANCH> container =
do_QueryInterface(c);
if (!container) {
SetValidityState(VALIDITY_STATE_VALUE_MISSING, required && !selected);
return;
}
nsAutoString name;
GetNameIfExists(name);
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
// If the current radio is required and not ignored, we can assume the entire
// group is required.
if (!required && container && !name.IsEmpty()) {
if (!required) {
required = (aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required))
? container->GetRequiredRadioCount(name) - 1
: container->GetRequiredRadioCount(name);
@ -3855,7 +3835,6 @@ nsHTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
valueMissing = required && !selected;
if (container && !name.IsEmpty()) {
if (container->GetValueMissingState(name) != valueMissing) {
container->SetValueMissingState(name, valueMissing);
@ -3865,9 +3844,6 @@ nsHTMLInputElement::UpdateValueMissingValidityStateForRadio(bool aIgnoreSelf)
new nsRadioSetValueMissingState(this, valueMissing, notify);
VisitGroup(visitor, notify);
}
} else {
SetValidityState(VALIDITY_STATE_VALUE_MISSING, valueMissing);
}
}
void

Просмотреть файл

@ -225,11 +225,6 @@ public:
}
void AddedToRadioGroup();
void WillRemoveFromRadioGroup();
/**
* Get the radio group container for this button (form or document)
* @return the radio group container (or null if no form or document)
*/
virtual already_AddRefed<nsIRadioGroupContainer> GetRadioGroupContainer();
/**
* Helper function returning the currently selected button in the radio group.
@ -577,6 +572,14 @@ protected:
}
}
/**
* Returns the radio group container if the element has one, null otherwise.
* The radio group container will be the form owner if there is one.
* The current document otherwise.
* @return the radio group container if the element has one, null otherwise.
*/
nsIRadioGroupContainer* GetRadioGroupContainer() const;
nsCOMPtr<nsIControllers> mControllers;
/**