--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -103,17 +103,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsURILoad
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDocLoader, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsOSHelperAppService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExternalProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlockedExternalProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefetchService, Init)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheUpdateService,
nsOfflineCacheUpdateService::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsOfflineCacheUpdate)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsLocalHandlerApp)
+NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t)
#if defined(XP_MAC) || defined(XP_MACOSX)
#include "nsInternetConfigService.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsInternetConfigService)
#endif
// session history
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHEntry)
@@ -213,17 +213,18 @@ static const nsModuleComponentInfo gDocS
nsBlockedExternalProtocolHandlerConstructor, },
{ NS_PREFETCHSERVICE_CLASSNAME, NS_PREFETCHSERVICE_CID, NS_PREFETCHSERVICE_CONTRACTID,
nsPrefetchServiceConstructor, },
{ NS_OFFLINECACHEUPDATESERVICE_CLASSNAME, NS_OFFLINECACHEUPDATESERVICE_CID, NS_OFFLINECACHEUPDATESERVICE_CONTRACTID,
nsOfflineCacheUpdateServiceConstructor, },
{ NS_OFFLINECACHEUPDATE_CLASSNAME, NS_OFFLINECACHEUPDATE_CID, NS_OFFLINECACHEUPDATE_CONTRACTID,
nsOfflineCacheUpdateConstructor, },
{ "Local Application Handler App", NS_LOCALHANDLERAPP_CID,
- NS_LOCALHANDLERAPP_CONTRACTID, nsLocalHandlerAppConstructor, },
+ NS_LOCALHANDLERAPP_CONTRACTID, PlatformLocalHandlerApp_tConstructor, },
+
#if defined(XP_MAC) || defined(XP_MACOSX)
{ "Internet Config Service", NS_INTERNETCONFIGSERVICE_CID, NS_INTERNETCONFIGSERVICE_CONTRACTID,
nsInternetConfigServiceConstructor, },
#endif
// session history
{ "nsSHEntry", NS_SHENTRY_CID,
NS_SHENTRY_CONTRACTID, nsSHEntryConstructor },
--- a/netwerk/mime/public/nsIMIMEInfo.idl
+++ b/netwerk/mime/public/nsIMIMEInfo.idl
@@ -47,17 +47,17 @@ interface nsIMutableArray;
interface nsIInterfaceRequestor;
typedef long nsHandlerInfoAction;
/**
* nsIHandlerInfo gives access to the information about how a given protocol
* scheme or MIME-type is handled.
*/
-[scriptable, uuid(325e56a7-3762-4312-aec7-f1fcf84b4145)]
+[scriptable, uuid(325e56a7-3762-4312-aec7-f1fcf84b4145)]
interface nsIHandlerInfo : nsISupports {
/**
* The type of this handler info. For MIME handlers, this is the MIME type.
* For protocol handlers, it's the scheme.
*
* @return String representing the type.
*/
readonly attribute ACString type;
@@ -234,17 +234,17 @@ interface nsIMIMEInfo : nsIHandlerInfo {
/**
* nsIHandlerApp represents an external application that can handle content
* of some sort (either a MIME type or a protocol).
*
* FIXME: now that we've made nsIWebHandlerApp inherit from nsIHandlerApp,
* we should also try to make nsIWebContentHandlerInfo inherit from or possibly
* be replaced by nsIWebHandlerApp (bug 394710).
*/
-[scriptable, uuid(b504f39e-d88a-4435-8e0d-e13f1070f7e7)]
+[scriptable, uuid(8d298761-0963-4c90-99e2-6ea498825e82)]
interface nsIHandlerApp : nsISupports {
/**
* Human readable name for the handler
*/
attribute AString name;
/**
@@ -254,16 +254,31 @@ interface nsIHandlerApp : nsISupports {
* Two apps are the same if they are both either local or web handlers
* and their executables/URI templates are the same in a string comparison.
*
* @param aHandlerApp the handler app to compare to the invokant
*
* @returns true if the two are logically equivalent, false otherwise
*/
boolean equals(in nsIHandlerApp aHandlerApp);
+
+ /**
+ * Launches the application with the specified URI.
+ *
+ * @param aURI
+ * The URI to launch this application with
+ *
+ * @param aWindowContext
+ * Required for web handlers; is passed through to
+ * nsIURILoader.openURI, but see bug 394483 for info on
+ * how this needs to evolve.
+ */
+ void launchWithURI(in nsIURI aURI,
+ [optional] in nsIInterfaceRequestor aWindowContext);
+
};
/**
* nsILocalHandlerApp is a local OS-level executable
*/
[scriptable, uuid(9812be73-273c-478c-8170-c3e0db08ae7c)]
interface nsILocalHandlerApp : nsIHandlerApp {
--- a/toolkit/toolkit-makefiles.sh
+++ b/toolkit/toolkit-makefiles.sh
@@ -362,16 +362,17 @@ MAKEFILES_netwerk="
netwerk/system/win32/Makefile
"
MAKEFILES_uriloader="
uriloader/Makefile
uriloader/base/Makefile
uriloader/exthandler/Makefile
uriloader/exthandler/tests/Makefile
+ uriloader/exthandler/tests/browser/Makefile
"
MAKEFILES_profile="
profile/Makefile
profile/public/Makefile
profile/dirserviceprovider/Makefile
profile/dirserviceprovider/public/Makefile
profile/dirserviceprovider/src/Makefile
--- a/uriloader/exthandler/Makefile.in
+++ b/uriloader/exthandler/Makefile.in
@@ -98,16 +98,17 @@ REQUIRES += windowwatcher \
endif
OSHELPER = nsOSHelperAppService.cpp
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
OSHELPER += nsInternetConfig.cpp \
nsInternetConfigService.cpp \
nsMIMEInfoMac.cpp \
+ nsLocalHandlerAppMac.cpp \
$(NULL)
endif
LOCAL_INCLUDES = -I$(srcdir)
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
OSHELPER += nsGNOMERegistry.cpp
OSHELPER += nsMIMEInfoUnix.cpp
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsLocalHandlerAppMac.cpp
@@ -0,0 +1,95 @@
+/* ***** 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 code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 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
+ * 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 <LaunchServices.h>
+
+#include "nsLocalHandlerAppMac.h"
+#include "nsILocalFileMac.h"
+#include "nsIURI.h"
+
+/**
+ * mostly copy/pasted from nsMacShellService.cpp (which is in browser/,
+ * so we can't depend on it here). This code probably really wants to live
+ * somewhere more central (see bug 389922).
+ */
+NS_IMETHODIMP
+nsLocalHandlerAppMac::LaunchWithURI(nsIURI *aURI,
+ nsIInterfaceRequestor *aWindowContext)
+{
+ nsresult rv;
+ nsCOMPtr<nsILocalFileMac> lfm(do_QueryInterface(mExecutable, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ CFURLRef appURL;
+ rv = lfm->GetCFURL(&appURL);
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCAutoString uriSpec;
+ aURI->GetSpec(uriSpec);
+
+ const UInt8* uriString = reinterpret_cast<const UInt8*>(uriSpec.get());
+ CFURLRef uri = ::CFURLCreateWithBytes(NULL, uriString, uriSpec.Length(),
+ kCFStringEncodingUTF8, NULL);
+ if (!uri) {
+ ::CFRelease(appURL);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ CFArrayRef uris = ::CFArrayCreate(NULL, reinterpret_cast<const void**>(&uri),
+ 1, NULL);
+ if (!uris) {
+ ::CFRelease(uri);
+ ::CFRelease(appURL);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ LSLaunchURLSpec launchSpec;
+ launchSpec.appURL = appURL;
+ launchSpec.itemURLs = uris;
+ launchSpec.passThruParams = NULL;
+ launchSpec.launchFlags = kLSLaunchDefaults;
+ launchSpec.asyncRefCon = NULL;
+
+ OSErr err = ::LSOpenFromURLSpec(&launchSpec, NULL);
+
+ ::CFRelease(uris);
+ ::CFRelease(uri);
+ ::CFRelease(appURL);
+
+ return err != noErr ? NS_ERROR_FAILURE : NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsLocalHandlerAppMac.h
@@ -0,0 +1,59 @@
+/* ***** 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 code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 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
+ * 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 NSLOCALHANDLERAPPMAC_H_
+#define NSLOCALHANDLERAPPMAC_H_
+
+#include "nsLocalHandlerApp.h"
+
+class nsLocalHandlerAppMac : public nsLocalHandlerApp {
+
+ public:
+ nsLocalHandlerAppMac() { }
+
+ nsLocalHandlerAppMac(const PRUnichar *aName, nsIFile *aExecutable)
+ : nsLocalHandlerApp(aName, aExecutable) {}
+
+ nsLocalHandlerAppMac(const nsAString & aName, nsIFile *aExecutable)
+ : nsLocalHandlerApp(aName, aExecutable) {}
+ virtual ~nsLocalHandlerAppMac() { }
+
+ NS_IMETHOD LaunchWithURI(nsIURI* aURI,
+ nsIInterfaceRequestor* aWindowContext);
+};
+
+#endif /*NSLOCALHANDLERAPPMAC_H_*/
--- a/uriloader/exthandler/mac/nsMIMEInfoMac.cpp
+++ b/uriloader/exthandler/mac/nsMIMEInfoMac.cpp
@@ -94,59 +94,16 @@ nsMIMEInfoMac::LaunchWithFile(nsIFile *a
} else {
return NS_ERROR_FAILURE;
}
}
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(aFile);
return app->LaunchWithDoc(localFile, PR_FALSE);
}
-NS_IMETHODIMP
-nsMIMEInfoMac::LaunchWithURI(nsIURI* aURI,
- nsIInterfaceRequestor* aWindowContext)
-{
- nsCOMPtr<nsIFile> application;
- nsresult rv;
-
- // for now, this is only being called with protocol handlers; that
- // will change once we get to more general registerContentHandler
- // support
- NS_ASSERTION(mClass == eProtocolInfo,
- "nsMIMEInfoBase should be a protocol handler");
-
- if (mPreferredAction == useHelperApp) {
-
- // check for and launch with web handler app
- nsCOMPtr<nsIWebHandlerApp> webHandlerApp =
- do_QueryInterface(mPreferredApplication, &rv);
- if (NS_SUCCEEDED(rv)) {
- return LaunchWithWebHandler(webHandlerApp, aURI, aWindowContext);
- }
-
- // otherwise, get the application executable from the handler
- nsCOMPtr<nsILocalHandlerApp> localHandlerApp =
- do_QueryInterface(mPreferredApplication, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = localHandlerApp->GetExecutable(getter_AddRefs(application));
- NS_ENSURE_SUCCESS(rv, rv);
-
- // pass the entire URI to the handler.
- nsCAutoString spec;
- aURI->GetSpec(spec);
- return OpenApplicationWithURI(application, spec);
- }
-
- if (mPreferredAction == useSystemDefault) {
- return LoadUriInternal(aURI);
- }
-
- return NS_ERROR_INVALID_ARG;
-}
-
nsresult
nsMIMEInfoMac::LoadUriInternal(nsIURI *aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
nsresult rv = NS_ERROR_FAILURE;
nsCAutoString uri;
aURI->GetSpec(uri);
@@ -162,56 +119,8 @@ nsMIMEInfoMac::LoadUriInternal(nsIURI *a
NS_IMETHODIMP
nsMIMEInfoMac::GetHasDefaultHandler(PRBool *_retval)
{
// We have a default application if we have a description
*_retval = !mDefaultAppDescription.IsEmpty();
return NS_OK;
}
-/**
- * static; mostly copy/pasted from nsMacShellService.cpp (which is in browser/,
- * so we can't depend on it here). This code probably really wants to live
- * somewhere more central; see bug 389922.
- */
-nsresult
-nsMIMEInfoMac::OpenApplicationWithURI(nsIFile* aApplication,
- const nsCString& aURI)
-{
- nsresult rv;
- nsCOMPtr<nsILocalFileMac> lfm(do_QueryInterface(aApplication, &rv));
- NS_ENSURE_SUCCESS(rv, rv);
-
- CFURLRef appURL;
- rv = lfm->GetCFURL(&appURL);
- if (NS_FAILED(rv))
- return rv;
-
- const UInt8* uriString = (const UInt8*)aURI.get();
- CFURLRef uri = ::CFURLCreateWithBytes(NULL, uriString, aURI.Length(),
- kCFStringEncodingUTF8, NULL);
- if (!uri) {
- ::CFRelease(appURL);
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- CFArrayRef uris = ::CFArrayCreate(NULL, (const void**)&uri, 1, NULL);
- if (!uris) {
- ::CFRelease(uri);
- ::CFRelease(appURL);
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- LSLaunchURLSpec launchSpec;
- launchSpec.appURL = appURL;
- launchSpec.itemURLs = uris;
- launchSpec.passThruParams = NULL;
- launchSpec.launchFlags = kLSLaunchDefaults;
- launchSpec.asyncRefCon = NULL;
-
- OSErr err = ::LSOpenFromURLSpec(&launchSpec, NULL);
-
- ::CFRelease(uris);
- ::CFRelease(uri);
- ::CFRelease(appURL);
-
- return err != noErr ? NS_ERROR_FAILURE : NS_OK;
-}
--- a/uriloader/exthandler/mac/nsMIMEInfoMac.h
+++ b/uriloader/exthandler/mac/nsMIMEInfoMac.h
@@ -41,18 +41,16 @@
class nsMIMEInfoMac : public nsMIMEInfoImpl {
public:
nsMIMEInfoMac(const char* aMIMEType = "") : nsMIMEInfoImpl(aMIMEType) {}
nsMIMEInfoMac(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {}
nsMIMEInfoMac(const nsACString& aType, HandlerClass aClass) :
nsMIMEInfoImpl(aType, aClass) {}
- NS_IMETHOD LaunchWithURI(nsIURI* aURI,
- nsIInterfaceRequestor* aWindowContext);
NS_IMETHOD LaunchWithFile(nsIFile* aFile);
NS_IMETHOD GetHasDefaultHandler(PRBool *_retval);
protected:
virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI);
#ifdef DEBUG
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile) {
NS_NOTREACHED("do not call this method, use LaunchWithFile");
return NS_ERROR_UNEXPECTED;
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -2025,29 +2025,28 @@ nsresult nsExternalAppHandler::OpenWithA
return rv;
}
// LaunchWithApplication should only be called by the helper app dialog which allows
// the user to say launch with application or save to disk. It doesn't actually
// perform launch with application. That won't happen until we are done downloading
// the content and are sure we've showna progress dialog. This was done to simplify the
// logic that was showing up in this method.
-
NS_IMETHODIMP nsExternalAppHandler::LaunchWithApplication(nsIFile * aApplication, PRBool aRememberThisPreference)
{
if (mCanceled)
return NS_OK;
// user has chosen to launch using an application, fire any refresh tags now...
ProcessAnyRefreshTags();
mReceivedDispositionInfo = PR_TRUE;
if (mMimeInfo && aApplication) {
- nsLocalHandlerApp *handlerApp(new nsLocalHandlerApp(EmptyString(),
- aApplication));
+ PlatformLocalHandlerApp_t *handlerApp =
+ new PlatformLocalHandlerApp_t(EmptyString(), aApplication);
mMimeInfo->SetPreferredApplicationHandler(handlerApp);
}
// Now check if the file is local, in which case we won't bother with saving
// it to a temporary directory and just launch it from where it is
nsCOMPtr<nsIFileURL> fileUrl(do_QueryInterface(mSourceUrl));
if (fileUrl && mIsFileChannel)
{
--- a/uriloader/exthandler/nsLocalHandlerApp.cpp
+++ b/uriloader/exthandler/nsLocalHandlerApp.cpp
@@ -34,16 +34,18 @@
* 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 "nsLocalHandlerApp.h"
+#include "nsIURI.h"
+#include "nsIProcess.h"
// XXX why does nsMIMEInfoImpl have a threadsafe nsISupports? do we need one
// here too?
NS_IMPL_ISUPPORTS2(nsLocalHandlerApp, nsILocalHandlerApp, nsIHandlerApp)
////////////////////////////////////////////////////////////////////////////////
//// nsIHandlerApp
@@ -86,16 +88,42 @@ nsLocalHandlerApp::Equals(nsIHandlerApp
if (NS_FAILED(rv) || !executable || !mExecutable) {
*_retval = PR_FALSE;
return NS_OK;
}
return executable->Equals(mExecutable, _retval);
}
+NS_IMETHODIMP
+nsLocalHandlerApp::LaunchWithURI(nsIURI *aURI,
+ nsIInterfaceRequestor *aWindowContext)
+{
+ // pass the entire URI to the handler.
+ nsCAutoString spec;
+ aURI->GetSpec(spec);
+ return LaunchWithIProcess(spec);
+}
+
+nsresult
+nsLocalHandlerApp::LaunchWithIProcess(const nsCString& aArg)
+{
+ nsresult rv;
+ nsCOMPtr<nsIProcess> process = do_CreateInstance(NS_PROCESS_CONTRACTID, &rv);
+ if (NS_FAILED(rv))
+ return rv;
+
+ if (NS_FAILED(rv = process->Init(mExecutable)))
+ return rv;
+
+ const char *string = aArg.get();
+
+ PRUint32 pid;
+ return process->Run(PR_FALSE, &string, 1, &pid);
+}
////////////////////////////////////////////////////////////////////////////////
//// nsILocalHandlerApp
NS_IMETHODIMP nsLocalHandlerApp::GetExecutable(nsIFile **aExecutable)
{
NS_IF_ADDREF(*aExecutable = mExecutable);
return NS_OK;
--- a/uriloader/exthandler/nsLocalHandlerApp.h
+++ b/uriloader/exthandler/nsLocalHandlerApp.h
@@ -58,11 +58,33 @@ public:
nsLocalHandlerApp(const nsAString & aName, nsIFile *aExecutable)
: mName(aName), mExecutable(aExecutable) { }
virtual ~nsLocalHandlerApp() { }
protected:
nsString mName;
nsCOMPtr<nsIFile> mExecutable;
+
+ /**
+ * Launches this application with a single argument (typically either
+ * a file path or a URI spec). This is meant as a helper method for
+ * implementations of (e.g.) LaunchWithURI.
+ *
+ * @param aApp The application to launch (may not be null)
+ * @param aArg The argument to pass on the command line
+ */
+ NS_HIDDEN_(nsresult) LaunchWithIProcess(const nsCString &aArg);
+
};
+// any platforms that need a platform-specific class instead of just
+// using nsLocalHandlerApp need to add an include and a typedef here.
+#ifdef XP_MACOSX
+# ifndef NSLOCALHANDLERAPPMAC_H_
+# include "mac/nsLocalHandlerAppMac.h"
+typedef nsLocalHandlerAppMac PlatformLocalHandlerApp_t;
+# endif
+#else
+typedef nsLocalHandlerApp PlatformLocalHandlerApp_t;
+#endif
+
#endif // __nsLocalHandlerAppImpl_h__
--- a/uriloader/exthandler/nsMIMEInfoImpl.cpp
+++ b/uriloader/exthandler/nsMIMEInfoImpl.cpp
@@ -382,52 +382,31 @@ nsMIMEInfoBase::LaunchWithFile(nsIFile*
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI,
nsIInterfaceRequestor* aWindowContext)
{
- nsresult rv;
-
// for now, this is only being called with protocol handlers; that
// will change once we get to more general registerContentHandler
// support
NS_ASSERTION(mClass == eProtocolInfo,
"nsMIMEInfoBase should be a protocol handler");
if (mPreferredAction == useSystemDefault) {
return LoadUriInternal(aURI);
}
if (mPreferredAction == useHelperApp) {
if (!mPreferredApplication)
return NS_ERROR_FILE_NOT_FOUND;
- // check for and possibly launch with web application
- nsCOMPtr<nsIWebHandlerApp> webHandler =
- do_QueryInterface(mPreferredApplication, &rv);
- if (NS_SUCCEEDED(rv)) {
- return LaunchWithWebHandler(webHandler, aURI, aWindowContext);
- }
-
- // 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);
-
- // pass the entire URI to the handler.
- nsCAutoString spec;
- aURI->GetSpec(spec);
- return LaunchWithIProcess(executable, spec);
+ return mPreferredApplication->LaunchWithURI(aURI, aWindowContext);
}
return NS_ERROR_INVALID_ARG;
}
void
nsMIMEInfoBase::CopyBasicDataTo(nsMIMEInfoBase* aOther)
{
@@ -454,80 +433,16 @@ nsMIMEInfoBase::LaunchWithIProcess(nsIFi
return rv;
const char *string = aArg.get();
PRUint32 pid;
return process->Run(PR_FALSE, &string, 1, &pid);
}
-/* static */
-nsresult
-nsMIMEInfoBase::LaunchWithWebHandler(nsIWebHandlerApp *aApp, nsIURI *aURI,
- nsIInterfaceRequestor *aWindowContext)
-{
-
- nsCAutoString uriTemplate;
- nsresult rv = aApp->GetUriTemplate(uriTemplate);
- if (NS_FAILED(rv)) {
- return NS_ERROR_INVALID_ARG;
- }
-
- // get the URI spec so we can escape it for insertion into the template
- nsCAutoString uriSpecToHandle;
- rv = aURI->GetSpec(uriSpecToHandle);
- if (NS_FAILED(rv)) {
- return NS_ERROR_INVALID_ARG;
- }
-
- // XXX need to strip passwd & username from URI to handle, as per the
- // WhatWG HTML5 draft. nsSimpleURL, which is what we're going to get,
- // can't do this directly. Ideally, we'd fix nsStandardURL to make it
- // possible to turn off all of its quirks handling, and use that...
-
- // XXX this doesn't exactly match how the HTML5 draft is requesting us to
- // escape; at the very least, it should be escaping @ signs, and there
- // may well be more issues (bug 382019).
- nsCAutoString escapedUriSpecToHandle;
- NS_EscapeURL(uriSpecToHandle, esc_Minimal | esc_Forced | esc_Colon,
- escapedUriSpecToHandle);
-
- // XXX note that this replace all occurrences of %s with the URL to be
- // handled, instead of just the first, as specified by the current draft
- // of the spec. Bug 394476 filed to track this.
- uriTemplate.ReplaceSubstring(NS_LITERAL_CSTRING("%s"),
- escapedUriSpecToHandle);
-
- // convert spec to URI; no original charset needed since there's no way
- // to communicate that information to any handler
- nsCOMPtr<nsIURI> uriToSend;
- rv = NS_NewURI(getter_AddRefs(uriToSend), uriTemplate);
- if (NS_FAILED(rv))
- return rv;
-
- // create a channel
- nsCOMPtr<nsIChannel> newChannel;
- rv = NS_NewChannel(getter_AddRefs(newChannel), uriToSend, nsnull, nsnull,
- nsnull, nsIChannel::LOAD_DOCUMENT_URI);
- if (NS_FAILED(rv))
- return rv;
-
- // load the URI
- nsCOMPtr<nsIURILoader> uriLoader = do_GetService(NS_URI_LOADER_CONTRACTID,
- &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- // XXX ideally, aIsContentPreferred (the second param) should really be
- // passed in from above. Practically, PR_TRUE is probably a reasonable
- // default since browsers don't care much, and link click is likely to be
- // the more interesting case for non-browser apps. See
- // <https://bugzilla.mozilla.org/show_bug.cgi?id=392957#c9> for details.
- return uriLoader->OpenURI(newChannel, PR_TRUE, aWindowContext);
-}
-
// 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
@@ -151,34 +151,16 @@ class nsMIMEInfoBase : public nsIMIMEInf
*
* @param aApp The application to launch (may not be null)
* @param aArg The argument to pass on the command line
*/
static NS_HIDDEN_(nsresult) LaunchWithIProcess(nsIFile* aApp,
const nsCString &aArg);
/**
- * Used to launch a web-based handler with this URI.
- *
- * @param aURI The URI to launch with.
- *
- * @param aWindowContext
- * The window to parent the dialog against, and, if a web handler
- * is chosen, it is loaded in this window as well. This parameter
- * may be ultimately passed nsIURILoader.openURI in the case of a
- * web handler, and aWindowContext is null or not present, web
- * handlers will fail. We need to do better than that; bug 394483
- * filed in order to track.
- *
- */
- static NS_HIDDEN_(nsresult)
- LaunchWithWebHandler(nsIWebHandlerApp *aApp, nsIURI *aURI,
- nsIInterfaceRequestor *aWindowContext);
-
- /**
* 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);
--- a/uriloader/exthandler/nsWebHandlerApp.js
+++ b/uriloader/exthandler/nsWebHandlerApp.js
@@ -16,16 +16,17 @@
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Shawn Wilsher <me@shawnwilsher.com>
* Myk Melez <myk@mozilla.org>
+ * 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
@@ -79,16 +80,48 @@ nsWebHandlerApp.prototype = {
aHandlerApp.uriTemplate &&
this.uriTemplate &&
aHandlerApp.uriTemplate == this.uriTemplate)
return true;
return false;
},
+ launchWithURI: function nWHA__launchWithURI(aURI, aWindowContext) {
+
+ // XXX need to strip passwd & username from URI to handle, as per the
+ // WhatWG HTML5 draft. nsSimpleURL, which is what we're going to get,
+ // can't do this directly. Ideally, we'd fix nsStandardURL to make it
+ // possible to turn off all of its quirks handling, and use that...
+
+ // encode the URI to be handled
+ var escapedUriSpecToHandle = encodeURIComponent(aURI.spec);
+
+ // insert the encoded URI
+ var uriToSend = this.uriTemplate.replace("%s", escapedUriSpecToHandle);
+
+ // create a channel from this URI
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"].
+ getService(Components.interfaces.nsIIOService);
+ var channel = ioService.newChannel(uriToSend, null, null);
+ channel.loadFlags = Components.interfaces.nsIChannel.LOAD_DOCUMENT_URI;
+
+ // load the channel
+ var uriLoader = Components.classes["@mozilla.org/uriloader;1"].
+ getService(Components.interfaces.nsIURILoader);
+ // XXX ideally, aIsContentPreferred (the second param) should really be
+ // passed in from above. Practically, true is probably a reasonable
+ // default since browsers don't care much, and link click is likely to be
+ // the more interesting case for non-browser apps. See
+ // <https://bugzilla.mozilla.org/show_bug.cgi?id=392957#c9> for details.
+ uriLoader.openURI(channel, true, aWindowContext);
+
+ return;
+ },
+
//////////////////////////////////////////////////////////////////////////////
//// nsIWebHandlerApp
get uriTemplate() {
return this._uriTemplate;
},
set uriTemplate(aURITemplate) {
--- a/uriloader/exthandler/tests/Makefile.in
+++ b/uriloader/exthandler/tests/Makefile.in
@@ -15,16 +15,17 @@
# The Original Code is the Mozilla browser.
#
# The Initial Developer of the Original Code is Mozilla.
# Portions created by the Initial Developer are Copyright (C) 2007
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Myk Melez <myk@mozilla.org>
+# 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
@@ -35,15 +36,18 @@
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
+DIRS += mochitest \
+ $(NULL)
+
include $(DEPTH)/config/autoconf.mk
MODULE = test_uriloader_exthandler
XPCSHELL_TESTS = unit
include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/tests/mochitest/Makefile.in
@@ -0,0 +1,54 @@
+# ***** 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
+# Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# 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
+# 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 *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+relativesrcdir = uriloader/exthandler/tests/mochitest
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES = \
+ test_handlerApps.xhtml \
+ handlerApps.js \
+ handlerApp.xhtml \
+ $(NULL)
+
+libs:: $(_TEST_FILES)
+ $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/tests/mochitest/handlerApp.xhtml
@@ -0,0 +1,27 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Pseudo Web Handler App</title>
+ <script type="text/javascript" src="/MochiKit/packed.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="onLoad()">
+Pseudo Web Handler App
+
+<script class="testbody" type="text/javascript">
+<![CDATA[
+function onLoad() {
+
+ var originalUriToHandle = encodeURIComponent(window.opener.testURI);
+
+ window.opener.is(location.search, "?uri=" + originalUriToHandle,
+ "uri passed to web-handler app");
+ window.opener.SimpleTest.finish()
+ window.close();
+}
+]]>
+</script>
+
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/tests/mochitest/handlerApps.js
@@ -0,0 +1,128 @@
+/* ***** 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 code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 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
+ * 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 ***** */
+
+// handlerApp.xhtml grabs this for verification purposes via window.opener
+var testURI = "webcal://127.0.0.1/rheeeeet.html";
+
+function test() {
+
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+
+ // set up the web handler object
+ var webHandler =
+ Components.classes["@mozilla.org/uriloader/web-handler-app;1"].
+ createInstance(Components.interfaces.nsIWebHandlerApp);
+ webHandler.name = "Test Web Handler App";
+ webHandler.uriTemplate =
+ "http://localhost:8888/tests/uriloader/exthandler/tests/mochitest/" +
+ "handlerApp.xhtml?uri=%s";
+
+ // set up the uri to test with
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"].
+ getService(Components.interfaces.nsIIOService);
+ var uri = ioService.newURI(testURI, null, null);
+
+ // create a window, and launch the handler in it
+ var newWindow = window.open("", "handlerWindow", "height=300,width=300");
+ var windowContext =
+ newWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ getInterface(Components.interfaces.nsIWebNavigation).
+ QueryInterface(Components.interfaces.nsIDocShell);
+
+ webHandler.launchWithURI(uri, windowContext);
+
+ // if we get this far without an exception, we've passed
+ ok(true, "webHandler launchWithURI test");
+
+
+ // set up the local handler object
+ var localHandler =
+ Components.classes["@mozilla.org/uriloader/local-handler-app;1"].
+ createInstance(Components.interfaces.nsILocalHandlerApp);
+ localHandler.name = "Test Local Handler App";
+
+ // get a local app that we know will be there and do something sane
+ var osString = Components.classes["@mozilla.org/xre/app-info;1"].
+ getService(Components.interfaces.nsIXULRuntime).OS;
+
+ var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].
+ getService(Components.interfaces.nsIDirectoryServiceProvider);
+ if (osString == "WINNT") {
+ var windowsDir = dirSvc.getFile("WinD", {});
+ var exe = windowsDir.clone();
+ exe.appendRelativePath("SYSTEM32\\HOSTNAME.EXE");
+
+ } else if (osString == "Darwin") {
+ var localAppsDir = dirSvc.getFile("LocApp", {});
+ exe = localAppsDir.clone();
+ exe.append("iCal.app"); // lingers after the tests finish, but this seems
+ // seems better than explicitly killing it, since
+ // developers who run the tests locally may well
+ // information in their running copy of iCal
+ } else {
+ // assume a generic UNIX variant
+ exe = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(Components.interfaces.nsILocalFile);
+ exe.initWithPath("/bin/test");
+ }
+
+ localHandler.executable = exe;
+ localHandler.launchWithURI(ioService.newURI(testURI, null, null));
+
+ // if we get this far without an exception, we've passed
+ ok(true, "localHandler launchWithURI test");
+
+ // if we ever decide that killing iCal is the right thing to do, change
+ // the if statement below from "NOTDarwin" to "Darwin"
+ if (osString == "NOTDarwin") {
+
+ var killall = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(Components.interfaces.nsILocalFile);
+ killall.initWithPath("/usr/bin/killall");
+
+ var process = Components.classes["@mozilla.org/process/util;1"].
+ createInstance(Components.interfaces.nsIProcess);
+ process.init(killall);
+
+ var args = ['iCal'];
+ process.run(false, args, args.length);
+ }
+
+ SimpleTest.waitForExplicitFinish();
+}
+
+test();
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/tests/mochitest/test_handlerApps.xhtml
@@ -0,0 +1,13 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Test for Handler Apps </title>
+ <script type="text/javascript" src="/MochiKit/packed.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="handlerApps.js"/>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+</body>
+</html>
+