diff --git a/content/html/content/src/nsHTMLFormElement.cpp b/content/html/content/src/nsHTMLFormElement.cpp
index c5a7c173fd8..c5fd612a181 100644
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -285,7 +285,7 @@ protected:
nsIContent* aSubmitElement);
/**
- * Notify any submit observsers of the submit.
+ * Notify any submit observers of the submit.
*
* @param aActionURL the URL being submitted to
* @param aCancelSubmit out param where submit observers can specify that the
@@ -319,6 +319,10 @@ protected:
PRPackedBool mIsSubmitting;
/** Whether the submission is to be deferred in case a script triggers it */
PRPackedBool mDeferSubmission;
+ /** Whether we notified NS_FORMSUBMIT_SUBJECT listeners already */
+ PRPackedBool mNotifiedObservers;
+ /** If we notified the listeners early, what was the result? */
+ PRPackedBool mNotifiedObserversResult;
/** Keep track of what the popup state was when the submit was initiated */
PopupControlState mSubmitPopupState;
/** Keep track of whether a submission was user-initiated or not */
@@ -484,6 +488,8 @@ nsHTMLFormElement::nsHTMLFormElement(nsINodeInfo *aNodeInfo)
mGeneratingReset(PR_FALSE),
mIsSubmitting(PR_FALSE),
mDeferSubmission(PR_FALSE),
+ mNotifiedObservers(PR_FALSE),
+ mNotifiedObserversResult(PR_FALSE),
mSubmitPopupState(openAbused),
mSubmitInitiatedFromUserInput(PR_FALSE),
mPendingSubmission(nsnull),
@@ -950,11 +956,15 @@ nsHTMLFormElement::SubmitSubmission(nsIFormSubmission* aFormSubmission)
//
// Notify observers of submit
//
- PRBool aCancelSubmit = PR_FALSE;
- rv = NotifySubmitObservers(actionURI, &aCancelSubmit);
- NS_ENSURE_SUBMIT_SUCCESS(rv);
+ PRBool cancelSubmit = PR_FALSE;
+ if (mNotifiedObservers) {
+ cancelSubmit = mNotifiedObserversResult;
+ } else {
+ rv = NotifySubmitObservers(actionURI, &cancelSubmit);
+ NS_ENSURE_SUBMIT_SUCCESS(rv);
+ }
- if (aCancelSubmit) {
+ if (cancelSubmit) {
mIsSubmitting = PR_FALSE;
return NS_OK;
}
@@ -1298,6 +1308,27 @@ NS_IMETHODIMP
nsHTMLFormElement::OnSubmitClickBegin()
{
mDeferSubmission = PR_TRUE;
+
+ // Prepare to run NotifySubmitObservers early before the
+ // scripts on the page get to modify the form data, possibly
+ // throwing off any password manager. (bug 257781)
+ nsCOMPtr actionURI;
+ nsresult rv;
+
+ rv = GetActionURL(getter_AddRefs(actionURI));
+ if (NS_FAILED(rv) || !actionURI)
+ return NS_OK;
+
+ //
+ // Notify observers of submit
+ //
+ PRBool cancelSubmit = PR_FALSE;
+ rv = NotifySubmitObservers(actionURI, &cancelSubmit);
+ if (NS_SUCCEEDED(rv)) {
+ mNotifiedObservers = PR_TRUE;
+ mNotifiedObserversResult = cancelSubmit;
+ }
+
return NS_OK;
}
@@ -1437,6 +1468,7 @@ nsHTMLFormElement::GetLength(PRInt32* aLength)
void
nsHTMLFormElement::ForgetCurrentSubmission()
{
+ mNotifiedObservers = PR_FALSE;
mIsSubmitting = PR_FALSE;
mSubmittingRequest = nsnull;
if (mWebProgress) {