334747, 339893 - desktop application feed readers do not display their app name properly or launch with the specified feed on OSX due to lack of support for a function to get the application bundle name, and a method to invoke an application bundle on OS X with a URL. Add an attribute to nsILocalFileMac called bundleDisplayName to show the application's name, and a method to nsIShellService called openApplicationWithURL which launches an application with a URL parameter appropriately across platforms (nsIProcess on windows and linux, LaunchServices on OS X). Update the client code to use bundleDisplayName, and also the <filefield> binding in preferences to use it too. r=mark sr=darin

This commit is contained in:
beng%bengoodger.com 2006-06-27 22:38:55 +00:00
Родитель 10a0c2ec34
Коммит 65ef342f8e
9 изменённых файлов: 176 добавлений и 29 удалений

Просмотреть файл

@ -301,7 +301,7 @@ var FeedResultService = {
/**
* See nsIFeedService.idl
*/
addToClientReader: function FRS_addToClientReader(uri) {
addToClientReader: function FRS_addToClientReader(spec) {
var prefs =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
@ -315,11 +315,31 @@ var FeedResultService = {
catch (e) {
return;
}
var process =
Cc["@mozilla.org/process/util;1"].
createInstance(Ci.nsIProcess);
process.init(clientApp);
process.run(false, [uri], 1);
#ifdef XP_MACOSX
// On OS X, the built in feed dispatcher (Safari) sends feeds to other
// applications (When Default Reader is adjusted) in the following format:
//
// http urls: replace scheme with feed, e.g.
// http://foo.com/index.rdf -> feed://foo.com/index.rdf
// other urils: prepend feed: scheme, e.g.
// https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
//
// We duplicate this here for compatibility.
var ios =
Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var macURI = ios.newURI(spec, null, null);
if (macURI.schemeIs("http")) {
macURI.scheme = "feed";
spec = macURI.spec;
}
else
spec = "feed:" + spec;
#endif
var ss =
Cc["@mozilla.org/browser/shell-service;1"].
getService(Ci.nsIShellService);
ss.openApplicationWithURI(clientApp, spec);
break;
case "bookmarks":
var wm =
@ -327,9 +347,9 @@ var FeedResultService = {
getService(Ci.nsIWindowMediator);
var topWindow = wm.getMostRecentWindow("navigator:browser");
#ifdef MOZ_PLACES
topWindow.PlacesCommandHook.addLiveBookmark(uri);
topWindow.PlacesCommandHook.addLiveBookmark(spec);
#else
topWindow.FeedHandler.addLiveBookmark(uri);
topWindow.FeedHandler.addLiveBookmark(spec);
#endif
break;
}

Просмотреть файл

@ -278,8 +278,7 @@ FeedWriter.prototype = {
#ifdef XP_MACOSX
var lfm = file.QueryInterface(Components.interfaces.nsILocalFileMac);
try {
if (lfm.isPackage())
return lfm.bundleName;
return lfm.bundleDisplayName;
}
catch (e) {
// fall through to the file name

Просмотреть файл

@ -38,8 +38,9 @@
#include "nsISupports.idl"
interface nsIDOMElement;
interface nsILocalFile;
[scriptable, uuid(d6f62053-3769-46f6-bd2b-0a1440d6c394)]
[scriptable, uuid(FD63944D-F851-4116-A372-962E4D030B2D)]
interface nsIShellService : nsISupports
{
/**
@ -112,5 +113,14 @@ interface nsIShellService : nsISupports
* entire screen. A rgb value, where (r << 16 | g << 8 | b)
*/
attribute unsigned long desktopBackgroundColor;
/**
* Opens an application with a specific URI to load.
* @param application
* The application file (or bundle directory, on OS X)
* @param uri
* The uri to be loaded by the application
*/
void openApplicationWithURI(in nsILocalFile aApplication, in ACString aURI);
};

Просмотреть файл

@ -49,6 +49,7 @@
#include "nsIStringBundle.h"
#include "gfxIImageFrame.h"
#include "nsIOutputStream.h"
#include "nsIProcess.h"
#include "nsNetUtil.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIImageLoadingContent.h"
@ -541,3 +542,22 @@ nsGNOMEShellService::OpenApplication(PRInt32 aApplication)
return err ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsGNOMEShellService::OpenApplicationWithURI(nsILocalFile* aApplication, const nsACString& aURI)
{
nsresult rv;
nsCOMPtr<nsIProcess> process =
do_CreateInstance("@mozilla.org/process/util;1", &rv);
if (NS_FAILED(rv))
return rv;
rv = process->Init(aApplication);
if (NS_FAILED(rv))
return rv;
const nsPromiseFlatCString& spec = PromiseFlatCString(aURI);
const char* specStr = spec.get();
PRUint32 pid;
return process->Run(PR_FALSE, &specStr, 1, &pid);
}

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsIImageLoadingContent.h"
#include "nsIDocument.h"
#include "nsIContent.h"
#include "nsILocalFileMac.h"
#include "nsIObserverService.h"
#include "nsIPrefService.h"
#include "nsIServiceManager.h"
@ -457,3 +458,41 @@ nsMacShellService::SetDesktopBackgroundColor(PRUint32 aColor)
// supports.
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMacShellService::OpenApplicationWithURI(nsILocalFile* aApplication, const nsACString& aURI)
{
nsCOMPtr<nsILocalFileMac> lfm(do_QueryInterface(aApplication));
CFURLRef appURL;
nsresult rv = lfm->GetCFURL(&appURL);
if (NS_FAILED(rv))
return rv;
const nsPromiseFlatCString& spec = PromiseFlatCString(aURI);
const UInt8* uriString = (const UInt8*)spec.get();
CFURLRef uri = ::CFURLCreateWithBytes(NULL, uriString, aURI.Length(),
kCFStringEncodingUTF8, NULL);
if (!uri)
return NS_ERROR_OUT_OF_MEMORY;
CFArrayRef uris = ::CFArrayCreate(NULL, (const void**)&uri, 1, NULL);
if (!uris) {
::CFRelease(uri);
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);
return err != noErr ? NS_ERROR_FAILURE : NS_OK;
}

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsShellService.h"
#include "nsWindowsShellService.h"
#include "nsIObserverService.h"
#include "nsIProcess.h"
#include "nsICategoryManager.h"
#include "nsBrowserCompsCID.h"
#include "nsNativeCharsetUtils.h"
@ -1079,3 +1080,22 @@ nsWindowsShellService::Observe(nsISupports* aObject, const char* aTopic, const P
return NS_OK;
}
NS_IMETHODIMP
nsWindowsShellService::OpenApplicationWithURI(nsILocalFile* aApplication, const ACString& aURI)
{
nsresult rv;
nsCOMPtr<nsIProcess> process =
do_CreateInstance("@mozilla.org/process/util;1", &rv);
if (NS_FAILED(rv))
return rv;
rv = process->Init(aApplication);
if (NS_FAILED(rv))
return rv;
const nsPromiseFlatCString& spec = PromiseFlatCString(aURI);
const char* specStr = spec.get();
PRUint32 pid;
return process->Run(PR_FALSE, &specStr, 1, &pid);
}

Просмотреть файл

@ -58,7 +58,15 @@
// fall through to the filename
}
#endif
// XXXben - Read the bundle name on OS X.
#ifdef XP_MACOSX
var lfm = aFile.QueryInterface(Components.interfaces.nsILocalFileMac);
try {
return lfm.bundleDisplayName;
}
catch (e) {
// fall through to the file name
}
#endif
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var url = ios.newFileURI(aFile).QueryInterface(Components.interfaces.nsIURL);

Просмотреть файл

@ -51,7 +51,7 @@
[ptr] native FSRefPtr(FSRef);
native CFURLRef(CFURLRef);
[uuid(614c3010-1dd2-11b2-be04-bcd57a64ffc9)]
[scriptable, uuid(FC93A109-7BF2-4CEF-B283-2E973E5DCF7E)]
interface nsILocalFileMac : nsILocalFile
{
/**
@ -65,7 +65,7 @@ interface nsILocalFileMac : nsILocalFile
* @param aCFURL the CoreFoundation URL
*
*/
void initWithCFURL(in CFURLRef aCFURL);
[noscript] void initWithCFURL(in CFURLRef aCFURL);
/**
* initWithFSRef
@ -77,7 +77,7 @@ interface nsILocalFileMac : nsILocalFile
* @param aFSRef the native file spec
*
*/
void initWithFSRef([const] in FSRefPtr aFSRef);
[noscript] void initWithFSRef([const] in FSRefPtr aFSRef);
/**
* initWithFSSpec
@ -88,7 +88,7 @@ interface nsILocalFileMac : nsILocalFile
* @param aFileSpec the native file spec
*
*/
void initWithFSSpec([const] in FSSpecPtr aFileSpec);
[noscript] void initWithFSSpec([const] in FSSpecPtr aFileSpec);
/**
* initToAppWithCreatorCode
@ -100,7 +100,7 @@ interface nsILocalFileMac : nsILocalFile
* @param aAppCreator the signature of the app
*
*/
void initToAppWithCreatorCode(in OSType aAppCreator);
[noscript] void initToAppWithCreatorCode(in OSType aAppCreator);
/**
* getCFURL
@ -118,7 +118,7 @@ interface nsILocalFileMac : nsILocalFile
* @return
*
*/
CFURLRef getCFURL();
[noscript] CFURLRef getCFURL();
/**
* getFSRef
@ -135,7 +135,7 @@ interface nsILocalFileMac : nsILocalFile
* @return
*
*/
FSRef getFSRef();
[noscript] FSRef getFSRef();
/**
* getFSSpec
@ -150,7 +150,7 @@ interface nsILocalFileMac : nsILocalFile
* @return
*
*/
FSSpec getFSSpec();
[noscript] FSSpec getFSSpec();
/**
* fileSizeWithResFork
@ -160,12 +160,12 @@ interface nsILocalFileMac : nsILocalFile
* as returned by GetFileSize()
*
*/
readonly attribute PRInt64 fileSizeWithResFork;
readonly attribute PRInt64 fileSizeWithResFork;
/**
* Use with SetFileType() to specify the signature of current process
*/
const unsigned long CURRENT_PROCESS_CREATOR = 0x8000000;
const unsigned long CURRENT_PROCESS_CREATOR = 0x8000000;
/**
* fileType, creator
@ -173,8 +173,8 @@ interface nsILocalFileMac : nsILocalFile
* File type and creator attributes
*
*/
attribute OSType fileType;
attribute OSType fileCreator;
[noscript] attribute OSType fileType;
[noscript] attribute OSType fileCreator;
/**
* setFileTypeAndCreatorFromMIMEType
@ -185,7 +185,7 @@ interface nsILocalFileMac : nsILocalFile
* @param aMIMEType
*
*/
void setFileTypeAndCreatorFromMIMEType(in string aMIMEType);
void setFileTypeAndCreatorFromMIMEType(in string aMIMEType);
/**
* setFileTypeAndCreatorFromExtension
@ -196,7 +196,7 @@ interface nsILocalFileMac : nsILocalFile
* @param aExtension
*
*/
void setFileTypeAndCreatorFromExtension(in string aExtension);
void setFileTypeAndCreatorFromExtension(in string aExtension);
/**
* launchWithDoc
@ -207,7 +207,7 @@ interface nsILocalFileMac : nsILocalFile
* @param aLaunchInBackground TRUE if the application should not come to the front.
*
*/
void launchWithDoc(in nsILocalFile aDocToLoad, in boolean aLaunchInBackground);
void launchWithDoc(in nsILocalFile aDocToLoad, in boolean aLaunchInBackground);
/**
* openDocWithApp
@ -220,7 +220,7 @@ interface nsILocalFileMac : nsILocalFile
* @param aLaunchInBackground TRUE if the application should not come to the front.
*
*/
void openDocWithApp(in nsILocalFile aAppToOpenWith, in boolean aLaunchInBackground);
void openDocWithApp(in nsILocalFile aAppToOpenWith, in boolean aLaunchInBackground);
/**
* isPackage
@ -228,7 +228,15 @@ interface nsILocalFileMac : nsILocalFile
* returns true if a directory is determined to be a package under Mac OS 9/X
*
*/
boolean isPackage();
boolean isPackage();
/**
* bundleDisplayName
*
* returns the display name of the application bundle (usually the human
* readable name of the application)
*/
readonly attribute AString bundleDisplayName;
};
%{C++

Просмотреть файл

@ -1827,6 +1827,29 @@ NS_IMETHODIMP nsLocalFile::IsPackage(PRBool *_retval)
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::GetBundleDisplayName(nsAString& outBundleName)
{
PRBool isPackage = PR_FALSE;
nsresult rv = IsPackage(&isPackage);
if (NS_FAILED(rv) || !isPackage)
return NS_ERROR_FAILURE;
nsAutoString name;
rv = GetLeafName(name);
if (NS_FAILED(rv))
return rv;
PRInt32 length = name.Length();
if (Substring(name, length - 4, length).EqualsLiteral(".app")) {
// 4 characters in ".app"
outBundleName = Substring(name, 0, length - 4);
}
else
outBundleName = name;
return NS_OK;
}
//*****************************************************************************
// nsLocalFile Methods