fixed so script can find out if an option is selected when no frame exists

no all DOM calls can be made on a select or an option with or without a frame
and the results will be correct
All the PresState info (for now) is kept in the select content, a couple of new
methods were added to nsISelectElement to make it easier for the option to
Get/Set its index
Bug 45760 r=kmcclusk
This commit is contained in:
rods%netscape.com 2000-09-05 13:37:16 +00:00
Родитель 79fb5e0d32
Коммит 2ec6128d8f
6 изменённых файлов: 486 добавлений и 102 удалений

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

@ -29,6 +29,7 @@
{ 0xa6cf90f6, 0x15b3, 0x11d2, \
{ 0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
class nsIDOMHTMLOptionElement;
/**
* This interface is used to notify a SELECT when OPTION
@ -65,6 +66,17 @@ public:
* to the select during document loading.
*/
NS_IMETHOD IsDoneAddingContent(PRBool * aIsDone) = 0;
/**
* Returns whether we're the option is selected
*/
NS_IMETHOD IsOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool * aIsSelected) = 0;
/**
* Sets an option selected or delselected
*/
NS_IMETHOD SetOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool aIsSelected) = 0;
};
#endif // nsISelectElement_h___

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

@ -222,6 +222,9 @@ nsHTMLOptionElement::GetForm(nsIDOMHTMLFormElement** aForm)
NS_IMETHODIMP
nsHTMLOptionElement::GetSelected(PRBool* aValue)
{
NS_ENSURE_ARG_POINTER(aValue);
*aValue = PR_FALSE;
nsIFormControlFrame* formControlFrame = nsnull;
nsresult rv = GetPrimaryFrame(formControlFrame);
if (NS_SUCCEEDED(rv)) {
@ -232,7 +235,21 @@ nsHTMLOptionElement::GetSelected(PRBool* aValue)
formControlFrame->GetProperty(nsHTMLAtoms::selected, value);
*aValue = value.EqualsWithConversion("1");
}
} else {
// Note: The select content obj maintains all the PresState
// so defer to it to get the answer
rv = NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMNode> parentNode;
if (NS_SUCCEEDED(this->GetParentNode(getter_AddRefs(parentNode)))) {
if (parentNode) {
nsCOMPtr<nsISelectElement> selectElement(do_QueryInterface(parentNode));
if (selectElement) {
return selectElement->IsOptionSelected(this, aValue);
}
}
}
}
return rv;
}
@ -248,7 +265,20 @@ nsHTMLOptionElement::SetSelected(PRBool aValue)
PRInt32 indx;
result = GetIndex(&indx);
if (NS_SUCCEEDED(result)) {
selectFrame->SetOptionSelected(indx, aValue);
return selectFrame->SetOptionSelected(indx, aValue);
}
}
} else {
// Note: The select content obj maintains all the PresState
// so defer to it to get the answer
nsCOMPtr<nsIDOMNode> parentNode;
result = NS_ERROR_FAILURE;
if (NS_SUCCEEDED(this->GetParentNode(getter_AddRefs(parentNode)))) {
if (parentNode) {
nsCOMPtr<nsISelectElement> selectElement(do_QueryInterface(parentNode));
if (selectElement) {
return selectElement->SetOptionSelected(this, aValue);
}
}
}
}

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

@ -287,6 +287,8 @@ public:
NS_IMETHOD RemoveOption(nsIContent* aContent);
NS_IMETHOD DoneAddingContent(PRBool aIsDone);
NS_IMETHOD IsDoneAddingContent(PRBool * aIsDone);
NS_IMETHOD IsOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool * aIsSelected);
NS_IMETHOD SetOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool aIsSelected);
// nsIJSScriptObject
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner)
@ -305,7 +307,10 @@ public:
virtual void Finalize(JSContext *aContext, JSObject *aObj);
protected:
NS_IMETHOD GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
// Helper Methods
nsresult GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
nsresult GetOptionIndex(nsIDOMHTMLOptionElement* aOption, PRUint32 * anIndex);
nsresult SetOptionSelectedByIndex(PRInt32 aIndex, PRBool aIsSelected);
nsGenericHTMLContainerFormElement mInner;
nsIForm* mForm;
@ -755,53 +760,178 @@ nsHTMLSelectElement::SetSelectedIndex(PRInt32 aIndex)
formControlFrame->SetProperty(presContext, nsHTMLAtoms::selectedindex, value);
NS_IF_RELEASE(presContext);
} else {
// Since there are no frames, then we must adjust which options
// are selcted in the content and the current select state is kept in
// the PreState
//
// First, get whether this is a select with
// multiple items that can be slected
PRBool isMultiple;
nsresult res = GetMultiple(&isMultiple); // Must not be multiple
if (NS_FAILED(res)) {
isMultiple = PR_FALSE;
}
SetOptionSelectedByIndex(aIndex, PR_TRUE);
}
return NS_OK;
}
// Call the helper method to get the PresState and
// the SupportsArray that contains the value
//
nsCOMPtr<nsIPresState> presState;
nsCOMPtr<nsISupportsArray> value;
res = GetPresState(getter_AddRefs(presState), getter_AddRefs(value));
if (NS_SUCCEEDED(res) && !presState) {
nsresult
nsHTMLSelectElement::GetOptionIndex(nsIDOMHTMLOptionElement* aOption, PRUint32 * anIndex)
{
// first find index of option
nsCOMPtr<nsIDOMNSHTMLOptionCollection> options;
nsresult rv = GetOptions(getter_AddRefs(options));
if (NS_SUCCEEDED(rv) && options) {
PRUint32 numOptions;
rv = options->GetLength(&numOptions);
if (NS_SUCCEEDED(rv)) {
for (PRUint32 i = 0; i < numOptions; i++) {
nsCOMPtr<nsIDOMNode> node;
rv = options->Item(i, getter_AddRefs(node));
if (NS_SUCCEEDED(rv) && node) {
nsCOMPtr<nsIDOMHTMLOptionElement> option = do_QueryInterface(node, &rv);
if (NS_SUCCEEDED(rv) && option && option.get() == aOption) {
*anIndex = i;
return NS_OK;
}
}
}
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsHTMLSelectElement::IsOptionSelected(nsIDOMHTMLOptionElement* aOption, PRBool * aIsSelected)
{
// start off by assuming it isn't in the list of index objects
*aIsSelected = PR_FALSE;
// first find the index of the incoming option
PRUint32 index = 0;
if (NS_FAILED(GetOptionIndex(aOption, &index))) {
return NS_ERROR_FAILURE;
}
// The PresState hold a nsISupportsArray that contain nsISupportsPRInt32 objects that hold
// the index of the option that is selected, for example, there are 10 options and option
// 2 and oiption 8 are selected then the array hold to objects, one that contains 2 and one that contains 8
nsCOMPtr<nsIPresState> presState;
nsCOMPtr<nsISupportsArray> value;
nsresult res = GetPresState(getter_AddRefs(presState), getter_AddRefs(value));
if (NS_SUCCEEDED(res) && presState) {
// get the property by name
// I am not sure why this is done, versus just using the value array above
nsCOMPtr<nsISupports> supp;
presState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("selecteditems"), getter_AddRefs(supp));
res = NS_ERROR_NULL_POINTER;
if (supp) {
// Query for nsISupportArray from nsISupports
nsCOMPtr<nsISupportsArray> svalue = do_QueryInterface(supp);
if (svalue) {
PRUint32 count = 0; // num items in array
svalue->Count(&count);
// loop through the array look for "index" object and
// then we compare it against the option's index to see if there is a match
nsCOMPtr<nsISupportsPRInt32> thisVal;
for (PRUint32 i=0; i<count; i++) {
// get index obj
nsCOMPtr<nsISupports> suppval = getter_AddRefs(svalue->ElementAt(i));
thisVal = do_QueryInterface(suppval);
if (thisVal) {
// get out the index
PRInt32 optIndex;
res = thisVal->GetData(&optIndex);
if (NS_SUCCEEDED(res)) {
// ccompare them then bail if they match
if (PRUint32(optIndex) == index) {
*aIsSelected = PR_TRUE;
return NS_OK;
}
}
} else {
res = NS_ERROR_UNEXPECTED;
}
if (!NS_SUCCEEDED(res)) break;
}
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::SetOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool aIsSelected)
{
PRUint32 index = 0;
if (NS_FAILED(GetOptionIndex(anOption, &index))) {
return NS_ERROR_FAILURE;
}
return SetOptionSelectedByIndex(index, aIsSelected);
}
nsresult
nsHTMLSelectElement::SetOptionSelectedByIndex(PRInt32 aIndex, PRBool aIsSelected)
{
// Since there are no frames, then we must adjust which options
// are selcted in the content and the current select state is kept in
// the PreState
//
// First, get whether this is a select with
// multiple items that can be slected
PRBool isMultiple;
nsresult res = GetMultiple(&isMultiple); // Must not be multiple
if (NS_FAILED(res)) {
isMultiple = PR_FALSE;
}
// Call the helper method to get the PresState and
// the SupportsArray that contains the value
//
nsCOMPtr<nsIPresState> presState;
nsCOMPtr<nsISupportsArray> value;
res = GetPresState(getter_AddRefs(presState), getter_AddRefs(value));
if (NS_SUCCEEDED(res) && !presState) {
return NS_OK;
}
// If the nsISupportsArray doesn't exist then we must creat one
// cache the values
PRBool doesExist = PR_FALSE;
if (!value) {
// if we are selecting an options continue on
// but if the array doesn't exist and we are unselecting an option bail out
// because we don't need to do anything
if (aIsSelected) {
res = NS_NewISupportsArray(getter_AddRefs(value));
} else {
return NS_OK;
}
} else {
doesExist = PR_TRUE;
}
if (NS_SUCCEEDED(res) && value) {
// The nsISupportArray will hold a list of indexes
// of the items that are selected
// get the count of selected items
PRUint32 count = 0;
value->Count(&count);
// If there are no items and we are unselecting an option
// then we don't have to do anything.
if (count == 0 && !aIsSelected) {
return NS_OK;
}
// If the nsISupportsArray doesn't exist then we must creat one
// cache the values
PRBool doesExist = PR_FALSE;
if (!value) {
res = NS_NewISupportsArray(getter_AddRefs(value));
} else {
doesExist = PR_TRUE;
// if not multiple then only one item can be selected
// so we clear the list of selcted items
if (!isMultiple || (-1 == aIndex)) { // -1 -> deselect all (bug 28143)
value->Clear();
count = 0;
}
if (NS_SUCCEEDED(res) && value) {
// The nsISupportArray will hold a list of indexes
// of the items that are selected
// get the count of selected items
PRUint32 count = 0;
value->Count(&count);
// if not multiple then only one item can be selected
// so we clear the list of selcted items
if (!isMultiple || (-1 == aIndex)) { // -1 -> deselect all (bug 28143)
value->Clear();
count = 0;
}
// Set the index as selected and add it to the array
if (-1 != aIndex) {
// Set the index as selected and add it to the array
if (-1 != aIndex) {
if (aIsSelected) {
nsCOMPtr<nsISupportsPRInt32> thisVal;
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(thisVal));
@ -812,15 +942,35 @@ nsHTMLSelectElement::SetSelectedIndex(PRInt32 aIndex)
if (!okay) res = NS_ERROR_OUT_OF_MEMORY; // Most likely cause;
}
}
} else {
// deselecting the option -> remove it from the list
nsCOMPtr<nsISupportsPRInt32> thisVal;
for (PRUint32 i=0; i<count; i++) {
nsCOMPtr<nsISupports> suppval = getter_AddRefs(value->ElementAt(i));
thisVal = do_QueryInterface(suppval);
if (thisVal) {
PRInt32 optIndex;
res = thisVal->GetData(&optIndex);
if (NS_SUCCEEDED(res)) {
if (optIndex == aIndex) {
value->RemoveElementAt(i);
return NS_OK;
}
}
} else {
res = NS_ERROR_UNEXPECTED;
}
if (!NS_SUCCEEDED(res)) break;
}
}
}
// If it is a new nsISupportsArray then
// set it into the PresState
if (!doesExist) {
presState->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("selecteditems"), value);
}
} // if
}
// If it is a new nsISupportsArray then
// set it into the PresState
if (!doesExist) {
presState->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("selecteditems"), value);
}
} // if
return NS_OK;
}
@ -1030,7 +1180,7 @@ nsHTMLSelectElement::AddOption(nsIContent* aContent)
// aValueArray will be null if it didn't exist and non-null if it did
// always return NS_OK whether aValueArray was nsnull or not
//-----------------------------------------------------------------
NS_IMETHODIMP
nsresult
nsHTMLSelectElement::GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray)
{
*aValueArray = nsnull;

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

@ -29,6 +29,7 @@
{ 0xa6cf90f6, 0x15b3, 0x11d2, \
{ 0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
class nsIDOMHTMLOptionElement;
/**
* This interface is used to notify a SELECT when OPTION
@ -65,6 +66,17 @@ public:
* to the select during document loading.
*/
NS_IMETHOD IsDoneAddingContent(PRBool * aIsDone) = 0;
/**
* Returns whether we're the option is selected
*/
NS_IMETHOD IsOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool * aIsSelected) = 0;
/**
* Sets an option selected or delselected
*/
NS_IMETHOD SetOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool aIsSelected) = 0;
};
#endif // nsISelectElement_h___

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

@ -222,6 +222,9 @@ nsHTMLOptionElement::GetForm(nsIDOMHTMLFormElement** aForm)
NS_IMETHODIMP
nsHTMLOptionElement::GetSelected(PRBool* aValue)
{
NS_ENSURE_ARG_POINTER(aValue);
*aValue = PR_FALSE;
nsIFormControlFrame* formControlFrame = nsnull;
nsresult rv = GetPrimaryFrame(formControlFrame);
if (NS_SUCCEEDED(rv)) {
@ -232,7 +235,21 @@ nsHTMLOptionElement::GetSelected(PRBool* aValue)
formControlFrame->GetProperty(nsHTMLAtoms::selected, value);
*aValue = value.EqualsWithConversion("1");
}
} else {
// Note: The select content obj maintains all the PresState
// so defer to it to get the answer
rv = NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMNode> parentNode;
if (NS_SUCCEEDED(this->GetParentNode(getter_AddRefs(parentNode)))) {
if (parentNode) {
nsCOMPtr<nsISelectElement> selectElement(do_QueryInterface(parentNode));
if (selectElement) {
return selectElement->IsOptionSelected(this, aValue);
}
}
}
}
return rv;
}
@ -248,7 +265,20 @@ nsHTMLOptionElement::SetSelected(PRBool aValue)
PRInt32 indx;
result = GetIndex(&indx);
if (NS_SUCCEEDED(result)) {
selectFrame->SetOptionSelected(indx, aValue);
return selectFrame->SetOptionSelected(indx, aValue);
}
}
} else {
// Note: The select content obj maintains all the PresState
// so defer to it to get the answer
nsCOMPtr<nsIDOMNode> parentNode;
result = NS_ERROR_FAILURE;
if (NS_SUCCEEDED(this->GetParentNode(getter_AddRefs(parentNode)))) {
if (parentNode) {
nsCOMPtr<nsISelectElement> selectElement(do_QueryInterface(parentNode));
if (selectElement) {
return selectElement->SetOptionSelected(this, aValue);
}
}
}
}

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

