diff --git a/content/html/content/public/nsIFormSubmitObserver.h b/content/html/content/public/nsIFormSubmitObserver.h
index 8c510f88411..997a7a73d0a 100644
--- a/content/html/content/public/nsIFormSubmitObserver.h
+++ b/content/html/content/public/nsIFormSubmitObserver.h
@@ -30,8 +30,10 @@
#ifndef nsIFormSubmitObserver_h__
#define nsIFormSubmitObserver_h__
-#include "nsISupports.h"
+#include "nsIObserver.h"
#include "prtypes.h"
+#include "nsIDOMWindow.h"
+#include "nsIURI.h"
class nsString;
@@ -41,15 +43,19 @@ class nsString;
#define NS_FORMSUBMIT_SUBJECT "formsubmit"
-class nsIFormSubmitObserver : public nsISupports {
+class nsIFormSubmitObserver : public nsIObserver {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFORMSUBMITOBSERVER_IID)
/*
* Subject calls the observer when the form is submitted
* @param formNode- the dom node corresonding to this form.
+ * @param window- the window that the form submit occured in.
+ * NOTE: This is not necessarily the same window the form submit result
+ * will be loaded in (form could have target attribute set)
+ * @param actionURL- URL to which the form will be submitted.
*/
- NS_IMETHOD Notify(nsIContent* formNode) = 0;
+ NS_IMETHOD Notify(nsIContent* formNode, nsIDOMWindow* window, nsIURI* actionURL) = 0;
};
diff --git a/extensions/wallet/src/nsWalletService.cpp b/extensions/wallet/src/nsWalletService.cpp
index 8d52544defc..b3e51584323 100644
--- a/extensions/wallet/src/nsWalletService.cpp
+++ b/extensions/wallet/src/nsWalletService.cpp
@@ -39,6 +39,7 @@
#include "nsIDOMHTMLInputElement.h"
#include "nsIFormControl.h"
#include "nsIDocShell.h"
+#include "nsIDOMWindow.h"
static NS_DEFINE_IID(kDocLoaderServiceCID, NS_DOCUMENTLOADER_SERVICE_CID);
@@ -62,9 +63,8 @@ nsWalletlibService::~nsWalletlibService()
NS_IF_RELEASE(gKeyedStreamGenerator);
}
-NS_IMPL_THREADSAFE_ISUPPORTS6(nsWalletlibService,
+NS_IMPL_THREADSAFE_ISUPPORTS5(nsWalletlibService,
nsIWalletService,
- nsIObserver,
nsIFormSubmitObserver,
nsIDocumentLoaderObserver,
nsIPasswordSink,
@@ -176,7 +176,7 @@ NS_IMETHODIMP nsWalletlibService::Observe(nsISupports*, const PRUnichar*, const
}
#define CRLF "\015\012"
-NS_IMETHODIMP nsWalletlibService::Notify(nsIContent* formNode)
+NS_IMETHODIMP nsWalletlibService::Notify(nsIContent* formNode, nsIDOMWindow* window, nsIURI* actionURL)
{
if (!formNode) {
return NS_ERROR_FAILURE;
diff --git a/extensions/wallet/src/nsWalletService.h b/extensions/wallet/src/nsWalletService.h
index 870e89338fa..3c2fed99f97 100644
--- a/extensions/wallet/src/nsWalletService.h
+++ b/extensions/wallet/src/nsWalletService.h
@@ -29,9 +29,10 @@
#include "nsIDocumentLoaderObserver.h"
#include "nsWeakReference.h"
#include "nsIPasswordSink.h"
+#include "nsIDOMWindow.h"
+#include "nsIURI.h"
class nsWalletlibService : public nsIWalletService,
- public nsIObserver,
public nsIFormSubmitObserver,
public nsIDocumentLoaderObserver,
public nsIPasswordSink,
@@ -75,7 +76,7 @@ public:
// nsIObserver
NS_DECL_NSIOBSERVER
- NS_IMETHOD Notify(nsIContent* formNode);
+ NS_IMETHOD Notify(nsIContent* formNode, nsIDOMWindow* window, nsIURI* actionURL);
// nsIDocumentLoaderObserver
NS_DECL_NSIDOCUMENTLOADEROBSERVER
diff --git a/layout/html/forms/public/nsIFormSubmitObserver.h b/layout/html/forms/public/nsIFormSubmitObserver.h
index 8c510f88411..997a7a73d0a 100644
--- a/layout/html/forms/public/nsIFormSubmitObserver.h
+++ b/layout/html/forms/public/nsIFormSubmitObserver.h
@@ -30,8 +30,10 @@
#ifndef nsIFormSubmitObserver_h__
#define nsIFormSubmitObserver_h__
-#include "nsISupports.h"
+#include "nsIObserver.h"
#include "prtypes.h"
+#include "nsIDOMWindow.h"
+#include "nsIURI.h"
class nsString;
@@ -41,15 +43,19 @@ class nsString;
#define NS_FORMSUBMIT_SUBJECT "formsubmit"
-class nsIFormSubmitObserver : public nsISupports {
+class nsIFormSubmitObserver : public nsIObserver {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFORMSUBMITOBSERVER_IID)
/*
* Subject calls the observer when the form is submitted
* @param formNode- the dom node corresonding to this form.
+ * @param window- the window that the form submit occured in.
+ * NOTE: This is not necessarily the same window the form submit result
+ * will be loaded in (form could have target attribute set)
+ * @param actionURL- URL to which the form will be submitted.
*/
- NS_IMETHOD Notify(nsIContent* formNode) = 0;
+ NS_IMETHOD Notify(nsIContent* formNode, nsIDOMWindow* window, nsIURI* actionURL) = 0;
};
diff --git a/layout/html/forms/src/nsFormFrame.cpp b/layout/html/forms/src/nsFormFrame.cpp
index 6860d93cf7f..82e2e249e39 100644
--- a/layout/html/forms/src/nsFormFrame.cpp
+++ b/layout/html/forms/src/nsFormFrame.cpp
@@ -109,6 +109,8 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
// Security
#include "nsIScriptSecurityManager.h"
+#include "nsIDOMWindow.h"
+
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
static NS_DEFINE_CID(kPlatformCharsetCID, NS_PLATFORMCHARSET_CID);
static NS_DEFINE_CID(kMIMEServiceCID, NS_MIMESERVICE_CID);
@@ -691,29 +693,6 @@ nsFormFrame::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame)
aFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
}
- // Notify observers that the form is being submitted.
- result = NS_OK;
- NS_WITH_SERVICE(nsIObserverService, service, NS_OBSERVERSERVICE_PROGID, &result);
- if (NS_FAILED(result)) return result;
-
- nsString theTopic; theTopic.AssignWithConversion(NS_FORMSUBMIT_SUBJECT);
- nsIEnumerator* theEnum;
- result = service->EnumerateObserverList(theTopic.GetUnicode(), &theEnum);
- if (NS_SUCCEEDED(result) && theEnum){
- nsCOMPtr inst;
-
- for (theEnum->First(); theEnum->IsDone() != NS_OK; theEnum->Next()) {
- result = theEnum->CurrentItem(getter_AddRefs(inst));
- if (NS_SUCCEEDED(result) && inst) {
- nsCOMPtr formSubmitObserver = do_QueryInterface(inst, &result);
- if (NS_SUCCEEDED(result) && formSubmitObserver) {
- formSubmitObserver->Notify(mContent);
- }
- }
- }
- NS_RELEASE(theEnum);
- }
-
nsIFileSpec* multipartDataFile = nsnull;
if (isURLEncoded) {
result = ProcessAsURLEncoded(formProcessor, isPost, data, fcFrame);
@@ -734,13 +713,16 @@ nsFormFrame::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame)
nsAutoString href;
GetAction(&href);
+ // Get the document.
+ // We'll need it now to form the URL we're submitting to.
+ // We'll also need it later to get the DOM window when notifying form submit observers (bug 33203)
+ nsCOMPtr document;
+ mContent->GetDocument(*getter_AddRefs(document));
+ if (!document) return NS_OK; // No doc means don't submit, see Bug 28988
+
// Resolve url to an absolute url
nsCOMPtr docURL;
- nsCOMPtr doc;
- mContent->GetDocument(*getter_AddRefs(doc));
- if (!doc) return NS_OK; // No doc means don't submit, see Bug 28988
-
- doc->GetBaseURL(*getter_AddRefs(docURL));
+ document->GetBaseURL(*getter_AddRefs(docURL));
NS_ASSERTION(docURL, "No Base URL found in Form Submit!\n");
// If an action is not specified and we are inside
@@ -752,7 +734,7 @@ nsFormFrame::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame)
if (href.IsEmpty()) {
nsCOMPtr htmlDoc;
- if (PR_FALSE == NS_SUCCEEDED(doc->QueryInterface(kIHTMLDocumentIID,
+ if (PR_FALSE == NS_SUCCEEDED(document->QueryInterface(kIHTMLDocumentIID,
getter_AddRefs(htmlDoc)))) {
// Must be a XML, XUL or other non-HTML document type
// so do nothing.
@@ -761,12 +743,11 @@ nsFormFrame::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame)
// Necko's MakeAbsoluteURI doesn't reuse the baseURL's rel path if it is
// passed a zero length rel path.
- char* relPath = nsnull;
- docURL->GetSpec(&relPath);
+ nsXPIDLCString relPath;
+ docURL->GetSpec(getter_Copies(relPath));
NS_ASSERTION(relPath, "Rel path couldn't be formed in form submit!\n");
if (relPath) {
href.AppendWithConversion(relPath);
- nsCRT::free(relPath);
// If re-using the same URL, chop off old query string (bug 25330)
PRInt32 queryStart = href.FindChar('?');
@@ -834,6 +815,40 @@ nsFormFrame::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame)
result = NS_MakeAbsoluteURI(absURLSpec, href, docURL);
if (NS_FAILED(result)) return result;
+ // Notify observers that the form is being submitted.
+ result = NS_OK;
+ NS_WITH_SERVICE(nsIObserverService, service, NS_OBSERVERSERVICE_PROGID, &result);
+ if (NS_FAILED(result)) return result;
+
+ nsString theTopic; theTopic.AssignWithConversion(NS_FORMSUBMIT_SUBJECT);
+ nsIEnumerator* theEnum;
+ result = service->EnumerateObserverList(theTopic.GetUnicode(), &theEnum);
+ if (NS_SUCCEEDED(result) && theEnum){
+ nsCOMPtr inst;
+ nsresult submitStatus = NS_OK;
+
+ nsCOMPtr globalObject;
+ document->GetScriptGlobalObject(getter_AddRefs(globalObject));
+ nsCOMPtr window = do_QueryInterface(globalObject);
+
+ for (theEnum->First(); theEnum->IsDone() != NS_OK; theEnum->Next()) {
+ result = theEnum->CurrentItem(getter_AddRefs(inst));
+ if (NS_SUCCEEDED(result) && inst) {
+ nsCOMPtr formSubmitObserver = do_QueryInterface(inst, &result);
+ if (NS_SUCCEEDED(result) && formSubmitObserver) {
+ nsresult notifyStatus = formSubmitObserver->Notify(mContent, window, actionURL);
+ if (NS_FAILED(notifyStatus)) {
+ submitStatus = notifyStatus;
+ }
+ }
+ }
+ }
+ NS_RELEASE(theEnum);
+ if (NS_FAILED(submitStatus)) {
+ return submitStatus;
+ }
+ }
+
// Now pass on absolute url to the click handler
nsIInputStream* postDataStream = nsnull;
if (isPost) {