diff --git a/content/html/content/public/nsIForm.h b/content/html/content/public/nsIForm.h
index 142da196f79..7d81714a9df 100644
--- a/content/html/content/public/nsIForm.h
+++ b/content/html/content/public/nsIForm.h
@@ -84,6 +84,19 @@ public:
*/
NS_IMETHOD RemoveElement(nsIFormControl* aElement) = 0;
+ /**
+ * Remove an element from the lookup table mainted by the form.
+ * We can't fold this method into RemoveElement() because when
+ * RemoveElement() is called it doesn't know if the element is
+ * removed because the id attribute has changed, or bacause the
+ * name attribute has changed.
+ *
+ * @param aElement the element to remove
+ * @param aName the name or id of the element to remove
+ * @return NS_OK if the element was successfully removed.
+ */
+ NS_IMETHOD RemoveElementFromTable(nsIFormControl* aElement, const nsString& aName) = 0;
+
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const = 0;
};
diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp
index 767f5aafdac..3206ed1bb97 100644
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -3607,8 +3607,14 @@ nsGenericHTMLLeafFormElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
// Add the control to the hash table
nsCOMPtr control;
control = do_QueryInterface(mContent);
- if (mForm && (nsHTMLAtoms::name == aName || nsHTMLAtoms::id == aName))
+ if (mForm && (nsHTMLAtoms::name == aName || nsHTMLAtoms::id == aName)) {
+ nsAutoString tmp;
+ nsresult rv = GetAttribute(kNameSpaceID_None, aName, tmp);
+ if (rv == NS_CONTENT_ATTR_HAS_VALUE)
+ mForm->RemoveElementFromTable(control, tmp);
+
mForm->AddElementToTable(control, aValue);
+ }
return nsGenericHTMLElement::SetAttribute(aNameSpaceID, aName, aValue, aNotify);
}
diff --git a/content/html/content/src/nsHTMLButtonElement.cpp b/content/html/content/src/nsHTMLButtonElement.cpp
index 919d07d21d5..59f67d9a4f3 100644
--- a/content/html/content/src/nsHTMLButtonElement.cpp
+++ b/content/html/content/src/nsHTMLButtonElement.cpp
@@ -189,10 +189,7 @@ nsHTMLButtonElement::nsHTMLButtonElement(nsINodeInfo *aNodeInfo)
nsHTMLButtonElement::~nsHTMLButtonElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
// nsISupports
@@ -614,15 +611,32 @@ nsHTMLButtonElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/content/html/content/src/nsHTMLFieldSetElement.cpp b/content/html/content/src/nsHTMLFieldSetElement.cpp
index 83efb13ac5b..c61980ff788 100644
--- a/content/html/content/src/nsHTMLFieldSetElement.cpp
+++ b/content/html/content/src/nsHTMLFieldSetElement.cpp
@@ -110,10 +110,7 @@ nsHTMLFieldSetElement::nsHTMLFieldSetElement(nsINodeInfo *aNodeInfo)
nsHTMLFieldSetElement::~nsHTMLFieldSetElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
// nsISupports
@@ -187,15 +184,32 @@ nsHTMLFieldSetElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/content/html/content/src/nsHTMLFormElement.cpp b/content/html/content/src/nsHTMLFormElement.cpp
index 24978ba6aa0..fb8d0f092a3 100644
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -117,6 +117,7 @@ public:
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
NS_IMETHOD RemoveElement(nsIFormControl* aElement);
+ NS_IMETHOD RemoveElementFromTable(nsIFormControl* aElement, const nsString& aName);
protected:
nsFormControlList* mControls;
@@ -145,7 +146,7 @@ public:
nsresult GetNamedObject(JSContext* aContext, jsval aID, JSObject** aObj);
nsresult AddElementToTable(nsIFormControl* aChild, const nsString& aName);
- nsresult RemoveElementFromTable(nsIFormControl* aChild);
+ nsresult RemoveElementFromTable(nsIFormControl* aChild, const nsString& aName);
#ifdef DEBUG
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
@@ -470,13 +471,17 @@ nsHTMLFormElement::AddElementToTable(nsIFormControl* aChild, const nsString& aNa
NS_IMETHODIMP
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild)
-{
- PRBool rv = mControls->mElements.RemoveElement(aChild);
- if (rv) {
- mControls->RemoveElementFromTable(aChild);
- // WEAK - don't release
- }
- return rv;
+{
+ mControls->mElements.RemoveElement(aChild);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLFormElement::RemoveElementFromTable(nsIFormControl* aElement,
+ const nsString& aName)
+{
+ return mControls->RemoveElementFromTable(aElement, aName);
}
NS_IMETHODIMP
@@ -607,7 +612,36 @@ nsHTMLFormElement::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
return PR_FALSE;
}
- if (nsnull != obj) {
+ if (!obj && mInner.mDocument) {
+ nsCOMPtr htmlDoc = do_QueryInterface(mInner.mDocument);
+ if (htmlDoc) {
+ nsCOMPtr list;
+ result = htmlDoc->GetElementsByName(name, getter_AddRefs(list));
+ if (NS_FAILED(result)) {
+ return PR_FALSE;
+ }
+ if (list) {
+ PRUint32 count;
+ list->GetLength(&count);
+ if (count > 0) {
+ nsCOMPtr node;
+ result = list->Item(0, getter_AddRefs(node));
+ if (NS_FAILED(result)) {
+ return PR_FALSE;
+ }
+ if (node) {
+ nsCOMPtr owner = do_QueryInterface(node);
+ result = owner->GetScriptObject(scriptContext, (void**)&obj);
+ if (NS_FAILED(result)) {
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (obj) {
JSObject* myObj;
result = mInner.GetScriptObject(scriptContext, (void**)&myObj);
ret = ::JS_DefineProperty(aContext, myObj,
@@ -690,14 +724,10 @@ nsFormControlList::SetForm(nsIDOMHTMLFormElement* aForm)
void
nsFormControlList::Clear()
{
- PRUint32 numElements = mElements.Count();
- for (PRUint32 i = 0; i < numElements; i++) {
- nsIFormControl* elem = (nsIFormControl*) mElements.ElementAt(i);
- if (mLookupTable) {
- RemoveElementFromTable(elem);
- }
- // WEAK, don't release
- }
+ mElements.Clear();
+
+ if (mLookupTable)
+ mLookupTable->Reset();
}
NS_IMPL_ISUPPORTS3(nsFormControlList, nsIDOMHTMLCollection, nsIDOMHTMLFormControlList, nsIScriptObjectOwner)
@@ -985,15 +1015,13 @@ nsFormControlList::AddElementToTable(nsIFormControl* aChild, const nsString& aNa
}
nsresult
-nsFormControlList::RemoveElementFromTable(nsIFormControl* aChild)
+nsFormControlList::RemoveElementFromTable(nsIFormControl* aChild,
+ const nsString& aName)
{
nsAutoString name;
nsCOMPtr content = do_QueryInterface(aChild);
- 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);
+ if (mLookupTable && content) {
+ nsStringKey key(aName);
nsCOMPtr supports;
supports = dont_AddRef((nsISupports *)mLookupTable->Get(&key));
diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp
index 908c7b2f0e4..8a0ed07240e 100644
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -237,10 +237,7 @@ nsHTMLInputElement::nsHTMLInputElement(nsINodeInfo *aNodeInfo)
nsHTMLInputElement::~nsHTMLInputElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
// nsISupports
@@ -1179,15 +1176,32 @@ nsHTMLInputElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/content/html/content/src/nsHTMLLabelElement.cpp b/content/html/content/src/nsHTMLLabelElement.cpp
index 4ab958b810d..798db1953ad 100644
--- a/content/html/content/src/nsHTMLLabelElement.cpp
+++ b/content/html/content/src/nsHTMLLabelElement.cpp
@@ -191,10 +191,7 @@ nsHTMLLabelElement::nsHTMLLabelElement(nsINodeInfo *aNodeInfo)
nsHTMLLabelElement::~nsHTMLLabelElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
// nsISupports
@@ -268,15 +265,32 @@ nsHTMLLabelElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/content/html/content/src/nsHTMLLegendElement.cpp b/content/html/content/src/nsHTMLLegendElement.cpp
index 269c45c715c..f005725713b 100644
--- a/content/html/content/src/nsHTMLLegendElement.cpp
+++ b/content/html/content/src/nsHTMLLegendElement.cpp
@@ -112,10 +112,7 @@ nsHTMLLegendElement::nsHTMLLegendElement(nsINodeInfo *aNodeInfo)
nsHTMLLegendElement::~nsHTMLLegendElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
NS_IMPL_ADDREF(nsHTMLLegendElement)
@@ -187,15 +184,32 @@ nsHTMLLegendElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(NS_GET_IID(nsIFormControl), getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/content/html/content/src/nsHTMLSelectElement.cpp b/content/html/content/src/nsHTMLSelectElement.cpp
index 738fa1c7fd5..b5d69e67741 100644
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -248,10 +248,7 @@ nsHTMLSelectElement::nsHTMLSelectElement(nsINodeInfo *aNodeInfo)
nsHTMLSelectElement::~nsHTMLSelectElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
if (nsnull != mOptions) {
mOptions->Clear();
mOptions->DropReference();
@@ -1151,15 +1148,32 @@ nsHTMLSelectElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/content/html/content/src/nsHTMLTextAreaElement.cpp b/content/html/content/src/nsHTMLTextAreaElement.cpp
index d678072d12e..80c761127e3 100644
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -151,10 +151,7 @@ nsHTMLTextAreaElement::nsHTMLTextAreaElement(nsINodeInfo *aNodeInfo)
nsHTMLTextAreaElement::~nsHTMLTextAreaElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
NS_IMPL_ADDREF(nsHTMLTextAreaElement)
@@ -555,15 +552,32 @@ nsHTMLTextAreaElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/layout/html/content/public/nsIForm.h b/layout/html/content/public/nsIForm.h
index 142da196f79..7d81714a9df 100644
--- a/layout/html/content/public/nsIForm.h
+++ b/layout/html/content/public/nsIForm.h
@@ -84,6 +84,19 @@ public:
*/
NS_IMETHOD RemoveElement(nsIFormControl* aElement) = 0;
+ /**
+ * Remove an element from the lookup table mainted by the form.
+ * We can't fold this method into RemoveElement() because when
+ * RemoveElement() is called it doesn't know if the element is
+ * removed because the id attribute has changed, or bacause the
+ * name attribute has changed.
+ *
+ * @param aElement the element to remove
+ * @param aName the name or id of the element to remove
+ * @return NS_OK if the element was successfully removed.
+ */
+ NS_IMETHOD RemoveElementFromTable(nsIFormControl* aElement, const nsString& aName) = 0;
+
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const = 0;
};
diff --git a/layout/html/content/src/nsGenericHTMLElement.cpp b/layout/html/content/src/nsGenericHTMLElement.cpp
index 767f5aafdac..3206ed1bb97 100644
--- a/layout/html/content/src/nsGenericHTMLElement.cpp
+++ b/layout/html/content/src/nsGenericHTMLElement.cpp
@@ -3607,8 +3607,14 @@ nsGenericHTMLLeafFormElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
// Add the control to the hash table
nsCOMPtr control;
control = do_QueryInterface(mContent);
- if (mForm && (nsHTMLAtoms::name == aName || nsHTMLAtoms::id == aName))
+ if (mForm && (nsHTMLAtoms::name == aName || nsHTMLAtoms::id == aName)) {
+ nsAutoString tmp;
+ nsresult rv = GetAttribute(kNameSpaceID_None, aName, tmp);
+ if (rv == NS_CONTENT_ATTR_HAS_VALUE)
+ mForm->RemoveElementFromTable(control, tmp);
+
mForm->AddElementToTable(control, aValue);
+ }
return nsGenericHTMLElement::SetAttribute(aNameSpaceID, aName, aValue, aNotify);
}
diff --git a/layout/html/content/src/nsHTMLButtonElement.cpp b/layout/html/content/src/nsHTMLButtonElement.cpp
index 919d07d21d5..59f67d9a4f3 100644
--- a/layout/html/content/src/nsHTMLButtonElement.cpp
+++ b/layout/html/content/src/nsHTMLButtonElement.cpp
@@ -189,10 +189,7 @@ nsHTMLButtonElement::nsHTMLButtonElement(nsINodeInfo *aNodeInfo)
nsHTMLButtonElement::~nsHTMLButtonElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
// nsISupports
@@ -614,15 +611,32 @@ nsHTMLButtonElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/layout/html/content/src/nsHTMLFieldSetElement.cpp b/layout/html/content/src/nsHTMLFieldSetElement.cpp
index 83efb13ac5b..c61980ff788 100644
--- a/layout/html/content/src/nsHTMLFieldSetElement.cpp
+++ b/layout/html/content/src/nsHTMLFieldSetElement.cpp
@@ -110,10 +110,7 @@ nsHTMLFieldSetElement::nsHTMLFieldSetElement(nsINodeInfo *aNodeInfo)
nsHTMLFieldSetElement::~nsHTMLFieldSetElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
// nsISupports
@@ -187,15 +184,32 @@ nsHTMLFieldSetElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/layout/html/content/src/nsHTMLFormElement.cpp b/layout/html/content/src/nsHTMLFormElement.cpp
index 24978ba6aa0..fb8d0f092a3 100644
--- a/layout/html/content/src/nsHTMLFormElement.cpp
+++ b/layout/html/content/src/nsHTMLFormElement.cpp
@@ -117,6 +117,7 @@ public:
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
NS_IMETHOD RemoveElement(nsIFormControl* aElement);
+ NS_IMETHOD RemoveElementFromTable(nsIFormControl* aElement, const nsString& aName);
protected:
nsFormControlList* mControls;
@@ -145,7 +146,7 @@ public:
nsresult GetNamedObject(JSContext* aContext, jsval aID, JSObject** aObj);
nsresult AddElementToTable(nsIFormControl* aChild, const nsString& aName);
- nsresult RemoveElementFromTable(nsIFormControl* aChild);
+ nsresult RemoveElementFromTable(nsIFormControl* aChild, const nsString& aName);
#ifdef DEBUG
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
@@ -470,13 +471,17 @@ nsHTMLFormElement::AddElementToTable(nsIFormControl* aChild, const nsString& aNa
NS_IMETHODIMP
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild)
-{
- PRBool rv = mControls->mElements.RemoveElement(aChild);
- if (rv) {
- mControls->RemoveElementFromTable(aChild);
- // WEAK - don't release
- }
- return rv;
+{
+ mControls->mElements.RemoveElement(aChild);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLFormElement::RemoveElementFromTable(nsIFormControl* aElement,
+ const nsString& aName)
+{
+ return mControls->RemoveElementFromTable(aElement, aName);
}
NS_IMETHODIMP
@@ -607,7 +612,36 @@ nsHTMLFormElement::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
return PR_FALSE;
}
- if (nsnull != obj) {
+ if (!obj && mInner.mDocument) {
+ nsCOMPtr htmlDoc = do_QueryInterface(mInner.mDocument);
+ if (htmlDoc) {
+ nsCOMPtr list;
+ result = htmlDoc->GetElementsByName(name, getter_AddRefs(list));
+ if (NS_FAILED(result)) {
+ return PR_FALSE;
+ }
+ if (list) {
+ PRUint32 count;
+ list->GetLength(&count);
+ if (count > 0) {
+ nsCOMPtr node;
+ result = list->Item(0, getter_AddRefs(node));
+ if (NS_FAILED(result)) {
+ return PR_FALSE;
+ }
+ if (node) {
+ nsCOMPtr owner = do_QueryInterface(node);
+ result = owner->GetScriptObject(scriptContext, (void**)&obj);
+ if (NS_FAILED(result)) {
+ return PR_FALSE;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (obj) {
JSObject* myObj;
result = mInner.GetScriptObject(scriptContext, (void**)&myObj);
ret = ::JS_DefineProperty(aContext, myObj,
@@ -690,14 +724,10 @@ nsFormControlList::SetForm(nsIDOMHTMLFormElement* aForm)
void
nsFormControlList::Clear()
{
- PRUint32 numElements = mElements.Count();
- for (PRUint32 i = 0; i < numElements; i++) {
- nsIFormControl* elem = (nsIFormControl*) mElements.ElementAt(i);
- if (mLookupTable) {
- RemoveElementFromTable(elem);
- }
- // WEAK, don't release
- }
+ mElements.Clear();
+
+ if (mLookupTable)
+ mLookupTable->Reset();
}
NS_IMPL_ISUPPORTS3(nsFormControlList, nsIDOMHTMLCollection, nsIDOMHTMLFormControlList, nsIScriptObjectOwner)
@@ -985,15 +1015,13 @@ nsFormControlList::AddElementToTable(nsIFormControl* aChild, const nsString& aNa
}
nsresult
-nsFormControlList::RemoveElementFromTable(nsIFormControl* aChild)
+nsFormControlList::RemoveElementFromTable(nsIFormControl* aChild,
+ const nsString& aName)
{
nsAutoString name;
nsCOMPtr content = do_QueryInterface(aChild);
- 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);
+ if (mLookupTable && content) {
+ nsStringKey key(aName);
nsCOMPtr supports;
supports = dont_AddRef((nsISupports *)mLookupTable->Get(&key));
diff --git a/layout/html/content/src/nsHTMLInputElement.cpp b/layout/html/content/src/nsHTMLInputElement.cpp
index 908c7b2f0e4..8a0ed07240e 100644
--- a/layout/html/content/src/nsHTMLInputElement.cpp
+++ b/layout/html/content/src/nsHTMLInputElement.cpp
@@ -237,10 +237,7 @@ nsHTMLInputElement::nsHTMLInputElement(nsINodeInfo *aNodeInfo)
nsHTMLInputElement::~nsHTMLInputElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
// nsISupports
@@ -1179,15 +1176,32 @@ nsHTMLInputElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/layout/html/content/src/nsHTMLLabelElement.cpp b/layout/html/content/src/nsHTMLLabelElement.cpp
index 4ab958b810d..798db1953ad 100644
--- a/layout/html/content/src/nsHTMLLabelElement.cpp
+++ b/layout/html/content/src/nsHTMLLabelElement.cpp
@@ -191,10 +191,7 @@ nsHTMLLabelElement::nsHTMLLabelElement(nsINodeInfo *aNodeInfo)
nsHTMLLabelElement::~nsHTMLLabelElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
// nsISupports
@@ -268,15 +265,32 @@ nsHTMLLabelElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/layout/html/content/src/nsHTMLLegendElement.cpp b/layout/html/content/src/nsHTMLLegendElement.cpp
index 269c45c715c..f005725713b 100644
--- a/layout/html/content/src/nsHTMLLegendElement.cpp
+++ b/layout/html/content/src/nsHTMLLegendElement.cpp
@@ -112,10 +112,7 @@ nsHTMLLegendElement::nsHTMLLegendElement(nsINodeInfo *aNodeInfo)
nsHTMLLegendElement::~nsHTMLLegendElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
NS_IMPL_ADDREF(nsHTMLLegendElement)
@@ -187,15 +184,32 @@ nsHTMLLegendElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(NS_GET_IID(nsIFormControl), getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/layout/html/content/src/nsHTMLSelectElement.cpp b/layout/html/content/src/nsHTMLSelectElement.cpp
index 738fa1c7fd5..b5d69e67741 100644
--- a/layout/html/content/src/nsHTMLSelectElement.cpp
+++ b/layout/html/content/src/nsHTMLSelectElement.cpp
@@ -248,10 +248,7 @@ nsHTMLSelectElement::nsHTMLSelectElement(nsINodeInfo *aNodeInfo)
nsHTMLSelectElement::~nsHTMLSelectElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
if (nsnull != mOptions) {
mOptions->Clear();
mOptions->DropReference();
@@ -1151,15 +1148,32 @@ nsHTMLSelectElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {
diff --git a/layout/html/content/src/nsHTMLTextAreaElement.cpp b/layout/html/content/src/nsHTMLTextAreaElement.cpp
index d678072d12e..80c761127e3 100644
--- a/layout/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/layout/html/content/src/nsHTMLTextAreaElement.cpp
@@ -151,10 +151,7 @@ nsHTMLTextAreaElement::nsHTMLTextAreaElement(nsINodeInfo *aNodeInfo)
nsHTMLTextAreaElement::~nsHTMLTextAreaElement()
{
// Null out form's pointer to us - no ref counting here!
- if (mForm) {
- mForm->RemoveElement(this);
- mForm = nsnull;
- }
+ SetForm(nsnull);
}
NS_IMPL_ADDREF(nsHTMLTextAreaElement)
@@ -555,15 +552,32 @@ nsHTMLTextAreaElement::SetForm(nsIDOMHTMLFormElement* aForm)
nsresult result = QueryInterface(kIFormControlIID, getter_AddRefs(formControl));
if (NS_FAILED(result)) formControl = nsnull;
- if (mForm && formControl)
+ nsAutoString nameVal, idVal;
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::name, nameVal);
+ mInner.GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, idVal);
+
+ if (mForm && formControl) {
mForm->RemoveElement(formControl);
+ if (nameVal.Length())
+ mForm->RemoveElementFromTable(this, nameVal);
+
+ if (idVal.Length())
+ mForm->RemoveElementFromTable(this, idVal);
+ }
+
if (aForm) {
nsCOMPtr theForm = do_QueryInterface(aForm, &result);
mForm = theForm; // Even if we fail, update mForm (nsnull in failure)
if ((NS_OK == result) && theForm) {
if (formControl) {
theForm->AddElement(formControl);
+
+ if (nameVal.Length())
+ theForm->AddElementToTable(this, nameVal);
+
+ if (idVal.Length())
+ theForm->AddElementToTable(this, idVal);
}
}
} else {