@ -287,6 +287,8 @@ public:
NS_IMETHOD RemoveOption(nsIContent* aContent);
NS_IMETHOD DoneAddingContent(PRBool aIsDone);
NS_IMETHOD IsDoneAddingContent(PRBool * aIsDone);
NS_IMETHOD IsOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool * aIsSelected);
NS_IMETHOD SetOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool aIsSelected);
// nsIJSScriptObject
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner)
@ -305,7 +307,10 @@ public:
virtual void Finalize(JSContext *aContext, JSObject *aObj);
protected:
NS_IMETHOD GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
// Helper Methods
nsresult GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
nsresult GetOptionIndex(nsIDOMHTMLOptionElement* aOption, PRUint32 * anIndex);
nsresult SetOptionSelectedByIndex(PRInt32 aIndex, PRBool aIsSelected);
nsGenericHTMLContainerFormElement mInner;
nsIForm* mForm;
@ -755,53 +760,178 @@ nsHTMLSelectElement::SetSelectedIndex(PRInt32 aIndex)
formControlFrame->SetProperty(presContext, nsHTMLAtoms::selectedindex, value);
NS_IF_RELEASE(presContext);
} else {
// Since there are no frames, then we must adjust which options
// are selcted in the content and the current select state is kept in
// the PreState
//
// First, get whether this is a select with
// multiple items that can be slected
PRBool isMultiple;
nsresult res = GetMultiple(&isMultiple); // Must not be multiple
if (NS_FAILED(res)) {
isMultiple = PR_FALSE;
}
SetOptionSelectedByIndex(aIndex, PR_TRUE);
}
return NS_OK;
}
// Call the helper method to get the PresState and
// the SupportsArray that contains the value
//
nsCOMPtr<nsIPresState> presState;
nsCOMPtr<nsISupportsArray> value;
res = GetPresState(getter_AddRefs(presState), getter_AddRefs(value));
if (NS_SUCCEEDED(res) && !presState) {
nsresult
nsHTMLSelectElement::GetOptionIndex(nsIDOMHTMLOptionElement* aOption, PRUint32 * anIndex)
{
// first find index of option
nsCOMPtr<nsIDOMNSHTMLOptionCollection> options;
nsresult rv = GetOptions(getter_AddRefs(options));
if (NS_SUCCEEDED(rv) && options) {
PRUint32 numOptions;
rv = options->GetLength(&numOptions);
if (NS_SUCCEEDED(rv)) {
for (PRUint32 i = 0; i < numOptions; i++) {
nsCOMPtr<nsIDOMNode> node;
rv = options->Item(i, getter_AddRefs(node));
if (NS_SUCCEEDED(rv) && node) {
nsCOMPtr<nsIDOMHTMLOptionElement> option = do_QueryInterface(node, &rv);
if (NS_SUCCEEDED(rv) && option && option.get() == aOption) {
*anIndex = i;
return NS_OK;
}
}
}
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsHTMLSelectElement::IsOptionSelected(nsIDOMHTMLOptionElement* aOption, PRBool * aIsSelected)
{
// start off by assuming it isn't in the list of index objects
*aIsSelected = PR_FALSE;
// first find the index of the incoming option
PRUint32 index = 0;
if (NS_FAILED(GetOptionIndex(aOption, &index))) {
return NS_ERROR_FAILURE;
}
// The PresState hold a nsISupportsArray that contain nsISupportsPRInt32 objects that hold
// the index of the option that is selected, for example, there are 10 options and option
// 2 and oiption 8 are selected then the array hold to objects, one that contains 2 and one that contains 8
nsCOMPtr<nsIPresState> presState;
nsCOMPtr<nsISupportsArray> value;
nsresult res = GetPresState(getter_AddRefs(presState), getter_AddRefs(value));
if (NS_SUCCEEDED(res) && presState) {
// get the property by name
// I am not sure why this is done, versus just using the value array above
nsCOMPtr<nsISupports> supp;
presState->GetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("selecteditems"), getter_AddRefs(supp));
res = NS_ERROR_NULL_POINTER;
if (supp) {
// Query for nsISupportArray from nsISupports
nsCOMPtr<nsISupportsArray> svalue = do_QueryInterface(supp);
if (svalue) {
PRUint32 count = 0; // num items in array
svalue->Count(&count);
// loop through the array look for "index" object and
// then we compare it against the option's index to see if there is a match
nsCOMPtr<nsISupportsPRInt32> thisVal;
for (PRUint32 i=0; i<count; i++) {
// get index obj
nsCOMPtr<nsISupports> suppval = getter_AddRefs(svalue->ElementAt(i));
thisVal = do_QueryInterface(suppval);
if (thisVal) {
// get out the index
PRInt32 optIndex;
res = thisVal->GetData(&optIndex);
if (NS_SUCCEEDED(res)) {
// ccompare them then bail if they match
if (PRUint32(optIndex) == index) {
*aIsSelected = PR_TRUE;
return NS_OK;
}
}
} else {
res = NS_ERROR_UNEXPECTED;
}
if (!NS_SUCCEEDED(res)) break;
}
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::SetOptionSelected(nsIDOMHTMLOptionElement* anOption, PRBool aIsSelected)
{
PRUint32 index = 0;
if (NS_FAILED(GetOptionIndex(anOption, &index))) {
return NS_ERROR_FAILURE;
}
return SetOptionSelectedByIndex(index, aIsSelected);
}
nsresult
nsHTMLSelectElement::SetOptionSelectedByIndex(PRInt32 aIndex, PRBool aIsSelected)
{
// Since there are no frames, then we must adjust which options
// are selcted in the content and the current select state is kept in
// the PreState
//
// First, get whether this is a select with
// multiple items that can be slected
PRBool isMultiple;
nsresult res = GetMultiple(&isMultiple); // Must not be multiple
if (NS_FAILED(res)) {
isMultiple = PR_FALSE;
}
// Call the helper method to get the PresState and
// the SupportsArray that contains the value
//
nsCOMPtr<nsIPresState> presState;
nsCOMPtr<nsISupportsArray> value;
res = GetPresState(getter_AddRefs(presState), getter_AddRefs(value));
if (NS_SUCCEEDED(res) && !presState) {
return NS_OK;
}
// If the nsISupportsArray doesn't exist then we must creat one
// cache the values
PRBool doesExist = PR_FALSE;
if (!value) {
// if we are selecting an options continue on
// but if the array doesn't exist and we are unselecting an option bail out
// because we don't need to do anything
if (aIsSelected) {
res = NS_NewISupportsArray(getter_AddRefs(value));
} else {
return NS_OK;
}
} else {
doesExist = PR_TRUE;
}
if (NS_SUCCEEDED(res) && value) {
// The nsISupportArray will hold a list of indexes
// of the items that are selected
// get the count of selected items
PRUint32 count = 0;
value->Count(&count);
// If there are no items and we are unselecting an option
// then we don't have to do anything.
if (count == 0 && !aIsSelected) {
return NS_OK;
}
// If the nsISupportsArray doesn't exist then we must creat one
// cache the values
PRBool doesExist = PR_FALSE;
if (!value) {
res = NS_NewISupportsArray(getter_AddRefs(value));
} else {
doesExist = PR_TRUE;
// if not multiple then only one item can be selected
// so we clear the list of selcted items
if (!isMultiple || (-1 == aIndex)) { // -1 -> deselect all (bug 28143)
value->Clear();
count = 0;
}
if (NS_SUCCEEDED(res) && value) {
// The nsISupportArray will hold a list of indexes
// of the items that are selected
// get the count of selected items
PRUint32 count = 0;
value->Count(&count);
// if not multiple then only one item can be selected
// so we clear the list of selcted items
if (!isMultiple || (-1 == aIndex)) { // -1 -> deselect all (bug 28143)
value->Clear();
count = 0;
}
// Set the index as selected and add it to the array
if (-1 != aIndex) {
// Set the index as selected and add it to the array
if (-1 != aIndex) {
if (aIsSelected) {
nsCOMPtr<nsISupportsPRInt32> thisVal;
res = nsComponentManager::CreateInstance(NS_SUPPORTS_PRINT32_PROGID,
nsnull, NS_GET_IID(nsISupportsPRInt32), (void**)getter_AddRefs(thisVal));
@ -812,15 +942,35 @@ nsHTMLSelectElement::SetSelectedIndex(PRInt32 aIndex)
if (!okay) res = NS_ERROR_OUT_OF_MEMORY; // Most likely cause;
}
}
} else {
// deselecting the option -> remove it from the list
nsCOMPtr<nsISupportsPRInt32> thisVal;
for (PRUint32 i=0; i<count; i++) {
nsCOMPtr<nsISupports> suppval = getter_AddRefs(value->ElementAt(i));
thisVal = do_QueryInterface(suppval);
if (thisVal) {
PRInt32 optIndex;
res = thisVal->GetData(&optIndex);
if (NS_SUCCEEDED(res)) {
if (optIndex == aIndex) {
value->RemoveElementAt(i);
return NS_OK;
}
}
} else {
res = NS_ERROR_UNEXPECTED;
}
if (!NS_SUCCEEDED(res)) break;
}
}
}
// If it is a new nsISupportsArray then
// set it into the PresState
if (!doesExist) {
presState->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("selecteditems"), value);
}
} // if
}
// If it is a new nsISupportsArray then
// set it into the PresState
if (!doesExist) {
presState->SetStatePropertyAsSupports(NS_ConvertASCIItoUCS2("selecteditems"), value);
}
} // if
return NS_OK;
}
@ -1030,7 +1180,7 @@ nsHTMLSelectElement::AddOption(nsIContent* aContent)
// aValueArray will be null if it didn't exist and non-null if it did
// always return NS_OK whether aValueArray was nsnull or not
//-----------------------------------------------------------------
NS_IMETHODIMP
nsresult
nsHTMLSelectElement::GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray)
{
*aValueArray = nsnull;