--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -216,22 +216,16 @@ pref("browser.urlbar.filter.javascript",
// the maximum number of results to show in autocomplete when doing richResults
pref("browser.urlbar.maxRichResults", 25);
// Size of "chunks" affects the number of places to process between each search
// timeout (ms). Too big and the UI will be unresponsive; too small and we'll
// be waiting on the timeout too often without many results.
pref("browser.urlbar.search.chunkSize", 1000);
pref("browser.urlbar.search.timeout", 50);
-// Number of milliseconds to wait for the http headers (and thus
-// the Content-Disposition filename) before giving up and falling back to
-// picking a filename without that info in hand so that the user sees some
-// feedback from their action.
-pref("browser.download.saveLinkAsFilenameTimeout", 1000);
-
pref("browser.download.useDownloadDir", true);
pref("browser.download.folderList", 0);
pref("browser.download.manager.showAlertOnComplete", true);
pref("browser.download.manager.showAlertInterval", 2000);
pref("browser.download.manager.retention", 2);
pref("browser.download.manager.showWhenStarting", true);
pref("browser.download.manager.useWindow", true);
pref("browser.download.manager.closeWhenDone", false);
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -36,17 +36,16 @@
# Tom Germeau <tom.germeau@epigoon.com>
# Jesse Ruderman <jruderman@gmail.com>
# Joe Hughes <joe@retrovirus.com>
# Pamela Greene <pamg.bugs@gmail.com>
# Michael Ventnor <ventnors_dogs234@yahoo.com.au>
# Simon Bünzli <zeniko@gmail.com>
# Gijs Kruitbosch <gijskruitbosch@gmail.com>
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
-# Dan Mosedale <dmose@mozilla.org>
#
# 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
@@ -822,132 +821,20 @@ nsContextMenu.prototype = {
// Save URL of clicked-on frame.
saveFrame: function () {
saveDocument(this.target.ownerDocument);
},
// Save URL of clicked-on link.
saveLink: function() {
- // canonical def in nsURILoader.h
- const NS_ERROR_SAVE_LINK_AS_TIMEOUT = 0x805d0020;
-
var doc = this.target.ownerDocument;
urlSecurityCheck(this.linkURL, doc.nodePrincipal);
- var linkText = this.linkText();
- var linkURL = this.linkURL;
-
-
- // an object to proxy the data through to
- // nsIExternalHelperAppService.doContent, which will wait for the
- // appropriate MIME-type headers and then prompt the user with a
- // file picker
- function saveAsListener() {}
- saveAsListener.prototype = {
- extListener: null,
-
- onStartRequest: function saveLinkAs_onStartRequest(aRequest, aContext) {
-
- // if the timer fired, the error status will have been caused by that,
- // and we'll be restarting in onStopRequest, so no reason to notify
- // the user
- if (aRequest.status == NS_ERROR_SAVE_LINK_AS_TIMEOUT)
- return;
-
- timer.cancel();
-
- // some other error occured; notify the user...
- if (!Components.isSuccessCode(aRequest.status)) {
- try {
- const sbs = Cc["@mozilla.org/intl/stringbundle;1"].
- getService(Ci.nsIStringBundleService);
- const bundle = sbs.createBundle(
- "chrome://mozapps/locale/downloads/downloads.properties");
-
- const title = bundle.GetStringFromName("downloadErrorAlertTitle");
- const msg = bundle.GetStringFromName("downloadErrorGeneric");
-
- const promptSvc = Cc["@mozilla.org/embedcomp/prompt-service;1"].
- getService(Ci.nsIPromptService);
- promptSvc.alert(doc.defaultView, title, msg);
- } catch (ex) {}
- return;
- }
-
- var extHelperAppSvc =
- Cc["@mozilla.org/uriloader/external-helper-app-service;1"].
- getService(Ci.nsIExternalHelperAppService);
- this.extListener =
- extHelperAppSvc.doContent(aRequest.contentType, aRequest,
- doc.defaultView, true);
- this.extListener.onStartRequest(aRequest, aContext);
- },
-
- onStopRequest: function saveLinkAs_onStopRequest(aRequest, aContext,
- aStatusCode) {
- if (aStatusCode == NS_ERROR_SAVE_LINK_AS_TIMEOUT) {
- // do it the old fashioned way, which will pick the best filename
- // it can without waiting.
- saveURL(linkURL, linkText, null, true, false, doc.documentURIObject);
- }
- if (this.extListener)
- this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
- },
-
- onDataAvailable: function saveLinkAs_onDataAvailable(aRequest, aContext,
- aInputStream,
- aOffset, aCount) {
- this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
- aOffset, aCount);
- }
- }
-
- // in case we need to prompt the user for authentication
- function callbacks() {}
- callbacks.prototype = {
- getInterface: function sLA_callbacks_getInterface(aIID) {
- if (aIID.equals(Ci.nsIAuthPrompt) || aIID.equals(Ci.nsIAuthPrompt2)) {
- var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Ci.nsIPromptFactory);
- return ww.getPrompt(doc.defaultView, aIID);
- }
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- }
-
- // if it we don't have the headers after a short time, the user
- // won't have received any feedback from their click. that's bad. so
- // we give up waiting for the filename.
- function timerCallback() {}
- timerCallback.prototype = {
- notify: function sLA_timer_notify(aTimer) {
- channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT);
- return;
- }
- }
-
- // set up a channel to do the saving
- var ioService = Cc["@mozilla.org/network/io-service;1"].
- getService(Ci.nsIIOService);
- var channel = ioService.newChannelFromURI(this.getLinkURI());
- channel.notificationCallbacks = new callbacks();
- channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE |
- Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS;
- if (channel instanceof Ci.nsIHttpChannel)
- channel.referrer = doc.documentURIObject;
-
- // fallback to the old way if we don't see the headers quickly
- var timeToWait =
- gPrefService.getIntPref("browser.download.saveLinkAsFilenameTimeout");
- var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.initWithCallback(new timerCallback(), timeToWait,
- timer.TYPE_ONE_SHOT);
-
- // kick off the channel with our proxy object as the listener
- channel.asyncOpen(new saveAsListener(), null);
+ saveURL(this.linkURL, this.linkText(), null, true, false,
+ doc.documentURIObject);
},
sendLink: function() {
// we don't know the title of the link so pass in an empty string
MailIntegration.sendMessage( this.linkURL, "" );
},
// Save URL of clicked-on image.
--- a/uriloader/base/nsURILoader.cpp
+++ b/uriloader/base/nsURILoader.cpp
@@ -589,17 +589,16 @@ nsresult nsDocumentOpenInfo::DispatchCon
if (isGuessFromExt) {
mContentType = APPLICATION_GUESS_FROM_EXT;
aChannel->SetContentType(NS_LITERAL_CSTRING(APPLICATION_GUESS_FROM_EXT));
}
rv = helperAppService->DoContent(mContentType,
request,
m_originalContext,
- PR_FALSE,
getter_AddRefs(m_targetStreamListener));
if (NS_FAILED(rv)) {
request->SetLoadFlags(loadFlags);
m_targetStreamListener = nsnull;
}
}
NS_ASSERTION(m_targetStreamListener || NS_FAILED(rv),
--- a/uriloader/base/nsURILoader.h
+++ b/uriloader/base/nsURILoader.h
@@ -94,15 +94,9 @@ protected:
/**
* The load has been cancelled because it was found on a malware or phishing blacklist.
* XXX: this belongs in an nsDocShellErrors.h file of some sort.
*/
#define NS_ERROR_MALWARE_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_URILOADER, 30)
#define NS_ERROR_PHISHING_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_URILOADER, 31)
-/**
- * Used when "Save Link As..." doesn't see the headers quickly enough to choose
- * a filename. See nsContextMenu.js.
- */
-#define NS_ERROR_SAVE_LINK_AS_TIMEOUT NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_URILOADER, 32);
-
#endif /* nsURILoader_h__ */
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -519,17 +519,16 @@ nsresult nsExternalHelperAppService::Ini
nsExternalHelperAppService::~nsExternalHelperAppService()
{
gExtProtSvc = nsnull;
}
NS_IMETHODIMP nsExternalHelperAppService::DoContent(const nsACString& aMimeContentType,
nsIRequest *aRequest,
nsIInterfaceRequestor *aWindowContext,
- PRBool aForceSave,
nsIStreamListener ** aStreamListener)
{
nsAutoString fileName;
nsCAutoString fileExtension;
PRUint32 reason = nsIHelperAppLauncherDialog::REASON_CANTHANDLE;
nsresult rv;
// Get the file extension and name that we will need later
@@ -636,18 +635,17 @@ NS_IMETHODIMP nsExternalHelperAppService
// nsExternalAppHandler
nsCAutoString buf;
mimeInfo->GetPrimaryExtension(buf);
nsExternalAppHandler * handler = new nsExternalAppHandler(mimeInfo,
buf,
aWindowContext,
fileName,
- reason,
- aForceSave);
+ reason);
if (!handler)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aStreamListener = handler);
return NS_OK;
}
NS_IMETHODIMP nsExternalHelperAppService::ApplyDecodingForExtension(const nsACString& aExtension,
@@ -988,22 +986,21 @@ NS_INTERFACE_MAP_BEGIN(nsExternalAppHand
NS_INTERFACE_MAP_ENTRY(nsICancelable)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_END_THREADSAFE
nsExternalAppHandler::nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo,
const nsCSubstring& aTempFileExtension,
nsIInterfaceRequestor* aWindowContext,
const nsAString& aSuggestedFilename,
- PRUint32 aReason, PRBool aForceSave)
+ PRUint32 aReason)
: mMimeInfo(aMIMEInfo)
, mWindowContext(aWindowContext)
, mWindowToClose(nsnull)
, mSuggestedFileName(aSuggestedFilename)
-, mForceSave(aForceSave)
, mCanceled(PR_FALSE)
, mShouldCloseWindow(PR_FALSE)
, mReceivedDispositionInfo(PR_FALSE)
, mStopRequestIssued(PR_FALSE)
, mProgressListenerInitialized(PR_FALSE)
, mReason(aReason)
, mContentLength(-1)
, mProgress(0)
@@ -1468,23 +1465,16 @@ NS_IMETHODIMP nsExternalAppHandler::OnSt
// OK, now check why we're here
if (!alwaysAsk && mReason != nsIHelperAppLauncherDialog::REASON_CANTHANDLE) {
// Force asking if we're not saving. See comment back when we fetched the
// alwaysAsk boolean for details.
alwaysAsk = (action != nsIMIMEInfo::saveToDisk);
}
- // if we were told that we _must_ save to disk without asking, all the stuff
- // before this is irrelevant; override it
- if (mForceSave) {
- alwaysAsk = PR_FALSE;
- action = nsIMIMEInfo::saveToDisk;
- }
-
if (alwaysAsk)
{
// do this first! make sure we don't try to take an action until the user tells us what they want to do
// with it...
mReceivedDispositionInfo = PR_FALSE;
// invoke the dialog!!!!! use mWindowContext as the window context parameter for the dialog request
mDialog = do_CreateInstance( NS_IHELPERAPPLAUNCHERDLG_CONTRACTID, &rv );
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -246,17 +246,17 @@ public:
* @param aWindowContext Window context, as passed to DoContent
* @param aFileName The filename to use
* @param aReason A constant from nsIHelperAppLauncherDialog indicating
* why the request is handled by a helper app.
*/
nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo, const nsCSubstring& aFileExtension,
nsIInterfaceRequestor * aWindowContext,
const nsAString& aFilename,
- PRUint32 aReason, PRBool aForceSave);
+ PRUint32 aReason);
~nsExternalAppHandler();
protected:
nsCOMPtr<nsIFile> mTempFile;
nsCOMPtr<nsIURI> mSourceUrl;
nsString mTempFileExtension;
/**
@@ -276,23 +276,16 @@ protected:
/**
* The following field is set if we were processing an http channel that had
* a content disposition header which specified the SUGGESTED file name we
* should present to the user in the save to disk dialog.
*/
nsString mSuggestedFileName;
/**
- * If set, this handler should forcibly save the file to disk regardless of
- * MIME info settings or anything else, without ever popping up the
- * unknown content type handling dialog.
- */
- PRPackedBool mForceSave;
-
- /**
* The canceled flag is set if the user canceled the launching of this
* application before we finished saving the data to a temp file.
*/
PRPackedBool mCanceled;
/**
* This is set based on whether the channel indicates that a new window
* was opened specifically for this download. If so, then we
--- a/uriloader/exthandler/nsIExternalHelperAppService.idl
+++ b/uriloader/exthandler/nsIExternalHelperAppService.idl
@@ -46,36 +46,33 @@ interface nsIFile;
interface nsIMIMEInfo;
interface nsIWebProgressListener2;
interface nsIInterfaceRequestor;
/**
* The external helper app service is used for finding and launching
* platform specific external applications for a given mime content type.
*/
-[scriptable, uuid(9e456297-ba3e-42b1-92bd-b7db014268cb)]
+[scriptable, uuid(0ea90cf3-2dd9-470f-8f76-f141743c5678)]
interface nsIExternalHelperAppService : nsISupports
{
/**
* Binds an external helper application to a stream listener. The caller
* should pump data into the returned stream listener. When the OnStopRequest
* is issued, the stream listener implementation will launch the helper app
* with this data.
* @param aMimeContentType The content type of the incoming data
* @param aRequest The request corresponding to the incoming data
* @param aWindowContext Use GetInterface to retrieve properties like the
* dom window or parent window...
* The service might need this in order to bring up dialogs.
- * @param aForceSave True to always save this content to disk, regardless of
- * nsIMIMEInfo and other such influences.
* @return A nsIStreamListener which the caller should pump the data into.
*/
nsIStreamListener doContent (in ACString aMimeContentType, in nsIRequest aRequest,
- in nsIInterfaceRequestor aWindowContext,
- in boolean aForceSave);
+ in nsIInterfaceRequestor aWindowContext);
/**
* Returns true if data from a URL with this extension combination
* is to be decoded from aEncodingType prior to saving or passing
* off to helper apps, false otherwise.
*/
boolean applyDecodingForExtension(in AUTF8String aExtension,
in ACString aEncodingType);