From 309dbcad16dcdd190d13a97e8010836abb7130eb Mon Sep 17 00:00:00 2001 From: "rods%netscape.com" <rods%netscape.com> Date: Fri, 28 Sep 2001 00:33:23 +0000 Subject: [PATCH] Use the nsIWebProgressListener to make sure two submits do not happen the listener is used to know when the submit got thru so it can unreg itself Bug 85286 r=rpotts sr=kin a=pdt --- content/html/content/src/Makefile.in | 1 + content/html/content/src/makefile.win | 1 + .../html/content/src/nsHTMLFormElement.cpp | 95 ++++++++++++++++++- 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/content/html/content/src/Makefile.in b/content/html/content/src/Makefile.in index b6487a67c000f..96e100f278646 100644 --- a/content/html/content/src/Makefile.in +++ b/content/html/content/src/Makefile.in @@ -32,6 +32,7 @@ REQUIRES = xpcom \ string \ gfx \ layout \ + uriloader \ widget \ dom \ js \ diff --git a/content/html/content/src/makefile.win b/content/html/content/src/makefile.win index 5c89a92c21412..c46592d7d06e6 100644 --- a/content/html/content/src/makefile.win +++ b/content/html/content/src/makefile.win @@ -28,6 +28,7 @@ REQUIRES = xpcom \ widget \ dom \ js \ + uriloader \ locale \ webshell \ htmlparser \ diff --git a/content/html/content/src/nsHTMLFormElement.cpp b/content/html/content/src/nsHTMLFormElement.cpp index 564d0228c4f62..b24b8f3bdaee8 100644 --- a/content/html/content/src/nsHTMLFormElement.cpp +++ b/content/html/content/src/nsHTMLFormElement.cpp @@ -63,6 +63,12 @@ #include "nsContentList.h" #include "nsGUIEvent.h" +// For notification of cancelling or failure of submission +#include "nsIWebProgressListener.h" +#include "nsIWebProgress.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsWeakReference.h" + static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16; class nsFormControlList; @@ -72,7 +78,10 @@ class nsFormControlList; class nsHTMLFormElement : public nsGenericHTMLContainerElement, public nsIDOMHTMLFormElement, public nsIDOMNSHTMLFormElement, - public nsIForm + public nsIForm, + public nsSupportsWeakReference, + public nsIWebProgressListener + { public: nsHTMLFormElement(); @@ -120,15 +129,20 @@ public: NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags, nsEventStatus* aEventStatus); + // nsIWebProgressListener + NS_DECL_NSIWEBPROGRESSLISTENER protected: nsresult DoSubmitOrReset(nsIPresContext* aPresContext, nsEvent* aEvent, PRInt32 aMessage); + nsresult RemoveSelfAsWebProgressListener(); nsFormControlList* mControls; PRPackedBool mGeneratingSubmit; PRPackedBool mGeneratingReset; + + nsCOMPtr<nsIWebProgress> mWebProgress; // Indicates whether there is a current submit happening }; // nsFormControlList @@ -291,6 +305,8 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLFormElement, NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLFormElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFormElement) NS_INTERFACE_MAP_ENTRY(nsIForm) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLFormElement) NS_HTML_CONTENT_INTERFACE_MAP_END @@ -491,6 +507,25 @@ nsHTMLFormElement::DoSubmitOrReset(nsIPresContext* aPresContext, PRInt32 aMessage) { NS_ENSURE_ARG_POINTER(aPresContext); + // If mWebProgress is not null then we are in the middle of a submit + // if it is null, then we need to add the form content as a listener + // to check for double submits (Bug 72906) or whether someone is doing a submit + // from the "onsubmit" handler (Bug 85286). + if (mWebProgress) { + return NS_OK; + } else { + // Get out container and add ourself as a listener for progress + nsCOMPtr<nsISupports> supps; + aPresContext->GetContainer(getter_AddRefs(supps)); + if (supps) { + nsresult rv; + mWebProgress = do_GetInterface(supps, &rv); + if (NS_SUCCEEDED(rv)) { + mWebProgress->AddProgressListener(NS_STATIC_CAST(nsIWebProgressListener *, this)); + } + } + } + // Make sure the presentation is up-to-date nsCOMPtr<nsIDocument> doc; GetDocument(*getter_AddRefs(doc)); @@ -994,3 +1029,61 @@ nsHTMLFormElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const return NS_OK; } + +//--------------------------------------------------------------------- +//-- nsIWebProgressListener +//--------------------------------------------------------------------- + +// Helper Function +nsresult nsHTMLFormElement::RemoveSelfAsWebProgressListener() +{ + // Remove ourselves as a progress listener + if (mWebProgress) { + mWebProgress->RemoveProgressListener(NS_STATIC_CAST(nsIWebProgressListener *, this)); + mWebProgress = do_QueryInterface(nsnull); + } + return NS_OK; +} + +//------------------------ +// Callbacks to interface + +/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */ +NS_IMETHODIMP +nsHTMLFormElement::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aStateFlags, PRUint32 aStatus) +{ + // This will fire when a submit gets cancelled or times out + if ((aStateFlags & nsIWebProgressListener::STATE_IS_DOCUMENT) && + (aStateFlags & nsIWebProgressListener::STATE_STOP)) { + return RemoveSelfAsWebProgressListener(); + } + return NS_OK; +} + +/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ +NS_IMETHODIMP +nsHTMLFormElement::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress) +{ + return RemoveSelfAsWebProgressListener(); +} + +/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */ +NS_IMETHODIMP +nsHTMLFormElement::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location) +{ + return NS_OK; +} + +/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ +NS_IMETHODIMP +nsHTMLFormElement::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage) +{ + return NS_OK; +} + +/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */ +NS_IMETHODIMP +nsHTMLFormElement::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 state) +{ + return NS_OK; +} -- GitLab