When a form control is removed from the document and no longer has a form, also

check whether it's still in the same subtree as its mForm.  If it is, then
don't remove it from the form.  Bug 291042, r=sicking, sr=peterv, a=chofmann
This commit is contained in:
bzbarsky%mit.edu 2005-05-02 04:41:06 +00:00
parent 4a070ac8cf
commit 7ce5669331
2 changed files with 37 additions and 10 deletions

View File

@ -1335,7 +1335,7 @@ nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
}
already_AddRefed<nsIDOMHTMLFormElement>
nsGenericHTMLElement::FindForm()
nsGenericHTMLElement::FindForm(nsIForm* aCurrentForm)
{
nsIContent* content = this;
while (content) {
@ -1348,23 +1348,46 @@ nsGenericHTMLElement::FindForm()
return form;
}
nsIContent *tmp = content;
content = tmp->GetParent();
nsIContent *prevContent = content;
content = prevContent->GetParent();
if (!content && aCurrentForm) {
// We got to the root of the subtree we're in, and we're being removed
// from the DOM (the only time we get into this method with a non-null
// aCurrentForm). Check whether aCurrentForm is in the same subtree. If
// it is, we want to return aCurrentForm, since this case means that
// we're one of those inputs-in-a-table that have a hacked mForm pointer
// and a subtree containing both us and the form got removed from the
// DOM.
nsCOMPtr<nsIContent> formCOMPtr = do_QueryInterface(aCurrentForm);
NS_ASSERTION(formCOMPtr, "aCurrentForm isn't an nsIContent?");
// Use an nsIContent temporary to reduce addref/releasing as we go up the
// tree
nsIContent* iter = formCOMPtr;
do {
iter = iter->GetParent();
if (iter == prevContent) {
nsIDOMHTMLFormElement* form;
CallQueryInterface(aCurrentForm, &form);
return form;
}
} while (iter);
}
if (content) {
PRInt32 i = content->IndexOf(tmp);
PRInt32 i = content->IndexOf(prevContent);
if (i < 0) {
// This means 'tmp' is anonymous content, form controls in
// This means 'prevContent' is anonymous content, form controls in
// anonymous content can't refer to the real form, if they do
// they end up in form.elements n' such, and that's wrong...
return NS_OK;
return nsnull;
}
}
}
return NS_OK;
return nsnull;
}
static PRBool
@ -3260,7 +3283,7 @@ nsGenericHTMLFormElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
SetForm(nsnull);
} else {
// Recheck whether we should still have an mForm.
nsCOMPtr<nsIDOMHTMLFormElement> form = FindForm();
nsCOMPtr<nsIDOMHTMLFormElement> form = FindForm(mForm);
if (!form) {
SetForm(nsnull);
}

View File

@ -580,9 +580,13 @@ public:
// Form Helper Routines
/**
* Find an ancestor of this content node which is a form (could be null)
* @param aForm the form ancestore [OUT]
* @param aCurrentForm the current form for this node. If this is
* non-null, and no ancestor form is found, and the current form is in
* a connected subtree with the node, the current form will be
* returned. This is needed to handle cases when HTML elements have a
* current form that they're not descendants of.
*/
already_AddRefed<nsIDOMHTMLFormElement> FindForm();
already_AddRefed<nsIDOMHTMLFormElement> FindForm(nsIForm* aCurrentForm = nsnull);
/**
* See if the document being tested has nav-quirks mode enabled.