Change nsIHandlerInfo::LaunchWithFile to be launchWithURI (
bug 386078), r+sr=biesi
--- a/netwerk/mime/public/nsIMIMEInfo.idl
+++ b/netwerk/mime/public/nsIMIMEInfo.idl
@@ -44,17 +44,17 @@ interface nsIUTF8StringEnumerator;
interface nsIHandlerApp;
typedef long nsHandlerInfoAction;
/**
* nsIHandlerInfo gives access to the information about how a given protocol
* scheme or MIME-type is handled.
*/
-[scriptable, uuid(feaa5a46-45aa-4124-8e9e-bc23d517c2d4)]
+[scriptable, uuid(2ec1216d-59e7-424c-aa1e-70aa3c897520)]
interface nsIHandlerInfo : nsISupports {
/**
* A human readable description of the handler type
*/
attribute AString description;
/**
* The application the user has said they want associated with this content
@@ -71,26 +71,27 @@ interface nsIHandlerInfo : nsISupports {
/**
* A pretty name description of the associated default application. Only
* usable if hasDefaultHandler is true.
*/
readonly attribute AString defaultDescription;
/**
- * Launches the application with the specified file, in a way that
+ * Launches the application with the specified URI, in a way that
* depends on the value of preferredAction. preferredAction must be
* useHelperApp or useSystemDefault.
*
- * @param aFile The file to launch this application with.
+ * @param aURI The URI to launch this application with; this may or may
+ * not be a local file.
*
* @throw NS_ERROR_INVALID_ARG if action is not valid for this function.
* Other exceptions may be thrown.
*/
- void launchWithFile(in nsIFile aFile);
+ void launchWithURI(in nsIURI aURI);
/**
* preferredAction is how the user specified they would like to handle
* this content type: save to disk, use specified helper app, use OS
* default handler or handle using navigator; possible value constants
* listed below
*/
attribute nsHandlerInfoAction preferredAction;
--- a/uriloader/exthandler/mac/nsMIMEInfoMac.cpp
+++ b/uriloader/exthandler/mac/nsMIMEInfoMac.cpp
@@ -18,16 +18,17 @@
* The Initial Developer of the Original Code is
* Netscape Communications, Inc.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
* Christian Biesinger <cbiesinger@web.de>
+ * Dan Mosedale <dmose@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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
@@ -37,61 +38,69 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <LaunchServices.h>
#include "nsMIMEInfoMac.h"
#include "nsILocalFileMac.h"
+#include "nsIFileURL.h"
NS_IMETHODIMP
-nsMIMEInfoMac::LaunchWithFile(nsIFile* aFile)
+nsMIMEInfoMac::LaunchWithURI(nsIURI* aURI)
{
nsCOMPtr<nsIFile> application;
-
+ nsresult rv;
+
if (mPreferredAction == useHelperApp) {
- nsresult rv;
+
+ // check for and launch with web handler app
+ nsCOMPtr<nsIWebHandlerApp> webHandlerApp =
+ do_QueryInterface(mPreferredApplication, &rv);
+ if (NS_SUCCEEDED(rv)) {
+ return LaunchWithWebHandler(webHandlerApp, aURI);
+ }
+
+ // otherwise, get the application executable from the handler
nsCOMPtr<nsILocalHandlerApp> localHandlerApp =
- do_QueryInterface(mPreferredApplication, &rv);
+ do_QueryInterface(mPreferredApplication, &rv);
NS_ENSURE_SUCCESS(rv, rv);
-
+
rv = localHandlerApp->GetExecutable(getter_AddRefs(application));
NS_ENSURE_SUCCESS(rv, rv);
+
} else if (mPreferredAction == useSystemDefault)
application = mDefaultApplication;
else
return NS_ERROR_INVALID_ARG;
+ // get the nsILocalFile version of the doc to launch with
+ nsCOMPtr<nsILocalFile> docToLoad;
+ rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
+ if (NS_FAILED(rv)) return rv;
+
+ // if we've already got an app, just QI so we have the launchWithDoc method
+ nsCOMPtr<nsILocalFileMac> app;
if (application) {
- nsresult rv;
- nsCOMPtr<nsILocalFileMac> app = do_QueryInterface(application, &rv);
+ app = do_QueryInterface(application, &rv);
if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsILocalFile> docToLoad = do_QueryInterface(aFile, &rv);
+ } else {
+ // otherwise ask LaunchServices for an app directly
+ nsCOMPtr<nsILocalFileMac> tempFile = do_QueryInterface(docToLoad, &rv);
if (NS_FAILED(rv)) return rv;
- return app->LaunchWithDoc(docToLoad, PR_FALSE);
- }
-#ifdef XP_MACOSX
- // We didn't get an application to handle the file from aMIMEInfo, ask LaunchServices directly
- nsresult rv;
- nsCOMPtr <nsILocalFileMac> tempFile = do_QueryInterface(aFile, &rv);
- if (NS_FAILED(rv)) return rv;
-
- FSRef tempFileRef;
- tempFile->GetFSRef(&tempFileRef);
+ FSRef tempFileRef;
+ tempFile->GetFSRef(&tempFileRef);
- FSRef appFSRef;
- if (::LSGetApplicationForItem(&tempFileRef, kLSRolesAll, &appFSRef, nsnull) == noErr)
- {
- nsCOMPtr<nsILocalFileMac> app(do_CreateInstance("@mozilla.org/file/local;1"));
- if (!app) return NS_ERROR_FAILURE;
- app->InitWithFSRef(&appFSRef);
-
- nsCOMPtr <nsILocalFile> docToLoad = do_QueryInterface(aFile, &rv);
- if (NS_FAILED(rv)) return rv;
-
- rv = app->LaunchWithDoc(docToLoad, PR_FALSE);
+ FSRef appFSRef;
+ if (::LSGetApplicationForItem(&tempFileRef, kLSRolesAll, &appFSRef, nsnull) == noErr)
+ {
+ app = (do_CreateInstance("@mozilla.org/file/local;1"));
+ if (!app) return NS_ERROR_FAILURE;
+ app->InitWithFSRef(&appFSRef);
+ } else {
+ return NS_ERROR_FAILURE;
+ }
}
- return rv;
-#endif
+
+ return app->LaunchWithDoc(docToLoad, PR_FALSE);
}
--- a/uriloader/exthandler/mac/nsMIMEInfoMac.h
+++ b/uriloader/exthandler/mac/nsMIMEInfoMac.h
@@ -39,17 +39,17 @@
#include "nsMIMEInfoImpl.h"
class nsMIMEInfoMac : public nsMIMEInfoImpl {
public:
nsMIMEInfoMac(const char* aMIMEType = "") : nsMIMEInfoImpl(aMIMEType) {}
nsMIMEInfoMac(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {}
- NS_IMETHOD LaunchWithFile(nsIFile* aFile);
+ NS_IMETHOD LaunchWithURI(nsIURI* aURI);
#ifdef DEBUG
protected:
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile) {
NS_NOTREACHED("do not call this method, use LaunchWithFile");
return NS_ERROR_UNEXPECTED;
}
#endif
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -2543,17 +2543,21 @@ nsresult nsExternalAppHandler::OpenWithA
return NS_OK;
// we only should have gotten here if the on stop request had been fired already.
NS_ASSERTION(mStopRequestIssued, "uhoh, how did we get here if we aren't done getting data?");
// if a stop request was already issued then proceed with launching the application.
if (mStopRequestIssued)
{
- rv = mMimeInfo->LaunchWithFile(mFinalFileDestination);
+ nsCOMPtr<nsIURI> fileUri;
+ rv = NS_NewFileURI(getter_AddRefs(fileUri), mFinalFileDestination);
+ if (NS_SUCCEEDED(rv)) {
+ rv = mMimeInfo->LaunchWithURI(fileUri);
+ }
if (NS_FAILED(rv))
{
// Send error notification.
nsAutoString path;
mFinalFileDestination->GetPath(path);
SendStatusChange(kLaunchError, rv, nsnull, path);
Cancel(rv); // Cancel, and clean up temp file.
}
@@ -2614,17 +2618,17 @@ NS_IMETHODIMP nsExternalAppHandler::Laun
if (fileUrl && mIsFileChannel)
{
Cancel(NS_BINDING_ABORTED);
nsCOMPtr<nsIFile> file;
nsresult rv = fileUrl->GetFile(getter_AddRefs(file));
if (NS_SUCCEEDED(rv))
{
- rv = mMimeInfo->LaunchWithFile(file);
+ rv = mMimeInfo->LaunchWithURI(fileUrl);
if (NS_SUCCEEDED(rv))
return NS_OK;
}
nsAutoString path;
if (file)
file->GetPath(path);
// If we get here, an error happened
SendStatusChange(kLaunchError, rv, nsnull, path);
--- a/uriloader/exthandler/nsMIMEInfoImpl.cpp
+++ b/uriloader/exthandler/nsMIMEInfoImpl.cpp
@@ -36,16 +36,18 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsMIMEInfoImpl.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsStringEnumerator.h"
#include "nsIProcess.h"
+#include "nsILocalFile.h"
+#include "nsIFileURL.h"
// nsISupports methods
NS_IMPL_THREADSAFE_ISUPPORTS2(nsMIMEInfoBase, nsIMIMEInfo, nsIHandlerInfo)
// nsMIMEInfoImpl methods
nsMIMEInfoBase::nsMIMEInfoBase(const char *aMIMEType) :
mMacType(0),
mMacCreator(0),
@@ -271,36 +273,69 @@ nsMIMEInfoBase::GetAlwaysAskBeforeHandli
NS_IMETHODIMP
nsMIMEInfoBase::SetAlwaysAskBeforeHandling(PRBool aAlwaysAsk)
{
mAlwaysAskBeforeHandling = aAlwaysAsk;
return NS_OK;
}
+/* static */
+nsresult
+nsMIMEInfoBase::GetLocalFileFromURI(nsIURI *aURI, nsILocalFile **aFile)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(aURI, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ nsCOMPtr<nsIFile> file;
+ rv = fileUrl->GetFile(getter_AddRefs(file));
+ if (NS_FAILED(rv)) return rv;
+
+ return CallQueryInterface(file, aFile);
+}
+
+
NS_IMETHODIMP
-nsMIMEInfoBase::LaunchWithFile(nsIFile* aFile)
+nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI)
{
+ nsCOMPtr<nsILocalFile> docToLoad;
+ nsresult rv;
+
if (mPreferredAction == useHelperApp) {
if (!mPreferredApplication)
return NS_ERROR_FILE_NOT_FOUND;
- nsCOMPtr<nsILocalHandlerApp> localHandler;
- nsresult rv;
- localHandler = do_QueryInterface(mPreferredApplication, &rv);
+ // check for and possibly launch with web application
+ nsCOMPtr<nsIWebHandlerApp> webHandler =
+ do_QueryInterface(mPreferredApplication, &rv);
+ if (NS_SUCCEEDED(rv)) {
+ return LaunchWithWebHandler(webHandler, aURI);
+ }
+
+ // ok, we must have a local handler app
+ nsCOMPtr<nsILocalHandlerApp> localHandler =
+ do_QueryInterface(mPreferredApplication, &rv);
NS_ENSURE_SUCCESS(rv, rv);
-
+
nsCOMPtr<nsIFile> executable;
rv = localHandler->GetExecutable(getter_AddRefs(executable));
NS_ENSURE_SUCCESS(rv, rv);
-
- return LaunchWithIProcess(executable, aFile);
+
+ rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return LaunchWithIProcess(executable, docToLoad);
}
else if (mPreferredAction == useSystemDefault) {
- return LaunchDefaultWithFile(aFile);
+ rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return LaunchDefaultWithFile(docToLoad);
}
return NS_ERROR_INVALID_ARG;
}
void
nsMIMEInfoBase::CopyBasicDataTo(nsMIMEInfoBase* aOther)
{
@@ -330,16 +365,24 @@ nsMIMEInfoBase::LaunchWithIProcess(nsIFi
aFile->GetNativePath(path);
const char * strPath = path.get();
PRUint32 pid;
return process->Run(PR_FALSE, &strPath, 1, &pid);
}
+/* static */
+nsresult
+nsMIMEInfoBase::LaunchWithWebHandler(nsIWebHandlerApp *aApp, nsIURI *aURI)
+{
+ // we'll be implementing this Real Soon Now!
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
// nsMIMEInfoImpl implementation
NS_IMETHODIMP
nsMIMEInfoImpl::GetDefaultDescription(nsAString& aDefaultDescription)
{
if (mDefaultAppDescription.IsEmpty() && mDefaultApplication) {
// Don't want to cache this, just in case someone resets the app
// without changing the description....
mDefaultApplication->GetLeafName(aDefaultDescription);
--- a/uriloader/exthandler/nsMIMEInfoImpl.h
+++ b/uriloader/exthandler/nsMIMEInfoImpl.h
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 et: */
/* ***** 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/
*
@@ -80,17 +80,17 @@ class nsMIMEInfoBase : public nsIMIMEInf
NS_IMETHOD GetMacType(PRUint32 *aMacType);
NS_IMETHOD SetMacType(PRUint32 aMacType);
NS_IMETHOD GetMacCreator(PRUint32 *aMacCreator);
NS_IMETHOD SetMacCreator(PRUint32 aMacCreator);
NS_IMETHOD Equals(nsIMIMEInfo *aMIMEInfo, PRBool *_retval);
NS_IMETHOD GetPreferredApplicationHandler(nsIHandlerApp * *aPreferredApplicationHandler);
NS_IMETHOD SetPreferredApplicationHandler(nsIHandlerApp * aPreferredApplicationHandler);
NS_IMETHOD GetDefaultDescription(nsAString & aDefaultDescription);
- NS_IMETHOD LaunchWithFile(nsIFile *aFile);
+ NS_IMETHOD LaunchWithURI(nsIURI *aURI);
NS_IMETHOD GetPreferredAction(nsHandlerInfoAction *aPreferredAction);
NS_IMETHOD SetPreferredAction(nsHandlerInfoAction aPreferredAction);
NS_IMETHOD GetAlwaysAskBeforeHandling(PRBool *aAlwaysAskBeforeHandling);
NS_IMETHOD SetAlwaysAskBeforeHandling(PRBool aAlwaysAskBeforeHandling);
// nsMIMEInfoBase methods
nsMIMEInfoBase(const char *aMIMEType = "") NS_HIDDEN;
nsMIMEInfoBase(const nsACString& aMIMEType) NS_HIDDEN;
@@ -132,16 +132,33 @@ class nsMIMEInfoBase : public nsIMIMEInf
* LaunchWithFile/LaunchDefaultWithFile.
* Neither aApp nor aFile may be null.
*
* @param aApp The application to launch
* @param aFile The file to open in the application
*/
static NS_HIDDEN_(nsresult) LaunchWithIProcess(nsIFile* aApp, nsIFile* aFile);
+ /**
+ * Used to launch a web-based handler with this URI.
+ *
+ * @param aURI The URI to launch with.
+ */
+ static NS_HIDDEN_(nsresult) LaunchWithWebHandler(nsIWebHandlerApp *aApp,
+ nsIURI *aURI);
+
+ /**
+ * Given a file: nsIURI, return the associated nsILocalFile
+ *
+ * @param aURI the file: URI in question
+ * @param aFile the associated nsILocalFile (out param)
+ */
+ static NS_HIDDEN_(nsresult) GetLocalFileFromURI(nsIURI *aURI,
+ nsILocalFile **aFile);
+
// member variables
nsCStringArray mExtensions; ///< array of file extensions associated w/ this MIME obj
nsString mDescription; ///< human readable description
PRUint32 mMacType, mMacCreator; ///< Mac file type and creator
nsCString mMIMEType;
nsCOMPtr<nsIHandlerApp> mPreferredApplication;
nsHandlerInfoAction mPreferredAction; ///< preferred action to associate with this type
nsString mPreferredAppDescription;
@@ -149,18 +166,19 @@ class nsMIMEInfoBase : public nsIMIMEInf
PRBool mAlwaysAskBeforeHandling;
};
/**
* This is a complete implementation of nsIMIMEInfo, and contains all necessary
* methods. However, depending on your platform you may want to use a different
* way of launching applications. This class stores the default application in a
- * member variable and provides a function for setting it. Launching is done
- * using nsIProcess, native path of the file to open as first argument.
+ * member variable and provides a function for setting it. For local
+ * applications, launching is done using nsIProcess, native path of the file to
+ * open as first argument.
*/
class nsMIMEInfoImpl : public nsMIMEInfoBase {
public:
nsMIMEInfoImpl(const char *aMIMEType = "") : nsMIMEInfoBase(aMIMEType) {}
nsMIMEInfoImpl(const nsACString& aMIMEType) : nsMIMEInfoBase(aMIMEType) {}
virtual ~nsMIMEInfoImpl() {}
// nsIMIMEInfo methods
--- a/uriloader/exthandler/os2/nsMIMEInfoOS2.cpp
+++ b/uriloader/exthandler/os2/nsMIMEInfoOS2.cpp
@@ -58,23 +58,27 @@ static const PRUnichar table[] =
'u','v','w','x','y','z','0','1','2','3',
'4','5','6','7','8','9'};
nsMIMEInfoOS2::~nsMIMEInfoOS2()
{
}
-NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithFile(nsIFile* aFile)
+NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithURI(nsIFile* aURI)
{
nsresult rv = NS_OK;
+ nsCOMPtr<nsILocalFile> docToLoad;
+ rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
+ NS_ENSURE_SUCCESS(rv, rv);
+
nsCAutoString path;
- aFile->GetNativePath(path);
-
+ docToLoad->GetNativePath(path);
+
nsCOMPtr<nsIFile> application;
if (mPreferredAction == useHelperApp) {
nsCOMPtr<nsILocalHandlerApp> localHandlerApp =
do_QueryInterface(mPreferredApplication, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = localHandlerApp->GetExecutable(getter_AddRefs(application));
NS_ENSURE_SUCCESS(rv, rv);
@@ -103,17 +107,17 @@ NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithF
FAPPTYP_WINDOWSPROT |
FAPPTYP_WINDOWSREAL)) {
// if the helper application is a DOS app, create an 8.3 filename
// we do this even if the filename is valid because it's 8.3, who cares
nsCOMPtr<nsPIExternalAppLauncher> helperAppService (do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID));
if (helperAppService)
{
nsCAutoString leafName;
- aFile->GetNativeLeafName(leafName);
+ docToLoad->GetNativeLeafName(leafName);
const char* lastDot = strrchr(leafName.get(), '.');
char suffix[CCHMAXPATH + 1] = "";
if (lastDot)
{
strcpy(suffix, lastDot);
}
suffix[4] = '\0';
@@ -125,20 +129,20 @@ NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithF
double fpTime;
LL_L2D(fpTime, PR_Now());
srand((uint)(fpTime * 1e-6 + 0.5));
PRInt32 i;
for (i=0;i<SALT_SIZE;i++) {
saltedTempLeafName.Append(table[(rand()%TABLE_SIZE)]);
}
AppendASCIItoUTF16(suffix, saltedTempLeafName);
- rv = aFile->MoveTo(nsnull, saltedTempLeafName);
+ rv = docToLoad->MoveTo(nsnull, saltedTempLeafName);
} while (NS_FAILED(rv));
- helperAppService->DeleteTemporaryFileOnExit(aFile);
- aFile->GetNativePath(path);
+ helperAppService->DeleteTemporaryFileOnExit(docToLoad);
+ docToLoad->GetNativePath(path);
}
} else {
path.Insert('\"', 0);
path.Append('\"');
}
const char * strPath = path.get();
// if we were given an application to use then use it....otherwise
--- a/uriloader/exthandler/os2/nsMIMEInfoOS2.h
+++ b/uriloader/exthandler/os2/nsMIMEInfoOS2.h
@@ -41,17 +41,17 @@
class nsMIMEInfoOS2 : public nsMIMEInfoImpl
{
public:
nsMIMEInfoOS2(const char* aType = "") : nsMIMEInfoImpl(aType) {}
nsMIMEInfoOS2(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {}
virtual ~nsMIMEInfoOS2();
- NS_IMETHOD LaunchWithFile(nsIFile* aFile);
+ NS_IMETHOD LaunchWithURI(nsIURI* aURI);
#ifdef DEBUG
protected:
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile) {
NS_NOTREACHED("Do not call this, use LaunchWithFile");
return NS_ERROR_UNEXPECTED;
}
#endif