зеркало из https://github.com/mozilla/pjs.git
Fix for bug 30091. nsFormControlList::NamedItem() was doing a linear walk through the form control list. Now it uses a hash table lookup. This greatly reduces the time for the screen to update when one clicks on the Program list box on the Bugzilla query page.
This commit is contained in:
Родитель
e731b49281
Коммит
d6a5b5bf19
|
@ -23,6 +23,7 @@
|
||||||
#define nsIForm_h___
|
#define nsIForm_h___
|
||||||
|
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
|
#include "nsString.h"
|
||||||
class nsIFormControl;
|
class nsIFormControl;
|
||||||
class nsISizeOfHandler;
|
class nsISizeOfHandler;
|
||||||
|
|
||||||
|
@ -51,6 +52,15 @@ public:
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD AddElement(nsIFormControl* aElement) = 0;
|
NS_IMETHOD AddElement(nsIFormControl* aElement) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an element to the lookup table mainted by the form.
|
||||||
|
* We can't fold this method into AddElement() because when
|
||||||
|
* AddElement() is called, the form control has no
|
||||||
|
* attributes. The name or id attributes of the form control
|
||||||
|
* are used as a key into the table.
|
||||||
|
*/
|
||||||
|
NS_IMETHOD AddElementToTable(nsIFormControl* aElement, const nsString& aName) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the element at a specified index position
|
* Get the element at a specified index position
|
||||||
* @param aIndex the index
|
* @param aIndex the index
|
||||||
|
|
|
@ -3121,3 +3121,69 @@ nsGenericHTMLContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsGenericHTMLContainerFormElement::nsGenericHTMLContainerFormElement()
|
||||||
|
{
|
||||||
|
mForm = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsGenericHTMLContainerFormElement::~nsGenericHTMLContainerFormElement()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLContainerFormElement::SetForm(nsIForm* aForm)
|
||||||
|
{
|
||||||
|
mForm = aForm;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLContainerFormElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue,
|
||||||
|
PRBool aNotify)
|
||||||
|
{
|
||||||
|
// Add the control to the hash table
|
||||||
|
nsCOMPtr<nsIFormControl> control;
|
||||||
|
control = do_QueryInterface(mContent);
|
||||||
|
if (mForm && (nsHTMLAtoms::name == aName || nsHTMLAtoms::id == aName))
|
||||||
|
mForm->AddElementToTable(control, aValue);
|
||||||
|
|
||||||
|
return nsGenericHTMLElement::SetAttribute(aNameSpaceID, aName, aValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsGenericHTMLLeafFormElement::nsGenericHTMLLeafFormElement()
|
||||||
|
{
|
||||||
|
mForm = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsGenericHTMLLeafFormElement::~nsGenericHTMLLeafFormElement()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLLeafFormElement::SetForm(nsIForm* aForm)
|
||||||
|
{
|
||||||
|
mForm = aForm;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLLeafFormElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue,
|
||||||
|
PRBool aNotify)
|
||||||
|
{
|
||||||
|
// Add the control to the hash table
|
||||||
|
nsCOMPtr<nsIFormControl> control;
|
||||||
|
control = do_QueryInterface(mContent);
|
||||||
|
if (mForm && (nsHTMLAtoms::name == aName || nsHTMLAtoms::id == aName))
|
||||||
|
mForm->AddElementToTable(control, aValue);
|
||||||
|
|
||||||
|
return nsGenericHTMLElement::SetAttribute(aNameSpaceID, aName, aValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
|
@ -454,6 +454,42 @@ public:
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
class nsGenericHTMLContainerFormElement : public nsGenericHTMLContainerElement {
|
||||||
|
public:
|
||||||
|
nsGenericHTMLContainerFormElement();
|
||||||
|
~nsGenericHTMLContainerFormElement();
|
||||||
|
|
||||||
|
nsresult SetForm(nsIForm* aForm);
|
||||||
|
nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue,
|
||||||
|
PRBool aNotify);
|
||||||
|
nsresult SetAttribute(const nsString& aName, const nsString& aValue)
|
||||||
|
{
|
||||||
|
return nsGenericHTMLElement::SetAttribute(aName, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIForm* mForm;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
class nsGenericHTMLLeafFormElement : public nsGenericHTMLLeafElement {
|
||||||
|
public:
|
||||||
|
nsGenericHTMLLeafFormElement();
|
||||||
|
~nsGenericHTMLLeafFormElement();
|
||||||
|
|
||||||
|
nsresult SetForm(nsIForm* aForm);
|
||||||
|
nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue,
|
||||||
|
PRBool aNotify);
|
||||||
|
nsresult SetAttribute(const nsString& aName, const nsString& aValue)
|
||||||
|
{
|
||||||
|
return nsGenericHTMLElement::SetAttribute(aName, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIForm* mForm;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Implement the nsIDOMHTMLElement API by forwarding the methods to a
|
* Implement the nsIDOMHTMLElement API by forwarding the methods to a
|
||||||
* generic content object (either nsGenericHTMLLeafElement or
|
* generic content object (either nsGenericHTMLLeafElement or
|
||||||
|
|
|
@ -97,9 +97,9 @@ public:
|
||||||
NS_IMETHOD Init() { return NS_OK; }
|
NS_IMETHOD Init() { return NS_OK; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
PRInt32 mType;
|
PRInt32 mType;
|
||||||
};
|
};
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
|
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
|
||||||
|
@ -528,6 +528,9 @@ nsHTMLButtonElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,8 @@ public:
|
||||||
NS_IMETHOD Init() { return NS_OK; }
|
NS_IMETHOD Init() { return NS_OK; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
// construction, destruction
|
// construction, destruction
|
||||||
|
@ -224,6 +224,9 @@ nsHTMLFieldSetElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
#include "nsIScriptGlobalObject.h"
|
#include "nsIScriptGlobalObject.h"
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
|
#include "nsHashTable.h"
|
||||||
|
|
||||||
|
static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 64;
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
|
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
|
||||||
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
|
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
|
||||||
|
@ -109,6 +112,7 @@ public:
|
||||||
|
|
||||||
// nsIForm
|
// nsIForm
|
||||||
NS_IMETHOD AddElement(nsIFormControl* aElement);
|
NS_IMETHOD AddElement(nsIFormControl* aElement);
|
||||||
|
NS_IMETHOD AddElementToTable(nsIFormControl* aChild, const nsString& aName);
|
||||||
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
|
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
|
||||||
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
|
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
|
||||||
NS_IMETHOD RemoveElement(nsIFormControl* aElement, PRBool aChildIsRef = PR_TRUE);
|
NS_IMETHOD RemoveElement(nsIFormControl* aElement, PRBool aChildIsRef = PR_TRUE);
|
||||||
|
@ -137,14 +141,21 @@ public:
|
||||||
NS_DECL_IDOMHTMLCOLLECTION
|
NS_DECL_IDOMHTMLCOLLECTION
|
||||||
NS_DECL_IDOMHTMLFORMCONTROLLIST
|
NS_DECL_IDOMHTMLFORMCONTROLLIST
|
||||||
|
|
||||||
nsresult GetNamedObject(JSContext* aContext, jsval aID, JSObject** aObj);
|
nsresult GetNamedObject(JSContext* aContext, jsval aID, JSObject** aObj);
|
||||||
|
|
||||||
|
nsresult AddElementToTable(nsIFormControl* aChild, const nsString& aName);
|
||||||
|
nsresult RemoveElementFromTable(nsIFormControl* aChild, PRBool aChildIsRef);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *mScriptObject;
|
void *mScriptObject;
|
||||||
nsVoidArray mElements;
|
nsVoidArray mElements;
|
||||||
nsIDOMHTMLFormElement* mForm; // WEAK - the form owns me
|
nsIDOMHTMLFormElement* mForm; // WEAK - the form owns me
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsHashtable* mLookupTable; // A map from an ID or NAME attribute to the form control
|
||||||
};
|
};
|
||||||
|
|
||||||
// nsHTMLFormElement implementation
|
// nsHTMLFormElement implementation
|
||||||
|
@ -468,21 +479,32 @@ nsHTMLFormElement::GetElementAt(PRInt32 aIndex, nsIFormControl** aFormControl) c
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLFormElement::AddElement(nsIFormControl* aChild)
|
nsHTMLFormElement::AddElement(nsIFormControl* aChild)
|
||||||
{
|
{
|
||||||
PRBool rv = mControls->mElements.AppendElement(aChild);
|
PRBool rv = mControls->mElements.AppendElement(aChild);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
NS_ADDREF(aChild);
|
NS_ADDREF(aChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLFormElement::AddElementToTable(nsIFormControl* aChild, const nsString& aName)
|
||||||
|
{
|
||||||
|
return mControls->AddElementToTable(aChild, aName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild, PRBool aChildIsRef)
|
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild, PRBool aChildIsRef)
|
||||||
{
|
{
|
||||||
PRBool rv = mControls->mElements.RemoveElement(aChild);
|
PRBool rv = mControls->mElements.RemoveElement(aChild);
|
||||||
if (rv && aChildIsRef) {
|
if (rv) {
|
||||||
NS_RELEASE(aChild);
|
mControls->RemoveElementFromTable(aChild, aChildIsRef);
|
||||||
|
if (aChildIsRef) {
|
||||||
|
NS_RELEASE(aChild);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -701,10 +723,15 @@ nsFormControlList::nsFormControlList(nsIDOMHTMLFormElement* aForm)
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
mScriptObject = nsnull;
|
mScriptObject = nsnull;
|
||||||
mForm = aForm; // WEAK - the form owns me
|
mForm = aForm; // WEAK - the form owns me
|
||||||
|
mLookupTable = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsFormControlList::~nsFormControlList()
|
nsFormControlList::~nsFormControlList()
|
||||||
{
|
{
|
||||||
|
if (mLookupTable) {
|
||||||
|
delete mLookupTable;
|
||||||
|
mLookupTable = nsnull;
|
||||||
|
}
|
||||||
mForm = nsnull;
|
mForm = nsnull;
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
@ -728,6 +755,9 @@ nsFormControlList::Clear()
|
||||||
PRUint32 numElements = mElements.Count();
|
PRUint32 numElements = mElements.Count();
|
||||||
for (PRUint32 i = 0; i < numElements; i++) {
|
for (PRUint32 i = 0; i < numElements; i++) {
|
||||||
nsIFormControl* elem = (nsIFormControl*) mElements.ElementAt(i);
|
nsIFormControl* elem = (nsIFormControl*) mElements.ElementAt(i);
|
||||||
|
if (mLookupTable) {
|
||||||
|
RemoveElementFromTable(elem, PR_TRUE);
|
||||||
|
}
|
||||||
NS_IF_RELEASE(elem);
|
NS_IF_RELEASE(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -947,31 +977,57 @@ nsFormControlList::NamedItem(JSContext* cx, jsval* argv, PRUint32 argc, jsval* a
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFormControlList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
nsFormControlList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
||||||
{
|
{
|
||||||
PRUint32 count = mElements.Count();
|
|
||||||
nsresult result = NS_OK;
|
nsresult result = NS_OK;
|
||||||
|
nsStringKey key(aName);
|
||||||
|
nsIFormControl* control = nsnull;
|
||||||
*aReturn = nsnull;
|
*aReturn = nsnull;
|
||||||
for (PRUint32 i = 0; i < count && *aReturn == nsnull; i++) {
|
|
||||||
nsIFormControl *control = (nsIFormControl*)mElements.ElementAt(i);
|
if (mLookupTable) {
|
||||||
if (nsnull != control) {
|
control = (nsIFormControl*) mLookupTable->Get(&key);
|
||||||
nsIContent *content;
|
}
|
||||||
|
|
||||||
result = control->QueryInterface(kIContentIID, (void **)&content);
|
if (control) {
|
||||||
if (NS_OK == result) {
|
result = control->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||||
nsAutoString name;
|
}
|
||||||
// XXX Should it be an EqualsIgnoreCase?
|
|
||||||
if (((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
return result;
|
||||||
(aName.Equals(name))) ||
|
}
|
||||||
((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
|
||||||
(aName.Equals(name)))) {
|
nsresult
|
||||||
result = control->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
nsFormControlList::AddElementToTable(nsIFormControl* aChild, const nsString& aName)
|
||||||
}
|
{
|
||||||
NS_RELEASE(content);
|
nsStringKey key(aName);
|
||||||
}
|
if (!mLookupTable)
|
||||||
}
|
mLookupTable = (nsHashtable*) new nsHashtable(NS_FORM_CONTROL_LIST_HASHTABLE_SIZE);
|
||||||
|
|
||||||
|
mLookupTable->Put(&key, NS_STATIC_CAST(void*, aChild));
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsFormControlList::RemoveElementFromTable(nsIFormControl* aChild, PRBool aChildIsRef)
|
||||||
|
{
|
||||||
|
// This nsIContent* cannot be a COM pointer because it shouldn't
|
||||||
|
// be released at the end of this function when aChildIsRef is FALSE.
|
||||||
|
nsIContent* content = nsnull;
|
||||||
|
nsAutoString name;
|
||||||
|
|
||||||
|
aChild->QueryInterface(kIContentIID, (void**) &content);
|
||||||
|
|
||||||
|
if (mLookupTable && content &&
|
||||||
|
(content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE ||
|
||||||
|
content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE))
|
||||||
|
{
|
||||||
|
nsStringKey key(name);
|
||||||
|
mLookupTable->Remove(&key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
if (aChildIsRef)
|
||||||
|
{
|
||||||
|
NS_RELEASE(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -159,7 +159,7 @@ protected:
|
||||||
nsresult GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd);
|
nsresult GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLLeafElement mInner;
|
nsGenericHTMLLeafFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
PRInt32 mType;
|
PRInt32 mType;
|
||||||
PRBool mSkipFocusEvent;
|
PRBool mSkipFocusEvent;
|
||||||
|
@ -167,6 +167,7 @@ protected:
|
||||||
nsCOMPtr<nsIXBLBinding> mBinding;
|
nsCOMPtr<nsIXBLBinding> mBinding;
|
||||||
PRBool mDidMouseDown;
|
PRBool mDidMouseDown;
|
||||||
|
|
||||||
|
|
||||||
PRBool IsImage() const {
|
PRBool IsImage() const {
|
||||||
nsAutoString tmp;
|
nsAutoString tmp;
|
||||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, tmp);
|
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, tmp);
|
||||||
|
@ -1072,6 +1073,9 @@ nsHTMLInputElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,8 +128,8 @@ public:
|
||||||
NS_IMETHOD Init() { return NS_OK; }
|
NS_IMETHOD Init() { return NS_OK; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
// construction, destruction
|
// construction, destruction
|
||||||
|
@ -272,6 +272,9 @@ nsHTMLLabelElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,8 @@ public:
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -199,6 +199,9 @@ nsHTMLLegendElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
NS_RELEASE(formControl);
|
NS_RELEASE(formControl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerElement mInner;
|
||||||
|
|
||||||
// Get the primary frame associated with this content
|
// Get the primary frame associated with this content
|
||||||
nsresult GetPrimaryFrame(nsIFormControlFrame *&aFormControlFrame);
|
nsresult GetPrimaryFrame(nsIFormControlFrame *&aFormControlFrame, PRBool aFlushNotifications = PR_TRUE);
|
||||||
|
|
||||||
// Get the select content element that contains this option
|
// Get the select content element that contains this option
|
||||||
nsresult GetSelect(nsIDOMHTMLSelectElement *&aSelectElement);
|
nsresult GetSelect(nsIDOMHTMLSelectElement *&aSelectElement);
|
||||||
|
@ -249,14 +249,14 @@ nsHTMLOptionElement::GetSelected(PRBool* aValue)
|
||||||
*aValue = value.EqualsWithConversion("1");
|
*aValue = value.EqualsWithConversion("1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLOptionElement::SetSelected(PRBool aValue)
|
nsHTMLOptionElement::SetSelected(PRBool aValue)
|
||||||
{
|
{
|
||||||
nsIFormControlFrame* fcFrame = nsnull;
|
nsIFormControlFrame* fcFrame = nsnull;
|
||||||
nsresult result = GetPrimaryFrame(fcFrame);
|
nsresult result = GetPrimaryFrame(fcFrame, PR_FALSE);
|
||||||
if (NS_SUCCEEDED(result) && (nsnull != fcFrame)) {
|
if (NS_SUCCEEDED(result) && (nsnull != fcFrame)) {
|
||||||
nsISelectControlFrame* selectFrame = nsnull;
|
nsISelectControlFrame* selectFrame = nsnull;
|
||||||
result = fcFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),(void **) &selectFrame);
|
result = fcFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),(void **) &selectFrame);
|
||||||
|
@ -542,7 +542,7 @@ nsHTMLOptionElement::SetText(const nsString& aText)
|
||||||
|
|
||||||
// Options don't have frames - get the select content node
|
// Options don't have frames - get the select content node
|
||||||
// then call nsGenericHTMLElement::GetPrimaryFrame()
|
// then call nsGenericHTMLElement::GetPrimaryFrame()
|
||||||
nsresult nsHTMLOptionElement::GetPrimaryFrame(nsIFormControlFrame *&aIFormControlFrame)
|
nsresult nsHTMLOptionElement::GetPrimaryFrame(nsIFormControlFrame *&aIFormControlFrame, PRBool aFlushNotifications)
|
||||||
{
|
{
|
||||||
nsIDOMHTMLSelectElement* selectElement = nsnull;
|
nsIDOMHTMLSelectElement* selectElement = nsnull;
|
||||||
nsresult res = GetSelect(selectElement);
|
nsresult res = GetSelect(selectElement);
|
||||||
|
@ -552,7 +552,7 @@ nsresult nsHTMLOptionElement::GetPrimaryFrame(nsIFormControlFrame *&aIFormContro
|
||||||
NS_RELEASE(selectElement);
|
NS_RELEASE(selectElement);
|
||||||
|
|
||||||
if (NS_OK == gotContent) {
|
if (NS_OK == gotContent) {
|
||||||
res = nsGenericHTMLElement::GetPrimaryFrame(selectContent, aIFormControlFrame);
|
res = nsGenericHTMLElement::GetPrimaryFrame(selectContent, aIFormControlFrame, aFlushNotifications);
|
||||||
NS_RELEASE(selectContent);
|
NS_RELEASE(selectContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
NS_IMETHOD GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
|
NS_IMETHOD GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
|
||||||
|
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
nsHTMLOptionCollection* mOptions;
|
nsHTMLOptionCollection* mOptions;
|
||||||
PRBool mIsDoneAddingContent;
|
PRBool mIsDoneAddingContent;
|
||||||
|
@ -1128,6 +1128,9 @@ nsHTMLSelectElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ public:
|
||||||
NS_IMETHOD GetBaseTag(nsIAtom** aResult);
|
NS_IMETHOD GetBaseTag(nsIAtom** aResult);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
nsCOMPtr<nsIControllers> mControllers;
|
nsCOMPtr<nsIControllers> mControllers;
|
||||||
nsCOMPtr<nsIXBLBinding> mBinding;
|
nsCOMPtr<nsIXBLBinding> mBinding;
|
||||||
|
@ -564,6 +564,9 @@ nsHTMLTextAreaElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#define nsIForm_h___
|
#define nsIForm_h___
|
||||||
|
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
|
#include "nsString.h"
|
||||||
class nsIFormControl;
|
class nsIFormControl;
|
||||||
class nsISizeOfHandler;
|
class nsISizeOfHandler;
|
||||||
|
|
||||||
|
@ -51,6 +52,15 @@ public:
|
||||||
*/
|
*/
|
||||||
NS_IMETHOD AddElement(nsIFormControl* aElement) = 0;
|
NS_IMETHOD AddElement(nsIFormControl* aElement) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an element to the lookup table mainted by the form.
|
||||||
|
* We can't fold this method into AddElement() because when
|
||||||
|
* AddElement() is called, the form control has no
|
||||||
|
* attributes. The name or id attributes of the form control
|
||||||
|
* are used as a key into the table.
|
||||||
|
*/
|
||||||
|
NS_IMETHOD AddElementToTable(nsIFormControl* aElement, const nsString& aName) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the element at a specified index position
|
* Get the element at a specified index position
|
||||||
* @param aIndex the index
|
* @param aIndex the index
|
||||||
|
|
|
@ -3121,3 +3121,69 @@ nsGenericHTMLContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsGenericHTMLContainerFormElement::nsGenericHTMLContainerFormElement()
|
||||||
|
{
|
||||||
|
mForm = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsGenericHTMLContainerFormElement::~nsGenericHTMLContainerFormElement()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLContainerFormElement::SetForm(nsIForm* aForm)
|
||||||
|
{
|
||||||
|
mForm = aForm;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLContainerFormElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue,
|
||||||
|
PRBool aNotify)
|
||||||
|
{
|
||||||
|
// Add the control to the hash table
|
||||||
|
nsCOMPtr<nsIFormControl> control;
|
||||||
|
control = do_QueryInterface(mContent);
|
||||||
|
if (mForm && (nsHTMLAtoms::name == aName || nsHTMLAtoms::id == aName))
|
||||||
|
mForm->AddElementToTable(control, aValue);
|
||||||
|
|
||||||
|
return nsGenericHTMLElement::SetAttribute(aNameSpaceID, aName, aValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
nsGenericHTMLLeafFormElement::nsGenericHTMLLeafFormElement()
|
||||||
|
{
|
||||||
|
mForm = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsGenericHTMLLeafFormElement::~nsGenericHTMLLeafFormElement()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLLeafFormElement::SetForm(nsIForm* aForm)
|
||||||
|
{
|
||||||
|
mForm = aForm;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLLeafFormElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue,
|
||||||
|
PRBool aNotify)
|
||||||
|
{
|
||||||
|
// Add the control to the hash table
|
||||||
|
nsCOMPtr<nsIFormControl> control;
|
||||||
|
control = do_QueryInterface(mContent);
|
||||||
|
if (mForm && (nsHTMLAtoms::name == aName || nsHTMLAtoms::id == aName))
|
||||||
|
mForm->AddElementToTable(control, aValue);
|
||||||
|
|
||||||
|
return nsGenericHTMLElement::SetAttribute(aNameSpaceID, aName, aValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
|
@ -454,6 +454,42 @@ public:
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
class nsGenericHTMLContainerFormElement : public nsGenericHTMLContainerElement {
|
||||||
|
public:
|
||||||
|
nsGenericHTMLContainerFormElement();
|
||||||
|
~nsGenericHTMLContainerFormElement();
|
||||||
|
|
||||||
|
nsresult SetForm(nsIForm* aForm);
|
||||||
|
nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue,
|
||||||
|
PRBool aNotify);
|
||||||
|
nsresult SetAttribute(const nsString& aName, const nsString& aValue)
|
||||||
|
{
|
||||||
|
return nsGenericHTMLElement::SetAttribute(aName, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIForm* mForm;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
class nsGenericHTMLLeafFormElement : public nsGenericHTMLLeafElement {
|
||||||
|
public:
|
||||||
|
nsGenericHTMLLeafFormElement();
|
||||||
|
~nsGenericHTMLLeafFormElement();
|
||||||
|
|
||||||
|
nsresult SetForm(nsIForm* aForm);
|
||||||
|
nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue,
|
||||||
|
PRBool aNotify);
|
||||||
|
nsresult SetAttribute(const nsString& aName, const nsString& aValue)
|
||||||
|
{
|
||||||
|
return nsGenericHTMLElement::SetAttribute(aName, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIForm* mForm;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Implement the nsIDOMHTMLElement API by forwarding the methods to a
|
* Implement the nsIDOMHTMLElement API by forwarding the methods to a
|
||||||
* generic content object (either nsGenericHTMLLeafElement or
|
* generic content object (either nsGenericHTMLLeafElement or
|
||||||
|
|
|
@ -97,9 +97,9 @@ public:
|
||||||
NS_IMETHOD Init() { return NS_OK; }
|
NS_IMETHOD Init() { return NS_OK; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
PRInt32 mType;
|
PRInt32 mType;
|
||||||
};
|
};
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
|
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
|
||||||
|
@ -528,6 +528,9 @@ nsHTMLButtonElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,8 @@ public:
|
||||||
NS_IMETHOD Init() { return NS_OK; }
|
NS_IMETHOD Init() { return NS_OK; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
// construction, destruction
|
// construction, destruction
|
||||||
|
@ -224,6 +224,9 @@ nsHTMLFieldSetElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
#include "nsIScriptGlobalObject.h"
|
#include "nsIScriptGlobalObject.h"
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
|
#include "nsHashTable.h"
|
||||||
|
|
||||||
|
static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 64;
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
|
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
|
||||||
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
|
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
|
||||||
|
@ -109,6 +112,7 @@ public:
|
||||||
|
|
||||||
// nsIForm
|
// nsIForm
|
||||||
NS_IMETHOD AddElement(nsIFormControl* aElement);
|
NS_IMETHOD AddElement(nsIFormControl* aElement);
|
||||||
|
NS_IMETHOD AddElementToTable(nsIFormControl* aChild, const nsString& aName);
|
||||||
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
|
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
|
||||||
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
|
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
|
||||||
NS_IMETHOD RemoveElement(nsIFormControl* aElement, PRBool aChildIsRef = PR_TRUE);
|
NS_IMETHOD RemoveElement(nsIFormControl* aElement, PRBool aChildIsRef = PR_TRUE);
|
||||||
|
@ -137,14 +141,21 @@ public:
|
||||||
NS_DECL_IDOMHTMLCOLLECTION
|
NS_DECL_IDOMHTMLCOLLECTION
|
||||||
NS_DECL_IDOMHTMLFORMCONTROLLIST
|
NS_DECL_IDOMHTMLFORMCONTROLLIST
|
||||||
|
|
||||||
nsresult GetNamedObject(JSContext* aContext, jsval aID, JSObject** aObj);
|
nsresult GetNamedObject(JSContext* aContext, jsval aID, JSObject** aObj);
|
||||||
|
|
||||||
|
nsresult AddElementToTable(nsIFormControl* aChild, const nsString& aName);
|
||||||
|
nsresult RemoveElementFromTable(nsIFormControl* aChild, PRBool aChildIsRef);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *mScriptObject;
|
void *mScriptObject;
|
||||||
nsVoidArray mElements;
|
nsVoidArray mElements;
|
||||||
nsIDOMHTMLFormElement* mForm; // WEAK - the form owns me
|
nsIDOMHTMLFormElement* mForm; // WEAK - the form owns me
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsHashtable* mLookupTable; // A map from an ID or NAME attribute to the form control
|
||||||
};
|
};
|
||||||
|
|
||||||
// nsHTMLFormElement implementation
|
// nsHTMLFormElement implementation
|
||||||
|
@ -468,21 +479,32 @@ nsHTMLFormElement::GetElementAt(PRInt32 aIndex, nsIFormControl** aFormControl) c
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLFormElement::AddElement(nsIFormControl* aChild)
|
nsHTMLFormElement::AddElement(nsIFormControl* aChild)
|
||||||
{
|
{
|
||||||
PRBool rv = mControls->mElements.AppendElement(aChild);
|
PRBool rv = mControls->mElements.AppendElement(aChild);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
NS_ADDREF(aChild);
|
NS_ADDREF(aChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLFormElement::AddElementToTable(nsIFormControl* aChild, const nsString& aName)
|
||||||
|
{
|
||||||
|
return mControls->AddElementToTable(aChild, aName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild, PRBool aChildIsRef)
|
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild, PRBool aChildIsRef)
|
||||||
{
|
{
|
||||||
PRBool rv = mControls->mElements.RemoveElement(aChild);
|
PRBool rv = mControls->mElements.RemoveElement(aChild);
|
||||||
if (rv && aChildIsRef) {
|
if (rv) {
|
||||||
NS_RELEASE(aChild);
|
mControls->RemoveElementFromTable(aChild, aChildIsRef);
|
||||||
|
if (aChildIsRef) {
|
||||||
|
NS_RELEASE(aChild);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -701,10 +723,15 @@ nsFormControlList::nsFormControlList(nsIDOMHTMLFormElement* aForm)
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
mScriptObject = nsnull;
|
mScriptObject = nsnull;
|
||||||
mForm = aForm; // WEAK - the form owns me
|
mForm = aForm; // WEAK - the form owns me
|
||||||
|
mLookupTable = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsFormControlList::~nsFormControlList()
|
nsFormControlList::~nsFormControlList()
|
||||||
{
|
{
|
||||||
|
if (mLookupTable) {
|
||||||
|
delete mLookupTable;
|
||||||
|
mLookupTable = nsnull;
|
||||||
|
}
|
||||||
mForm = nsnull;
|
mForm = nsnull;
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
@ -728,6 +755,9 @@ nsFormControlList::Clear()
|
||||||
PRUint32 numElements = mElements.Count();
|
PRUint32 numElements = mElements.Count();
|
||||||
for (PRUint32 i = 0; i < numElements; i++) {
|
for (PRUint32 i = 0; i < numElements; i++) {
|
||||||
nsIFormControl* elem = (nsIFormControl*) mElements.ElementAt(i);
|
nsIFormControl* elem = (nsIFormControl*) mElements.ElementAt(i);
|
||||||
|
if (mLookupTable) {
|
||||||
|
RemoveElementFromTable(elem, PR_TRUE);
|
||||||
|
}
|
||||||
NS_IF_RELEASE(elem);
|
NS_IF_RELEASE(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -947,31 +977,57 @@ nsFormControlList::NamedItem(JSContext* cx, jsval* argv, PRUint32 argc, jsval* a
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFormControlList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
nsFormControlList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
||||||
{
|
{
|
||||||
PRUint32 count = mElements.Count();
|
|
||||||
nsresult result = NS_OK;
|
nsresult result = NS_OK;
|
||||||
|
nsStringKey key(aName);
|
||||||
|
nsIFormControl* control = nsnull;
|
||||||
*aReturn = nsnull;
|
*aReturn = nsnull;
|
||||||
for (PRUint32 i = 0; i < count && *aReturn == nsnull; i++) {
|
|
||||||
nsIFormControl *control = (nsIFormControl*)mElements.ElementAt(i);
|
if (mLookupTable) {
|
||||||
if (nsnull != control) {
|
control = (nsIFormControl*) mLookupTable->Get(&key);
|
||||||
nsIContent *content;
|
}
|
||||||
|
|
||||||
result = control->QueryInterface(kIContentIID, (void **)&content);
|
if (control) {
|
||||||
if (NS_OK == result) {
|
result = control->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
||||||
nsAutoString name;
|
}
|
||||||
// XXX Should it be an EqualsIgnoreCase?
|
|
||||||
if (((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
return result;
|
||||||
(aName.Equals(name))) ||
|
}
|
||||||
((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
|
||||||
(aName.Equals(name)))) {
|
nsresult
|
||||||
result = control->QueryInterface(kIDOMNodeIID, (void **)aReturn);
|
nsFormControlList::AddElementToTable(nsIFormControl* aChild, const nsString& aName)
|
||||||
}
|
{
|
||||||
NS_RELEASE(content);
|
nsStringKey key(aName);
|
||||||
}
|
if (!mLookupTable)
|
||||||
}
|
mLookupTable = (nsHashtable*) new nsHashtable(NS_FORM_CONTROL_LIST_HASHTABLE_SIZE);
|
||||||
|
|
||||||
|
mLookupTable->Put(&key, NS_STATIC_CAST(void*, aChild));
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsFormControlList::RemoveElementFromTable(nsIFormControl* aChild, PRBool aChildIsRef)
|
||||||
|
{
|
||||||
|
// This nsIContent* cannot be a COM pointer because it shouldn't
|
||||||
|
// be released at the end of this function when aChildIsRef is FALSE.
|
||||||
|
nsIContent* content = nsnull;
|
||||||
|
nsAutoString name;
|
||||||
|
|
||||||
|
aChild->QueryInterface(kIContentIID, (void**) &content);
|
||||||
|
|
||||||
|
if (mLookupTable && content &&
|
||||||
|
(content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE ||
|
||||||
|
content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE))
|
||||||
|
{
|
||||||
|
nsStringKey key(name);
|
||||||
|
mLookupTable->Remove(&key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
if (aChildIsRef)
|
||||||
|
{
|
||||||
|
NS_RELEASE(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -159,7 +159,7 @@ protected:
|
||||||
nsresult GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd);
|
nsresult GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLLeafElement mInner;
|
nsGenericHTMLLeafFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
PRInt32 mType;
|
PRInt32 mType;
|
||||||
PRBool mSkipFocusEvent;
|
PRBool mSkipFocusEvent;
|
||||||
|
@ -167,6 +167,7 @@ protected:
|
||||||
nsCOMPtr<nsIXBLBinding> mBinding;
|
nsCOMPtr<nsIXBLBinding> mBinding;
|
||||||
PRBool mDidMouseDown;
|
PRBool mDidMouseDown;
|
||||||
|
|
||||||
|
|
||||||
PRBool IsImage() const {
|
PRBool IsImage() const {
|
||||||
nsAutoString tmp;
|
nsAutoString tmp;
|
||||||
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, tmp);
|
mInner.GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, tmp);
|
||||||
|
@ -1072,6 +1073,9 @@ nsHTMLInputElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,8 +128,8 @@ public:
|
||||||
NS_IMETHOD Init() { return NS_OK; }
|
NS_IMETHOD Init() { return NS_OK; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
// construction, destruction
|
// construction, destruction
|
||||||
|
@ -272,6 +272,9 @@ nsHTMLLabelElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,8 @@ public:
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -199,6 +199,9 @@ nsHTMLLegendElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
NS_RELEASE(formControl);
|
NS_RELEASE(formControl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerElement mInner;
|
||||||
|
|
||||||
// Get the primary frame associated with this content
|
// Get the primary frame associated with this content
|
||||||
nsresult GetPrimaryFrame(nsIFormControlFrame *&aFormControlFrame);
|
nsresult GetPrimaryFrame(nsIFormControlFrame *&aFormControlFrame, PRBool aFlushNotifications = PR_TRUE);
|
||||||
|
|
||||||
// Get the select content element that contains this option
|
// Get the select content element that contains this option
|
||||||
nsresult GetSelect(nsIDOMHTMLSelectElement *&aSelectElement);
|
nsresult GetSelect(nsIDOMHTMLSelectElement *&aSelectElement);
|
||||||
|
@ -249,14 +249,14 @@ nsHTMLOptionElement::GetSelected(PRBool* aValue)
|
||||||
*aValue = value.EqualsWithConversion("1");
|
*aValue = value.EqualsWithConversion("1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLOptionElement::SetSelected(PRBool aValue)
|
nsHTMLOptionElement::SetSelected(PRBool aValue)
|
||||||
{
|
{
|
||||||
nsIFormControlFrame* fcFrame = nsnull;
|
nsIFormControlFrame* fcFrame = nsnull;
|
||||||
nsresult result = GetPrimaryFrame(fcFrame);
|
nsresult result = GetPrimaryFrame(fcFrame, PR_FALSE);
|
||||||
if (NS_SUCCEEDED(result) && (nsnull != fcFrame)) {
|
if (NS_SUCCEEDED(result) && (nsnull != fcFrame)) {
|
||||||
nsISelectControlFrame* selectFrame = nsnull;
|
nsISelectControlFrame* selectFrame = nsnull;
|
||||||
result = fcFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),(void **) &selectFrame);
|
result = fcFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),(void **) &selectFrame);
|
||||||
|
@ -542,7 +542,7 @@ nsHTMLOptionElement::SetText(const nsString& aText)
|
||||||
|
|
||||||
// Options don't have frames - get the select content node
|
// Options don't have frames - get the select content node
|
||||||
// then call nsGenericHTMLElement::GetPrimaryFrame()
|
// then call nsGenericHTMLElement::GetPrimaryFrame()
|
||||||
nsresult nsHTMLOptionElement::GetPrimaryFrame(nsIFormControlFrame *&aIFormControlFrame)
|
nsresult nsHTMLOptionElement::GetPrimaryFrame(nsIFormControlFrame *&aIFormControlFrame, PRBool aFlushNotifications)
|
||||||
{
|
{
|
||||||
nsIDOMHTMLSelectElement* selectElement = nsnull;
|
nsIDOMHTMLSelectElement* selectElement = nsnull;
|
||||||
nsresult res = GetSelect(selectElement);
|
nsresult res = GetSelect(selectElement);
|
||||||
|
@ -552,7 +552,7 @@ nsresult nsHTMLOptionElement::GetPrimaryFrame(nsIFormControlFrame *&aIFormContro
|
||||||
NS_RELEASE(selectElement);
|
NS_RELEASE(selectElement);
|
||||||
|
|
||||||
if (NS_OK == gotContent) {
|
if (NS_OK == gotContent) {
|
||||||
res = nsGenericHTMLElement::GetPrimaryFrame(selectContent, aIFormControlFrame);
|
res = nsGenericHTMLElement::GetPrimaryFrame(selectContent, aIFormControlFrame, aFlushNotifications);
|
||||||
NS_RELEASE(selectContent);
|
NS_RELEASE(selectContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
NS_IMETHOD GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
|
NS_IMETHOD GetPresState(nsIPresState** aPresState, nsISupportsArray** aValueArray);
|
||||||
|
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
nsHTMLOptionCollection* mOptions;
|
nsHTMLOptionCollection* mOptions;
|
||||||
PRBool mIsDoneAddingContent;
|
PRBool mIsDoneAddingContent;
|
||||||
|
@ -1128,6 +1128,9 @@ nsHTMLSelectElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ public:
|
||||||
NS_IMETHOD GetBaseTag(nsIAtom** aResult);
|
NS_IMETHOD GetBaseTag(nsIAtom** aResult);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsGenericHTMLContainerElement mInner;
|
nsGenericHTMLContainerFormElement mInner;
|
||||||
nsIForm* mForm;
|
nsIForm* mForm;
|
||||||
nsCOMPtr<nsIControllers> mControllers;
|
nsCOMPtr<nsIControllers> mControllers;
|
||||||
nsCOMPtr<nsIXBLBinding> mBinding;
|
nsCOMPtr<nsIXBLBinding> mBinding;
|
||||||
|
@ -564,6 +564,9 @@ nsHTMLTextAreaElement::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(formControl);
|
NS_IF_RELEASE(formControl);
|
||||||
|
|
||||||
|
mInner.SetForm(mForm);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче