зеркало из https://github.com/mozilla/gecko-dev.git
Bug 641720 - Make nsHTMLInputElement::GetRadioGroupContainer saner. r=sicking,bz
This commit is contained in:
Родитель
75fc1888ff
Коммит
ad4633017a
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче