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:
rods%netscape.com 2000-02-15 23:02:55 +00:00
Родитель 512277b8af
Коммит e0e813fecd
6 изменённых файлов: 222 добавлений и 46 удалений

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

@ -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 {