[Bug 901656] nsIRadioGroupContainer can use HTMLInputElement r=Ms2ger

This commit is contained in:
David Zbarsky 2013-08-09 21:17:51 -04:00
parent 237b3ec440
commit 0e2f11839b
6 changed files with 60 additions and 65 deletions

View File

@ -498,7 +498,7 @@ struct nsRadioGroupStruct
/**
* A strong pointer to the currently selected radio button.
*/
nsCOMPtr<nsIDOMHTMLInputElement> mSelectedRadioButton;
nsRefPtr<HTMLInputElement> mSelectedRadioButton;
nsCOMArray<nsIFormControl> mRadioButtons;
uint32_t mRequiredRadioCount;
bool mGroupSuffersFromValueMissing;
@ -1670,7 +1670,7 @@ RadioGroupsTraverser(const nsAString& aKey, nsRadioGroupStruct* aData,
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb,
"mRadioGroups entry->mSelectedRadioButton");
cb->NoteXPCOMChild(aData->mSelectedRadioButton);
cb->NoteXPCOMChild(ToSupports(aData->mSelectedRadioButton));
uint32_t i, count = aData->mRadioButtons.Count();
for (i = 0; i < count; ++i) {
@ -7272,13 +7272,13 @@ nsDocument::GetOrCreateRadioGroup(const nsAString& aName)
void
nsDocument::SetCurrentRadioButton(const nsAString& aName,
nsIDOMHTMLInputElement* aRadio)
HTMLInputElement* aRadio)
{
nsRadioGroupStruct* radioGroup = GetOrCreateRadioGroup(aName);
radioGroup->mSelectedRadioButton = aRadio;
}
nsIDOMHTMLInputElement*
HTMLInputElement*
nsDocument::GetCurrentRadioButton(const nsAString& aName)
{
return GetOrCreateRadioGroup(aName)->mSelectedRadioButton;
@ -7287,8 +7287,8 @@ nsDocument::GetCurrentRadioButton(const nsAString& aName)
NS_IMETHODIMP
nsDocument::GetNextRadioButton(const nsAString& aName,
const bool aPrevious,
nsIDOMHTMLInputElement* aFocusedRadio,
nsIDOMHTMLInputElement** aRadioOut)
HTMLInputElement* aFocusedRadio,
HTMLInputElement** aRadioOut)
{
// XXX Can we combine the HTML radio button method impls of
// nsDocument and nsHTMLFormControl?
@ -7300,7 +7300,7 @@ nsDocument::GetNextRadioButton(const nsAString& aName,
// Return the radio button relative to the focused radio button.
// If no radio is focused, get the radio relative to the selected one.
nsCOMPtr<nsIDOMHTMLInputElement> currentRadio;
nsRefPtr<HTMLInputElement> currentRadio;
if (aFocusedRadio) {
currentRadio = aFocusedRadio;
}
@ -7310,15 +7310,13 @@ nsDocument::GetNextRadioButton(const nsAString& aName,
return NS_ERROR_FAILURE;
}
}
nsCOMPtr<nsIFormControl> radioControl(do_QueryInterface(currentRadio));
int32_t index = radioGroup->mRadioButtons.IndexOf(radioControl);
int32_t index = radioGroup->mRadioButtons.IndexOf(currentRadio);
if (index < 0) {
return NS_ERROR_FAILURE;
}
int32_t numRadios = radioGroup->mRadioButtons.Count();
bool disabled;
nsCOMPtr<nsIDOMHTMLInputElement> radio;
nsRefPtr<HTMLInputElement> radio;
do {
if (aPrevious) {
if (--index < 0) {
@ -7328,12 +7326,12 @@ nsDocument::GetNextRadioButton(const nsAString& aName,
else if (++index >= numRadios) {
index = 0;
}
radio = do_QueryInterface(radioGroup->mRadioButtons[index]);
NS_ASSERTION(radio, "mRadioButtons holding a non-radio button");
radio->GetDisabled(&disabled);
} while (disabled && radio != currentRadio);
NS_ASSERTION(static_cast<nsGenericHTMLFormElement*>(radioGroup->mRadioButtons[index])->IsHTML(nsGkAtoms::input),
"mRadioButtons holding a non-radio button");
radio = static_cast<HTMLInputElement*>(radioGroup->mRadioButtons[index]);
} while (radio->Disabled() && radio != currentRadio);
NS_IF_ADDREF(*aRadioOut = radio);
radio.forget(aRadioOut);
return NS_OK;
}

View File

@ -726,13 +726,16 @@ public:
NS_IMETHOD WalkRadioGroup(const nsAString& aName,
nsIRadioVisitor* aVisitor,
bool aFlushContent) MOZ_OVERRIDE;
virtual void SetCurrentRadioButton(const nsAString& aName,
nsIDOMHTMLInputElement* aRadio) MOZ_OVERRIDE;
virtual nsIDOMHTMLInputElement* GetCurrentRadioButton(const nsAString& aName) MOZ_OVERRIDE;
NS_IMETHOD GetNextRadioButton(const nsAString& aName,
virtual void
SetCurrentRadioButton(const nsAString& aName,
mozilla::dom::HTMLInputElement* aRadio) MOZ_OVERRIDE;
virtual mozilla::dom::HTMLInputElement*
GetCurrentRadioButton(const nsAString& aName) MOZ_OVERRIDE;
NS_IMETHOD
GetNextRadioButton(const nsAString& aName,
const bool aPrevious,
nsIDOMHTMLInputElement* aFocusedRadio,
nsIDOMHTMLInputElement** aRadioOut) MOZ_OVERRIDE;
mozilla::dom::HTMLInputElement* aFocusedRadio,
mozilla::dom::HTMLInputElement** aRadioOut) MOZ_OVERRIDE;
virtual void AddToRadioGroup(const nsAString& aName,
nsIFormControl* aRadio) MOZ_OVERRIDE;
virtual void RemoveFromRadioGroup(const nsAString& aName,

View File

@ -7,11 +7,16 @@
#include "nsISupports.h"
class nsIDOMHTMLInputElement;
class nsString;
class nsIRadioVisitor;
class nsIFormControl;
namespace mozilla {
namespace dom {
class HTMLInputElement;
}
}
#define NS_IRADIOGROUPCONTAINER_IID \
{ 0x22924a01, 0x4360, 0x401b, \
{ 0xb1, 0xd1, 0x56, 0x8d, 0xf5, 0xa3, 0xda, 0x71 } }
@ -42,14 +47,14 @@ public:
* @param aRadio the currently selected radio button
*/
virtual void SetCurrentRadioButton(const nsAString& aName,
nsIDOMHTMLInputElement* aRadio) = 0;
mozilla::dom::HTMLInputElement* aRadio) = 0;
/**
* Get the current radio button in a group
* @param aName the group name
* @return the currently selected radio button
*/
virtual nsIDOMHTMLInputElement* GetCurrentRadioButton(const nsAString& aName) = 0;
virtual mozilla::dom::HTMLInputElement* GetCurrentRadioButton(const nsAString& aName) = 0;
/**
* Get the next/prev radio button in a group
@ -60,8 +65,8 @@ public:
*/
NS_IMETHOD GetNextRadioButton(const nsAString& aName,
const bool aPrevious,
nsIDOMHTMLInputElement* aFocusedRadio,
nsIDOMHTMLInputElement** aRadio) = 0;
mozilla::dom::HTMLInputElement* aFocusedRadio,
mozilla::dom::HTMLInputElement** aRadio) = 0;
/**
* Add radio button to radio group

View File

@ -38,7 +38,6 @@
#include "nsFormSubmissionConstants.h"
// radio buttons
#include "nsIDOMHTMLInputElement.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "nsIRadioVisitor.h"
@ -286,13 +285,13 @@ HTMLFormElement::Init()
// nsISupports
static PLDHashOperator
ElementTraverser(const nsAString& key, nsIDOMHTMLInputElement* element,
ElementTraverser(const nsAString& key, HTMLInputElement* element,
void* userArg)
{
nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback*>(userArg);
cb->NoteXPCOMChild(element);
cb->NoteXPCOMChild(ToSupports(element));
return PL_DHASH_NEXT;
}
@ -2119,12 +2118,12 @@ HTMLFormElement::IndexOfControl(nsIFormControl* aControl)
void
HTMLFormElement::SetCurrentRadioButton(const nsAString& aName,
nsIDOMHTMLInputElement* aRadio)
HTMLInputElement* aRadio)
{
mSelectedRadioButtons.Put(aName, aRadio);
}
nsIDOMHTMLInputElement*
HTMLInputElement*
HTMLFormElement::GetCurrentRadioButton(const nsAString& aName)
{
return mSelectedRadioButtons.GetWeak(aName);
@ -2133,14 +2132,14 @@ HTMLFormElement::GetCurrentRadioButton(const nsAString& aName)
NS_IMETHODIMP
HTMLFormElement::GetNextRadioButton(const nsAString& aName,
const bool aPrevious,
nsIDOMHTMLInputElement* aFocusedRadio,
nsIDOMHTMLInputElement** aRadioOut)
HTMLInputElement* aFocusedRadio,
HTMLInputElement** aRadioOut)
{
// Return the radio button relative to the focused radio button.
// If no radio is focused, get the radio relative to the selected one.
*aRadioOut = nullptr;
nsCOMPtr<nsIDOMHTMLInputElement> currentRadio;
nsRefPtr<HTMLInputElement> currentRadio;
if (aFocusedRadio) {
currentRadio = aFocusedRadio;
}
@ -2155,18 +2154,14 @@ HTMLFormElement::GetNextRadioButton(const nsAString& aName,
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIContent> currentRadioNode(do_QueryInterface(currentRadio));
NS_ASSERTION(currentRadioNode, "No nsIContent for current radio button");
int32_t index = radioGroup->IndexOf(currentRadioNode);
int32_t index = radioGroup->IndexOf(currentRadio);
if (index < 0) {
return NS_ERROR_FAILURE;
}
uint32_t numRadios;
radioGroup->GetLength(&numRadios);
bool disabled = true;
nsCOMPtr<nsIDOMHTMLInputElement> radio;
nsCOMPtr<nsIFormControl> formControl;
nsRefPtr<HTMLInputElement> radio;
do {
if (aPrevious) {
@ -2177,17 +2172,14 @@ HTMLFormElement::GetNextRadioButton(const nsAString& aName,
else if (++index >= (int32_t)numRadios) {
index = 0;
}
radio = do_QueryInterface(radioGroup->Item(index));
radio = HTMLInputElement::FromContentOrNull(radioGroup->Item(index));
if (!radio)
continue;
// XXXbz why is this formControl check needed, exactly?
formControl = do_QueryInterface(radio);
if (!formControl || formControl->GetType() != NS_FORM_INPUT_RADIO)
if (radio->GetType() != NS_FORM_INPUT_RADIO)
continue;
radio->GetDisabled(&disabled);
} while (disabled && radio != currentRadio);
} while (radio->Disabled() && radio != currentRadio);
NS_IF_ADDREF(*aRadioOut = radio);
return NS_OK;

View File

@ -18,6 +18,7 @@
#include "nsIWeakReferenceUtils.h"
#include "nsThreadUtils.h"
#include "nsInterfaceHashtable.h"
#include "nsRefPtrHashtable.h"
#include "nsDataHashtable.h"
#include "nsAsyncDOMEvent.h"
@ -66,12 +67,12 @@ public:
// nsIRadioGroupContainer
void SetCurrentRadioButton(const nsAString& aName,
nsIDOMHTMLInputElement* aRadio) MOZ_OVERRIDE;
nsIDOMHTMLInputElement* GetCurrentRadioButton(const nsAString& aName) MOZ_OVERRIDE;
HTMLInputElement* aRadio) MOZ_OVERRIDE;
HTMLInputElement* GetCurrentRadioButton(const nsAString& aName) MOZ_OVERRIDE;
NS_IMETHOD GetNextRadioButton(const nsAString& aName,
const bool aPrevious,
nsIDOMHTMLInputElement* aFocusedRadio,
nsIDOMHTMLInputElement** aRadioOut) MOZ_OVERRIDE;
HTMLInputElement* aFocusedRadio,
HTMLInputElement** aRadioOut) MOZ_OVERRIDE;
NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor,
bool aFlushContent) MOZ_OVERRIDE;
void AddToRadioGroup(const nsAString& aName, nsIFormControl* aRadio) MOZ_OVERRIDE;
@ -538,7 +539,7 @@ protected:
/** The list of controls (form.elements as well as stuff not in elements) */
nsRefPtr<nsFormControlList> mControls;
/** The currently selected radio button of each group */
nsInterfaceHashtable<nsStringCaseInsensitiveHashKey,nsIDOMHTMLInputElement> mSelectedRadioButtons;
nsRefPtrHashtable<nsStringCaseInsensitiveHashKey, HTMLInputElement> mSelectedRadioButtons;
/** The number of required radio button of each group */
nsDataHashtable<nsStringCaseInsensitiveHashKey,uint32_t> mRequiredRadioButtonCounts;
/** The value missing state of each group */

View File

@ -3111,21 +3111,18 @@ HTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
if (container) {
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
nsRefPtr<HTMLInputElement> selectedRadioButton;
container->GetNextRadioButton(name, isMovingBack, this,
getter_AddRefs(selectedRadioButton));
nsCOMPtr<nsIContent> radioContent =
do_QueryInterface(selectedRadioButton);
if (radioContent) {
nsCOMPtr<nsIDOMHTMLElement> elem = do_QueryInterface(selectedRadioButton);
rv = elem->Focus();
if (selectedRadioButton) {
rv = selectedRadioButton->Focus();
if (NS_SUCCEEDED(rv)) {
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(aVisitor.mEvent->mFlags.mIsTrusted,
NS_MOUSE_CLICK, nullptr,
nsMouseEvent::eReal);
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
rv = nsEventDispatcher::Dispatch(radioContent,
rv = nsEventDispatcher::Dispatch(ToSupports(selectedRadioButton),
aVisitor.mPresContext,
&event, nullptr, &status);
if (NS_SUCCEEDED(rv)) {
@ -4975,8 +4972,7 @@ HTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable, int32_t*
nsAutoString name;
GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
nsCOMPtr<nsIDOMHTMLInputElement> currentRadio = container->GetCurrentRadioButton(name);
if (currentRadio) {
if (container->GetCurrentRadioButton(name)) {
*aTabIndex = -1;
}
*aIsFocusable = defaultFocusable;