зеркало из https://github.com/mozilla/gecko-dev.git
radio button now remembers state, and in standard mode it will always select
the first item. It will also perform rradiobutton behavior when the frame are hidden (no existent) b=27063 r=kmcclusk
This commit is contained in:
Родитель
512277b8af
Коммит
e0e813fecd
|
@ -53,6 +53,8 @@
|
|||
#include "nsISizeOfHandler.h"
|
||||
|
||||
#include "nsIPresState.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
|
||||
// XXX align=left, hspace, vspace, border? other nav4 attrs
|
||||
|
||||
|
@ -198,6 +200,11 @@ public:
|
|||
NS_IMETHOD SetBinding(nsIXBLBinding* aBinding);
|
||||
NS_IMETHOD GetBinding(nsIXBLBinding** aResult);
|
||||
|
||||
// Helper method
|
||||
NS_IMETHOD SetPresStateChecked(nsIHTMLContent * aHTMLContent,
|
||||
nsIStatefulFrame::StateType aStateType,
|
||||
PRBool aValue);
|
||||
|
||||
protected:
|
||||
nsGenericHTMLLeafElement mInner;
|
||||
nsIForm* mForm;
|
||||
|
@ -524,7 +531,11 @@ nsHTMLInputElement::GetChecked(PRBool* aValue)
|
|||
else {
|
||||
// Retrieve the presentation state instead.
|
||||
nsCOMPtr<nsIPresState> presState;
|
||||
nsGenericHTMLElement::GetPrimaryPresState(this, nsIStatefulFrame::eCheckboxType, getter_AddRefs(presState));
|
||||
PRInt32 type;
|
||||
GetType(&type);
|
||||
nsIStatefulFrame::StateType stateType = (type == NS_FORM_INPUT_CHECKBOX?nsIStatefulFrame::eCheckboxType:
|
||||
nsIStatefulFrame::eRadioType);
|
||||
nsGenericHTMLElement::GetPrimaryPresState(this, stateType, getter_AddRefs(presState));
|
||||
|
||||
// Obtain the value property from the presentation state.
|
||||
if (presState) {
|
||||
|
@ -540,34 +551,92 @@ nsHTMLInputElement::GetChecked(PRBool* aValue)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::SetPresStateChecked(nsIHTMLContent * aHTMLContent,
|
||||
nsIStatefulFrame::StateType aStateType,
|
||||
PRBool aValue)
|
||||
{
|
||||
nsCOMPtr<nsIPresState> presState;
|
||||
nsGenericHTMLElement::GetPrimaryPresState(aHTMLContent, aStateType, getter_AddRefs(presState));
|
||||
|
||||
// Obtain the value property from the presentation state.
|
||||
if (presState) {
|
||||
nsAutoString value;
|
||||
if (PR_TRUE == aValue)
|
||||
value = "1";
|
||||
else
|
||||
value = "0";
|
||||
presState->SetStateProperty("checked", value);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::SetChecked(PRBool aValue)
|
||||
{
|
||||
nsIFormControlFrame* formControlFrame = nsnull;
|
||||
if (NS_OK == nsGenericHTMLElement::GetPrimaryFrame(this, formControlFrame)) {
|
||||
|
||||
// First check to see if the new value
|
||||
// is different than our current Value
|
||||
// if so, then return
|
||||
nsAutoString checkedStr;
|
||||
formControlFrame->GetProperty(nsHTMLAtoms::checked, checkedStr);
|
||||
if ((checkedStr.Equals("1") && aValue) || (checkedStr.Equals("0") && !aValue)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// the value is being toggled
|
||||
nsIPresContext* presContext;
|
||||
nsGenericHTMLElement::GetPresContext(this, &presContext);
|
||||
if (PR_TRUE == aValue) {
|
||||
formControlFrame->SetProperty(presContext, nsHTMLAtoms::checked, "1");
|
||||
}
|
||||
else {
|
||||
formControlFrame->SetProperty(presContext, nsHTMLAtoms::checked, "0");
|
||||
}
|
||||
formControlFrame->SetProperty(presContext, nsHTMLAtoms::checked, PR_TRUE == aValue?"1":"0");
|
||||
NS_IF_RELEASE(presContext);
|
||||
}
|
||||
else {
|
||||
// Retrieve the presentation state instead.
|
||||
nsCOMPtr<nsIPresState> presState;
|
||||
nsGenericHTMLElement::GetPrimaryPresState(this, nsIStatefulFrame::eCheckboxType, getter_AddRefs(presState));
|
||||
PRInt32 type;
|
||||
GetType(&type);
|
||||
nsIStatefulFrame::StateType stateType = (type == NS_FORM_INPUT_CHECKBOX?nsIStatefulFrame::eCheckboxType:
|
||||
nsIStatefulFrame::eRadioType);
|
||||
if (NS_FAILED(SetPresStateChecked(this, stateType, aValue))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Obtain the value property from the presentation state.
|
||||
if (presState) {
|
||||
nsAutoString value;
|
||||
if (PR_TRUE == aValue)
|
||||
value = "1";
|
||||
else value = "0";
|
||||
presState->SetStateProperty("checked", value);
|
||||
if (stateType == nsIStatefulFrame::eRadioType) {
|
||||
nsIDOMHTMLInputElement * radioElement = (nsIDOMHTMLInputElement*)this;
|
||||
nsAutoString name;
|
||||
GetName(name);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> formElement;
|
||||
if (NS_SUCCEEDED(GetForm(getter_AddRefs(formElement)))) {
|
||||
nsCOMPtr<nsIDOMHTMLCollection> controls;
|
||||
nsresult rv = formElement->GetElements(getter_AddRefs(controls));
|
||||
if (controls) {
|
||||
if (NS_SUCCEEDED(rv) && nsnull != controls) {
|
||||
PRUint32 numControls;
|
||||
controls->GetLength(&numControls);
|
||||
for (PRUint32 i = 0; i < numControls; i++) {
|
||||
nsCOMPtr<nsIDOMNode> elementNode;
|
||||
controls->Item(i, getter_AddRefs(elementNode));
|
||||
if (elementNode) {
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(elementNode));
|
||||
if (NS_SUCCEEDED(rv) && inputElement && (radioElement != inputElement.get())) {
|
||||
nsAutoString childName;
|
||||
rv = inputElement->GetName(childName);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (name == childName) {
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(inputElement);
|
||||
SetPresStateChecked(htmlContent, nsIStatefulFrame::eRadioType, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,10 +126,17 @@ NS_IMETHODIMP nsGfxRadioControlFrame::SetProperty(nsIPresContext* aPresContext,
|
|||
{
|
||||
if (nsHTMLAtoms::checked == aName) {
|
||||
PRBool state = (aValue == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE;
|
||||
SetRadioState(aPresContext, state);
|
||||
|
||||
|
||||
// if there is no form than the radiobtn is an orphan
|
||||
if (mFormFrame) {
|
||||
mFormFrame->OnRadioChecked(aPresContext, *this, state);
|
||||
// if this failed then it didn't have a named radio group
|
||||
if (NS_FAILED(mFormFrame->OnRadioChecked(aPresContext, *this, state))) {
|
||||
// The line below is commented out to duplicate NavQuirks behavior
|
||||
//SetRadioState(aPresContext, state);
|
||||
}
|
||||
} else {
|
||||
SetRadioState(aPresContext, state);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#include "nsISizeOfHandler.h"
|
||||
|
||||
#include "nsIPresState.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
|
||||
// XXX align=left, hspace, vspace, border? other nav4 attrs
|
||||
|
||||
|
@ -198,6 +200,11 @@ public:
|
|||
NS_IMETHOD SetBinding(nsIXBLBinding* aBinding);
|
||||
NS_IMETHOD GetBinding(nsIXBLBinding** aResult);
|
||||
|
||||
// Helper method
|
||||
NS_IMETHOD SetPresStateChecked(nsIHTMLContent * aHTMLContent,
|
||||
nsIStatefulFrame::StateType aStateType,
|
||||
PRBool aValue);
|
||||
|
||||
protected:
|
||||
nsGenericHTMLLeafElement mInner;
|
||||
nsIForm* mForm;
|
||||
|
@ -524,7 +531,11 @@ nsHTMLInputElement::GetChecked(PRBool* aValue)
|
|||
else {
|
||||
// Retrieve the presentation state instead.
|
||||
nsCOMPtr<nsIPresState> presState;
|
||||
nsGenericHTMLElement::GetPrimaryPresState(this, nsIStatefulFrame::eCheckboxType, getter_AddRefs(presState));
|
||||
PRInt32 type;
|
||||
GetType(&type);
|
||||
nsIStatefulFrame::StateType stateType = (type == NS_FORM_INPUT_CHECKBOX?nsIStatefulFrame::eCheckboxType:
|
||||
nsIStatefulFrame::eRadioType);
|
||||
nsGenericHTMLElement::GetPrimaryPresState(this, stateType, getter_AddRefs(presState));
|
||||
|
||||
// Obtain the value property from the presentation state.
|
||||
if (presState) {
|
||||
|
@ -540,34 +551,92 @@ nsHTMLInputElement::GetChecked(PRBool* aValue)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::SetPresStateChecked(nsIHTMLContent * aHTMLContent,
|
||||
nsIStatefulFrame::StateType aStateType,
|
||||
PRBool aValue)
|
||||
{
|
||||
nsCOMPtr<nsIPresState> presState;
|
||||
nsGenericHTMLElement::GetPrimaryPresState(aHTMLContent, aStateType, getter_AddRefs(presState));
|
||||
|
||||
// Obtain the value property from the presentation state.
|
||||
if (presState) {
|
||||
nsAutoString value;
|
||||
if (PR_TRUE == aValue)
|
||||
value = "1";
|
||||
else
|
||||
value = "0";
|
||||
presState->SetStateProperty("checked", value);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::SetChecked(PRBool aValue)
|
||||
{
|
||||
nsIFormControlFrame* formControlFrame = nsnull;
|
||||
if (NS_OK == nsGenericHTMLElement::GetPrimaryFrame(this, formControlFrame)) {
|
||||
|
||||
// First check to see if the new value
|
||||
// is different than our current Value
|
||||
// if so, then return
|
||||
nsAutoString checkedStr;
|
||||
formControlFrame->GetProperty(nsHTMLAtoms::checked, checkedStr);
|
||||
if ((checkedStr.Equals("1") && aValue) || (checkedStr.Equals("0") && !aValue)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// the value is being toggled
|
||||
nsIPresContext* presContext;
|
||||
nsGenericHTMLElement::GetPresContext(this, &presContext);
|
||||
if (PR_TRUE == aValue) {
|
||||
formControlFrame->SetProperty(presContext, nsHTMLAtoms::checked, "1");
|
||||
}
|
||||
else {
|
||||
formControlFrame->SetProperty(presContext, nsHTMLAtoms::checked, "0");
|
||||
}
|
||||
formControlFrame->SetProperty(presContext, nsHTMLAtoms::checked, PR_TRUE == aValue?"1":"0");
|
||||
NS_IF_RELEASE(presContext);
|
||||
}
|
||||
else {
|
||||
// Retrieve the presentation state instead.
|
||||
nsCOMPtr<nsIPresState> presState;
|
||||
nsGenericHTMLElement::GetPrimaryPresState(this, nsIStatefulFrame::eCheckboxType, getter_AddRefs(presState));
|
||||
PRInt32 type;
|
||||
GetType(&type);
|
||||
nsIStatefulFrame::StateType stateType = (type == NS_FORM_INPUT_CHECKBOX?nsIStatefulFrame::eCheckboxType:
|
||||
nsIStatefulFrame::eRadioType);
|
||||
if (NS_FAILED(SetPresStateChecked(this, stateType, aValue))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Obtain the value property from the presentation state.
|
||||
if (presState) {
|
||||
nsAutoString value;
|
||||
if (PR_TRUE == aValue)
|
||||
value = "1";
|
||||
else value = "0";
|
||||
presState->SetStateProperty("checked", value);
|
||||
if (stateType == nsIStatefulFrame::eRadioType) {
|
||||
nsIDOMHTMLInputElement * radioElement = (nsIDOMHTMLInputElement*)this;
|
||||
nsAutoString name;
|
||||
GetName(name);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> formElement;
|
||||
if (NS_SUCCEEDED(GetForm(getter_AddRefs(formElement)))) {
|
||||
nsCOMPtr<nsIDOMHTMLCollection> controls;
|
||||
nsresult rv = formElement->GetElements(getter_AddRefs(controls));
|
||||
if (controls) {
|
||||
if (NS_SUCCEEDED(rv) && nsnull != controls) {
|
||||
PRUint32 numControls;
|
||||
controls->GetLength(&numControls);
|
||||
for (PRUint32 i = 0; i < numControls; i++) {
|
||||
nsCOMPtr<nsIDOMNode> elementNode;
|
||||
controls->Item(i, getter_AddRefs(elementNode));
|
||||
if (elementNode) {
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(elementNode));
|
||||
if (NS_SUCCEEDED(rv) && inputElement && (radioElement != inputElement.get())) {
|
||||
nsAutoString childName;
|
||||
rv = inputElement->GetName(childName);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (name == childName) {
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent = do_QueryInterface(inputElement);
|
||||
SetPresStateChecked(htmlContent, nsIStatefulFrame::eRadioType, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -442,7 +442,6 @@ void nsFormFrame::DoDefaultSelection(nsIPresContext* aPresContext,
|
|||
nsCOMPtr<nsIDOMHTMLInputElement> input(do_QueryInterface(content));
|
||||
if (input) {
|
||||
input->SetChecked(PR_TRUE);
|
||||
//OnRadioChecked(aPresContext, *radioBtn, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -521,13 +520,19 @@ void nsFormFrame::RemoveRadioControlFrame(nsIFormControlFrame * aFrame)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext, nsGfxRadioControlFrame& aControl, PRBool aChecked)
|
||||
//--------------------------------------------------------
|
||||
// returns NS_ERROR_FAILURE if the radiobtn doesn't have a group
|
||||
// returns NS_OK is it did have a radio group
|
||||
//--------------------------------------------------------
|
||||
nsresult
|
||||
nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext,
|
||||
nsGfxRadioControlFrame& aControl,
|
||||
PRBool aNewCheckedVal)
|
||||
{
|
||||
nsString radioName;
|
||||
aControl.GetName(&radioName);
|
||||
if (0 == radioName.Length()) { // don't consider a radio without a name
|
||||
return;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// locate the radio group with the name of aRadio
|
||||
|
@ -536,20 +541,35 @@ nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext, nsGfxRadioControlFrame
|
|||
nsRadioControlGroup* group = (nsRadioControlGroup *) mRadioGroups.ElementAt(j);
|
||||
nsString groupName;
|
||||
group->GetName(groupName);
|
||||
nsGfxRadioControlFrame* checkedRadio = group->GetCheckedRadio();
|
||||
// get the currently checked radio button
|
||||
nsGfxRadioControlFrame* currentCheckBtn = group->GetCheckedRadio();
|
||||
if (groupName.Equals(radioName)) {
|
||||
if (aChecked) {
|
||||
if (&aControl != checkedRadio) {
|
||||
if (checkedRadio) {
|
||||
checkedRadio->SetChecked(aPresContext, PR_FALSE, PR_FALSE);
|
||||
// is the new checked btn different than the current button?
|
||||
if (&aControl != currentCheckBtn) {
|
||||
// if the new button is being set to false
|
||||
// then don't do anything
|
||||
if (aNewCheckedVal) {
|
||||
// the current btn could be null
|
||||
if (currentCheckBtn != nsnull) {
|
||||
currentCheckBtn->SetChecked(aPresContext, !aNewCheckedVal, PR_FALSE);
|
||||
}
|
||||
aControl.SetChecked(aPresContext, aNewCheckedVal, PR_FALSE);
|
||||
group->SetCheckedRadio(&aControl);
|
||||
}
|
||||
} else if (&aControl == checkedRadio) {
|
||||
checkedRadio->SetChecked(aPresContext, PR_FALSE, PR_FALSE);
|
||||
} else {
|
||||
// here we are setting the same radio button
|
||||
// as the one that is currently checked
|
||||
//
|
||||
currentCheckBtn->SetChecked(aPresContext, aNewCheckedVal, PR_FALSE);
|
||||
// So if we are setting the current btn to be 0 or off
|
||||
// then we must set a default selction
|
||||
if (!aNewCheckedVal) {
|
||||
DoDefaultSelection(aPresContext, group, currentCheckBtn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,7 +65,11 @@ public:
|
|||
|
||||
// other methods
|
||||
|
||||
void OnRadioChecked(nsIPresContext* aPresContext, nsGfxRadioControlFrame& aRadio, PRBool aChecked = PR_TRUE);
|
||||
//--------------------------------------------------------
|
||||
// returns NS_ERROR_FAILURE if the radiobtn doesn't have a group
|
||||
// returns NS_OK is it did have a radio group
|
||||
//--------------------------------------------------------
|
||||
nsresult OnRadioChecked(nsIPresContext* aPresContext, nsGfxRadioControlFrame& aRadio, PRBool aChecked = PR_TRUE);
|
||||
|
||||
void AddFormControlFrame(nsIPresContext* aPresContext, nsIFormControlFrame& aFrame);
|
||||
static void AddFormControlFrame(nsIPresContext* aPresContext, nsIFrame& aFrame);
|
||||
|
|
|
@ -126,10 +126,17 @@ NS_IMETHODIMP nsGfxRadioControlFrame::SetProperty(nsIPresContext* aPresContext,
|
|||
{
|
||||
if (nsHTMLAtoms::checked == aName) {
|
||||
PRBool state = (aValue == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE;
|
||||
SetRadioState(aPresContext, state);
|
||||
|
||||
|
||||
// if there is no form than the radiobtn is an orphan
|
||||
if (mFormFrame) {
|
||||
mFormFrame->OnRadioChecked(aPresContext, *this, state);
|
||||
// if this failed then it didn't have a named radio group
|
||||
if (NS_FAILED(mFormFrame->OnRadioChecked(aPresContext, *this, state))) {
|
||||
// The line below is commented out to duplicate NavQuirks behavior
|
||||
//SetRadioState(aPresContext, state);
|
||||
}
|
||||
} else {
|
||||
SetRadioState(aPresContext, state);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче