diff --git a/docshell/build/nsDocShellModule.cpp b/docshell/build/nsDocShellModule.cpp index fb4acaed0324..0ac5bd5665a9 100644 --- a/docshell/build/nsDocShellModule.cpp +++ b/docshell/build/nsDocShellModule.cpp @@ -108,7 +108,7 @@ 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" @@ -218,7 +218,8 @@ static const nsModuleComponentInfo gDocShellModuleInfo[] = { { 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, }, diff --git a/netwerk/mime/public/nsIMIMEInfo.idl b/netwerk/mime/public/nsIMIMEInfo.idl index f31b6e5a1ea2..f4d94d7e29b8 100644 --- a/netwerk/mime/public/nsIMIMEInfo.idl +++ b/netwerk/mime/public/nsIMIMEInfo.idl @@ -52,7 +52,7 @@ 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. @@ -239,7 +239,7 @@ interface nsIMIMEInfo : nsIHandlerInfo { * 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 { /** @@ -259,6 +259,21 @@ interface nsIHandlerApp : nsISupports { * @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); + }; /** diff --git a/toolkit/toolkit-makefiles.sh b/toolkit/toolkit-makefiles.sh index 2f4df1d2e3ab..10404c80ad1e 100644 --- a/toolkit/toolkit-makefiles.sh +++ b/toolkit/toolkit-makefiles.sh @@ -367,6 +367,7 @@ MAKEFILES_uriloader=" uriloader/base/Makefile uriloader/exthandler/Makefile uriloader/exthandler/tests/Makefile + uriloader/exthandler/tests/browser/Makefile " MAKEFILES_profile=" diff --git a/uriloader/exthandler/Makefile.in b/uriloader/exthandler/Makefile.in index c3c56afd06b3..5b12b4debcbc 100644 --- a/uriloader/exthandler/Makefile.in +++ b/uriloader/exthandler/Makefile.in @@ -103,6 +103,7 @@ ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT))) OSHELPER += nsInternetConfig.cpp \ nsInternetConfigService.cpp \ nsMIMEInfoMac.cpp \ + nsLocalHandlerAppMac.cpp \ $(NULL) endif diff --git a/uriloader/exthandler/mac/nsLocalHandlerAppMac.cpp b/uriloader/exthandler/mac/nsLocalHandlerAppMac.cpp new file mode 100644 index 000000000000..83febe2d2c1c --- /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 + * + * 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 + +#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 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(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(&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; +} diff --git a/uriloader/exthandler/mac/nsLocalHandlerAppMac.h b/uriloader/exthandler/mac/nsLocalHandlerAppMac.h new file mode 100644 index 000000000000..50a907a87402 --- /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 + * + * 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_*/ diff --git a/uriloader/exthandler/mac/nsMIMEInfoMac.cpp b/uriloader/exthandler/mac/nsMIMEInfoMac.cpp index b6e5ad033170..18782f167403 100755 --- a/uriloader/exthandler/mac/nsMIMEInfoMac.cpp +++ b/uriloader/exthandler/mac/nsMIMEInfoMac.cpp @@ -99,49 +99,6 @@ nsMIMEInfoMac::LaunchWithFile(nsIFile *aFile) return app->LaunchWithDoc(localFile, PR_FALSE); } -NS_IMETHODIMP -nsMIMEInfoMac::LaunchWithURI(nsIURI* aURI, - nsIInterfaceRequestor* aWindowContext) -{ - nsCOMPtr 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 webHandlerApp = - do_QueryInterface(mPreferredApplication, &rv); - if (NS_SUCCEEDED(rv)) { - return LaunchWithWebHandler(webHandlerApp, aURI, aWindowContext); - } - - // otherwise, get the application executable from the handler - nsCOMPtr 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) { @@ -167,51 +124,3 @@ nsMIMEInfoMac::GetHasDefaultHandler(PRBool *_retval) 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 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; -} diff --git a/uriloader/exthandler/mac/nsMIMEInfoMac.h b/uriloader/exthandler/mac/nsMIMEInfoMac.h index bc302ef14689..08960eddcb17 100755 --- a/uriloader/exthandler/mac/nsMIMEInfoMac.h +++ b/uriloader/exthandler/mac/nsMIMEInfoMac.h @@ -46,8 +46,6 @@ class nsMIMEInfoMac : public nsMIMEInfoImpl { 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: diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index c23f93154839..57c498dee573 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -2030,7 +2030,6 @@ nsresult nsExternalAppHandler::OpenWithApplication() // 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) @@ -2041,8 +2040,8 @@ NS_IMETHODIMP nsExternalAppHandler::LaunchWithApplication(nsIFile * aApplication mReceivedDispositionInfo = PR_TRUE; if (mMimeInfo && aApplication) { - nsLocalHandlerApp *handlerApp(new nsLocalHandlerApp(EmptyString(), - aApplication)); + PlatformLocalHandlerApp_t *handlerApp = + new PlatformLocalHandlerApp_t(EmptyString(), aApplication); mMimeInfo->SetPreferredApplicationHandler(handlerApp); } diff --git a/uriloader/exthandler/nsLocalHandlerApp.cpp b/uriloader/exthandler/nsLocalHandlerApp.cpp index 8c303cad4e46..ae66332e58ad 100644 --- a/uriloader/exthandler/nsLocalHandlerApp.cpp +++ b/uriloader/exthandler/nsLocalHandlerApp.cpp @@ -39,6 +39,8 @@ * ***** 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? @@ -91,6 +93,32 @@ nsLocalHandlerApp::Equals(nsIHandlerApp *aHandlerApp, PRBool *_retval) 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 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 diff --git a/uriloader/exthandler/nsLocalHandlerApp.h b/uriloader/exthandler/nsLocalHandlerApp.h index 3318dcc4a055..03935c9569de 100644 --- a/uriloader/exthandler/nsLocalHandlerApp.h +++ b/uriloader/exthandler/nsLocalHandlerApp.h @@ -63,6 +63,28 @@ public: protected: nsString mName; nsCOMPtr 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__ diff --git a/uriloader/exthandler/nsMIMEInfoImpl.cpp b/uriloader/exthandler/nsMIMEInfoImpl.cpp index 63f650edfbc1..963dd3582939 100644 --- a/uriloader/exthandler/nsMIMEInfoImpl.cpp +++ b/uriloader/exthandler/nsMIMEInfoImpl.cpp @@ -387,8 +387,6 @@ 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 @@ -403,26 +401,7 @@ nsMIMEInfoBase::LaunchWithURI(nsIURI* aURI, if (!mPreferredApplication) return NS_ERROR_FILE_NOT_FOUND; - // check for and possibly launch with web application - nsCOMPtr webHandler = - do_QueryInterface(mPreferredApplication, &rv); - if (NS_SUCCEEDED(rv)) { - return LaunchWithWebHandler(webHandler, aURI, aWindowContext); - } - - // ok, we must have a local handler app - nsCOMPtr localHandler = - do_QueryInterface(mPreferredApplication, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr 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; @@ -459,70 +438,6 @@ nsMIMEInfoBase::LaunchWithIProcess(nsIFile* aApp, const nsCString& aArg) 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 uriToSend; - rv = NS_NewURI(getter_AddRefs(uriToSend), uriTemplate); - if (NS_FAILED(rv)) - return rv; - - // create a channel - nsCOMPtr 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 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 - // for details. - return uriLoader->OpenURI(newChannel, PR_TRUE, aWindowContext); -} - // nsMIMEInfoImpl implementation NS_IMETHODIMP nsMIMEInfoImpl::GetDefaultDescription(nsAString& aDefaultDescription) diff --git a/uriloader/exthandler/nsMIMEInfoImpl.h b/uriloader/exthandler/nsMIMEInfoImpl.h index ba322497fa8b..17ca162f972f 100644 --- a/uriloader/exthandler/nsMIMEInfoImpl.h +++ b/uriloader/exthandler/nsMIMEInfoImpl.h @@ -155,24 +155,6 @@ class nsMIMEInfoBase : public nsIMIMEInfo { 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 * diff --git a/uriloader/exthandler/nsWebHandlerApp.js b/uriloader/exthandler/nsWebHandlerApp.js index 05ff52b921d2..74d32c710efd 100644 --- a/uriloader/exthandler/nsWebHandlerApp.js +++ b/uriloader/exthandler/nsWebHandlerApp.js @@ -21,6 +21,7 @@ * Contributor(s): * Shawn Wilsher * Myk Melez + * Dan Mosedale * * 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 @@ -84,6 +85,38 @@ nsWebHandlerApp.prototype = { 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 + // for details. + uriLoader.openURI(channel, true, aWindowContext); + + return; + }, + ////////////////////////////////////////////////////////////////////////////// //// nsIWebHandlerApp diff --git a/uriloader/exthandler/tests/Makefile.in b/uriloader/exthandler/tests/Makefile.in index b755a66781a4..6de4e93f52b2 100755 --- a/uriloader/exthandler/tests/Makefile.in +++ b/uriloader/exthandler/tests/Makefile.in @@ -20,6 +20,7 @@ # # Contributor(s): # Myk Melez +# Dan Mosedale # # 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"), @@ -40,6 +41,9 @@ topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ +DIRS += mochitest \ + $(NULL) + include $(DEPTH)/config/autoconf.mk MODULE = test_uriloader_exthandler diff --git a/uriloader/exthandler/tests/mochitest/Makefile.in b/uriloader/exthandler/tests/mochitest/Makefile.in new file mode 100644 index 000000000000..15615b9e5fe0 --- /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 +# +# 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) diff --git a/uriloader/exthandler/tests/mochitest/handlerApp.xhtml b/uriloader/exthandler/tests/mochitest/handlerApp.xhtml new file mode 100644 index 000000000000..c6537a3fd4be --- /dev/null +++ b/uriloader/exthandler/tests/mochitest/handlerApp.xhtml @@ -0,0 +1,27 @@ + + + Pseudo Web Handler App + + + + + +Pseudo Web Handler App + + + + + + diff --git a/uriloader/exthandler/tests/mochitest/handlerApps.js b/uriloader/exthandler/tests/mochitest/handlerApps.js new file mode 100644 index 000000000000..13dfa8ebd89f --- /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 + * + * 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(); diff --git a/uriloader/exthandler/tests/mochitest/test_handlerApps.xhtml b/uriloader/exthandler/tests/mochitest/test_handlerApps.xhtml new file mode 100644 index 000000000000..e3c288a8e506 --- /dev/null +++ b/uriloader/exthandler/tests/mochitest/test_handlerApps.xhtml @@ -0,0 +1,13 @@ + + + Test for Handler Apps + + +