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) {