aboutsummaryrefslogtreecommitdiffstats
path: root/embed/mozilla
diff options
context:
space:
mode:
Diffstat (limited to 'embed/mozilla')
-rw-r--r--embed/mozilla/EphyDownload.cpp470
-rw-r--r--embed/mozilla/EphyDownload.h196
-rw-r--r--embed/mozilla/EphyHeaderSniffer.cpp457
-rw-r--r--embed/mozilla/EphyHeaderSniffer.h89
4 files changed, 1212 insertions, 0 deletions
diff --git a/embed/mozilla/EphyDownload.cpp b/embed/mozilla/EphyDownload.cpp
new file mode 100644
index 000000000..062abc983
--- /dev/null
+++ b/embed/mozilla/EphyDownload.cpp
@@ -0,0 +1,470 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Conrad Carlen <ccarlen@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "EphyDownload.h"
+
+#include "nsIExternalHelperAppService.h"
+//#include "nsILocalFIleMac.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsIRequest.h"
+#include "netCore.h"
+#include "nsIObserver.h"
+
+//#include "UDownloadDisplay.h"
+//#include "UMacUnicode.h"
+
+//#include "UNavServicesDialogs.h"
+
+
+//*****************************************************************************
+// EphyDownload
+//*****************************************************************************
+#pragma mark [EphyDownload]
+
+//ADownloadProgressView *EphyDownload::sProgressView;
+
+EphyDownload::EphyDownload() :
+ mGotFirstStateChange(false), mIsNetworkTransfer(false),
+ mUserCanceled(false),
+ mStatus(NS_OK)
+{
+}
+
+EphyDownload::~EphyDownload()
+{
+}
+
+NS_IMPL_ISUPPORTS2(EphyDownload, nsIDownload, nsIWebProgressListener)
+
+#pragma mark -
+#pragma mark [EphyDownload::nsIDownload]
+
+/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in nsIMIMEInfo aMIMEInfo, in long long startTime, in nsIWebBrowserPersist aPersist); */
+NS_IMETHODIMP
+EphyDownload::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName,
+ nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist)
+{
+ try {
+ mSource = aSource;
+ mDestination = aTarget;
+ mStartTime = startTime;
+ mPercentComplete = 0;
+ mInterval = 400000; // ms
+ mPriorKRate = 0;
+ mRateChanges = 0;
+ mRateChangeLimit = 2;
+ mIsPaused = PR_FALSE;
+ mStartTime = PR_Now();
+ mLastUpdate = mStartTime;
+ if (aPersist) {
+ mWebPersist = aPersist;
+ // We have to break this circular ref when the download is done -
+ // until nsIWebBrowserPersist supports weak refs - bug #163889.
+ aPersist->SetProgressListener(this);
+ }
+ // UI Rumba
+ mDownloaderView = EPHY_DOWNLOADER_VIEW (ephy_embed_shell_get_downloader_view
+ (embed_shell));
+ downloader_view_add_download (mDownloaderView, "A", "B", "C", (gpointer)this);
+ // EnsureProgressView();
+ // sProgressView->AddDownloadItem(this);
+ }
+ catch (...) {
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+/* readonly attribute nsIURI source; */
+NS_IMETHODIMP
+EphyDownload::GetSource(nsIURI * *aSource)
+{
+ NS_ENSURE_ARG_POINTER(aSource);
+ NS_IF_ADDREF(*aSource = mSource);
+ return NS_OK;
+}
+
+/* readonly attribute nsILocalFile target; */
+NS_IMETHODIMP
+EphyDownload::GetTarget(nsILocalFile * *aTarget)
+{
+ NS_ENSURE_ARG_POINTER(aTarget);
+ NS_IF_ADDREF(*aTarget = mDestination);
+ return NS_OK;
+}
+
+/* readonly attribute nsIWebBrowserPersist persist; */
+NS_IMETHODIMP
+EphyDownload::GetPersist(nsIWebBrowserPersist * *aPersist)
+{
+ NS_ENSURE_ARG_POINTER(aPersist);
+ NS_IF_ADDREF(*aPersist = mWebPersist);
+ return NS_OK;
+}
+
+/* readonly attribute PRInt32 percentComplete; */
+NS_IMETHODIMP
+EphyDownload::GetPercentComplete(PRInt32 *aPercentComplete)
+{
+ NS_ENSURE_ARG_POINTER(aPercentComplete);
+ *aPercentComplete = mPercentComplete;
+ return NS_OK;
+}
+
+/* attribute wstring displayName; */
+NS_IMETHODIMP
+EphyDownload::GetDisplayName(PRUnichar * *aDisplayName)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+EphyDownload::SetDisplayName(const PRUnichar * aDisplayName)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* readonly attribute long long startTime; */
+NS_IMETHODIMP
+EphyDownload::GetStartTime(PRInt64 *aStartTime)
+{
+ NS_ENSURE_ARG_POINTER(aStartTime);
+ *aStartTime = mStartTime;
+ return NS_OK;
+}
+
+/* readonly attribute nsIMIMEInfo MIMEInfo; */
+NS_IMETHODIMP
+EphyDownload::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute nsIWebProgressListener listener; */
+NS_IMETHODIMP
+EphyDownload::GetListener(nsIWebProgressListener * *aListener)
+{
+ NS_ENSURE_ARG_POINTER(aListener);
+ NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+EphyDownload::SetListener(nsIWebProgressListener * aListener)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute nsIObserver observer; */
+NS_IMETHODIMP
+EphyDownload::GetObserver(nsIObserver * *aObserver)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+EphyDownload::SetObserver(nsIObserver * aObserver)
+{
+ if (aObserver)
+ aObserver->QueryInterface(NS_GET_IID(nsIHelperAppLauncher), getter_AddRefs(mHelperAppLauncher));
+ return NS_OK;
+}
+
+#pragma mark -
+#pragma mark [EphyDownload::nsIWebProgressListener]
+
+/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */
+NS_IMETHODIMP
+EphyDownload::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest,
+ PRUint32 aStateFlags, nsresult aStatus)
+{
+ // For a file download via the external helper app service, we will never get a start
+ // notification. The helper app service has gotten that notification before it created us.
+ if (!mGotFirstStateChange) {
+ mIsNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
+ mGotFirstStateChange = PR_TRUE;
+ //BroadcastMessage(msg_OnDLStart, this);
+ }
+
+ if (NS_FAILED(aStatus) && NS_SUCCEEDED(mStatus))
+ mStatus = aStatus;
+
+ // We will get this even in the event of a cancel,
+ if ((aStateFlags & STATE_STOP) && (!mIsNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
+ if (mWebPersist) {
+ mWebPersist->SetProgressListener(nsnull);
+ mWebPersist = nsnull;
+ }
+ mHelperAppLauncher = nsnull;
+ //BroadcastMessage(msg_OnDLComplete, this);
+ }
+
+ 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
+EphyDownload::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest,
+ PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
+ PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
+{
+ if (mUserCanceled) {
+ if (mHelperAppLauncher)
+ mHelperAppLauncher->Cancel();
+ else if (aRequest)
+ aRequest->Cancel(NS_BINDING_ABORTED);
+ mUserCanceled = false;
+ }
+ if (aMaxTotalProgress == -1)
+ mPercentComplete = -1;
+ else
+ mPercentComplete = (PRInt32)(((float)aCurTotalProgress / (float)aMaxTotalProgress) * 100.0 + 0.5);
+
+ //MsgOnDLProgressChangeInfo info(this, aCurTotalProgress, aMaxTotalProgress);
+ // From ProgressListener
+ PRInt64 now = PR_Now();
+ mElapsed = now - mStartTime;
+
+ if ((now - mLastUpdate < mInterval) &&
+ (aMaxTotalProgress != -1) &&
+ (aCurTotalProgress < aMaxTotalProgress))
+ {
+ return NS_OK;
+ }
+ mLastUpdate = now;
+
+
+ gfloat progress = -1;
+ if (aMaxTotalProgress > 0)
+ {
+ progress = (gfloat)aCurTotalProgress /
+ (gfloat)aMaxTotalProgress;
+ }
+
+ /* compute download rate */
+ gfloat speed = -1;
+ PRInt64 currentRate;
+ if (mElapsed)
+ {
+ currentRate = ((PRInt64)(aCurTotalProgress)) * 1000000 / mElapsed;
+ }
+ else
+ {
+ currentRate = 0;
+ }
+
+ if (!mIsPaused && currentRate)
+ {
+ PRFloat64 currentKRate = ((PRFloat64)currentRate)/1024;
+ if (currentKRate != mPriorKRate)
+ {
+ if (mRateChanges++ == mRateChangeLimit)
+ {
+ mPriorKRate = currentKRate;
+ mRateChanges = 0;
+ }
+ else
+ {
+ currentKRate = mPriorKRate;
+ }
+ }
+ else
+ {
+ mRateChanges = 0;
+ }
+
+ speed = currentKRate;
+ }
+
+ /* compute time remaining */
+ gint remaining = -1;
+ if (currentRate && (aMaxTotalProgress > 0))
+ {
+ remaining = (gint)((aMaxTotalProgress - aCurTotalProgress)
+ /currentRate + 0.5);
+ }
+
+ //BroadcastMessage(msg_OnDLProgressChange, &info);
+ // UI Rumba
+ downloader_view_set_download_progress (mDownloaderView,
+ mElapsed / 1000000,
+ remaining,
+ speed,
+ aMaxTotalProgress / 1024.0 + 0.5,
+ aCurTotalProgress / 1024.0 + 0.5,
+ progress,
+ (gpointer)this);
+
+ return NS_OK;
+}
+
+/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
+NS_IMETHODIMP
+EphyDownload::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
+EphyDownload::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest,
+ nsresult aStatus, const PRUnichar *aMessage)
+{
+ return NS_OK;
+}
+
+/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
+NS_IMETHODIMP
+EphyDownload::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
+{
+ return NS_OK;
+}
+
+#pragma mark -
+#pragma mark [EphyDownload Internal Methods]
+
+void
+EphyDownload::Cancel()
+{
+ mUserCanceled = true;
+ // nsWebBrowserPersist does the right thing: After canceling, next time through
+ // OnStateChange(), aStatus != NS_OK. This isn't the case with nsExternalHelperAppService.
+ if (!mWebPersist)
+ mStatus = NS_ERROR_ABORT;
+}
+
+void
+EphyDownload::Pause()
+{
+}
+
+void
+EphyDownload::Resume()
+{
+}
+
+/*void
+EphyDownload::CreateProgressView()
+{
+ sProgressView = new CMultiDownloadProgress;
+ ThrowIfNil_(sProgressView);
+}*/
+
+
+//*****************************************************************************
+// CHelperAppLauncherDialog
+//*****************************************************************************
+/*#pragma mark -
+#pragma mark [CHelperAppLauncherDialog]
+
+CHelperAppLauncherDialog::CHelperAppLauncherDialog()
+{
+}
+
+CHelperAppLauncherDialog::~CHelperAppLauncherDialog()
+{
+}
+
+NS_IMPL_ISUPPORTS1(CHelperAppLauncherDialog, nsIHelperAppLauncherDialog)*/
+
+/* void show (in nsIHelperAppLauncher aLauncher, in nsISupports aContext, in boolean aForced); */
+/*NS_IMETHODIMP CHelperAppLauncherDialog::Show(nsIHelperAppLauncher *aLauncher, nsISupports *aContext, PRBool aForced)
+{
+ return aLauncher->SaveToDisk(nsnull, PR_FALSE);
+}*/
+
+/* nsILocalFile promptForSaveToFile (in nsIHelperAppLauncher aLauncher, in nsISupports aWindowContext, in wstring aDefaultFile, in wstring aSuggestedFileExtension); */
+/*NS_IMETHODIMP CHelperAppLauncherDialog::PromptForSaveToFile(nsIHelperAppLauncher* aLauncher,
+ nsISupports *aWindowContext,
+ const PRUnichar *aDefaultFile,
+ const PRUnichar *aSuggestedFileExtension,
+ nsILocalFile **_retval)
+{
+ NS_ENSURE_ARG_POINTER(_retval);
+ *_retval = nsnull;
+
+ static bool sFirstTime = true;
+ UNavServicesDialogs::LFileDesignator designator;
+
+ if (sFirstTime) {
+ // Get the default download folder and point Nav Sevices to it.
+ nsCOMPtr<nsIFile> defaultDownloadDir;
+ NS_GetSpecialDirectory(NS_MAC_DEFAULT_DOWNLOAD_DIR, getter_AddRefs(defaultDownloadDir));
+ if (defaultDownloadDir) {
+ nsCOMPtr<nsILocalFileMac> macDir(do_QueryInterface(defaultDownloadDir));
+ FSSpec defaultDownloadSpec;
+ if (NS_SUCCEEDED(macDir->GetFSSpec(&defaultDownloadSpec)))
+ designator.SetDefaultLocation(defaultDownloadSpec, true);
+ }
+ sFirstTime = false;
+ }
+
+ Str255 defaultName;
+ CPlatformUCSConversion::GetInstance()->UCSToPlatform(nsDependentString(aDefaultFile), defaultName);
+ bool result = designator.AskDesignateFile(defaultName);
+
+ // After the dialog is dismissed, process all activation an update events right away.
+ // The save dialog code calls UDesktop::Activate after dismissing the dialog. All that
+ // does is activate the now frontmost LWindow which was behind the dialog. It does not
+ // remove the activate event from the queue. If that event is not processed and removed
+ // before we show the progress window, bad things happen. Specifically, the progress
+ // dialog will show in front and then, shortly thereafter, the window which was behind this save
+ // dialog will be moved to the front.
+
+ if (LEventDispatcher::GetCurrentEventDispatcher()) { // Can this ever be NULL?
+ EventRecord theEvent;
+ while (::WaitNextEvent(updateMask | activMask, &theEvent, 0, nil))
+ LEventDispatcher::GetCurrentEventDispatcher()->DispatchEvent(theEvent);
+ }
+
+ if (result) {
+ FSSpec destSpec;
+ designator.GetFileSpec(destSpec);
+ nsCOMPtr<nsILocalFileMac> destFile;
+ NS_NewLocalFileWithFSSpec(&destSpec, PR_TRUE, getter_AddRefs(destFile));
+ if (!destFile)
+ return NS_ERROR_FAILURE;
+ *_retval = destFile;
+ NS_ADDREF(*_retval);
+ return NS_OK;
+ }
+ else
+ return NS_ERROR_ABORT;
+}*/
+
diff --git a/embed/mozilla/EphyDownload.h b/embed/mozilla/EphyDownload.h
new file mode 100644
index 000000000..a3abc7067
--- /dev/null
+++ b/embed/mozilla/EphyDownload.h
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Conrad Carlen <ccarlen@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef EphyDownload_h__
+#define EphyDownload_h__
+//#pragma once
+
+#include "nsIDownload.h"
+#include "nsIWebProgressListener.h"
+#include "nsIHelperAppLauncherDialog.h"
+#include "nsIExternalHelperAppService.h"
+
+#include "nsIURI.h"
+#include "nsILocalFile.h"
+#include "nsIWebBrowserPersist.h"
+
+#include "downloader-view.h"
+#include "ephy-embed-shell.h"
+
+//class ADownloadProgressView;
+
+//*****************************************************************************
+// EphyDownload
+//
+// Holds information used to display a single download in the UI. This object is
+// created in one of two ways:
+// (1) By nsExternalHelperAppHandler when Gecko encounters a MIME type which
+// it doesn't itself handle. In this case, the notifications sent to
+// nsIDownload are controlled by nsExternalHelperAppHandler.
+// (2) By the embedding app's file saving code when saving a web page or a link
+// target. See CHeaderSniffer.cpp. In this case, the notifications sent to
+// nsIDownload are controlled by the implementation of nsIWebBrowserPersist.
+//*****************************************************************************
+
+#define EPHY_DOWNLOAD_CID \
+{ /* d2a2f743-f126-4f1f-1234-d4e50490f112 */ \
+ 0xd2a2f743, \
+ 0xf126, \
+ 0x4f1f, \
+ {0x12, 0x34, 0xd4, 0xe5, 0x04, 0x90, 0xf1, 0x12} \
+}
+
+#define EPHY_DOWNLOAD_CLASSNAME "Ephy's Download Progress Dialog"
+//#define EPHY_DOWNLOAD_CONTRACTID "@mozilla.org/progressdialog;1"
+
+class EphyDownload : public nsIDownload,
+ public nsIWebProgressListener
+// public LBroadcaster
+{
+public:
+
+ // Messages we broadcast to listeners.
+ enum {
+ msg_OnDLStart = 57723, // param is EphyDownload*
+ msg_OnDLComplete, // param is EphyDownload*
+ msg_OnDLProgressChange // param is MsgOnDLProgressChangeInfo*
+ };
+
+/* struct MsgOnDLProgressChangeInfo
+ {
+ MsgOnDLProgressChangeInfo(EphyDownload* broadcaster, PRInt32 curProgress, PRInt32 maxProgress) :
+ mBroadcaster(broadcaster), mCurProgress(curProgress), mMaxProgress(maxProgress)
+ { }
+
+ EphyDownload *mBroadcaster;
+ PRInt32 mCurProgress, mMaxProgress;
+ };*/
+
+ EphyDownload();
+ virtual ~EphyDownload();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIDOWNLOAD
+ NS_DECL_NSIWEBPROGRESSLISTENER
+
+ virtual void Cancel();
+ virtual void Pause();
+ virtual void Resume();
+ virtual void GetStatus(nsresult& aStatus)
+ { aStatus = mStatus; }
+
+//protected:
+ // void EnsureProgressView()
+ // {
+ // if (!sProgressView)
+ // CreateProgressView();
+ // }
+ // virtual void CreateProgressView();
+ // sProgressView is a singleton. This will only be called once.
+
+protected:
+ nsCOMPtr<nsIURI> mSource;
+ nsCOMPtr<nsILocalFile> mDestination;
+ PRInt64 mStartTime;
+ PRInt64 mElapsed;
+ PRInt32 mPercentComplete;
+
+ bool mGotFirstStateChange, mIsNetworkTransfer;
+ bool mUserCanceled;
+ bool mIsPaused;
+ nsresult mStatus;
+
+ // These two are mutually exclusive.
+ nsCOMPtr<nsIWebBrowserPersist> mWebPersist;
+ nsCOMPtr<nsIHelperAppLauncher> mHelperAppLauncher;
+
+ PRFloat64 mPriorKRate;
+ PRInt32 mRateChanges;
+ PRInt32 mRateChangeLimit;
+ PRInt64 mLastUpdate;
+ PRInt32 mInterval;
+ DownloaderView *mDownloaderView;
+ // static ADownloadProgressView *sProgressView;
+};
+
+//*****************************************************************************
+// CHelperAppLauncherDialog
+//
+// The implementation of nsIExternalHelperAppService in Gecko creates one of
+// these at the beginning of the download and calls its Show() method. Typically,
+// this will create a non-modal dialog in which the user can decide whether to
+// save the file to disk or open it with an application. This implementation
+// just saves the file to disk unconditionally. The user can decide what they
+// wish to do with the download from the progress dialog.
+//*****************************************************************************
+
+/*class CHelperAppLauncherDialog : public nsIHelperAppLauncherDialog
+{
+public:
+ CHelperAppLauncherDialog();
+ virtual ~CHelperAppLauncherDialog();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIHELPERAPPLAUNCHERDIALOG
+
+protected:
+
+};*/
+
+
+//*****************************************************************************
+// ADownloadProgressView
+//
+// An abstract class which handles the display and interaction with a download.
+// Typically, it presents a progress dialog.
+//*****************************************************************************
+
+/*class ADownloadProgressView
+{
+ friend class EphyDownload;
+
+ virtual void AddDownloadItem(EphyDownload *aDownloadItem) = 0;
+ // A download is beginning. Initialize the UI for this download.
+ // Throughout the download process, the EphyDownload will broadcast
+ // status messages. The UI needs to call LBroadcaster::AddListener()
+ // on the EphyDownload at this point in order to get the messages.
+
+};*/
+
+
+#endif // EphyDownload_h__
diff --git a/embed/mozilla/EphyHeaderSniffer.cpp b/embed/mozilla/EphyHeaderSniffer.cpp
new file mode 100644
index 000000000..ea5df90a0
--- /dev/null
+++ b/embed/mozilla/EphyHeaderSniffer.cpp
@@ -0,0 +1,457 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Chimera code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * David Hyatt <hyatt@netscape.com>
+ * Simon Fraser <sfraser@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "EphyHeaderSniffer.h"
+//#include "UMacUnicode.h"
+
+//#include "UCustomNavServicesDialogs.h"
+
+#include "netCore.h"
+
+#include "nsIChannel.h"
+#include "nsIHttpChannel.h"
+#include "nsIURL.h"
+#include "nsIStringEnumerator.h"
+#include "nsIPrefService.h"
+#include "nsIMIMEService.h"
+#include "nsIMIMEInfo.h"
+#include "nsIDOMHTMLDocument.h"
+#include "nsIDownload.h"
+//#include "nsILocalFileMac.h"
+
+const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
+
+EphyHeaderSniffer::EphyHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
+ nsIDOMDocument* aDocument, nsIInputStream* aPostData,
+ const nsAString& aSuggestedFilename, PRBool aBypassCache, ESaveFormat aSaveFormat)
+: mPersist(aPersist)
+, mTmpFile(aFile)
+, mURL(aURL)
+, mDocument(aDocument)
+, mPostData(aPostData)
+, mDefaultFilename(aSuggestedFilename)
+, mBypassCache(aBypassCache)
+, mSaveFormat(aSaveFormat)
+{
+}
+
+EphyHeaderSniffer::~EphyHeaderSniffer()
+{
+}
+
+NS_IMPL_ISUPPORTS1(EphyHeaderSniffer, nsIWebProgressListener)
+
+#pragma mark -
+
+// Implementation of nsIWebProgressListener
+/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
+NS_IMETHODIMP
+EphyHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags,
+ PRUint32 aStatus)
+{
+ if (aStateFlags & nsIWebProgressListener::STATE_START)
+ {
+ nsCOMPtr<nsIWebBrowserPersist> kungFuDeathGrip(mPersist); // be sure to keep it alive while we save
+ // since it owns us as a listener
+ nsCOMPtr<nsIWebProgressListener> kungFuSuicideGrip(this); // and keep ourselves alive
+
+ nsresult rv;
+ nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest, &rv);
+ if (!channel) return rv;
+ channel->GetContentType(mContentType);
+
+ nsCOMPtr<nsIURI> origURI;
+ channel->GetOriginalURI(getter_AddRefs(origURI));
+
+ // Get the content-disposition if we're an HTTP channel.
+ nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
+ if (httpChannel)
+ httpChannel->GetResponseHeader(nsCAutoString("content-disposition"), mContentDisposition);
+
+ mPersist->CancelSave();
+ PRBool exists;
+ mTmpFile->Exists(&exists);
+ if (exists)
+ mTmpFile->Remove(PR_FALSE);
+
+ rv = PerformSave(origURI, mSaveFormat);
+ if (NS_FAILED(rv))
+ {
+ // put up some UI
+
+ }
+ }
+ 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
+EphyHeaderSniffer::OnProgressChange(nsIWebProgress *aWebProgress,
+ nsIRequest *aRequest,
+ PRInt32 aCurSelfProgress,
+ PRInt32 aMaxSelfProgress,
+ PRInt32 aCurTotalProgress,
+ PRInt32 aMaxTotalProgress)
+{
+ return NS_OK;
+}
+
+/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
+NS_IMETHODIMP
+EphyHeaderSniffer::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
+EphyHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress,
+ nsIRequest *aRequest,
+ nsresult aStatus,
+ const PRUnichar *aMessage)
+{
+ return NS_OK;
+}
+
+/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
+NS_IMETHODIMP
+EphyHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
+{
+ return NS_OK;
+}
+
+#pragma mark -
+
+static ESaveFormat SaveFormatFromPrefValue(PRInt32 inPrefValue)
+{
+ switch (inPrefValue)
+ {
+ case 0: return eSaveFormatHTMLComplete;
+ default: // fall through
+ case 1: return eSaveFormatHTML;
+ case 2: return eSaveFormatPlainText;
+ }
+}
+
+static PRInt32 PrefValueFromSaveFormat(ESaveFormat inSaveFormat)
+{
+ switch (inSaveFormat)
+ {
+ case eSaveFormatPlainText: return 2;
+ default: // fall through
+ case eSaveFormatHTML: return 1;
+ case eSaveFormatHTMLComplete: return 0;
+ }
+}
+
+nsresult EphyHeaderSniffer::PerformSave(nsIURI* inOriginalURI, const ESaveFormat inSaveFormat)
+{
+ nsresult rv;
+ // Are we an HTML document? If so, we will want to append an accessory view to
+ // the save dialog to provide the user with the option of doing a complete
+ // save vs. a single file save.
+ PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
+ mContentType.Equals("text/xml") ||
+ mContentType.Equals("application/xhtml+xml"));
+
+ // Next find out the directory that we should start in.
+ nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1", &rv));
+ if (!prefs)
+ return rv;
+ nsCOMPtr<nsIPrefBranch> dirBranch;
+ prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch));
+ PRInt32 filterIndex = 0;
+ if (inSaveFormat != eSaveFormatUnspecified) {
+ filterIndex = PrefValueFromSaveFormat(inSaveFormat);
+ }
+ else if (dirBranch) {
+ nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex);
+ if (NS_FAILED(rv))
+ filterIndex = 0;
+ }
+
+ // We need to figure out what file name to use.
+/* nsAutoString defaultFileName;
+ if (!mContentDisposition.IsEmpty()) {
+ // (1) Use the HTTP header suggestion.
+ PRInt32 index = mContentDisposition.Find("filename=");
+ if (index >= 0) {
+ // Take the substring following the prefix.
+ index += 9;
+ nsCAutoString filename;
+ mContentDisposition.Right(filename, mContentDisposition.Length() - index);
+ defaultFileName = NS_ConvertUTF8toUCS2(filename);
+ }
+ }
+
+ if (defaultFileName.IsEmpty()) {
+ nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
+ if (url) {
+ nsCAutoString fileNameCString;
+ url->GetFileName(fileNameCString); // (2) For file URLs, use the file name.
+ defaultFileName = NS_ConvertUTF8toUCS2(fileNameCString);
+ }
+ }
+
+ if (defaultFileName.IsEmpty() && mDocument && isHTML) {
+ nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
+ if (htmlDoc)
+ htmlDoc->GetTitle(defaultFileName); // (3) Use the title of the document.
+ }
+
+ if (defaultFileName.IsEmpty()) {
+ // (4) Use the caller provided name.
+ defaultFileName = mDefaultFilename;
+ }
+
+ if (defaultFileName.IsEmpty() && mURL) {
+ // (5) Use the host.
+ nsCAutoString hostName;
+ mURL->GetHost(hostName);
+ defaultFileName = NS_ConvertUTF8toUCS2(hostName);
+ }
+
+ // One last case to handle about:blank and other fruity untitled pages.
+ if (defaultFileName.IsEmpty())
+ defaultFileName.AssignWithConversion("untitled");
+
+ // Validate the file name to ensure legality.
+ for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
+ if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
+ defaultFileName.SetCharAt(i, PRUnichar(' '));
+
+ // Make sure the appropriate extension is appended to the suggested file name.
+ nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1"));
+ nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI, &rv));
+ if (!fileURL)
+ return rv;
+
+ fileURL->SetFilePath(NS_ConvertUCS2toUTF8(defaultFileName));
+
+ nsCAutoString fileExtension;
+ fileURL->GetFileExtension(fileExtension);
+
+ PRBool setExtension = PR_FALSE;
+ if (mContentType.Equals("text/html")) {
+ if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) {
+ defaultFileName.AppendWithConversion(".html");
+ setExtension = PR_TRUE;
+ }
+ }
+
+ if (!setExtension && fileExtension.IsEmpty()) {
+ nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv));
+ if (!mimeService)
+ return rv;
+ nsCOMPtr<nsIMIMEInfo> mimeInfo;
+ rv = mimeService->GetFromTypeAndExtension(mContentType.get(), nsnull, getter_AddRefs(mimeInfo));
+ if (!mimeInfo)
+ return rv;
+
+ nsCOMPtr<nsIUTF8StringEnumerator> extensions;
+ mimeInfo->GetFileExtensions(getter_AddRefs(extensions));
+
+ PRBool hasMore;
+ extensions->HasMore(&hasMore);
+ if (hasMore) {
+ nsCAutoString ext;
+ extensions->GetNext(ext);
+ defaultFileName.Append(PRUnichar('.'));
+ defaultFileName.Append(NS_ConvertUTF8toUCS2(ext));
+ }
+ }
+
+ // Now it's time to pose the save dialog.
+ FSSpec destFileSpec;
+ bool isReplacing = false;
+
+ {
+ Str255 defaultName;
+ bool result;
+
+ CPlatformUCSConversion::GetInstance()->UCSToPlatform(defaultFileName, defaultName);
+#ifndef XP_MACOSX
+ char tempBuf1[256], tempBuf2[64];
+ ::CopyPascalStringToC(defaultName, tempBuf1);
+ ::CopyCStringToPascal(NS_TruncNodeName(tempBuf1, tempBuf2), defaultName);
+#endif
+ if (isHTML) {
+ ESaveFormat saveFormat = SaveFormatFromPrefValue(filterIndex);
+ UNavServicesDialogs::LCustomFileDesignator customDesignator;
+ result = customDesignator.AskDesignateFile(defaultName, saveFormat);
+ if (!result)
+ return NS_OK; // user canceled
+ filterIndex = PrefValueFromSaveFormat(saveFormat);
+ customDesignator.GetFileSpec(destFileSpec);
+ isReplacing = customDesignator.IsReplacing();
+ }
+ else {
+ UNavServicesDialogs::LFileDesignator stdDesignator;
+ result = stdDesignator.AskDesignateFile(defaultName);
+ if (!result)
+ return NS_OK; // user canceled
+ stdDesignator.GetFileSpec(destFileSpec);
+ isReplacing = stdDesignator.IsReplacing();
+ }
+
+ // After the dialog is dismissed, process all activation an update events right away.
+ // The save dialog code calls UDesktop::Activate after dismissing the dialog. All that
+ // does is activate the now frontmost LWindow which was behind the dialog. It does not
+ // remove the activate event from the queue. If that event is not processed and removed
+ // before we show the progress window, bad things happen. Specifically, the progress
+ // dialog will show in front and then, shortly thereafter, the window which was behind this save
+ // dialog will be moved to the front.
+
+ if (LEventDispatcher::GetCurrentEventDispatcher()) { // Can this ever be NULL?
+ EventRecord theEvent;
+ while (::WaitNextEvent(updateMask | activMask, &theEvent, 0, nil))
+ LEventDispatcher::GetCurrentEventDispatcher()->DispatchEvent(theEvent);
+ }
+ }
+
+ // only save the pref if the frontend didn't specify a format
+ if (inSaveFormat == eSaveFormatUnspecified && isHTML)
+ dirBranch->SetIntPref("save_converter_index", filterIndex);
+
+ nsCOMPtr<nsILocalFile> destFile;
+
+ rv = NS_NewLocalFileWithFSSpec(&destFileSpec, PR_TRUE, getter_AddRefs(destFile));
+ if (NS_FAILED(rv))
+ return rv;
+
+ if (isReplacing) {
+ PRBool exists;
+ rv = destFile->Exists(&exists);
+ if (NS_SUCCEEDED(rv) && exists)
+ rv = destFile->Remove(PR_TRUE);
+ if (NS_FAILED(rv))
+ return rv;
+ }
+
+ // if the user chose plain text, set the content type
+ if (isHTML && filterIndex == 2)
+ mContentType = "text/plain";
+
+ nsCOMPtr<nsISupports> sourceData;
+ if (isHTML && filterIndex != 1)
+ sourceData = do_QueryInterface(mDocument); // HTML complete
+ else
+ sourceData = do_QueryInterface(mURL); // HTML or text only
+
+ return InitiateDownload(sourceData, destFile, inOriginalURI);*/
+}
+
+// inOriginalURI is always a URI. inSourceData can be an nsIURI or an nsIDOMDocument, depending
+// on what we're saving. It's that way for nsIWebBrowserPersist.
+nsresult EphyHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsILocalFile* inDestFile, nsIURI* inOriginalURI)
+{
+ nsresult rv = NS_OK;
+
+ nsCOMPtr<nsIWebBrowserPersist> webPersist = do_CreateInstance(persistContractID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ nsCOMPtr<nsIURI> sourceURI = do_QueryInterface(inSourceData);
+
+ PRInt64 timeNow = PR_Now();
+
+ nsAutoString fileDisplayName;
+ inDestFile->GetLeafName(fileDisplayName);
+
+ nsCOMPtr<nsIDownload> downloader = do_CreateInstance(NS_DOWNLOAD_CONTRACTID);
+ // dlListener attaches to its progress dialog here, which gains ownership
+ rv = downloader->Init(inOriginalURI, inDestFile, fileDisplayName.get(), nsnull, timeNow, webPersist);
+ if (NS_FAILED(rv)) return rv;
+
+ PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
+ nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+ if (mBypassCache)
+ flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
+ else
+ flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
+
+ webPersist->SetPersistFlags(flags);
+
+ if (sourceURI)
+ {
+ rv = webPersist->SaveURI(sourceURI, nsnull, nsnull, mPostData, nsnull, inDestFile);
+ }
+ else
+ {
+ nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(inSourceData, &rv);
+ if (!domDoc) return rv; // should never happen
+
+ PRInt32 encodingFlags = 0;
+ nsCOMPtr<nsILocalFile> filesFolder;
+
+ if (!mContentType.Equals("text/plain")) {
+ // Create a local directory in the same dir as our file. It
+ // will hold our associated files.
+ filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
+ nsAutoString unicodePath;
+ inDestFile->GetPath(unicodePath);
+ filesFolder->InitWithPath(unicodePath);
+
+ nsAutoString leafName;
+ filesFolder->GetLeafName(leafName);
+ nsAutoString nameMinusExt(leafName);
+ PRInt32 index = nameMinusExt.RFind(".");
+ if (index >= 0)
+ nameMinusExt.Left(nameMinusExt, index);
+ nameMinusExt += NS_LITERAL_STRING(" Files"); // XXXdwh needs to be localizable!
+ filesFolder->SetLeafName(nameMinusExt);
+ PRBool exists = PR_FALSE;
+ filesFolder->Exists(&exists);
+ if (!exists) {
+ rv = filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
+ if (NS_FAILED(rv))
+ return rv;
+ }
+ }
+ else
+ {
+ encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
+ nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
+ nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
+ }
+ rv = webPersist->SaveDocument(domDoc, inDestFile, filesFolder, mContentType.get(), encodingFlags, 80);
+ }
+
+ return rv;
+}
diff --git a/embed/mozilla/EphyHeaderSniffer.h b/embed/mozilla/EphyHeaderSniffer.h
new file mode 100644
index 000000000..8ef6afa01
--- /dev/null
+++ b/embed/mozilla/EphyHeaderSniffer.h
@@ -0,0 +1,89 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Chimera code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * David Hyatt <hyatt@netscape.com>
+ * Simon Fraser <sfraser@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ #pragma once
+
+#include "nsString.h"
+#include "nsIWebProgressListener.h"
+#include "nsIWebBrowserPersist.h"
+#include "nsIURI.h"
+#include "nsILocalFile.h"
+#include "nsIInputStream.h"
+#include "nsIDOMDocument.h"
+
+
+typedef enum
+{
+ eSaveFormatUnspecified = 0,
+ eSaveFormatPlainText, // items should match the MENU in resources
+ eSaveFormatHTML,
+ eSaveFormatHTMLComplete
+} ESaveFormat;
+
+// Implementation of a header sniffer class that is used when saving Web pages and images.
+class EphyHeaderSniffer : public nsIWebProgressListener
+{
+public:
+ EphyHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL,
+ nsIDOMDocument* aDocument, nsIInputStream* aPostData,
+ const nsAString& aSuggestedFilename, PRBool aBypassCache,
+ ESaveFormat aSaveFormat = eSaveFormatUnspecified);
+ virtual ~EphyHeaderSniffer();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEBPROGRESSLISTENER
+
+protected:
+
+ nsresult PerformSave(nsIURI* inOriginalURI, const ESaveFormat inSaveFormat);
+ nsresult InitiateDownload(nsISupports* inSourceData, nsILocalFile* inDestFile, nsIURI* inOriginalURI);
+
+private:
+
+ nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener.
+ nsCOMPtr<nsIFile> mTmpFile;
+ nsCOMPtr<nsIURI> mURL;
+ nsCOMPtr<nsIDOMDocument> mDocument;
+ nsCOMPtr<nsIInputStream> mPostData;
+ nsString mDefaultFilename;
+ PRBool mBypassCache;
+ ESaveFormat mSaveFormat;
+ nsCString mContentType;
+ nsCString mContentDisposition;
+};
+