Bug 12513: Add OptionCollection interface for Nav DOM compatability. r=vidur a=rickg

This commit is contained in:
pollmann%netscape.com 2000-02-24 00:08:00 +00:00
Родитель 19d1eed6ab
Коммит 2ed06994e0
14 изменённых файлов: 676 добавлений и 149 удалений

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

@ -22,6 +22,7 @@
*/
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLOptGroupElement.h"
#include "nsIDOMNSHTMLOptionCollection.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
@ -363,7 +364,7 @@ nsHTMLOptionElement::GetIndex(PRInt32* aIndex)
if (NS_OK == GetSelect(selectElement)) {
// Get the options from the select object.
nsIDOMHTMLCollection* options = nsnull;
nsIDOMNSHTMLOptionCollection* options = nsnull;
if (NS_OK == selectElement->GetOptions(&options)) {
// Walk the options to find out where we are in the list (ick, O(n))

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

@ -46,6 +46,7 @@
#include "nsISelectElement.h"
#include "nsISelectControlFrame.h"
#include "nsISizeOfHandler.h"
#include "nsIDOMNSHTMLOptionCollection.h"
// PresState
#include "nsISupportsArray.h"
@ -61,6 +62,7 @@
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMNSHTMLSelectElementIID, NS_IDOMNSHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMNSHTMLOptionCollectionIID, NS_IDOMNSHTMLOPTIONCOLLECTION_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
@ -71,19 +73,28 @@ static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLSelectElement;
// nsOptionList
class nsOptionList : public nsGenericDOMHTMLCollection,
public nsIJSScriptObject
// nsHTMLOptionCollection
class nsHTMLOptionCollection: public nsIDOMNSHTMLOptionCollection,
public nsGenericDOMHTMLCollection,
public nsIJSScriptObject
{
public:
nsOptionList(nsHTMLSelectElement* aSelect);
virtual ~nsOptionList();
nsHTMLOptionCollection(nsHTMLSelectElement* aSelect);
virtual ~nsHTMLOptionCollection();
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMNSHTMLOptionCollection interface
NS_IMETHOD SetLength(PRUint32 aLength);
NS_IMETHOD GetSelectedIndex(PRInt32 *aSelectedIndex);
NS_IMETHOD SetSelectedIndex(PRInt32 aSelectedIndex);
// nsIDOMHTMLCollection interface
NS_DECL_IDOMHTMLCOLLECTION
// nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
// nsIJSScriptObject interface
PRBool AddProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
@ -116,6 +127,7 @@ private:
class nsHTMLSelectElement : public nsIDOMHTMLSelectElement,
public nsIDOMNSHTMLSelectElement,
public nsIScriptObjectOwner,
public nsIJSScriptObject,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl,
@ -145,8 +157,9 @@ public:
NS_IMETHOD GetValue(nsString& aValue);
NS_IMETHOD SetValue(const nsString& aValue);
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD SetLength(PRUint32 aLength);
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm);
NS_IMETHOD GetOptions(nsIDOMHTMLCollection** aOptions);
NS_IMETHOD GetOptions(nsIDOMNSHTMLOptionCollection** aOptions);
NS_IMETHOD GetDisabled(PRBool* aDisabled);
NS_IMETHOD SetDisabled(PRBool aDisabled);
NS_IMETHOD GetMultiple(PRBool* aMultiple);
@ -163,7 +176,8 @@ public:
NS_IMETHOD Focus();
// nsIDOMNSHTMLSelectElement
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMElement** aReturn);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn);
// nsIScriptObjectOwner
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner)
@ -191,12 +205,27 @@ public:
NS_IMETHOD DoneAddingContent(PRBool aIsDone);
NS_IMETHOD IsDoneAddingContent(PRBool * aIsDone);
// nsIJSScriptObject
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool DeleteProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool GetProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
// Implement this to enable setting option via frm.select[x]
virtual PRBool SetProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool EnumerateProperty(JSContext *aContext, JSObject *aObj);
virtual PRBool Resolve(JSContext *aContext, JSObject *aObj, jsval aID);
virtual PRBool Convert(JSContext *aContext, JSObject *aObj, jsval aID);
virtual void Finalize(JSContext *aContext, JSObject *aObj);
protected:
NS_IMETHOD GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
nsGenericHTMLContainerElement mInner;
nsIForm* mForm;
nsOptionList* mOptions;
nsHTMLOptionCollection* mOptions;
PRBool mIsDoneAddingContent;
};
@ -212,7 +241,7 @@ NS_NewHTMLSelectElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsHTMLSelectElement(aTag);
nsHTMLSelectElement* it = new nsHTMLSelectElement(aTag);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -250,6 +279,16 @@ NS_IMPL_ADDREF(nsHTMLSelectElement)
nsresult
nsHTMLSelectElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
// NS_IMPL_HTML_CONTENT_QUERY_INTERFACE returns mInner as the script object
// We need to be our own so we can implement setprop to set select[i]
if (aIID.Equals(kIJSScriptObjectIID)) {
*aInstancePtr = (void*)(nsIJSScriptObject*) this;
NS_ADDREF_THIS();
return NS_OK;
}
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLSelectElementIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLSelectElement*)this;
@ -397,7 +436,7 @@ nsHTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
}
NS_IMETHODIMP
nsHTMLSelectElement::GetOptions(nsIDOMHTMLCollection** aValue)
nsHTMLSelectElement::GetOptions(nsIDOMNSHTMLOptionCollection** aValue)
{
if (nsnull == mOptions) {
Init();
@ -439,6 +478,26 @@ nsHTMLSelectElement::GetLength(PRUint32* aLength)
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsHTMLSelectElement::SetLength(PRUint32 aLength)
{
if (!mOptions) {
Init();
}
PRUint32 curlen;
nsresult result;
GetLength(&curlen);
if (curlen && (curlen > aLength)) { // Remove extra options
for (PRInt32 i = (curlen - 1); (i>=(PRInt32)aLength) && NS_SUCCEEDED(result); i--) {
result = Remove(i);
}
} else { // Add options?
}
return NS_OK;
}
//NS_IMPL_INT_ATTR(nsHTMLSelectElement, SelectedIndex, selectedindex)
NS_IMETHODIMP
nsHTMLSelectElement::GetSelectedIndex(PRInt32* aValue)
@ -473,7 +532,7 @@ nsHTMLSelectElement::GetSelectedIndex(PRInt32* aValue)
*aValue = 0;
}
}
nsCOMPtr<nsIDOMHTMLCollection> options;
nsCOMPtr<nsIDOMNSHTMLOptionCollection> options;
rv = GetOptions(getter_AddRefs(options));
if (NS_SUCCEEDED(rv) && options) {
PRUint32 numOptions;
@ -483,7 +542,7 @@ nsHTMLSelectElement::GetSelectedIndex(PRInt32* aValue)
nsCOMPtr<nsIDOMNode> node;
rv = options->Item(i, getter_AddRefs(node));
if (NS_SUCCEEDED(rv) && node) {
nsCOMPtr<nsIDOMHTMLOptionElement> option = do_QueryInterface(node);
nsCOMPtr<nsIDOMHTMLOptionElement> option = do_QueryInterface(node, &rv);
if (NS_SUCCEEDED(rv) && option) {
PRBool selected;
rv = option->GetDefaultSelected(&selected); // DefaultSelected == HTML Selected
@ -588,7 +647,7 @@ nsHTMLSelectElement::GetValue(nsString& aValue)
result = GetSelectedIndex(&selectedIndex);
if (NS_SUCCEEDED(result)) {
nsCOMPtr<nsIDOMHTMLCollection> options;
nsCOMPtr<nsIDOMNSHTMLOptionCollection> options;
result = GetOptions(getter_AddRefs(options));
if (NS_SUCCEEDED(result)) {
@ -619,7 +678,7 @@ NS_IMETHODIMP
nsHTMLSelectElement::SetValue(const nsString& aValue)
{
nsresult result = NS_OK;
nsCOMPtr<nsIDOMHTMLCollection> options;
nsCOMPtr<nsIDOMNSHTMLOptionCollection> options;
result = GetOptions(getter_AddRefs(options));
if (NS_SUCCEEDED(result)) {
@ -706,22 +765,25 @@ nsHTMLSelectElement::RemoveFocus(nsIPresContext* aPresContext)
}
NS_IMETHODIMP
nsHTMLSelectElement::Item(PRUint32 aIndex, nsIDOMElement** aReturn)
nsHTMLSelectElement::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
if (!mOptions) {
Init();
}
if (mOptions) {
nsIDOMNode *node;
nsresult result = mOptions->Item(aIndex, &node);
if ((NS_OK == result) && (nsnull != node)) {
result = node->QueryInterface(kIDOMElementIID, (void **)aReturn);
NS_RELEASE(node);
}
else {
*aReturn = nsnull;
}
return result;
return mOptions->Item(aIndex, aReturn);
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsHTMLSelectElement::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
if (!mOptions) {
Init();
}
if (mOptions) {
return mOptions->NamedItem(aName, aReturn);
}
return NS_ERROR_FAILURE;
}
@ -840,7 +902,7 @@ nsHTMLSelectElement::RemoveOption(nsIContent* aContent)
value->Count(&count);
// look through the list to see if the option being removed is selected
// then remove it from the nsIASupportsArray
// then remove it from the nsISupportsArray
PRInt32 j=0;
for (PRUint32 i=0; i<count; i++) {
nsCOMPtr<nsISupports> suppval = getter_AddRefs(value->ElementAt(i));
@ -1045,16 +1107,89 @@ NS_IMETHODIMP
nsHTMLSelectElement::Init()
{
if (nsnull == mOptions) {
mOptions = new nsOptionList(this);
mOptions = new nsHTMLOptionCollection(this);
NS_ADDREF(mOptions);
}
return NS_OK;
}
// nsIJSScriptObject interface
PRBool
nsHTMLSelectElement::AddProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::DeleteProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::GetProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::SetProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
{
nsresult res = NS_OK;
// Set options in the options list by indexing into select
if (JSVAL_IS_INT(aID) && mOptions) {
nsIJSScriptObject* optList = nsnull;
res = mOptions->QueryInterface(kIJSScriptObjectIID, (void **)&optList);
if (NS_SUCCEEDED(res) && optList) {
res = optList->SetProperty(aContext, aObj, aID, aVp);
}
} else {
res = mInner.SetProperty(aContext, aObj, aID, aVp);
}
return res;
}
PRBool
nsHTMLSelectElement::EnumerateProperty(JSContext *aContext, JSObject *aObj)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::Convert(JSContext *aContext, JSObject *aObj, jsval aID)
{
return PR_TRUE;
}
void
nsHTMLSelectElement::Finalize(JSContext *aContext, JSObject *aObj)
{
}
//----------------------------------------------------------------------
// nsOptionList implementation
// nsHTMLOptionCollection implementation
// XXX this was modified form nsHTMLFormElement.cpp. We need a base class implementation
static
@ -1079,7 +1214,7 @@ void GetOptionsRecurse(nsIContent* aContent, nsVoidArray& aOptions)
}
void
nsOptionList::GetOptions()
nsHTMLOptionCollection::GetOptions()
{
Clear();
GetOptionsRecurse(mSelect, mElements);
@ -1087,31 +1222,34 @@ nsOptionList::GetOptions()
}
nsOptionList::nsOptionList(nsHTMLSelectElement* aSelect)
nsHTMLOptionCollection::nsHTMLOptionCollection(nsHTMLSelectElement* aSelect)
{
mDirty = PR_TRUE;
// Do not maintain a reference counted reference. When
// the select goes away, it will let us know.
mSelect = aSelect;
mScriptObject = nsnull;
}
nsOptionList::~nsOptionList()
nsHTMLOptionCollection::~nsHTMLOptionCollection()
{
DropReference();
}
void
nsOptionList::DropReference()
nsHTMLOptionCollection::DropReference()
{
// Drop our (non ref-counted) reference
mSelect = nsnull;
}
NS_IMPL_ADDREF_INHERITED(nsOptionList, nsGenericDOMHTMLCollection)
NS_IMPL_RELEASE_INHERITED(nsOptionList, nsGenericDOMHTMLCollection)
// ISupports
NS_IMPL_ADDREF_INHERITED(nsHTMLOptionCollection, nsGenericDOMHTMLCollection)
NS_IMPL_RELEASE_INHERITED(nsHTMLOptionCollection, nsGenericDOMHTMLCollection)
nsresult
nsOptionList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
nsHTMLOptionCollection::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
if (aIID.Equals(kIJSScriptObjectIID)) {
@ -1119,15 +1257,18 @@ nsOptionList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
else {
return nsGenericDOMHTMLCollection::QueryInterface(aIID, aInstancePtr);
if (aIID.Equals(kIDOMNSHTMLOptionCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMNSHTMLOptionCollection*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return nsGenericDOMHTMLCollection::QueryInterface(aIID, aInstancePtr);
}
// nsIDOMHTMLCollection interface
// nsIDOMNSHTMLOptionCollection interface
NS_IMETHODIMP
nsOptionList::GetLength(PRUint32* aLength)
nsHTMLOptionCollection::GetLength(PRUint32* aLength)
{
if (mDirty && (nsnull != mSelect)) {
GetOptions();
@ -1138,7 +1279,46 @@ nsOptionList::GetLength(PRUint32* aLength)
}
NS_IMETHODIMP
nsOptionList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
nsHTMLOptionCollection::SetLength(PRUint32 aLength)
{
nsresult result = NS_ERROR_UNEXPECTED;
if (mSelect) {
if (mDirty) {
GetOptions();
}
result = mSelect->SetLength(aLength);
}
return result;
}
NS_IMETHODIMP
nsHTMLOptionCollection::GetSelectedIndex(PRInt32 *aSelectedIndex)
{
nsresult result = NS_ERROR_UNEXPECTED;
if (mSelect) {
if (mDirty) {
GetOptions();
}
result = mSelect->GetSelectedIndex(aSelectedIndex);
}
return result;
}
NS_IMETHODIMP
nsHTMLOptionCollection::SetSelectedIndex(PRInt32 aSelectedIndex)
{
nsresult result = NS_ERROR_UNEXPECTED;
if (mSelect) {
if (mDirty) {
GetOptions();
}
result = mSelect->SetSelectedIndex(aSelectedIndex);
}
return result;
}
NS_IMETHODIMP
nsHTMLOptionCollection::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
if (mDirty && (nsnull != mSelect)) {
GetOptions();
@ -1155,7 +1335,7 @@ nsOptionList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
}
NS_IMETHODIMP
nsOptionList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
nsHTMLOptionCollection::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
if (mDirty && (nsnull != mSelect)) {
GetOptions();
@ -1189,7 +1369,7 @@ nsOptionList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
}
void
nsOptionList::AddOption(nsIContent* aOption)
nsHTMLOptionCollection::AddOption(nsIContent* aOption)
{
// Just mark ourselves as dirty. The next time someone
// makes a call that requires us to look at the elements
@ -1198,7 +1378,7 @@ nsOptionList::AddOption(nsIContent* aOption)
}
void
nsOptionList::RemoveOption(nsIContent* aOption)
nsHTMLOptionCollection::RemoveOption(nsIContent* aOption)
{
nsIDOMHTMLOptionElement* option;
@ -1213,7 +1393,7 @@ nsOptionList::RemoveOption(nsIContent* aOption)
}
PRInt32
nsOptionList::IndexOf(nsIContent* aOption)
nsHTMLOptionCollection::IndexOf(nsIContent* aOption)
{
nsIDOMHTMLOptionElement* option;
@ -1227,8 +1407,24 @@ nsOptionList::IndexOf(nsIContent* aOption)
return -1;
}
// nsIScriptObjectOwner interface
NS_IMETHODIMP
nsHTMLOptionCollection::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
res = NS_NewScriptNSHTMLOptionCollection(aContext, (nsISupports *)(nsIDOMNSHTMLOptionCollection *)this, nsnull, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
return res;
}
// nsIJSScriptObject interface
PRBool
nsOptionList::AddProperty(JSContext *aContext,
nsHTMLOptionCollection::AddProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
@ -1237,7 +1433,7 @@ nsOptionList::AddProperty(JSContext *aContext,
}
PRBool
nsOptionList::DeleteProperty(JSContext *aContext,
nsHTMLOptionCollection::DeleteProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
@ -1246,7 +1442,7 @@ nsOptionList::DeleteProperty(JSContext *aContext,
}
PRBool
nsOptionList::GetProperty(JSContext *aContext,
nsHTMLOptionCollection::GetProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
@ -1255,7 +1451,7 @@ nsOptionList::GetProperty(JSContext *aContext,
}
PRBool
nsOptionList::SetProperty(JSContext *aContext,
nsHTMLOptionCollection::SetProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
@ -1319,30 +1515,30 @@ nsOptionList::SetProperty(JSContext *aContext,
}
PRBool
nsOptionList::EnumerateProperty(JSContext *aContext, JSObject *aObj)
nsHTMLOptionCollection::EnumerateProperty(JSContext *aContext, JSObject *aObj)
{
return PR_TRUE;
}
PRBool
nsOptionList::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
nsHTMLOptionCollection::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
{
return PR_TRUE;
}
PRBool
nsOptionList::Convert(JSContext *aContext, JSObject *aObj, jsval aID)
nsHTMLOptionCollection::Convert(JSContext *aContext, JSObject *aObj, jsval aID)
{
return PR_TRUE;
}
void
nsOptionList::Finalize(JSContext *aContext, JSObject *aObj)
nsHTMLOptionCollection::Finalize(JSContext *aContext, JSObject *aObj)
{
}
void
nsOptionList::Clear()
nsHTMLOptionCollection::Clear()
{
PRUint32 numOptions = mElements.Count();
for (PRUint32 i = 0; i < numOptions; i++) {

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

@ -29,9 +29,9 @@
#include "nsIScriptContext.h"
#include "nsIDOMHTMLElement.h"
class nsIDOMNSHTMLOptionCollection;
class nsIDOMHTMLElement;
class nsIDOMHTMLFormElement;
class nsIDOMHTMLCollection;
#define NS_IDOMHTMLSELECTELEMENT_IID \
{ 0xa6cf9090, 0x15b3, 0x11d2, \
@ -50,10 +50,11 @@ public:
NS_IMETHOD SetValue(const nsString& aValue)=0;
NS_IMETHOD GetLength(PRUint32* aLength)=0;
NS_IMETHOD SetLength(PRUint32 aLength)=0;
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm)=0;
NS_IMETHOD GetOptions(nsIDOMHTMLCollection** aOptions)=0;
NS_IMETHOD GetOptions(nsIDOMNSHTMLOptionCollection** aOptions)=0;
NS_IMETHOD GetDisabled(PRBool* aDisabled)=0;
NS_IMETHOD SetDisabled(PRBool aDisabled)=0;
@ -87,8 +88,9 @@ public:
NS_IMETHOD GetValue(nsString& aValue); \
NS_IMETHOD SetValue(const nsString& aValue); \
NS_IMETHOD GetLength(PRUint32* aLength); \
NS_IMETHOD SetLength(PRUint32 aLength); \
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm); \
NS_IMETHOD GetOptions(nsIDOMHTMLCollection** aOptions); \
NS_IMETHOD GetOptions(nsIDOMNSHTMLOptionCollection** aOptions); \
NS_IMETHOD GetDisabled(PRBool* aDisabled); \
NS_IMETHOD SetDisabled(PRBool aDisabled); \
NS_IMETHOD GetMultiple(PRBool* aMultiple); \
@ -113,8 +115,9 @@ public:
NS_IMETHOD GetValue(nsString& aValue) { return _to GetValue(aValue); } \
NS_IMETHOD SetValue(const nsString& aValue) { return _to SetValue(aValue); } \
NS_IMETHOD GetLength(PRUint32* aLength) { return _to GetLength(aLength); } \
NS_IMETHOD SetLength(PRUint32 aLength) { return _to SetLength(aLength); } \
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm) { return _to GetForm(aForm); } \
NS_IMETHOD GetOptions(nsIDOMHTMLCollection** aOptions) { return _to GetOptions(aOptions); } \
NS_IMETHOD GetOptions(nsIDOMNSHTMLOptionCollection** aOptions) { return _to GetOptions(aOptions); } \
NS_IMETHOD GetDisabled(PRBool* aDisabled) { return _to GetDisabled(aDisabled); } \
NS_IMETHOD SetDisabled(PRBool aDisabled) { return _to SetDisabled(aDisabled); } \
NS_IMETHOD GetMultiple(PRBool* aMultiple) { return _to GetMultiple(aMultiple); } \

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

@ -28,7 +28,7 @@
#include "nsString.h"
#include "nsIScriptContext.h"
class nsIDOMElement;
class nsIDOMNode;
#define NS_IDOMNSHTMLSELECTELEMENT_IID \
{ 0xa6cf9105, 0x15b3, 0x11d2, \
@ -38,17 +38,21 @@ class nsIDOMNSHTMLSelectElement : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOMNSHTMLSELECTELEMENT_IID; return iid; }
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMElement** aReturn)=0;
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn)=0;
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn)=0;
};
#define NS_DECL_IDOMNSHTMLSELECTELEMENT \
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMElement** aReturn); \
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn); \
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn); \
#define NS_FORWARD_IDOMNSHTMLSELECTELEMENT(_to) \
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMElement** aReturn) { return _to Item(aIndex, aReturn); } \
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn) { return _to Item(aIndex, aReturn); } \
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn) { return _to NamedItem(aName, aReturn); } \
#endif // nsIDOMNSHTMLSelectElement_h__

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

@ -5,9 +5,9 @@
readonly attribute DOMString type;
attribute long selectedIndex;
attribute DOMString value;
readonly attribute unsigned long length;
attribute unsigned long length;
readonly attribute HTMLFormElement form;
readonly attribute HTMLCollection options;
readonly attribute NSHTMLOptionCollection options;
attribute boolean disabled;
attribute boolean multiple;
attribute DOMString name;
@ -24,5 +24,6 @@
/* IID: { 0xa6cf9105, 0x15b3, 0x11d2, \
{ 0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } } */
Element item(in unsigned long index);
Node item(in unsigned long index);
Node namedItem(in DOMString name);
};

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

@ -73,6 +73,7 @@ CPPSRCS = \
nsJSHTMLOListElement.cpp \
nsJSHTMLObjectElement.cpp \
nsJSHTMLOptGroupElement.cpp \
nsJSNSHTMLOptionCollection.cpp \
nsJSHTMLOptionElement.cpp \
nsJSHTMLParagraphElement.cpp \
nsJSHTMLParamElement.cpp \

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

@ -69,6 +69,7 @@ CPPSRCS = \
nsJSHTMLOListElement.cpp \
nsJSHTMLObjectElement.cpp \
nsJSHTMLOptGroupElement.cpp \
nsJSNSHTMLOptionCollection.cpp \
nsJSHTMLOptionElement.cpp \
nsJSHTMLParagraphElement.cpp \
nsJSHTMLParamElement.cpp \
@ -130,6 +131,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsJSHTMLOListElement.obj \
.\$(OBJDIR)\nsJSHTMLObjectElement.obj \
.\$(OBJDIR)\nsJSHTMLOptGroupElement.obj \
.\$(OBJDIR)\nsJSNSHTMLOptionCollection.obj \
.\$(OBJDIR)\nsJSHTMLOptionElement.obj \
.\$(OBJDIR)\nsJSHTMLParagraphElement.obj \
.\$(OBJDIR)\nsJSHTMLParamElement.obj \

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

@ -34,23 +34,23 @@
#include "nsCOMPtr.h"
#include "nsDOMPropEnums.h"
#include "nsString.h"
#include "nsIDOMNSHTMLOptionCollection.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMNode.h"
#include "nsIDOMNSHTMLSelectElement.h"
#include "nsIDOMHTMLCollection.h"
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
static NS_DEFINE_IID(kIScriptGlobalObjectIID, NS_ISCRIPTGLOBALOBJECT_IID);
static NS_DEFINE_IID(kINSHTMLOptionCollectionIID, NS_IDOMNSHTMLOPTIONCOLLECTION_IID);
static NS_DEFINE_IID(kIHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIHTMLElementIID, NS_IDOMHTMLELEMENT_IID);
static NS_DEFINE_IID(kIHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kINodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kINSHTMLSelectElementIID, NS_IDOMNSHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
//
// HTMLSelectElement property ids
@ -83,6 +83,7 @@ GetHTMLSelectElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return JS_TRUE;
}
PRBool checkNamedItem = PR_TRUE;
if (JSVAL_IS_INT(id)) {
nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
@ -90,6 +91,7 @@ GetHTMLSelectElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
if (NS_FAILED(rv)) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
}
checkNamedItem = PR_FALSE;
switch(JSVAL_TO_INT(id)) {
case HTMLSELECTELEMENT_TYPE:
{
@ -183,7 +185,7 @@ GetHTMLSelectElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
if (NS_FAILED(rv)) {
return nsJSUtils::nsReportError(cx, obj, rv);
}
nsIDOMHTMLCollection* prop;
nsIDOMNSHTMLOptionCollection* prop;
nsresult result = NS_OK;
result = a->GetOptions(&prop);
if (NS_SUCCEEDED(result)) {
@ -282,7 +284,7 @@ GetHTMLSelectElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
default:
{
nsIDOMElement* prop;
nsIDOMNode* prop;
nsIDOMNSHTMLSelectElement* b;
if (NS_OK == a->QueryInterface(kINSHTMLSelectElementIID, (void **)&b)) {
nsresult result = NS_OK;
@ -303,6 +305,42 @@ GetHTMLSelectElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
}
}
if (checkNamedItem) {
nsIDOMNode* prop;
nsIDOMNSHTMLSelectElement* b;
nsAutoString name;
JSString *jsstring = JS_ValueToString(cx, id);
if (nsnull != jsstring) {
name.SetString(JS_GetStringChars(jsstring));
}
else {
name.SetString("");
}
if (NS_OK == a->QueryInterface(kINSHTMLSelectElementIID, (void **)&b)) {
nsresult result = NS_OK;
result = b->NamedItem(name, &prop);
if (NS_SUCCEEDED(result)) {
NS_RELEASE(b);
if (NULL != prop) {
// get the js object
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, obj, vp);
}
else {
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
}
}
else {
NS_RELEASE(b);
return nsJSUtils::nsReportError(cx, obj, result);
}
}
else {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_WRONG_TYPE_ERR);
}
}
else {
return nsJSUtils::nsCallJSScriptObjectGetProperty(a, cx, obj, id, vp);
}
@ -324,6 +362,7 @@ SetHTMLSelectElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
return JS_TRUE;
}
PRBool checkNamedItem = PR_TRUE;
if (JSVAL_IS_INT(id)) {
nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
@ -331,6 +370,7 @@ SetHTMLSelectElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
if (NS_FAILED(rv)) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_SECMAN_ERR);
}
checkNamedItem = PR_FALSE;
switch(JSVAL_TO_INT(id)) {
case HTMLSELECTELEMENT_SELECTEDINDEX:
{
@ -364,6 +404,25 @@ SetHTMLSelectElementProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
break;
}
case HTMLSELECTELEMENT_LENGTH:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_HTMLSELECTELEMENT_LENGTH, PR_TRUE);
if (NS_FAILED(rv)) {
return nsJSUtils::nsReportError(cx, obj, rv);
}
PRUint32 prop;
int32 temp;
if (JSVAL_IS_NUMBER(*vp) && JS_ValueToInt32(cx, *vp, &temp)) {
prop = (PRUint32)temp;
}
else {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_NOT_NUMBER_ERR);
}
a->SetLength(prop);
break;
}
case HTMLSELECTELEMENT_DISABLED:
{
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_HTMLSELECTELEMENT_DISABLED, PR_TRUE);
@ -696,7 +755,7 @@ NSHTMLSelectElementItem(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, j
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_WRONG_TYPE_ERR);
}
nsIDOMElement* nativeRet;
nsIDOMNode* nativeRet;
PRUint32 b0;
// If there's no private data, this must be the prototype, so ignore
if (!nativeThis) {
@ -739,6 +798,60 @@ NSHTMLSelectElementItem(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, j
}
//
// Native method NamedItem
//
PR_STATIC_CALLBACK(JSBool)
NSHTMLSelectElementNamedItem(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMHTMLSelectElement *privateThis = (nsIDOMHTMLSelectElement*)nsJSUtils::nsGetNativeThis(cx, obj);
nsCOMPtr<nsIDOMNSHTMLSelectElement> nativeThis;
nsresult result = NS_OK;
if (NS_OK != privateThis->QueryInterface(kINSHTMLSelectElementIID, getter_AddRefs(nativeThis))) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_WRONG_TYPE_ERR);
}
nsIDOMNode* nativeRet;
nsAutoString b0;
// If there's no private data, this must be the prototype, so ignore
if (!nativeThis) {
return JS_TRUE;
}
{
*rval = JSVAL_NULL;
{
nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, secMan,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = secMan->CheckScriptAccess(cx, obj, NS_DOM_PROP_NSHTMLSELECTELEMENT_NAMEDITEM, PR_FALSE);
}
if (NS_FAILED(rv)) {
return nsJSUtils::nsReportError(cx, obj, rv);
}
}
if (argc < 1) {
return nsJSUtils::nsReportError(cx, obj, NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR);
}
nsJSUtils::nsConvertJSValToString(b0, cx, argv[0]);
result = nativeThis->NamedItem(b0, &nativeRet);
if (NS_FAILED(result)) {
return nsJSUtils::nsReportError(cx, obj, result);
}
nsJSUtils::nsConvertObjectToJSVal(nativeRet, cx, obj, rval);
}
return JS_TRUE;
}
/***********************************************************************/
//
// class for HTMLSelectElement
@ -767,7 +880,7 @@ static JSPropertySpec HTMLSelectElementProperties[] =
{"type", HTMLSELECTELEMENT_TYPE, JSPROP_ENUMERATE | JSPROP_READONLY},
{"selectedIndex", HTMLSELECTELEMENT_SELECTEDINDEX, JSPROP_ENUMERATE},
{"value", HTMLSELECTELEMENT_VALUE, JSPROP_ENUMERATE},
{"length", HTMLSELECTELEMENT_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY},
{"length", HTMLSELECTELEMENT_LENGTH, JSPROP_ENUMERATE},
{"form", HTMLSELECTELEMENT_FORM, JSPROP_ENUMERATE | JSPROP_READONLY},
{"options", HTMLSELECTELEMENT_OPTIONS, JSPROP_ENUMERATE | JSPROP_READONLY},
{"disabled", HTMLSELECTELEMENT_DISABLED, JSPROP_ENUMERATE},
@ -789,6 +902,7 @@ static JSFunctionSpec HTMLSelectElementMethods[] =
{"blur", HTMLSelectElementBlur, 0},
{"focus", HTMLSelectElementFocus, 0},
{"item", NSHTMLSelectElementItem, 1},
{"namedItem", NSHTMLSelectElementNamedItem, 1},
{0}
};

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

