diff --git a/content/html/content/public/nsIFormSubmission.h b/content/html/content/public/nsIFormSubmission.h index 56a5edd14554..000bb4ee39cc 100644 --- a/content/html/content/public/nsIFormSubmission.h +++ b/content/html/content/public/nsIFormSubmission.h @@ -48,8 +48,10 @@ class nsIPresContext; class nsIContent; class nsIFormControl; class nsIDOMHTMLElement; +class nsIDocShell; +class nsIRequest; -#define NS_IFORMSUBMITTER_IID \ +#define NS_IFORMSUBMISSION_IID \ { 0x7ee38e3a, 0x1dd2, 0x11b2, \ {0x89, 0x6f, 0xab, 0x28, 0x03, 0x96, 0x25, 0xa9} } @@ -61,7 +63,7 @@ class nsIFormSubmission : public nsISupports { public: - NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFORMSUBMITTER_IID) + NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFORMSUBMISSION_IID) /** * Find out whether or not this form submission accepts files @@ -77,9 +79,13 @@ public: * @param aTarget the target window * @param aSource the element responsible for the submission (for web shell) * @param aPresContext the presentation context + * @param aDocShell (out param) the DocShell in which the submission was + * loaded + * @param aRequest (out param) the Request for the submission */ NS_IMETHOD SubmitTo(nsIURI* aActionURL, const nsAString& aTarget, - nsIContent* aSource, nsIPresContext* aPresContext) = 0; + nsIContent* aSource, nsIPresContext* aPresContext, + nsIDocShell** aDocShell, nsIRequest** aRequest) = 0; /** * Submit a name/value pair diff --git a/content/html/content/src/Makefile.in b/content/html/content/src/Makefile.in index 5f8e5dee5642..174cfb57cbe9 100644 --- a/content/html/content/src/Makefile.in +++ b/content/html/content/src/Makefile.in @@ -38,6 +38,7 @@ REQUIRES = xpcom \ locale \ unicharutil \ webshell \ + uriloader \ htmlparser \ necko \ view \ diff --git a/content/html/content/src/makefile.win b/content/html/content/src/makefile.win index 548e4ab316fd..48fe22672395 100644 --- a/content/html/content/src/makefile.win +++ b/content/html/content/src/makefile.win @@ -32,6 +32,7 @@ REQUIRES = xpcom \ webshell \ htmlparser \ necko \ + uriloader \ view \ pref \ docshell \ diff --git a/content/html/content/src/nsFormSubmission.cpp b/content/html/content/src/nsFormSubmission.cpp index 7d30356bb8c2..676b3c81528f 100644 --- a/content/html/content/src/nsFormSubmission.cpp +++ b/content/html/content/src/nsFormSubmission.cpp @@ -98,7 +98,8 @@ public: // nsIFormSubmission // NS_IMETHOD SubmitTo(nsIURI* aActionURL, const nsAString& aTarget, - nsIContent* aSource, nsIPresContext* aPresContext); + nsIContent* aSource, nsIPresContext* aPresContext, + nsIDocShell** aDocShell, nsIRequest** aRequest); NS_IMETHOD Init() = 0; @@ -719,7 +720,8 @@ GetSubmissionFromForm(nsIForm* aForm, NS_IMETHODIMP nsFormSubmission::SubmitTo(nsIURI* aActionURL, const nsAString& aTarget, - nsIContent* aSource, nsIPresContext* aPresContext) + nsIContent* aSource, nsIPresContext* aPresContext, + nsIDocShell** aDocShell, nsIRequest** aRequest) { nsresult rv; @@ -739,9 +741,11 @@ nsFormSubmission::SubmitTo(nsIURI* aActionURL, const nsAString& aTarget, nsCAutoString actionURLSpec; aActionURL->GetSpec(actionURLSpec); - handler->OnLinkClick(aSource, eLinkVerb_Replace, - NS_ConvertUTF8toUCS2(actionURLSpec).get(), - PromiseFlatString(aTarget).get(), postDataStream); + handler->OnLinkClickSync(aSource, eLinkVerb_Replace, + NS_ConvertUTF8toUCS2(actionURLSpec).get(), + PromiseFlatString(aTarget).get(), + postDataStream, nsnull, + aDocShell, aRequest); } return rv; diff --git a/content/html/content/src/nsHTMLFormElement.cpp b/content/html/content/src/nsHTMLFormElement.cpp index 06c693f6e05e..992858f2c10e 100644 --- a/content/html/content/src/nsHTMLFormElement.cpp +++ b/content/html/content/src/nsHTMLFormElement.cpp @@ -75,6 +75,10 @@ #include "nsRange.h" #include "nsIScriptSecurityManager.h" #include "nsNetUtil.h" +#include "nsIWebProgress.h" +#include "nsIDocShell.h" +#include "nsIWebProgressListener.h" +#include "nsWeakReference.h" // radio buttons #include "nsIDOMHTMLInputElement.h" @@ -88,15 +92,20 @@ class nsFormControlList; // nsHTMLFormElement class nsHTMLFormElement : public nsGenericHTMLContainerElement, + public nsSupportsWeakReference, public nsIDOMHTMLFormElement, public nsIDOMNSHTMLFormElement, + public nsIWebProgressListener, public nsIForm { public: nsHTMLFormElement() : mGeneratingSubmit(PR_FALSE), mGeneratingReset(PR_FALSE), - mDemotingForm(PR_FALSE) { }; + mDemotingForm(PR_FALSE), + mIsSubmitting(PR_FALSE), + mSubmittingRequest(nsnull) { } + virtual ~nsHTMLFormElement(); @@ -120,6 +129,9 @@ public: // nsIDOMNSHTMLFormElement NS_DECL_NSIDOMNSHTMLFORMELEMENT + // nsIWebProgressListener + NS_DECL_NSIWEBPROGRESSLISTENER + // nsIForm NS_IMETHOD AddElement(nsIFormControl* aElement); NS_IMETHOD AddElementToTable(nsIFormControl* aChild, @@ -217,6 +229,8 @@ protected: PRPackedBool mGeneratingSubmit; PRPackedBool mGeneratingReset; PRPackedBool mDemotingForm; + PRPackedBool mIsSubmitting; + nsCOMPtr mSubmittingRequest; protected: // Detection of first form to notify observers @@ -393,9 +407,11 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLFormElement, nsGenericElement) // QueryInterface implementation for nsHTMLFormElement NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLFormElement, nsGenericHTMLContainerElement) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLFormElement) NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFormElement) NS_INTERFACE_MAP_ENTRY(nsIForm) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLFormElement) NS_HTML_CONTENT_INTERFACE_MAP_END @@ -652,9 +668,26 @@ nsHTMLFormElement::DoReset() return NS_OK; } +#define NS_ENSURE_SUBMIT_SUCCESS(rv) \ + if (NS_FAILED(rv)) { \ + mIsSubmitting = PR_FALSE; \ + return rv; \ + } + nsresult nsHTMLFormElement::DoSubmit(nsIPresContext* aPresContext, nsEvent* aEvent) { + NS_ASSERTION(!mIsSubmitting, "Either two people are trying to submit or the " + "previous submit was not properly cancelled by the DocShell"); + if (mIsSubmitting) { + // XXX Should this return an error? + return NS_OK; + } + + // Mark us as submitting so that we don't try to submit again + mIsSubmitting = PR_TRUE; + mSubmittingRequest = nsnull; + nsIContent *originatingElement = nsnull; // Get the originating frame (failure is non-fatal) @@ -670,42 +703,54 @@ nsHTMLFormElement::DoSubmit(nsIPresContext* aPresContext, nsEvent* aEvent) nsCOMPtr submission; nsresult rv = GetSubmissionFromForm(this, aPresContext, getter_AddRefs(submission)); - NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_SUBMIT_SUCCESS(rv); // // Dump the data into the submission object // rv = WalkFormElements(submission, originatingElement); - NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_SUBMIT_SUCCESS(rv); // // Get the action and target // nsCOMPtr actionURI; rv = GetActionURL(getter_AddRefs(actionURI)); - NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_SUBMIT_SUCCESS(rv); - if (actionURI) { - nsAutoString target; - rv = GetTarget(target); - NS_ENSURE_SUCCESS(rv, rv); - - // - // Notify observers of submit - // - PRBool aCancelSubmit = PR_FALSE; - rv = NotifySubmitObservers(actionURI, &aCancelSubmit); - NS_ENSURE_SUCCESS(rv, rv); - - if (!aCancelSubmit) { - // - // Submit - // - rv = submission->SubmitTo(actionURI, target, this, aPresContext); - } + if (!actionURI) { + mIsSubmitting = PR_FALSE; + return NS_OK; } - return rv; + nsAutoString target; + rv = GetTarget(target); + NS_ENSURE_SUBMIT_SUCCESS(rv); + + // + // Notify observers of submit + // + PRBool aCancelSubmit = PR_FALSE; + rv = NotifySubmitObservers(actionURI, &aCancelSubmit); + NS_ENSURE_SUBMIT_SUCCESS(rv); + + if (aCancelSubmit) { + mIsSubmitting = PR_FALSE; + return NS_OK; + } + + // + // Submit + // + nsCOMPtr docShell; + rv = submission->SubmitTo(actionURI, target, this, aPresContext, + getter_AddRefs(docShell), + getter_AddRefs(mSubmittingRequest)); + NS_ENSURE_SUBMIT_SUCCESS(rv); + + nsCOMPtr webProgress = do_GetInterface(docShell); + NS_ASSERTION(webProgress, "nsIDocShell null or not converted to nsIWebProgress!"); + return webProgress->AddProgressListener(this); } @@ -1104,6 +1149,69 @@ nsHTMLFormElement::GetLength(PRInt32* aLength) return NS_OK; } +// nsIWebProgressListener +NS_IMETHODIMP +nsHTMLFormElement::OnStateChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + PRInt32 aStateFlags, + PRUint32 aStatus) +{ + // If STATE_STOP is never fired for any reason (redirect? Failed state + // change?) the form element will leak. It will be kept around by the + // nsIWebProgressListener (assuming it keeps a strong pointer). We will + // consequently leak the request. + if (aRequest == mSubmittingRequest && + aStateFlags & nsIWebProgressListener::STATE_STOP) { + mIsSubmitting = PR_FALSE; + mSubmittingRequest = nsnull; + aWebProgress->RemoveProgressListener(this); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLFormElement::OnProgressChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + PRInt32 aCurSelfProgress, + PRInt32 aMaxSelfProgress, + PRInt32 aCurTotalProgress, + PRInt32 aMaxTotalProgress) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLFormElement::OnLocationChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsIURI* location) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLFormElement::OnStatusChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + nsresult aStatus, + const PRUnichar* aMessage) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLFormElement::OnSecurityChange(nsIWebProgress* aWebProgress, + nsIRequest* aRequest, + PRInt32 state) +{ + return NS_OK; +} + + + + + + + NS_IMETHODIMP nsHTMLFormElement::IndexOfControl(nsIFormControl* aControl, PRInt32* aIndex) { diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index ee24d545ff96..aa70b81a8266 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -648,7 +648,9 @@ nsDocShell::LoadURI(nsIURI * aURI, nsnull, // No headers stream loadType, nsnull, // No SHEntry - firstParty); + firstParty, + nsnull, // No nsIDocShell + nsnull); // No nsIRequest } return rv; @@ -2417,8 +2419,10 @@ nsDocShell::Reload(PRUint32 aReloadFlags) nsnull, // No post data nsnull, // No headers data type, // Load type - nsnull, // No SHEntry - PR_TRUE); + nsnull, // No SHEntry + PR_TRUE, + nsnull, // No nsIDocShell + nsnull); // No nsIRequest return rv; } @@ -4285,9 +4289,19 @@ nsDocShell::InternalLoad(nsIURI * aURI, nsIInputStream * aHeadersData, PRUint32 aLoadType, nsISHEntry * aSHEntry, - PRBool firstParty) + PRBool firstParty, + nsIDocShell** aDocShell, + nsIRequest** aRequest) { - nsresult rv; + nsresult rv = NS_OK; + + // Initialize aDocShell/aRequest + if (aDocShell) { + *aDocShell = nsnull; + } + if (aRequest) { + *aRequest = nsnull; + } nsCOMPtr owner(aOwner); // @@ -4334,8 +4348,9 @@ nsDocShell::InternalLoad(nsIURI * aURI, extProtService->ExternalProtocolHandlerExists(urlScheme.get(), &haveHandler); - if (haveHandler) + if (haveHandler) { return extProtService->LoadUrl(aURI); + } } } } @@ -4397,7 +4412,9 @@ nsDocShell::InternalLoad(nsIURI * aURI, aHeadersData, aLoadType, aSHEntry, - firstParty); + firstParty, + aDocShell, + aRequest); if (rv == NS_ERROR_NO_CONTENT) { if (bIsNewWindow) { // @@ -4512,7 +4529,8 @@ nsDocShell::InternalLoad(nsIURI * aURI, // been called. mLSHE = aSHEntry; - rv = DoURILoad(aURI, aReferrer, owner, aPostData, aHeadersData, firstParty); + rv = DoURILoad(aURI, aReferrer, owner, aPostData, aHeadersData, firstParty, + aDocShell, aRequest); return rv; } @@ -4583,12 +4601,15 @@ nsDocShell::GetCurrentDocumentOwner(nsISupports ** aOwner) return rv; } -nsresult nsDocShell::DoURILoad(nsIURI * aURI, - nsIURI * aReferrerURI, - nsISupports * aOwner, - nsIInputStream * aPostData, - nsIInputStream * aHeadersData, - PRBool firstParty) +nsresult +nsDocShell::DoURILoad(nsIURI * aURI, + nsIURI * aReferrerURI, + nsISupports * aOwner, + nsIInputStream * aPostData, + nsIInputStream * aHeadersData, + PRBool firstParty, + nsIDocShell ** aDocShell, + nsIRequest ** aRequest) { nsresult rv; nsCOMPtr uriLoader; @@ -4716,6 +4737,20 @@ nsresult nsDocShell::DoURILoad(nsIURI * aURI, } rv = DoChannelLoad(channel, uriLoader); + + // + // If the channel load failed, we failed and nsIWebProgress just ain't + // gonna happen. + // + if (NS_SUCCEEDED(rv)) { + if (aDocShell) { + *aDocShell = this; + NS_ADDREF(*aDocShell); + } + if (aRequest) { + CallQueryInterface(channel, aRequest); + } + } return rv; } @@ -5497,7 +5532,9 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, PRUint32 aLoadType) nsnull, // No headers stream aLoadType, // Load type aEntry, // SHEntry - PR_TRUE); + PR_TRUE, + nsnull, // No nsIDocShell + nsnull); // No nsIRequest return rv; } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 2c21a9216ff0..8157e0eb7fb9 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -209,7 +209,9 @@ protected: nsISupports * aOwner, nsIInputStream * aPostData, nsIInputStream * aHeadersData, - PRBool firstParty); + PRBool firstParty, + nsIDocShell ** aDocShell, + nsIRequest ** aRequest); NS_IMETHOD AddHeadersToChannel(nsIInputStream * aHeadersData, nsIChannel * aChannel); virtual nsresult DoChannelLoad(nsIChannel * aChannel, diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index a762b8e8df1f..7ff241ec8f9d 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -44,6 +44,7 @@ interface nsIDocumentCharsetInfo; interface nsIWebNavigation; interface nsISimpleEnumerator; interface nsIInputStream; +interface nsIRequest; interface nsISHEntry; [scriptable, uuid(69E5DE00-7B8B-11d3-AF61-00A024FFC08C)] @@ -123,7 +124,9 @@ interface nsIDocShell : nsISupports in nsIInputStream aHeadersStream, in unsigned long aLoadFlags, in nsISHEntry aSHEntry, - in boolean firstParty); + in boolean firstParty, + out nsIDocShell aDocShell, + out nsIRequest aRequest); /** * Creates a DocShellLoadInfo object that you can manipulate and then pass diff --git a/docshell/base/nsWebShell.cpp b/docshell/base/nsWebShell.cpp index 43a5d1f28555..56fa735f76ee 100644 --- a/docshell/base/nsWebShell.cpp +++ b/docshell/base/nsWebShell.cpp @@ -455,17 +455,18 @@ struct OnLinkClickEvent : public PLEvent { ~OnLinkClickEvent(); void HandleEvent() { - mHandler->HandleLinkClickEvent(mContent, mVerb, mURLSpec->get(), - mTargetSpec->get(), mPostDataStream, - mHeadersDataStream); + mHandler->OnLinkClickSync(mContent, mVerb, mURLSpec.get(), + mTargetSpec.get(), mPostDataStream, + mHeadersDataStream, + nsnull, nsnull); } - nsWebShell* mHandler; - nsString* mURLSpec; - nsString* mTargetSpec; - nsIInputStream* mPostDataStream; - nsIInputStream* mHeadersDataStream; - nsIContent* mContent; + nsWebShell* mHandler; + nsString mURLSpec; + nsString mTargetSpec; + nsCOMPtr mPostDataStream; + nsCOMPtr mHeadersDataStream; + nsCOMPtr mContent; nsLinkVerb mVerb; }; @@ -489,14 +490,11 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler, { mHandler = aHandler; NS_ADDREF(aHandler); - mURLSpec = new nsString(aURLSpec); - mTargetSpec = new nsString(aTargetSpec); + mURLSpec.Assign(aURLSpec); + mTargetSpec.Assign(aTargetSpec); mPostDataStream = aPostDataStream; - NS_IF_ADDREF(mPostDataStream); mHeadersDataStream = aHeadersDataStream; - NS_IF_ADDREF(mHeadersDataStream); mContent = aContent; - NS_IF_ADDREF(mContent); mVerb = aVerb; PL_InitEvent(this, nsnull, @@ -512,13 +510,7 @@ OnLinkClickEvent::OnLinkClickEvent(nsWebShell* aHandler, OnLinkClickEvent::~OnLinkClickEvent() { - NS_IF_RELEASE(mContent); NS_IF_RELEASE(mHandler); - NS_IF_RELEASE(mPostDataStream); - NS_IF_RELEASE(mHeadersDataStream); - if (nsnull != mURLSpec) delete mURLSpec; - if (nsnull != mTargetSpec) delete mTargetSpec; - } //---------------------------------------- @@ -554,17 +546,27 @@ nsWebShell::GetEventQueue(nsIEventQueue **aQueue) return *aQueue ? NS_OK : NS_ERROR_FAILURE; } -void -nsWebShell::HandleLinkClickEvent(nsIContent *aContent, - nsLinkVerb aVerb, - const PRUnichar* aURLSpec, - const PRUnichar* aTargetSpec, - nsIInputStream* aPostDataStream, - nsIInputStream* aHeadersDataStream) +NS_IMETHODIMP +nsWebShell::OnLinkClickSync(nsIContent *aContent, + nsLinkVerb aVerb, + const PRUnichar* aURLSpec, + const PRUnichar* aTargetSpec, + nsIInputStream* aPostDataStream, + nsIInputStream* aHeadersDataStream, + nsIDocShell** aDocShell, + nsIRequest** aRequest) { nsresult rv; nsAutoString target(aTargetSpec); + // Initialize the DocShell / Request + if (aDocShell) { + *aDocShell = nsnull; + } + if (aRequest) { + *aRequest = nsnull; + } + switch(aVerb) { case eLinkVerb_New: target.Assign(NS_LITERAL_STRING("_blank")); @@ -599,19 +601,21 @@ nsWebShell::HandleLinkClickEvent(nsIContent *aContent, listener->OnStartURIOpen(uri, &abort); } } - return; + return rv; } - rv = InternalLoad(uri, // New URI - mCurrentURI, // Referer URI - nsnull, // No onwer - PR_TRUE, // Inherit owner from document - target.get(), // Window target - aPostDataStream, // Post data stream - aHeadersDataStream, // Headers stream - LOAD_LINK, // Load type - nsnull, // No SHEntry - PR_TRUE); // first party site + return InternalLoad(uri, // New URI + mCurrentURI, // Referer URI + nsnull, // No onwer + PR_TRUE, // Inherit owner from document + target.get(), // Window target + aPostDataStream, // Post data stream + aHeadersDataStream, // Headers stream + LOAD_LINK, // Load type + nsnull, // No SHEntry + PR_TRUE, // first party site + aDocShell, // DocShell out-param + aRequest); // Request out-param } break; case eLinkVerb_Embed: @@ -619,6 +623,7 @@ nsWebShell::HandleLinkClickEvent(nsIContent *aContent, // in NS 4.x default: NS_ABORT_IF_FALSE(0,"unexpected link verb"); + return NS_ERROR_UNEXPECTED; } } @@ -997,7 +1002,9 @@ nsresult nsWebShell::EndPageLoad(nsIWebProgress *aProgress, nsnull, // No headers stream LOAD_RELOAD_BYPASS_PROXY_AND_CACHE,// Load type nsnull, // No SHEntry - PR_TRUE); // first party site + PR_TRUE, // first party site + nsnull, // No nsIDocShell + nsnull); // No nsIRequest } } } diff --git a/docshell/base/nsWebShell.h b/docshell/base/nsWebShell.h index 75c90d8cbc8c..1e3cd8938c8f 100644 --- a/docshell/base/nsWebShell.h +++ b/docshell/base/nsWebShell.h @@ -71,6 +71,14 @@ public: const PRUnichar* aTargetSpec, nsIInputStream* aPostDataStream = 0, nsIInputStream* aHeadersDataStream = 0); + NS_IMETHOD OnLinkClickSync(nsIContent* aContent, + nsLinkVerb aVerb, + const PRUnichar* aURLSpec, + const PRUnichar* aTargetSpec, + nsIInputStream* aPostDataStream = 0, + nsIInputStream* aHeadersDataStream = 0, + nsIDocShell** aDocShell = 0, + nsIRequest** aRequest = 0); NS_IMETHOD OnOverLink(nsIContent* aContent, const PRUnichar* aURLSpec, const PRUnichar* aTargetSpec); @@ -81,12 +89,6 @@ public: // nsWebShell nsresult GetEventQueue(nsIEventQueue **aQueue); - void HandleLinkClickEvent(nsIContent *aContent, - nsLinkVerb aVerb, - const PRUnichar* aURLSpec, - const PRUnichar* aTargetSpec, - nsIInputStream* aPostDataStream = 0, - nsIInputStream* aHeadersDataStream = 0); static nsEventStatus PR_CALLBACK HandleEvent(nsGUIEvent *aEvent); diff --git a/webshell/public/nsILinkHandler.h b/webshell/public/nsILinkHandler.h index 4c3f9e581961..411901b68b9e 100644 --- a/webshell/public/nsILinkHandler.h +++ b/webshell/public/nsILinkHandler.h @@ -40,6 +40,8 @@ #include "nsISupports.h" class nsIInputStream; +class nsIDocShell; +class nsIRequest; class nsIContent; class nsString; struct nsGUIEvent; @@ -73,11 +75,16 @@ public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_ILINKHANDLER_IID) /** - * Process a click on a link. aContent is the content for the frame - * that generated the trigger. aURLSpec is an absolute url spec that - * defines the destination for the link. aTargetSpec indicates where - * the link is targeted (it may be an empty string). aVerb indicates - * the verb to use when the link is triggered. + * Process a click on a link. + * + * @param aContent the content for the frame that generated the trigger + * @param aVerb the verb to use when the link is triggered + * @param aURLSpec an absolute URL spec that defines the destination for the + * link + * @param aTargetSpec indicates where the link is targeted (may be an empty + * string) + * @param aPostDataStream the POST data to send + * @param aHeadersDataStream ??? */ NS_IMETHOD OnLinkClick(nsIContent* aContent, nsLinkVerb aVerb, @@ -87,10 +94,39 @@ public: nsIInputStream* aHeadersDataStream = 0) = 0; /** - * Process a mouse-over a link. aContent is the - * linked content. aURLSpec is an absolute url spec that defines the - * destination for the link. aTargetSpec indicates where the link is - * targeted (it may be an empty string). + * Process a click on a link. + * + * Works the same as OnLinkClick() except it happens immediately rather than + * through an event. + * + * @param aContent the content for the frame that generated the trigger + * @param aVerb the verb to use when the link is triggered + * @param aURLSpec an absolute URL spec that defines the destination for the + * link + * @param aTargetSpec indicates where the link is targeted (may be an empty + * string) + * @param aPostDataStream the POST data to send + * @param aHeadersDataStream ??? + * @param aDocShell (out-param) the DocShell that the request was opened on + * @param aRequest the request that was opened + */ + NS_IMETHOD OnLinkClickSync(nsIContent* aContent, + nsLinkVerb aVerb, + const PRUnichar* aURLSpec, + const PRUnichar* aTargetSpec, + nsIInputStream* aPostDataStream = 0, + nsIInputStream* aHeadersDataStream = 0, + nsIDocShell** aDocShell = 0, + nsIRequest** aRequest = 0) = 0; + + /** + * Process a mouse-over a link. + * + * @param aContent the linked content. + * @param aURLSpec an absolute url spec that defines the destination for the + * link + * @param aTargetSpec indicates where the link is targeted (it may be an empty + * string) */ NS_IMETHOD OnOverLink(nsIContent* aContent, const PRUnichar* aURLSpec,