@ -33,7 +33,7 @@
#include "nsIServiceManager.h"
#include "nsIDocument.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNSHTMLOptionCollection.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLSelectElement.h"
@ -2329,7 +2329,7 @@ wallet_GetSelectIndex(
nsresult result;
PRUint32 length;
selectElement->GetLength(&length);
nsIDOMHTMLCollection * options;
nsIDOMNSHTMLOptionCollection * options;
result = selectElement->GetOptions(&options);
if ((NS_SUCCEEDED(result)) && (nsnull != options)) {
PRUint32 numOptions;

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

@ -31,6 +31,7 @@
#include "nsINameSpaceManager.h"
#include "nsIDeviceContext.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNSHTMLOptionCollection.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIComboboxControlFrame.h"
@ -1262,19 +1263,21 @@ nsListControlFrame::GetOptionContent(PRInt32 aIndex)
nsIDOMHTMLCollection*
nsListControlFrame::GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* aSelect)
{
nsIDOMNSHTMLOptionCollection* optCol = nsnull;
nsIDOMHTMLCollection* options = nsnull;
if (!aSelect) {
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement = getter_AddRefs(GetSelect(aContent));
if (selectElement) {
selectElement->GetOptions(&options); // AddRefs
return options;
} else {
return nsnull;
selectElement->GetOptions(&optCol); // AddRefs (1)
}
} else {
aSelect->GetOptions(&options); // AddRefs
return options;
aSelect->GetOptions(&optCol); // AddRefs (1)
}
if (optCol) {
nsresult res = optCol->QueryInterface(NS_GET_IID(nsIDOMHTMLCollection), (void **)&options); // AddRefs (2)
NS_RELEASE(optCol); // Release (1)
}
return options;
}
//---------------------------------------------------------

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

@ -22,6 +22,7 @@
*/
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLOptGroupElement.h"
#include "nsIDOMNSHTMLOptionCollection.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
@ -363,7 +364,7 @@ nsHTMLOptionElement::GetIndex(PRInt32* aIndex)
if (NS_OK == GetSelect(selectElement)) {
// Get the options from the select object.
nsIDOMHTMLCollection* options = nsnull;
nsIDOMNSHTMLOptionCollection* options = nsnull;
if (NS_OK == selectElement->GetOptions(&options)) {
// Walk the options to find out where we are in the list (ick, O(n))

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

@ -46,6 +46,7 @@
#include "nsISelectElement.h"
#include "nsISelectControlFrame.h"
#include "nsISizeOfHandler.h"
#include "nsIDOMNSHTMLOptionCollection.h"
// PresState
#include "nsISupportsArray.h"
@ -61,6 +62,7 @@
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMNSHTMLSelectElementIID, NS_IDOMNSHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMNSHTMLOptionCollectionIID, NS_IDOMNSHTMLOPTIONCOLLECTION_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
@ -71,19 +73,28 @@ static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
class nsHTMLSelectElement;
// nsOptionList
class nsOptionList : public nsGenericDOMHTMLCollection,
public nsIJSScriptObject
// nsHTMLOptionCollection
class nsHTMLOptionCollection: public nsIDOMNSHTMLOptionCollection,
public nsGenericDOMHTMLCollection,
public nsIJSScriptObject
{
public:
nsOptionList(nsHTMLSelectElement* aSelect);
virtual ~nsOptionList();
nsHTMLOptionCollection(nsHTMLSelectElement* aSelect);
virtual ~nsHTMLOptionCollection();
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMNSHTMLOptionCollection interface
NS_IMETHOD SetLength(PRUint32 aLength);
NS_IMETHOD GetSelectedIndex(PRInt32 *aSelectedIndex);
NS_IMETHOD SetSelectedIndex(PRInt32 aSelectedIndex);
// nsIDOMHTMLCollection interface
NS_DECL_IDOMHTMLCOLLECTION
// nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
// nsIJSScriptObject interface
PRBool AddProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
@ -116,6 +127,7 @@ private:
class nsHTMLSelectElement : public nsIDOMHTMLSelectElement,
public nsIDOMNSHTMLSelectElement,
public nsIScriptObjectOwner,
public nsIJSScriptObject,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl,
@ -145,8 +157,9 @@ public:
NS_IMETHOD GetValue(nsString& aValue);
NS_IMETHOD SetValue(const nsString& aValue);
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD SetLength(PRUint32 aLength);
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm);
NS_IMETHOD GetOptions(nsIDOMHTMLCollection** aOptions);
NS_IMETHOD GetOptions(nsIDOMNSHTMLOptionCollection** aOptions);
NS_IMETHOD GetDisabled(PRBool* aDisabled);
NS_IMETHOD SetDisabled(PRBool aDisabled);
NS_IMETHOD GetMultiple(PRBool* aMultiple);
@ -163,7 +176,8 @@ public:
NS_IMETHOD Focus();
// nsIDOMNSHTMLSelectElement
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMElement** aReturn);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn);
// nsIScriptObjectOwner
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner)
@ -191,12 +205,27 @@ public:
NS_IMETHOD DoneAddingContent(PRBool aIsDone);
NS_IMETHOD IsDoneAddingContent(PRBool * aIsDone);
// nsIJSScriptObject
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool DeleteProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool GetProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
// Implement this to enable setting option via frm.select[x]
virtual PRBool SetProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool EnumerateProperty(JSContext *aContext, JSObject *aObj);
virtual PRBool Resolve(JSContext *aContext, JSObject *aObj, jsval aID);
virtual PRBool Convert(JSContext *aContext, JSObject *aObj, jsval aID);
virtual void Finalize(JSContext *aContext, JSObject *aObj);
protected:
NS_IMETHOD GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
nsGenericHTMLContainerElement mInner;
nsIForm* mForm;
nsOptionList* mOptions;
nsHTMLOptionCollection* mOptions;
PRBool mIsDoneAddingContent;
};
@ -212,7 +241,7 @@ NS_NewHTMLSelectElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsHTMLSelectElement(aTag);
nsHTMLSelectElement* it = new nsHTMLSelectElement(aTag);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -250,6 +279,16 @@ NS_IMPL_ADDREF(nsHTMLSelectElement)
nsresult
nsHTMLSelectElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
// NS_IMPL_HTML_CONTENT_QUERY_INTERFACE returns mInner as the script object
// We need to be our own so we can implement setprop to set select[i]
if (aIID.Equals(kIJSScriptObjectIID)) {
*aInstancePtr = (void*)(nsIJSScriptObject*) this;
NS_ADDREF_THIS();
return NS_OK;
}
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLSelectElementIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLSelectElement*)this;
@ -397,7 +436,7 @@ nsHTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
}
NS_IMETHODIMP
nsHTMLSelectElement::GetOptions(nsIDOMHTMLCollection** aValue)
nsHTMLSelectElement::GetOptions(nsIDOMNSHTMLOptionCollection** aValue)
{
if (nsnull == mOptions) {
Init();
@ -439,6 +478,26 @@ nsHTMLSelectElement::GetLength(PRUint32* aLength)
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsHTMLSelectElement::SetLength(PRUint32 aLength)
{
if (!mOptions) {
Init();
}
PRUint32 curlen;
nsresult result;
GetLength(&curlen);
if (curlen && (curlen > aLength)) { // Remove extra options
for (PRInt32 i = (curlen - 1); (i>=(PRInt32)aLength) && NS_SUCCEEDED(result); i--) {
result = Remove(i);
}
} else { // Add options?
}
return NS_OK;
}
//NS_IMPL_INT_ATTR(nsHTMLSelectElement, SelectedIndex, selectedindex)
NS_IMETHODIMP
nsHTMLSelectElement::GetSelectedIndex(PRInt32* aValue)
@ -473,7 +532,7 @@ nsHTMLSelectElement::GetSelectedIndex(PRInt32* aValue)
*aValue = 0;
}
}
nsCOMPtr<nsIDOMHTMLCollection> options;
nsCOMPtr<nsIDOMNSHTMLOptionCollection> options;
rv = GetOptions(getter_AddRefs(options));
if (NS_SUCCEEDED(rv) && options) {
PRUint32 numOptions;
@ -483,7 +542,7 @@ nsHTMLSelectElement::GetSelectedIndex(PRInt32* aValue)
nsCOMPtr<nsIDOMNode> node;
rv = options->Item(i, getter_AddRefs(node));
if (NS_SUCCEEDED(rv) && node) {
nsCOMPtr<nsIDOMHTMLOptionElement> option = do_QueryInterface(node);
nsCOMPtr<nsIDOMHTMLOptionElement> option = do_QueryInterface(node, &rv);
if (NS_SUCCEEDED(rv) && option) {
PRBool selected;
rv = option->GetDefaultSelected(&selected); // DefaultSelected == HTML Selected
@ -588,7 +647,7 @@ nsHTMLSelectElement::GetValue(nsString& aValue)
result = GetSelectedIndex(&selectedIndex);
if (NS_SUCCEEDED(result)) {
nsCOMPtr<nsIDOMHTMLCollection> options;
nsCOMPtr<nsIDOMNSHTMLOptionCollection> options;
result = GetOptions(getter_AddRefs(options));
if (NS_SUCCEEDED(result)) {
@ -619,7 +678,7 @@ NS_IMETHODIMP
nsHTMLSelectElement::SetValue(const nsString& aValue)
{
nsresult result = NS_OK;
nsCOMPtr<nsIDOMHTMLCollection> options;
nsCOMPtr<nsIDOMNSHTMLOptionCollection> options;
result = GetOptions(getter_AddRefs(options));
if (NS_SUCCEEDED(result)) {
@ -706,22 +765,25 @@ nsHTMLSelectElement::RemoveFocus(nsIPresContext* aPresContext)
}
NS_IMETHODIMP
nsHTMLSelectElement::Item(PRUint32 aIndex, nsIDOMElement** aReturn)
nsHTMLSelectElement::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
if (!mOptions) {
Init();
}
if (mOptions) {
nsIDOMNode *node;
nsresult result = mOptions->Item(aIndex, &node);
if ((NS_OK == result) && (nsnull != node)) {
result = node->QueryInterface(kIDOMElementIID, (void **)aReturn);
NS_RELEASE(node);
}
else {
*aReturn = nsnull;
}
return result;
return mOptions->Item(aIndex, aReturn);
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsHTMLSelectElement::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
if (!mOptions) {
Init();
}
if (mOptions) {
return mOptions->NamedItem(aName, aReturn);
}
return NS_ERROR_FAILURE;
}
@ -840,7 +902,7 @@ nsHTMLSelectElement::RemoveOption(nsIContent* aContent)
value->Count(&count);
// look through the list to see if the option being removed is selected
// then remove it from the nsIASupportsArray
// then remove it from the nsISupportsArray
PRInt32 j=0;
for (PRUint32 i=0; i<count; i++) {
nsCOMPtr<nsISupports> suppval = getter_AddRefs(value->ElementAt(i));
@ -1045,16 +1107,89 @@ NS_IMETHODIMP
nsHTMLSelectElement::Init()
{
if (nsnull == mOptions) {
mOptions = new nsOptionList(this);
mOptions = new nsHTMLOptionCollection(this);
NS_ADDREF(mOptions);
}
return NS_OK;
}
// nsIJSScriptObject interface
PRBool
nsHTMLSelectElement::AddProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::DeleteProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::GetProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::SetProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
{
nsresult res = NS_OK;
// Set options in the options list by indexing into select
if (JSVAL_IS_INT(aID) && mOptions) {
nsIJSScriptObject* optList = nsnull;
res = mOptions->QueryInterface(kIJSScriptObjectIID, (void **)&optList);
if (NS_SUCCEEDED(res) && optList) {
res = optList->SetProperty(aContext, aObj, aID, aVp);
}
} else {
res = mInner.SetProperty(aContext, aObj, aID, aVp);
}
return res;
}
PRBool
nsHTMLSelectElement::EnumerateProperty(JSContext *aContext, JSObject *aObj)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
{
return PR_TRUE;
}
PRBool
nsHTMLSelectElement::Convert(JSContext *aContext, JSObject *aObj, jsval aID)
{
return PR_TRUE;
}
void
nsHTMLSelectElement::Finalize(JSContext *aContext, JSObject *aObj)
{
}
//----------------------------------------------------------------------
// nsOptionList implementation
// nsHTMLOptionCollection implementation
// XXX this was modified form nsHTMLFormElement.cpp. We need a base class implementation
static
@ -1079,7 +1214,7 @@ void GetOptionsRecurse(nsIContent* aContent, nsVoidArray& aOptions)
}
void
nsOptionList::GetOptions()
nsHTMLOptionCollection::GetOptions()
{
Clear();
GetOptionsRecurse(mSelect, mElements);
@ -1087,31 +1222,34 @@ nsOptionList::GetOptions()
}
nsOptionList::nsOptionList(nsHTMLSelectElement* aSelect)
nsHTMLOptionCollection::nsHTMLOptionCollection(nsHTMLSelectElement* aSelect)
{
mDirty = PR_TRUE;
// Do not maintain a reference counted reference. When
// the select goes away, it will let us know.
mSelect = aSelect;
mScriptObject = nsnull;
}
nsOptionList::~nsOptionList()
nsHTMLOptionCollection::~nsHTMLOptionCollection()
{
DropReference();
}
void
nsOptionList::DropReference()
nsHTMLOptionCollection::DropReference()
{
// Drop our (non ref-counted) reference
mSelect = nsnull;
}
NS_IMPL_ADDREF_INHERITED(nsOptionList, nsGenericDOMHTMLCollection)
NS_IMPL_RELEASE_INHERITED(nsOptionList, nsGenericDOMHTMLCollection)
// ISupports
NS_IMPL_ADDREF_INHERITED(nsHTMLOptionCollection, nsGenericDOMHTMLCollection)
NS_IMPL_RELEASE_INHERITED(nsHTMLOptionCollection, nsGenericDOMHTMLCollection)
nsresult
nsOptionList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
nsHTMLOptionCollection::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
if (aIID.Equals(kIJSScriptObjectIID)) {
@ -1119,15 +1257,18 @@ nsOptionList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
else {
return nsGenericDOMHTMLCollection::QueryInterface(aIID, aInstancePtr);
if (aIID.Equals(kIDOMNSHTMLOptionCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMNSHTMLOptionCollection*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return nsGenericDOMHTMLCollection::QueryInterface(aIID, aInstancePtr);
}
// nsIDOMHTMLCollection interface
// nsIDOMNSHTMLOptionCollection interface
NS_IMETHODIMP
nsOptionList::GetLength(PRUint32* aLength)
nsHTMLOptionCollection::GetLength(PRUint32* aLength)
{
if (mDirty && (nsnull != mSelect)) {
GetOptions();
@ -1138,7 +1279,46 @@ nsOptionList::GetLength(PRUint32* aLength)
}
NS_IMETHODIMP
nsOptionList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
nsHTMLOptionCollection::SetLength(PRUint32 aLength)
{
nsresult result = NS_ERROR_UNEXPECTED;
if (mSelect) {
if (mDirty) {
GetOptions();
}
result = mSelect->SetLength(aLength);
}
return result;
}
NS_IMETHODIMP
nsHTMLOptionCollection::GetSelectedIndex(PRInt32 *aSelectedIndex)
{
nsresult result = NS_ERROR_UNEXPECTED;
if (mSelect) {
if (mDirty) {
GetOptions();
}
result = mSelect->GetSelectedIndex(aSelectedIndex);
}
return result;
}
NS_IMETHODIMP
nsHTMLOptionCollection::SetSelectedIndex(PRInt32 aSelectedIndex)
{
nsresult result = NS_ERROR_UNEXPECTED;
if (mSelect) {
if (mDirty) {
GetOptions();
}
result = mSelect->SetSelectedIndex(aSelectedIndex);
}
return result;
}
NS_IMETHODIMP
nsHTMLOptionCollection::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
if (mDirty && (nsnull != mSelect)) {
GetOptions();
@ -1155,7 +1335,7 @@ nsOptionList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
}
NS_IMETHODIMP
nsOptionList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
nsHTMLOptionCollection::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
if (mDirty && (nsnull != mSelect)) {
GetOptions();
@ -1189,7 +1369,7 @@ nsOptionList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
}
void
nsOptionList::AddOption(nsIContent* aOption)
nsHTMLOptionCollection::AddOption(nsIContent* aOption)
{
// Just mark ourselves as dirty. The next time someone
// makes a call that requires us to look at the elements
@ -1198,7 +1378,7 @@ nsOptionList::AddOption(nsIContent* aOption)
}
void
nsOptionList::RemoveOption(nsIContent* aOption)
nsHTMLOptionCollection::RemoveOption(nsIContent* aOption)
{
nsIDOMHTMLOptionElement* option;
@ -1213,7 +1393,7 @@ nsOptionList::RemoveOption(nsIContent* aOption)
}
PRInt32
nsOptionList::IndexOf(nsIContent* aOption)
nsHTMLOptionCollection::IndexOf(nsIContent* aOption)
{
nsIDOMHTMLOptionElement* option;
@ -1227,8 +1407,24 @@ nsOptionList::IndexOf(nsIContent* aOption)
return -1;
}
// nsIScriptObjectOwner interface
NS_IMETHODIMP
nsHTMLOptionCollection::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
res = NS_NewScriptNSHTMLOptionCollection(aContext, (nsISupports *)(nsIDOMNSHTMLOptionCollection *)this, nsnull, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
return res;
}
// nsIJSScriptObject interface
PRBool
nsOptionList::AddProperty(JSContext *aContext,
nsHTMLOptionCollection::AddProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
@ -1237,7 +1433,7 @@ nsOptionList::AddProperty(JSContext *aContext,
}
PRBool
nsOptionList::DeleteProperty(JSContext *aContext,
nsHTMLOptionCollection::DeleteProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
@ -1246,7 +1442,7 @@ nsOptionList::DeleteProperty(JSContext *aContext,
}
PRBool
nsOptionList::GetProperty(JSContext *aContext,
nsHTMLOptionCollection::GetProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
@ -1255,7 +1451,7 @@ nsOptionList::GetProperty(JSContext *aContext,
}
PRBool
nsOptionList::SetProperty(JSContext *aContext,
nsHTMLOptionCollection::SetProperty(JSContext *aContext,
JSObject *aObj,
jsval aID,
jsval *aVp)
@ -1319,30 +1515,30 @@ nsOptionList::SetProperty(JSContext *aContext,
}
PRBool
nsOptionList::EnumerateProperty(JSContext *aContext, JSObject *aObj)
nsHTMLOptionCollection::EnumerateProperty(JSContext *aContext, JSObject *aObj)
{
return PR_TRUE;
}
PRBool
nsOptionList::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
nsHTMLOptionCollection::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
{
return PR_TRUE;
}
PRBool
nsOptionList::Convert(JSContext *aContext, JSObject *aObj, jsval aID)
nsHTMLOptionCollection::Convert(JSContext *aContext, JSObject *aObj, jsval aID)
{
return PR_TRUE;
}
void
nsOptionList::Finalize(JSContext *aContext, JSObject *aObj)
nsHTMLOptionCollection::Finalize(JSContext *aContext, JSObject *aObj)
{
}
void
nsOptionList::Clear()
nsHTMLOptionCollection::Clear()
{
PRUint32 numOptions = mElements.Count();
for (PRUint32 i = 0; i < numOptions; i++) {

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

@ -32,6 +32,7 @@
#include "nsINameSpaceManager.h"
#include "nsIDeviceContext.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNSHTMLOptionCollection.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIComboboxControlFrame.h"
@ -1581,20 +1582,21 @@ nsGfxListControlFrame::GetOptionContent(PRInt32 aIndex)
nsIDOMHTMLCollection*
nsGfxListControlFrame::GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* aSelect)
{
nsIDOMNSHTMLOptionCollection* optCol = nsnull;
nsIDOMHTMLCollection* options = nsnull;
if (!aSelect) {
nsIDOMHTMLSelectElement* selectElement = GetSelect(aContent);
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement = getter_AddRefs(GetSelect(aContent));
if (selectElement) {
selectElement->GetOptions(&options);
NS_RELEASE(selectElement);
return options;
} else {
return nsnull;
selectElement->GetOptions(&optCol); // AddRefs (1)
}
} else {
aSelect->GetOptions(&options);
return options;
aSelect->GetOptions(&optCol); // AddRefs (1)
}
if (optCol) {
nsresult res = optCol->QueryInterface(NS_GET_IID(nsIDOMHTMLCollection), (void **)&options); // AddRefs (2)
NS_RELEASE(optCol); // Release (1)
}
return options;
}
//---------------------------------------------------------

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

@ -31,6 +31,7 @@
#include "nsINameSpaceManager.h"
#include "nsIDeviceContext.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNSHTMLOptionCollection.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIComboboxControlFrame.h"
@ -1262,19 +1263,21 @@ nsListControlFrame::GetOptionContent(PRInt32 aIndex)
nsIDOMHTMLCollection*
nsListControlFrame::GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* aSelect)
{
nsIDOMNSHTMLOptionCollection* optCol = nsnull;
nsIDOMHTMLCollection* options = nsnull;
if (!aSelect) {
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement = getter_AddRefs(GetSelect(aContent));
if (selectElement) {
selectElement->GetOptions(&options); // AddRefs
return options;
} else {
return nsnull;
selectElement->GetOptions(&optCol); // AddRefs (1)
}
} else {
aSelect->GetOptions(&options); // AddRefs
return options;
aSelect->GetOptions(&optCol); // AddRefs (1)
}
if (optCol) {
nsresult res = optCol->QueryInterface(NS_GET_IID(nsIDOMHTMLCollection), (void **)&options); // AddRefs (2)
NS_RELEASE(optCol); // Release (1)
}
return options;
}
//---------------------------------------------------------