--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -114,16 +114,21 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPr
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsOfflineCacheUpdateService,
nsOfflineCacheUpdateService::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsOfflineCacheUpdate)
NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t)
#ifdef MOZ_ENABLE_DBUS
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp)
#endif
+#if defined(XP_MAC) || defined(XP_MACOSX)
+#include "nsInternetConfigService.h"
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsInternetConfigService)
+#endif
+
// session history
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHEntry)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHTransaction)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHistory)
// download history
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadHistory)
@@ -224,16 +229,20 @@ static const nsModuleComponentInfo gDocS
{ NS_OFFLINECACHEUPDATE_CLASSNAME, NS_OFFLINECACHEUPDATE_CID, NS_OFFLINECACHEUPDATE_CONTRACTID,
nsOfflineCacheUpdateConstructor, },
{ "Local Application Handler App", NS_LOCALHANDLERAPP_CID,
NS_LOCALHANDLERAPP_CONTRACTID, PlatformLocalHandlerApp_tConstructor, },
#ifdef MOZ_ENABLE_DBUS
{ "DBus Handler App", NS_DBUSHANDLERAPP_CID,
NS_DBUSHANDLERAPP_CONTRACTID, nsDBusHandlerAppConstructor},
#endif
+#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 },
{ "nsSHEntry", NS_HISTORYENTRY_CID,
NS_HISTORYENTRY_CONTRACTID, nsSHEntryConstructor },
{ "nsSHTransaction", NS_SHTRANSACTION_CID,
NS_SHTRANSACTION_CONTRACTID, nsSHTransactionConstructor },
--- a/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
+++ b/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -264,17 +264,35 @@ nsresult nsIconChannel::MakeInputStream(
CFURLRef macURL;
if (NS_SUCCEEDED(localFileMac->GetCFURL(&macURL))) {
iconImage = [[NSWorkspace sharedWorkspace] iconForFile:[(NSURL*)macURL path]];
::CFRelease(macURL);
}
}
- // if we don't have an icon yet try to get one by extension
+ // try by HFS type if we don't have an icon yet
+ if (!iconImage) {
+ nsCOMPtr<nsIMIMEService> mimeService (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // if we were given an explicit content type, use it....
+ nsCOMPtr<nsIMIMEInfo> mimeInfo;
+ if (mimeService && (!contentType.IsEmpty() || !fileExt.IsEmpty()))
+ mimeService->GetFromTypeAndExtension(contentType, fileExt, getter_AddRefs(mimeInfo));
+
+ if (mimeInfo) {
+ // get the icon by HFS type
+ PRUint32 macType;
+ if (NS_SUCCEEDED(mimeInfo->GetMacType(&macType)))
+ iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(macType)];
+ }
+ }
+
+ // if we still don't have an icon, try to get one by extension
if (!iconImage && !fileExt.IsEmpty()) {
NSString* fileExtension = [NSString stringWithUTF8String:PromiseFlatCString(fileExt).get()];
iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:fileExtension];
}
if (!iconImage)
return NS_ERROR_FAILURE;
--- a/netwerk/mime/public/nsIMIMEInfo.idl
+++ b/netwerk/mime/public/nsIMIMEInfo.idl
@@ -48,17 +48,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(8E726396-3E02-467C-855E-5900E562BA42)]
+[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;
@@ -198,16 +198,22 @@ interface nsIMIMEInfo : nsIHandlerInfo {
*
* @return String representing the MIME type.
*
* @deprecated use nsIHandlerInfo::type instead.
*/
readonly attribute ACString MIMEType;
/**
+ * Mac Type and creator types
+ */
+ attribute PRUint32 macType;
+ attribute PRUint32 macCreator;
+
+ /**
* Returns whether or not these two nsIMIMEInfos are logically
* equivalent.
*
* @returns PR_TRUE if the two are considered equal
*/
boolean equals(in nsIMIMEInfo aMIMEInfo);
/**
--- a/uriloader/exthandler/Makefile.in
+++ b/uriloader/exthandler/Makefile.in
@@ -92,16 +92,18 @@ ifdef MOZ_PHOENIX
REQUIRES += toolkitcomps
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
REQUIRES += windowwatcher \
$(NULL)
CMMSRCS = nsOSHelperAppService.mm \
+ nsInternetConfig.mm \
+ nsInternetConfigService.mm \
nsMIMEInfoMac.mm \
nsLocalHandlerAppMac.mm \
$(NULL)
else
OSHELPER = nsOSHelperAppService.cpp
endif
LOCAL_INCLUDES = -I$(srcdir)
@@ -138,16 +140,20 @@ XPIDLSRCS = \
nsCExternalHandlerService.idl \
nsIExternalProtocolService.idl \
nsIExternalHelperAppService.idl \
nsIHelperAppLauncherDialog.idl \
nsIContentDispatchChooser.idl \
nsIHandlerService.idl \
$(NULL)
+ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
+XPIDLSRCS += nsIInternetConfigService.idl
+endif
+
CPPSRCS = \
nsExternalHelperAppService.cpp \
nsExternalProtocolHandler.cpp \
nsMIMEInfoImpl.cpp \
nsLocalHandlerApp.cpp \
$(OSHELPER) \
$(NULL)
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsInternetConfig.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+#ifndef __NS_INTERNETCONFIG_H__
+#define __NS_INTERNETCONFIG_H__
+
+#include <Carbon/Carbon.h>
+#include "prtypes.h"
+#include "nsError.h"
+
+class nsInternetConfig
+{
+public:
+ nsInternetConfig();
+ ~nsInternetConfig();
+
+ static ICInstance GetInstance();
+ static PRBool HasSeedChanged();
+private:
+ static ICInstance sInstance;
+ static long sSeed;
+ static PRInt32 sRefCount;
+};
+
+#endif /* __NS_INTERNETCONFIG_H__ */
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsInternetConfig.mm
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+#include "nsInternetConfig.h"
+#include "nsObjCExceptions.h"
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include "nsDebug.h"
+
+#include <Carbon/Carbon.h>
+
+ICInstance nsInternetConfig::sInstance = NULL;
+long nsInternetConfig::sSeed = 0;
+PRInt32 nsInternetConfig::sRefCount = 0;
+
+
+
+static OSType GetAppCreatorCode()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+ ProcessSerialNumber psn = { 0, kCurrentProcess } ;
+ ProcessInfoRec procInfo;
+
+ procInfo.processInfoLength = sizeof(ProcessInfoRec);
+ procInfo.processName = NULL;
+#ifndef __LP64__
+ procInfo.processAppSpec = NULL;
+#else
+ procInfo.processAppRef = NULL;
+#endif
+
+ GetProcessInformation(&psn, &procInfo);
+ return procInfo.processSignature;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0x0);
+}
+
+
+
+ICInstance nsInternetConfig::GetInstance()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+ if ( !sInstance )
+ {
+ OSType creator = GetAppCreatorCode();
+ OSStatus err = ::ICStart( &sInstance, creator );
+ if ( err != noErr )
+ {
+ ::ICStop( sInstance );
+ }
+ else
+ {
+ ::ICGetSeed( sInstance, &sSeed );
+ }
+ }
+ return sInstance;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NULL);
+}
+
+PRBool nsInternetConfig::HasSeedChanged()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+ ICInstance instance = nsInternetConfig::GetInstance();
+ if ( instance )
+ {
+ long newSeed = 0;
+ ::ICGetSeed( sInstance, &newSeed );
+ if ( newSeed != sSeed )
+ {
+ sSeed = newSeed;
+ return PR_TRUE;
+ }
+ }
+ return PR_FALSE;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
+}
+
+nsInternetConfig::nsInternetConfig()
+{
+ sRefCount++;
+}
+
+nsInternetConfig::~nsInternetConfig()
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+ sRefCount--;
+ if ( sRefCount == 0 && sInstance)
+ {
+ ::ICStop( sInstance );
+ sInstance = NULL;
+ }
+
+ NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsInternetConfigService.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+#ifndef __nsInternetConfigService_h
+#define __nsInternetConfigService_h
+
+#include "nsIInternetConfigService.h"
+#include "nsInternetConfig.h"
+
+#define NS_INTERNETCONFIGSERVICE_CID \
+ {0x9b8b9d81, 0x5f4f, 0x11d4, \
+ { 0x96, 0x96, 0x00, 0x60, 0x08, 0x3a, 0x0b, 0xcf }}
+
+class nsInternetConfigService : public nsIInternetConfigService
+{
+public:
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIINTERNETCONFIGSERVICE
+
+ nsresult GetMappingForMIMEType(const char *mimetype, const char *fileextension, ICMapEntry *entry);
+
+ nsInternetConfigService();
+ virtual ~nsInternetConfigService();
+protected:
+ // some private helper methods...
+ nsresult FillMIMEInfoForICEntry(ICMapEntry& entry, nsIMIMEInfo ** mimeinfo);
+
+ nsresult GetICKeyPascalString(PRUint32 inIndex, const unsigned char*& outICKey);
+ nsresult GetICPreference(PRUint32 inKey, void *outData, long *ioSize);
+};
+
+#endif
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/mac/nsInternetConfigService.mm
@@ -0,0 +1,629 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Steve Dagley <sdagley@netscape.com>
+ *
+ * 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 ***** */
+
+#include "nsInternetConfigService.h"
+#include "nsObjCExceptions.h"
+#include "nsCOMPtr.h"
+#include "nsIMIMEInfo.h"
+#include "nsMIMEInfoMac.h"
+#include "nsAutoPtr.h"
+#include "nsIFactory.h"
+#include "nsIComponentManager.h"
+#include "nsIURL.h"
+#include "nsXPIDLString.h"
+#include "nsReadableUtils.h"
+#include "nsString.h"
+#include "nsCRT.h"
+#include "nsILocalFileMac.h"
+#include "nsMimeTypes.h"
+
+#import <Carbon/Carbon.h>
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+
+/* This is an undocumented interface that seems to exist at least in 10.4 and 10.5 */
+@class NSURLFileTypeMappingsInternal;
+
+@interface NSURLFileTypeMappings : NSObject
+{
+ NSURLFileTypeMappingsInternal *_internal;
+}
+
++ (NSURLFileTypeMappings*)sharedMappings;
+- (NSString*)MIMETypeForExtension:(NSString*)fp8;
+- (NSString*)preferredExtensionForMIMEType:(NSString*)fp8;
+- (NSArray*)extensionsForMIMEType:(NSString*)fp8;
+@end
+
+// helper converter function.....
+static void ConvertCharStringToStr255(const char* inString, Str255& outString)
+{
+ if (inString == NULL)
+ return;
+
+ PRInt32 len = strlen(inString);
+ NS_ASSERTION(len <= 255 , " String is too big");
+ if (len> 255)
+ {
+ len = 255;
+ }
+ memcpy(&outString[1], inString, len);
+ outString[0] = len;
+}
+
+/* Define Class IDs */
+
+nsInternetConfigService::nsInternetConfigService()
+{
+}
+
+nsInternetConfigService::~nsInternetConfigService()
+{
+}
+
+
+/*
+ * Implement the nsISupports methods...
+ */
+NS_IMPL_ISUPPORTS1(nsInternetConfigService, nsIInternetConfigService)
+
+// void LaunchURL (in string url);
+// Given a url string, call ICLaunchURL using url
+// Under OS X use LaunchServices instead of IC
+NS_IMETHODIMP nsInternetConfigService::LaunchURL(const char *url)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ nsresult rv = NS_ERROR_FAILURE;
+
+ CFURLRef myURLRef = ::CFURLCreateWithBytes(
+ kCFAllocatorDefault,
+ (const UInt8*)url,
+ strlen(url),
+ kCFStringEncodingUTF8, NULL);
+ if (myURLRef)
+ {
+ rv = ::LSOpenCFURLRef(myURLRef, NULL);
+ ::CFRelease(myURLRef);
+ }
+
+ return rv;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+// boolean HasMappingForMIMEType (in string mimetype);
+// given a mime type, search Internet Config database for a mapping for that mime type
+NS_IMETHODIMP nsInternetConfigService::HasMappingForMIMEType(const char *mimetype, PRBool *_retval)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ ICMapEntry entry;
+ nsresult rv = GetMappingForMIMEType(mimetype, nsnull, &entry);
+ if (rv == noErr)
+ *_retval = PR_TRUE;
+ else
+ *_retval = PR_FALSE;
+ return rv;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+/* boolean hasProtocolHandler (in string protocol); */
+// returns NS_ERROR_NOT_AVAILABLE if the current application is registered
+// as the protocol handler for the given protocol
+NS_IMETHODIMP nsInternetConfigService::HasProtocolHandler(const char *protocol, PRBool *_retval)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ *_retval = PR_FALSE; // presume the OS doesn't have a handler
+ nsresult rv = NS_OK;
+
+ // Since protocol comes in with _just_ the protocol we have to add a ':' to
+ // the end of it or LaunchServices will be very unhappy with the CFURLRef
+ // created from it (crashes trying to look up a handler for it with
+ // LSGetApplicationForURL, at least under 10.2.1)
+ nsCAutoString scheme(protocol);
+ scheme += ":";
+ CFURLRef myURLRef = ::CFURLCreateWithBytes(
+ kCFAllocatorDefault,
+ (const UInt8 *)scheme.get(),
+ scheme.Length(),
+ kCFStringEncodingUTF8, NULL);
+ if (myURLRef)
+ {
+ FSRef appFSRef;
+
+ if (::LSGetApplicationForURL(myURLRef, kLSRolesAll, &appFSRef, NULL) == noErr)
+ { // Now see if the FSRef for the found app == the running app
+ ProcessSerialNumber psn;
+ if (::GetCurrentProcess(&psn) == noErr)
+ {
+ FSRef runningAppFSRef;
+ if (::GetProcessBundleLocation(&psn, &runningAppFSRef) == noErr)
+ {
+ if (::FSCompareFSRefs(&appFSRef, &runningAppFSRef) == noErr)
+ { // Oops, the current app is the handler which would cause infinite recursion
+ rv = NS_ERROR_NOT_AVAILABLE;
+ }
+ else
+ {
+ *_retval = PR_TRUE;
+ }
+ }
+ }
+ }
+ ::CFRelease(myURLRef);
+ }
+
+ return rv;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+// This method does the dirty work of traipsing through IC mappings database
+// looking for a mapping for mimetype
+nsresult nsInternetConfigService::GetMappingForMIMEType(const char *mimetype, const char *fileextension, ICMapEntry *entry)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ ICInstance inst = nsInternetConfig::GetInstance();
+ OSStatus err = noErr;
+ ICAttr attr;
+ Handle prefH;
+ PRBool domimecheck = PR_TRUE;
+ PRBool gotmatch = PR_FALSE;
+ ICMapEntry ent;
+
+ // if mime type is "unknown" or "octet stream" *AND* we have a file extension,
+ // then disable match on mime type
+ if (((nsCRT::strcasecmp(mimetype, UNKNOWN_CONTENT_TYPE) == 0) ||
+ (nsCRT::strcasecmp(mimetype, APPLICATION_OCTET_STREAM) == 0)) &&
+ fileextension)
+ domimecheck = PR_FALSE;
+
+ entry->totalLength = 0;
+ if (inst)
+ {
+ err = ::ICBegin(inst, icReadOnlyPerm);
+ if (err == noErr)
+ {
+ prefH = ::NewHandle(2048); // picked 2048 out of thin air
+ if (prefH)
+ {
+ err = ::ICFindPrefHandle(inst, kICMapping, &attr, prefH);
+ if (err == noErr)
+ {
+ long count;
+ err = ::ICCountMapEntries(inst, prefH, &count);
+ if (err == noErr)
+ {
+ long pos;
+ for (long i = 1; i <= count; ++i)
+ {
+ err = ::ICGetIndMapEntry(inst, prefH, i, &pos, &ent);
+ if (err == noErr)
+ {
+ // first, do mime type check
+ if (domimecheck)
+ {
+ nsCAutoString temp((char *)&ent.MIMEType[1], (int)ent.MIMEType[0]);
+ if (!temp.EqualsIgnoreCase(mimetype))
+ {
+ // we need to do mime check, and check failed
+ // nothing here to see, move along
+ continue;
+ }
+ }
+ if (fileextension)
+ {
+ // if fileextension was passed in, compare that also
+ if (ent.extension[0]) // check for non-empty pascal string
+ {
+ nsCAutoString temp((char *)&ent.extension[1], (int)ent.extension[0]);
+ if (temp.EqualsIgnoreCase(fileextension))
+ {
+ // mime type and file extension match, we're outta here
+ gotmatch = PR_TRUE;
+ // copy over ICMapEntry
+ *entry = ent;
+ break;
+ }
+ }
+ }
+ else if(domimecheck)
+ {
+ // at this point, we've got our match because
+ // domimecheck is true, the mime strings match, and fileextension isn't passed in
+ // bad thing is we'll stop on first match, but what can you do?
+ gotmatch = PR_TRUE;
+ // copy over ICMapEntry
+ *entry = ent;
+ break;
+ }
+ }
+ }
+ }
+ }
+ ::DisposeHandle(prefH);
+ }
+ else
+ {
+ err = memFullErr;
+ }
+ err = ::ICEnd(inst);
+ if (err == noErr && gotmatch == PR_FALSE)
+ {
+ err = fnfErr; // return SOME kind of error
+ }
+ }
+ }
+
+ if (err != noErr)
+ return NS_ERROR_FAILURE;
+ else
+ return NS_OK;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+nsresult nsInternetConfigService::FillMIMEInfoForICEntry(ICMapEntry& entry, nsIMIMEInfo ** mimeinfo)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ // create a mime info object and we'll fill it in based on the values from IC mapping entry
+ nsresult rv = NS_OK;
+ nsRefPtr<nsMIMEInfoMac> info (new nsMIMEInfoMac());
+ if (info)
+ {
+ nsCAutoString mimetype ((char *)&entry.MIMEType[1], entry.MIMEType[0]);
+ // check if entry.MIMEType is empty, if so, set mime type to APPLICATION_OCTET_STREAM
+ if (entry.MIMEType[0])
+ info->SetMIMEType(mimetype);
+ else
+ { // The IC mappings seem to not be very agressive about determining the mime type if
+ // all we have is a type or creator code. This is a bandaid approach for when we
+ // get a file of type 'TEXT' with no mime type mapping so that we'll display the
+ // file rather than trying to download it.
+ if (entry.fileType == 'TEXT')
+ info->SetMIMEType(NS_LITERAL_CSTRING(TEXT_PLAIN));
+ else
+ info->SetMIMEType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
+ }
+
+ nsCAutoString temp;
+
+ /* The internet config service seems to return the first extension
+ * from the map's list; however, that first extension is sometimes
+ * not the best one to use. Specifically, for image/jpeg, the
+ * internet config service will return "jfif", whereas the
+ * preferred extension is really "jpg". So, don't believe IC's
+ * lies, and ask NSURLFileTypeMappings instead (see bug 414201).
+ */
+ NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings];
+ NSString *mimeStr = [NSString stringWithCString:mimetype.get() encoding:NSASCIIStringEncoding];
+ NSString *realExtension = map ? [map preferredExtensionForMIMEType:mimeStr] : NULL;
+
+ if (realExtension) {
+ temp.Assign([realExtension cStringUsingEncoding:NSASCIIStringEncoding]);
+
+ info->AppendExtension(temp);
+ } else {
+ // convert entry.extension which is a Str255
+ // don't forget to remove the '.' in front of the file extension....
+ temp.Assign((char *)&entry.extension[2], entry.extension[0] > 0 ? (int)entry.extension[0]-1 : 0);
+
+ info->AppendExtension(temp);
+ }
+
+ info->SetMacType(entry.fileType);
+ info->SetMacCreator(entry.fileCreator);
+ temp.Assign((char *) &entry.entryName[1], entry.entryName[0]);
+ info->SetDescription(NS_ConvertASCIItoUTF16(temp));
+
+ temp.Assign((char *) &entry.postAppName[1], entry.postAppName[0]);
+ info->SetDefaultDescription(NS_ConvertASCIItoUTF16(temp));
+
+ if (entry.flags & kICMapPostMask)
+ {
+ // there is a post processor app
+ info->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
+ nsCOMPtr<nsILocalFileMac> file (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+ if (file)
+ {
+ rv = file->InitToAppWithCreatorCode(entry.postCreator);
+ if (rv == NS_OK)
+ {
+ nsCOMPtr<nsIFile> nsfile = do_QueryInterface(file, &rv);
+ if (rv == NS_OK)
+ info->SetDefaultApplication(nsfile);
+ }
+ }
+ }
+ else
+ {
+ // there isn't a post processor app so set the preferred action to be save to disk.
+ info->SetPreferredAction(nsIMIMEInfo::saveToDisk);
+ }
+
+ *mimeinfo = info;
+ NS_IF_ADDREF(*mimeinfo);
+ }
+ else // we failed to allocate the info object...
+ rv = NS_ERROR_FAILURE;
+
+ return rv;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+/* void FillInMIMEInfo (in string mimetype, in string fileExtension, out nsIMIMEInfo mimeinfo); */
+NS_IMETHODIMP nsInternetConfigService::FillInMIMEInfo(const char *mimetype, const char * aFileExtension, nsIMIMEInfo **mimeinfo)
+{
+ nsresult rv;
+ ICMapEntry entry;
+
+ NS_ENSURE_ARG_POINTER(mimeinfo);
+ *mimeinfo = nsnull;
+
+ if (aFileExtension && *aFileExtension)
+ {
+ nsCAutoString fileExtension;
+ fileExtension.Assign(".");
+ fileExtension.Append(aFileExtension);
+ rv = GetMappingForMIMEType(mimetype, fileExtension.get(), &entry);
+ }
+ else
+ {
+ rv = GetMappingForMIMEType(mimetype, nsnull, &entry);
+ }
+
+ if (rv == NS_OK)
+ rv = FillMIMEInfoForICEntry(entry, mimeinfo);
+ else
+ rv = NS_ERROR_FAILURE;
+
+ return rv;
+}
+
+NS_IMETHODIMP nsInternetConfigService::GetMIMEInfoFromExtension(const char *aFileExt, nsIMIMEInfo **_retval)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ nsresult rv = NS_ERROR_FAILURE;
+ ICInstance instance = nsInternetConfig::GetInstance();
+ if (instance)
+ {
+ nsCAutoString filename("foobar.");
+ filename += aFileExt;
+ Str255 pFileName;
+ ConvertCharStringToStr255(filename.get(), pFileName);
+ ICMapEntry entry;
+ OSStatus err = ::ICMapFilename(instance, pFileName, &entry);
+ if (err == noErr)
+ {
+ rv = FillMIMEInfoForICEntry(entry, _retval);
+ }
+ }
+ return rv;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+
+NS_IMETHODIMP nsInternetConfigService::GetMIMEInfoFromTypeCreator(PRUint32 aType, PRUint32 aCreator, const char *aFileExt, nsIMIMEInfo **_retval)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ nsresult rv = NS_ERROR_FAILURE;
+ ICInstance instance = nsInternetConfig::GetInstance();
+ if (instance)
+ {
+ nsCAutoString filename("foobar.");
+ filename += aFileExt;
+ Str255 pFileName;
+ ConvertCharStringToStr255(filename.get(), pFileName);
+ ICMapEntry entry;
+ OSStatus err = ::ICMapTypeCreator(instance, aType, aCreator, pFileName, &entry);
+ if (err == noErr)
+ rv = FillMIMEInfoForICEntry(entry,_retval);
+ }
+ return rv;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+nsresult nsInternetConfigService::GetICKeyPascalString(PRUint32 inIndex, const unsigned char*& outICKey)
+{
+ nsresult rv = NS_OK;
+
+ switch (inIndex)
+ {
+ case eICColor_WebBackgroundColour: outICKey = kICWebBackgroundColour; break;
+ case eICColor_WebReadColor: outICKey = kICWebReadColor; break;
+ case eICColor_WebTextColor: outICKey = kICWebTextColor; break;
+ case eICColor_WebUnreadColor: outICKey = kICWebUnreadColor; break;
+
+ case eICBoolean_WebUnderlineLinks: outICKey = kICWebUnderlineLinks; break;
+ case eICBoolean_UseFTPProxy: outICKey = kICUseFTPProxy; break;
+ case eICBoolean_UsePassiveFTP: outICKey = kICUsePassiveFTP; break;
+ case eICBoolean_UseHTTPProxy: outICKey = kICUseHTTPProxy; break;
+ case eICBoolean_NewMailDialog: outICKey = kICNewMailDialog; break;
+ case eICBoolean_NewMailFlashIcon: outICKey = kICNewMailFlashIcon; break;
+ case eICBoolean_NewMailPlaySound: outICKey = kICNewMailPlaySound; break;
+ case eICBoolean_UseGopherProxy: outICKey = kICUseGopherProxy; break;
+ case eICBoolean_UseSocks: outICKey = kICUseSocks; break;
+
+ case eICString_WWWHomePage: outICKey = kICWWWHomePage; break;
+ case eICString_WebSearchPagePrefs: outICKey = kICWebSearchPagePrefs; break;
+ case eICString_MacSearchHost: outICKey = kICMacSearchHost; break;
+ case eICString_FTPHost: outICKey = kICFTPHost; break;
+ case eICString_FTPProxyUser: outICKey = kICFTPProxyUser; break;
+ case eICString_FTPProxyAccount: outICKey = kICFTPProxyAccount; break;
+ case eICString_FTPProxyHost: outICKey = kICFTPProxyHost; break;
+ case eICString_FTPProxyPassword: outICKey = kICFTPProxyPassword; break;
+ case eICString_HTTPProxyHost: outICKey = kICHTTPProxyHost; break;
+ case eICString_LDAPSearchbase: outICKey = kICLDAPSearchbase; break;
+ case eICString_LDAPServer: outICKey = kICLDAPServer; break;
+ case eICString_SMTPHost: outICKey = kICSMTPHost; break;
+ case eICString_Email: outICKey = kICEmail; break;
+ case eICString_MailAccount: outICKey = kICMailAccount; break;
+ case eICString_MailPassword: outICKey = kICMailPassword; break;
+ case eICString_NewMailSoundName: outICKey = kICNewMailSoundName; break;
+ case eICString_NNTPHost: outICKey = kICNNTPHost; break;
+ case eICString_NewsAuthUsername: outICKey = kICNewsAuthUsername; break;
+ case eICString_NewsAuthPassword: outICKey = kICNewsAuthPassword; break;
+ case eICString_InfoMacPreferred: outICKey = kICInfoMacPreferred; break;
+ case eICString_Organization: outICKey = kICOrganization; break;
+ case eICString_QuotingString: outICKey = kICQuotingString; break;
+ case eICString_RealName: outICKey = kICRealName; break;
+ case eICString_FingerHost: outICKey = kICFingerHost; break;
+ case eICString_GopherHost: outICKey = kICGopherHost; break;
+ case eICString_GopherProxy: outICKey = kICGopherProxy; break;
+ case eICString_SocksHost: outICKey = kICSocksHost; break;
+ case eICString_TelnetHost: outICKey = kICTelnetHost; break;
+ case eICString_IRCHost: outICKey = kICIRCHost; break;
+ case eICString_UMichPreferred: outICKey = kICUMichPreferred; break;
+ case eICString_WAISGateway: outICKey = kICWAISGateway; break;
+ case eICString_WhoisHost: outICKey = kICWhoisHost; break;
+ case eICString_PhHost: outICKey = kICPhHost; break;
+ case eICString_NTPHost: outICKey = kICNTPHost; break;
+ case eICString_ArchiePreferred: outICKey = kICArchiePreferred; break;
+
+ case eICText_MailHeaders: outICKey = kICMailHeaders; break;
+ case eICText_Signature: outICKey = kICSignature; break;
+ case eICText_NewsHeaders: outICKey = kICNewsHeaders; break;
+ case eICText_SnailMailAddress: outICKey = kICSnailMailAddress; break;
+ case eICText_Plan: outICKey = kICPlan; break;
+
+ default:
+ rv = NS_ERROR_INVALID_ARG;
+ }
+ return rv;
+}
+
+
+nsresult nsInternetConfigService::GetICPreference(PRUint32 inKey,
+ void *outData, long *ioSize)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ const unsigned char *icKey;
+ nsresult rv = GetICKeyPascalString(inKey, icKey);
+ if (rv == NS_OK)
+ {
+ ICInstance instance = nsInternetConfig::GetInstance();
+ if (instance)
+ {
+ OSStatus err;
+ ICAttr junk;
+ err = ::ICGetPref(instance, icKey, &junk, outData, ioSize);
+ if (err != noErr)
+ rv = NS_ERROR_UNEXPECTED;
+ }
+ else
+ rv = NS_ERROR_FAILURE;
+ }
+ return rv;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+
+NS_IMETHODIMP nsInternetConfigService::GetString(PRUint32 inKey, nsACString& value)
+{
+ long size = 256;
+ char buffer[256];
+ nsresult rv = GetICPreference(inKey, (void *)&buffer, &size);
+ if (rv == NS_OK)
+ {
+ if (size == 0)
+ {
+ value = "";
+ rv = NS_ERROR_UNEXPECTED;
+ }
+ else
+ { // Buffer is a Pascal string so adjust for length byte when assigning
+ value.Assign(&buffer[1], (unsigned char)buffer[0]);
+ }
+ }
+ return rv;
+}
+
+
+NS_IMETHODIMP nsInternetConfigService::GetColor(PRUint32 inKey, PRUint32 *outColor)
+{
+// We're 'borrowing' this macro from nscolor.h so that uriloader doesn't depend on gfx.
+// Make a color out of r,g,b values. This assumes that the r,g,b values are
+// properly constrained to 0-255. This also assumes that a is 255.
+
+ #define MAKE_NS_RGB(_r,_g,_b) \
+ ((PRUint32) ((255 << 24) | ((_b)<<16) | ((_g)<<8) | (_r)))
+
+ RGBColor buffer;
+ long size = sizeof(RGBColor);
+ nsresult rv = GetICPreference(inKey, &buffer, &size);
+ if (rv == NS_OK)
+ {
+ if (size != sizeof(RGBColor))
+ { // default to white if we didn't get the right size
+ *outColor = MAKE_NS_RGB(0xff, 0xff, 0xff);
+ }
+ else
+ { // convert to a web color
+ *outColor = MAKE_NS_RGB(buffer.red >> 8, buffer.green >> 8, buffer.blue >> 8);
+ }
+ }
+ return rv;
+}
+
+
+NS_IMETHODIMP nsInternetConfigService::GetBoolean(PRUint32 inKey, PRBool *outFlag)
+{
+ Boolean buffer;
+ long size = sizeof(Boolean);
+ nsresult rv = GetICPreference(inKey, (void *)&buffer, &size);
+ if (rv == NS_OK)
+ {
+ if ((size_t)size < sizeof(Boolean))
+ *outFlag = PR_FALSE; // default to false if we didn't get the right amount of data
+ else
+ *outFlag = buffer;
+ }
+ return rv;
+}
--- a/uriloader/exthandler/mac/nsMIMEInfoMac.mm
+++ b/uriloader/exthandler/mac/nsMIMEInfoMac.mm
@@ -41,16 +41,17 @@
* ***** END LICENSE BLOCK ***** */
#import <Carbon/Carbon.h>
#include "nsObjCExceptions.h"
#include "nsMIMEInfoMac.h"
#include "nsILocalFileMac.h"
#include "nsIFileURL.h"
+#include "nsIInternetConfigService.h"
// We override this to make sure app bundles display their pretty name (without .app suffix)
NS_IMETHODIMP nsMIMEInfoMac::GetDefaultDescription(nsAString& aDefaultDescription)
{
if (mDefaultApplication) {
nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(mDefaultApplication);
if (macFile) {
PRBool isPackage;
@@ -118,34 +119,21 @@ nsMIMEInfoMac::LaunchWithFile(nsIFile *a
return app->LaunchWithDoc(localFile, PR_FALSE);
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
nsresult
nsMIMEInfoMac::LoadUriInternal(nsIURI *aURI)
{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
-
NS_ENSURE_ARG_POINTER(aURI);
-
nsresult rv = NS_ERROR_FAILURE;
-
+
nsCAutoString uri;
- aURI->GetSpec(uri);
+ aURI->GetAsciiSpec(uri);
if (!uri.IsEmpty()) {
- CFURLRef myURLRef = ::CFURLCreateWithBytes(kCFAllocatorDefault,
- (const UInt8*)uri.get(),
- strlen(uri.get()),
- kCFStringEncodingUTF8,
- NULL);
- if (myURLRef) {
- OSStatus status = ::LSOpenCFURLRef(myURLRef, NULL);
- if (status == noErr)
- rv = NS_OK;
- ::CFRelease(myURLRef);
- }
+ nsCOMPtr<nsIInternetConfigService> icService =
+ do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID);
+ if (icService)
+ rv = icService->LaunchURL(uri.get());
}
-
return rv;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
--- a/uriloader/exthandler/mac/nsOSHelperAppService.h
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.h
@@ -69,11 +69,15 @@ public:
// GetFileTokenForPath must be implemented by each platform.
// platformAppPath --> a platform specific path to an application that we got out of the
// rdf data source. This can be a mac file spec, a unix path or a windows path depending on the platform
// aFile --> an nsIFile representation of that platform application path.
virtual nsresult GetFileTokenForPath(const PRUnichar * platformAppPath, nsIFile ** aFile);
nsresult OSProtocolHandlerExists(const char * aScheme,
PRBool * aHandlerExists);
+
+protected:
+ // add any mac specific service state here
+ void UpdateCreatorInfo(nsIMIMEInfo * aMIMEInfo);
};
#endif // nsOSHelperAppService_h__
--- a/uriloader/exthandler/mac/nsOSHelperAppService.mm
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.mm
@@ -49,71 +49,64 @@
#include "nsILocalFile.h"
#include "nsILocalFileMac.h"
#include "nsMimeTypes.h"
#include "nsIStringBundle.h"
#include "nsIPromptService.h"
#include "nsMemory.h"
#include "nsCRT.h"
#include "nsMIMEInfoMac.h"
+#include "nsIInternetConfigService.h"
#include "nsEmbedCID.h"
#import <Carbon/Carbon.h>
// chrome URL's
#define HELPERAPPLAUNCHER_BUNDLE_URL "chrome://global/locale/helperAppLauncher.properties"
#define BRAND_BUNDLE_URL "chrome://branding/locale/brand.properties"
extern "C" {
// Returns the CFURL for application currently set as the default opener for
// the given URL scheme. appURL must be released by the caller.
extern OSStatus _LSCopyDefaultSchemeHandlerURL(CFStringRef scheme,
CFURLRef *appURL);
}
-/* This is an undocumented interface (in the Foundation framework) that has
- * been stable since at least 10.2.8 and is still present on SnowLeopard.
- * Furthermore WebKit has three public methods (in WebKitSystemInterface.h)
- * that are thin wrappers around this interface's last three methods. So
- * it's unlikely to change anytime soon. Now that we're no longer using
- * Internet Config Services, this is the only way to look up a MIME type
- * from an extension, or vice versa.
- */
-@class NSURLFileTypeMappingsInternal;
-
-@interface NSURLFileTypeMappings : NSObject
-{
- NSURLFileTypeMappingsInternal *_internal;
-}
-
-+ (NSURLFileTypeMappings*)sharedMappings;
-- (NSString*)MIMETypeForExtension:(NSString*)aString;
-- (NSString*)preferredExtensionForMIMEType:(NSString*)aString;
-- (NSArray*)extensionsForMIMEType:(NSString*)aString;
-@end
-
nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService()
{
}
nsOSHelperAppService::~nsOSHelperAppService()
{}
nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists)
{
- CFStringRef schemeString = ::CFStringCreateWithBytes(kCFAllocatorDefault,
- (const UInt8*)aProtocolScheme,
- strlen(aProtocolScheme),
- kCFStringEncodingUTF8,
- false);
- CFStringRef handlerString = ::LSCopyDefaultHandlerForURLScheme(schemeString);
- *aHandlerExists = !!handlerString;
- ::CFRelease(handlerString);
- ::CFRelease(schemeString);
- return NS_OK;
+ // look up the protocol scheme in Internet Config....if we find a match then we have a handler for it...
+ *aHandlerExists = PR_FALSE;
+ // ask the internet config service to look it up for us...
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+ if (icService)
+ {
+ rv = icService->HasProtocolHandler(aProtocolScheme, aHandlerExists);
+ if (rv == NS_ERROR_NOT_AVAILABLE)
+ {
+ // There is a protocol handler, but it's the current app! We can't let
+ // the current app handle the protocol, as that'll get us into an infinite
+ // loop, so we just pretend there's no protocol handler available.
+ *aHandlerExists = PR_FALSE;
+ rv = NS_OK;
+
+ // FIXME: instead of pretending there's no protocol handler available,
+ // let the caller know about the loop so it can deal with the problem
+ // (i.e. either fix it automatically, if there's some way to do that,
+ // or just provide the user with options for fixing it manually).
+ }
+ }
+ return rv;
}
NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
nsresult rv = NS_ERROR_NOT_AVAILABLE;
@@ -212,180 +205,133 @@ nsresult nsOSHelperAppService::GetFileTo
return rv;
*aFile = localFile;
NS_IF_ADDREF(*aFile);
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
+///////////////////////////
+// method overrides --> use internet config information for mime type lookup.
+///////////////////////////
NS_IMETHODIMP nsOSHelperAppService::GetFromTypeAndExtension(const nsACString& aType, const nsACString& aFileExt, nsIMIMEInfo ** aMIMEInfo)
{
- return nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo);
+ // first, ask our base class....
+ nsresult rv = nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo);
+ if (NS_SUCCEEDED(rv) && *aMIMEInfo)
+ {
+ UpdateCreatorInfo(*aMIMEInfo);
+ }
+ return rv;
}
-// aMIMEType and aFileExt might not match, This method's documentation (in
-// nsExternalHelperAppService.h) says that the MIME type is given preference.
already_AddRefed<nsIMIMEInfo>
nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType,
const nsACString& aFileExt,
PRBool * aFound)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSNULL;
- *aFound = PR_FALSE;
+ nsIMIMEInfo* mimeInfo = nsnull;
+ *aFound = PR_TRUE;
const nsCString& flatType = PromiseFlatCString(aMIMEType);
const nsCString& flatExt = PromiseFlatCString(aFileExt);
- PR_LOG(mLog, PR_LOG_DEBUG, ("Mac: HelperAppService lookup for type '%s' ext '%s'\n",
- flatType.get(), flatExt.get()));
-
- // Create a Mac-specific MIME info so we can use Mac-specific members.
- nsMIMEInfoMac* mimeInfoMac = new nsMIMEInfoMac(aMIMEType);
- if (!mimeInfoMac)
- return nsnull;
- NS_ADDREF(mimeInfoMac);
+ // ask the internet config service to look it up for us...
+ nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+ PR_LOG(mLog, PR_LOG_DEBUG, ("Mac: HelperAppService lookup for type '%s' ext '%s' (IC: 0x%p)\n",
+ flatType.get(), flatExt.get(), icService.get()));
+ if (icService)
+ {
+ nsCOMPtr<nsIMIMEInfo> miByType, miByExt;
+ if (!aMIMEType.IsEmpty())
+ icService->FillInMIMEInfo(flatType.get(), flatExt.get(), getter_AddRefs(miByType));
- OSStatus err;
- PRBool haveAppForType = PR_FALSE;
- PRBool haveAppForExt = PR_FALSE;
- PRBool typeAppIsDefault = PR_FALSE;
- PRBool extAppIsDefault = PR_FALSE;
- FSRef typeAppFSRef;
- FSRef extAppFSRef;
+ PRBool hasDefault = PR_FALSE;
+ if (miByType)
+ miByType->GetHasDefaultHandler(&hasDefault);
- if (!aMIMEType.IsEmpty()) {
- CFURLRef appURL = NULL;
- CFStringRef CFType = ::CFStringCreateWithCString(NULL, flatType.get(), kCFStringEncodingUTF8);
- err = ::LSCopyApplicationForMIMEType(CFType, kLSRolesAll, &appURL);
- if ((err == noErr) && appURL && ::CFURLGetFSRef(appURL, &typeAppFSRef)) {
- haveAppForType = PR_TRUE;
- PR_LOG(mLog, PR_LOG_DEBUG, ("LSCopyApplicationForMIMEType found a default application\n"));
+ if (!aFileExt.IsEmpty() && (!hasDefault || !miByType)) {
+ icService->GetMIMEInfoFromExtension(flatExt.get(), getter_AddRefs(miByExt));
+ if (miByExt && !aMIMEType.IsEmpty()) {
+ // XXX see XXX comment below
+ nsIMIMEInfo* pByExt = miByExt.get();
+ nsMIMEInfoBase* byExt = static_cast<nsMIMEInfoBase*>(pByExt);
+ byExt->SetMIMEType(aMIMEType);
+ }
}
- if (appURL)
- ::CFRelease(appURL);
- ::CFRelease(CFType);
- }
- if (!aFileExt.IsEmpty()) {
- CFStringRef CFExt = ::CFStringCreateWithCString(NULL, flatExt.get(), kCFStringEncodingUTF8);
- err = ::LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFExt,
- kLSRolesAll, &extAppFSRef, nsnull);
- if (err == noErr) {
- haveAppForExt = PR_TRUE;
- PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo found a default application\n"));
- }
- }
+ PR_LOG(mLog, PR_LOG_DEBUG, ("OS gave us: By Type: 0x%p By Ext: 0x%p type has default: %s\n",
+ miByType.get(), miByExt.get(), hasDefault ? "true" : "false"));
- if (haveAppForType && haveAppForExt) {
- typeAppIsDefault = PR_TRUE;
- // Only add the extension if aMIMEType and aFileExt match.
- if (::FSCompareFSRefs((const FSRef *) &typeAppFSRef, (const FSRef *) &extAppFSRef) == noErr)
- mimeInfoMac->AppendExtension(aFileExt);
- *aFound = PR_TRUE;
- } else if (haveAppForType) {
- typeAppIsDefault = PR_TRUE;
- *aFound = PR_TRUE;
- } else if (haveAppForExt) {
- extAppIsDefault = PR_TRUE;
- mimeInfoMac->AppendExtension(aFileExt);
- *aFound = PR_TRUE;
+ // If we got two matches, and the type has no default app, copy default app
+ if (!hasDefault && miByType && miByExt) {
+ // IC currently always uses nsMIMEInfoBase-derived classes.
+ // When it stops doing that, this code will need changing.
+ // XXX This assumes that IC will give os an nsMIMEInfoBase. I'd use
+ // dynamic_cast but that crashes.
+ // XXX these pBy* variables are needed because .get() returns an
+ // nsDerivedSafe thingy that can't be cast to nsMIMEInfoBase*
+ nsIMIMEInfo* pByType = miByType.get();
+ nsIMIMEInfo* pByExt = miByExt.get();
+ nsMIMEInfoBase* byType = static_cast<nsMIMEInfoBase*>(pByType);
+ nsMIMEInfoBase* byExt = static_cast<nsMIMEInfoBase*>(pByExt);
+ if (!byType || !byExt) {
+ NS_ERROR("IC gave us an nsIMIMEInfo that's no nsMIMEInfoBase! Fix nsOSHelperAppService.");
+ return nsnull;
+ }
+ // Copy the attributes of miByType onto miByExt
+ byType->CopyBasicDataTo(byExt);
+ miByType = miByExt;
+ }
+ if (miByType)
+ miByType.swap(mimeInfo);
+ else if (miByExt)
+ miByExt.swap(mimeInfo);
}
- if (aMIMEType.IsEmpty()) {
- if (haveAppForExt) {
- // If aMIMEType is empty and we've found a default app for aFileExt, try
- // to get the MIME type from aFileExt. (It might also be worth doing
- // this when aMIMEType isn't empty but haveAppForType is false -- but
- // the doc for this method says that if we have a MIME type (in
- // aMIMEType), we need to give it preference.)
- NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings];
- NSString *extStr = [NSString stringWithCString:flatExt.get() encoding:NSASCIIStringEncoding];
- NSString *typeStr = map ? [map MIMETypeForExtension:extStr] : NULL;
- if (typeStr) {
- nsCAutoString mimeType;
- mimeType.Assign((char *)[typeStr cStringUsingEncoding:NSASCIIStringEncoding]);
- mimeInfoMac->SetMIMEType(mimeType);
+ if (!mimeInfo) {
+ *aFound = PR_FALSE;
+ PR_LOG(mLog, PR_LOG_DEBUG, ("Creating new mimeinfo\n"));
+ // Create a Mac-specific MIME info so we can use Mac-specific members.
+ nsMIMEInfoMac* mimeInfoMac = new nsMIMEInfoMac(aMIMEType);
+ if (!mimeInfoMac)
+ return nsnull;
+ NS_ADDREF(mimeInfoMac);
+
+ if (!aFileExt.IsEmpty())
+ mimeInfoMac->AppendExtension(aFileExt);
+
+ // Now see if Launch Services knows of an application that should be run for this type.
+ OSStatus err;
+ FSRef appFSRef;
+ CFStringRef CFExt = ::CFStringCreateWithCString(NULL, flatExt.get(), kCFStringEncodingUTF8);
+ err = ::LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFExt,
+ kLSRolesAll, &appFSRef, nsnull);
+ if (err == noErr) {
+ nsCOMPtr<nsILocalFileMac> app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+ if (!app) {
+ ::CFRelease(CFExt);
+ NS_RELEASE(mimeInfoMac);
+ return nsnull;
}
+ app->InitWithFSRef(&appFSRef);
+ mimeInfoMac->SetDefaultApplication(app);
+ PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo found a default application\n"));
} else {
- // Otherwise set the MIME type to a reasonable fallback.
- mimeInfoMac->SetMIMEType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
- }
- }
-
- if (typeAppIsDefault || extAppIsDefault) {
- nsCOMPtr<nsILocalFileMac> app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
- if (!app) {
- NS_RELEASE(mimeInfoMac);
- return nsnull;
- }
-
- CFStringRef CFAppName = NULL;
- if (typeAppIsDefault) {
- app->InitWithFSRef(&typeAppFSRef);
- ::LSCopyItemAttribute((const FSRef *) &typeAppFSRef, kLSRolesAll,
- kLSItemDisplayName, (CFTypeRef *) &CFAppName);
- } else {
- app->InitWithFSRef(&extAppFSRef);
- ::LSCopyItemAttribute((const FSRef *) &extAppFSRef, kLSRolesAll,
- kLSItemDisplayName, (CFTypeRef *) &CFAppName);
+ // Just leave the default application unset.
+ PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo returned error code %d; default application was not set\n", err));
}
- if (CFAppName) {
- nsAutoTArray<UniChar, 255> buffer;
- CFIndex appNameLength = ::CFStringGetLength(CFAppName);
- buffer.SetLength(appNameLength);
- ::CFStringGetCharacters(CFAppName, CFRangeMake(0, appNameLength),
- buffer.Elements());
- nsAutoString appName;
- appName.Assign(buffer.Elements(), appNameLength);
- mimeInfoMac->SetDefaultDescription(appName);
- ::CFRelease(CFAppName);
- }
-
- mimeInfoMac->SetDefaultApplication(app);
- mimeInfoMac->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
- } else {
- mimeInfoMac->SetPreferredAction(nsIMIMEInfo::saveToDisk);
+ mimeInfo = mimeInfoMac;
+ ::CFRelease(CFExt);
}
-
- nsCAutoString mimeType;
- mimeInfoMac->GetMIMEType(mimeType);
- if (!mimeType.IsEmpty()) {
- // If we have a MIME type, make sure its preferred extension is included
- // in our list.
- NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings];
- NSString *typeStr = [NSString stringWithCString:mimeType.get() encoding:NSASCIIStringEncoding];
- NSString *extStr = map ? [map preferredExtensionForMIMEType:typeStr] : NULL;
- if (extStr) {
- nsCAutoString preferredExt;
- preferredExt.Assign((char *)[extStr cStringUsingEncoding:NSASCIIStringEncoding]);
- mimeInfoMac->AppendExtension(preferredExt);
- }
-
- CFStringRef CFType = ::CFStringCreateWithCString(NULL, mimeType.get(), kCFStringEncodingUTF8);
- CFStringRef CFTypeDesc = NULL;
- if (::LSCopyKindStringForMIMEType(CFType, &CFTypeDesc) == noErr) {
- nsAutoTArray<UniChar, 255> buffer;
- CFIndex typeDescLength = ::CFStringGetLength(CFTypeDesc);
- buffer.SetLength(typeDescLength);
- ::CFStringGetCharacters(CFTypeDesc, CFRangeMake(0, typeDescLength),
- buffer.Elements());
- nsAutoString typeDesc;
- typeDesc.Assign(buffer.Elements(), typeDescLength);
- mimeInfoMac->SetDescription(typeDesc);
- }
- if (CFTypeDesc)
- ::CFRelease(CFTypeDesc);
- ::CFRelease(CFType);
- }
-
- PR_LOG(mLog, PR_LOG_DEBUG, ("OS gave us: type '%s' found '%i'\n", mimeType.get(), *aFound));
-
- return mimeInfoMac;
+
+ return mimeInfo;
NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL;
}
NS_IMETHODIMP
nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString &aScheme,
PRBool *found,
nsIHandlerInfo **_retval)
@@ -409,8 +355,38 @@ nsOSHelperAppService::GetProtocolHandler
}
nsAutoString desc;
GetApplicationDescription(aScheme, desc);
handlerInfo->SetDefaultDescription(desc);
return NS_OK;
}
+
+// we never want to use a hard coded value for the creator and file type for the mac. always look these values up
+// from internet config.
+void nsOSHelperAppService::UpdateCreatorInfo(nsIMIMEInfo * aMIMEInfo)
+{
+ PRUint32 macCreatorType;
+ PRUint32 macFileType;
+ aMIMEInfo->GetMacType(&macFileType);
+ aMIMEInfo->GetMacCreator(&macCreatorType);
+
+ if (macFileType == 0 || macCreatorType == 0)
+ {
+ // okay these values haven't been initialized yet so fetch a mime object from internet config.
+ nsCAutoString mimeType;
+ aMIMEInfo->GetMIMEType(mimeType);
+ nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+ if (icService)
+ {
+ nsCOMPtr<nsIMIMEInfo> osMimeObject;
+ icService->FillInMIMEInfo(mimeType.get(), nsnull, getter_AddRefs(osMimeObject));
+ if (osMimeObject)
+ {
+ osMimeObject->GetMacType(&macFileType);
+ osMimeObject->GetMacCreator(&macCreatorType);
+ aMIMEInfo->SetMacCreator(macCreatorType);
+ aMIMEInfo->SetMacType(macFileType);
+ } // if we got an os object
+ } // if we got the ic service
+ } // if the creator or file type hasn't been initialized yet
+}
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -87,16 +87,17 @@
#include "nsIEncodedChannel.h"
#include "nsIMultiPartChannel.h"
#include "nsIFileChannel.h"
#include "nsIObserverService.h" // so we can be a profile change observer
#include "nsIPropertyBag2.h" // for the 64-bit content length
#ifdef XP_MACOSX
#include "nsILocalFileMac.h"
+#include "nsIInternetConfigService.h"
#ifndef __LP64__
#include "nsIAppleFileDecoder.h"
#endif
#elif defined(XP_OS2)
#include "nsILocalFileOS2.h"
#endif
#include "nsIPluginHost.h" // XXX needed for ext->type mapping (bug 233289)
@@ -486,16 +487,18 @@ static nsDefaultMimeTypeEntry defaultMim
/**
* This is a small private struct used to help us initialize some
* default mime types.
*/
struct nsExtraMimeTypeEntry {
const char* mMimeType;
const char* mFileExtensions;
const char* mDescription;
+ PRUint32 mMactype;
+ PRUint32 mMacCreator;
};
#ifdef XP_MACOSX
#define MAC_TYPE(x) x
#else
#define MAC_TYPE(x) 0
#endif
@@ -504,49 +507,49 @@ struct nsExtraMimeTypeEntry {
* file extensions. These entries also ensure that we provide a good descriptive name
* when we encounter files with these content types and/or extensions. These can be
* overridden by user helper app prefs.
* If you add types here, make sure they are lowercase, or you'll regret it.
*/
static nsExtraMimeTypeEntry extraMimeEntries [] =
{
#if defined(VMS)
- { APPLICATION_OCTET_STREAM, "exe,com,bin,sav,bck,pcsi,dcx_axpexe,dcx_vaxexe,sfx_axpexe,sfx_vaxexe", "Binary File" },
+ { APPLICATION_OCTET_STREAM, "exe,com,bin,sav,bck,pcsi,dcx_axpexe,dcx_vaxexe,sfx_axpexe,sfx_vaxexe", "Binary File", 0, 0 },
#elif defined(XP_MACOSX) // don't define .bin on the mac...use internet config to look that up...
- { APPLICATION_OCTET_STREAM, "exe,com", "Binary File" },
+ { APPLICATION_OCTET_STREAM, "exe,com", "Binary File", 0, 0 },
#else
- { APPLICATION_OCTET_STREAM, "exe,com,bin", "Binary File" },
+ { APPLICATION_OCTET_STREAM, "exe,com,bin", "Binary File", 0, 0 },
#endif
- { APPLICATION_GZIP2, "gz", "gzip" },
- { "application/x-arj", "arj", "ARJ file" },
- { APPLICATION_XPINSTALL, "xpi", "XPInstall Install" },
- { APPLICATION_POSTSCRIPT, "ps,eps,ai", "Postscript File" },
- { APPLICATION_JAVASCRIPT, "js", "Javascript Source File" },
- { IMAGE_ART, "art", "ART Image" },
- { IMAGE_BMP, "bmp", "BMP Image" },
- { IMAGE_GIF, "gif", "GIF Image" },
- { IMAGE_ICO, "ico,cur", "ICO Image" },
- { IMAGE_JPG, "jpeg,jpg,jfif,pjpeg,pjp", "JPEG Image" },
- { IMAGE_PNG, "png", "PNG Image" },
- { IMAGE_TIFF, "tiff,tif", "TIFF Image" },
- { IMAGE_XBM, "xbm", "XBM Image" },
- { "image/svg+xml", "svg", "Scalable Vector Graphics" },
- { MESSAGE_RFC822, "eml", "RFC-822 data" },
- { TEXT_PLAIN, "txt,text", "Text File" },
- { TEXT_HTML, "html,htm,shtml,ehtml", "HyperText Markup Language" },
- { "application/xhtml+xml", "xhtml,xht", "Extensible HyperText Markup Language" },
- { APPLICATION_RDF, "rdf", "Resource Description Framework" },
- { TEXT_XUL, "xul", "XML-Based User Interface Language" },
- { TEXT_XML, "xml,xsl,xbl", "Extensible Markup Language" },
- { TEXT_CSS, "css", "Style Sheet" },
- { VIDEO_OGG, "ogv", "Ogg Video" },
- { VIDEO_OGG, "ogg", "Ogg Video" },
- { APPLICATION_OGG, "ogg", "Ogg Video"},
- { AUDIO_OGG, "oga", "Ogg Audio" },
- { AUDIO_WAV, "wav", "Waveform Audio" }
+ { APPLICATION_GZIP2, "gz", "gzip", 0, 0 },
+ { "application/x-arj", "arj", "ARJ file", 0,0 },
+ { APPLICATION_XPINSTALL, "xpi", "XPInstall Install", MAC_TYPE('xpi*'), MAC_TYPE('MOSS') },
+ { APPLICATION_POSTSCRIPT, "ps,eps,ai", "Postscript File", 0, 0 },
+ { APPLICATION_JAVASCRIPT, "js", "Javascript Source File", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+ { IMAGE_ART, "art", "ART Image", 0, 0 },
+ { IMAGE_BMP, "bmp", "BMP Image", 0, 0 },
+ { IMAGE_GIF, "gif", "GIF Image", 0,0 },
+ { IMAGE_ICO, "ico,cur", "ICO Image", 0, 0 },
+ { IMAGE_JPG, "jpeg,jpg,jfif,pjpeg,pjp", "JPEG Image", 0, 0 },
+ { IMAGE_PNG, "png", "PNG Image", 0, 0 },
+ { IMAGE_TIFF, "tiff,tif", "TIFF Image", 0, 0 },
+ { IMAGE_XBM, "xbm", "XBM Image", 0, 0 },
+ { "image/svg+xml", "svg", "Scalable Vector Graphics", MAC_TYPE('svg '), MAC_TYPE('ttxt') },
+ { MESSAGE_RFC822, "eml", "RFC-822 data", MAC_TYPE('TEXT'), MAC_TYPE('MOSS') },
+ { TEXT_PLAIN, "txt,text", "Text File", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+ { TEXT_HTML, "html,htm,shtml,ehtml", "HyperText Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('MOSS') },
+ { "application/xhtml+xml", "xhtml,xht", "Extensible HyperText Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+ { APPLICATION_RDF, "rdf", "Resource Description Framework", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+ { TEXT_XUL, "xul", "XML-Based User Interface Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+ { TEXT_XML, "xml,xsl,xbl", "Extensible Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+ { TEXT_CSS, "css", "Style Sheet", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') },
+ { VIDEO_OGG, "ogv", "Ogg Video", 0, 0 },
+ { VIDEO_OGG, "ogg", "Ogg Video", 0, 0 },
+ { APPLICATION_OGG, "ogg", "Ogg Video", 0, 0},
+ { AUDIO_OGG, "oga", "Ogg Audio", 0, 0 },
+ { AUDIO_WAV, "wav", "Waveform Audio", 0, 0 }
};
#undef MAC_TYPE
/**
* File extensions for which decoding should be disabled.
* NOTE: These MUST be lower-case and ASCII.
*/
@@ -1354,16 +1357,29 @@ nsresult nsExternalAppHandler::SetUpTemp
NS_ENSURE_SUCCESS(rv, rv);
#ifndef XP_WIN
// On other platforms, the file permission bits are used, so we can just call
// IsExecutable
mTempFile->IsExecutable(&mTempFileIsExecutable);
#endif
+#ifdef XP_MACOSX
+ // Now that the file exists set Mac type if the file has no extension
+ // and we can determine a type.
+ if (ext.IsEmpty() && mMimeInfo) {
+ nsCOMPtr<nsILocalFileMac> macfile = do_QueryInterface(mTempFile);
+ if (macfile) {
+ PRUint32 type;
+ mMimeInfo->GetMacType(&type);
+ macfile->SetFileType(type);
+ }
+ }
+#endif
+
nsCOMPtr<nsIOutputStream> outputStream;
rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mTempFile,
PR_WRONLY | PR_CREATE_FILE, 0600);
if (NS_FAILED(rv)) {
mTempFile->Remove(PR_FALSE);
return rv;
}
@@ -2674,20 +2690,38 @@ NS_IMETHODIMP nsExternalHelperAppService
{
if (fileName[i] == PRUnichar('.'))
{
CopyUTF16toUTF8(fileName.get() + i + 1, fileExt);
break;
}
}
}
+
+#ifdef XP_MACOSX
+ nsCOMPtr<nsILocalFileMac> macFile;
+ macFile = do_QueryInterface( aFile, &rv );
+ if (NS_SUCCEEDED( rv ) && fileExt.IsEmpty())
+ {
+ PRUint32 type, creator;
+ macFile->GetFileType( (OSType*)&type );
+ macFile->GetFileCreator( (OSType*)&creator );
+ nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+ if (icService)
+ {
+ rv = icService->GetMIMEInfoFromTypeCreator(type, creator, fileExt.get(), getter_AddRefs(info));
+ if (NS_SUCCEEDED(rv))
+ return info->GetMIMEType(aContentType);
+ }
+ }
+#endif
+ // Windows, unix and mac when no type match occured.
if (fileExt.IsEmpty())
- return NS_ERROR_FAILURE;
-
+ return NS_ERROR_FAILURE;
return GetTypeFromExtension(fileExt, aContentType);
}
nsresult nsExternalHelperAppService::FillMIMEInfoForMimeTypeFromExtras(
const nsACString& aContentType, nsIMIMEInfo * aMIMEInfo)
{
NS_ENSURE_ARG( aMIMEInfo );
@@ -2699,16 +2733,19 @@ nsresult nsExternalHelperAppService::Fil
PRInt32 numEntries = NS_ARRAY_LENGTH(extraMimeEntries);
for (PRInt32 index = 0; index < numEntries; index++)
{
if ( MIMEType.Equals(extraMimeEntries[index].mMimeType) )
{
// This is the one. Set attributes appropriately.
aMIMEInfo->SetFileExtensions(nsDependentCString(extraMimeEntries[index].mFileExtensions));
aMIMEInfo->SetDescription(NS_ConvertASCIItoUTF16(extraMimeEntries[index].mDescription));
+ aMIMEInfo->SetMacType(extraMimeEntries[index].mMactype);
+ aMIMEInfo->SetMacCreator(extraMimeEntries[index].mMacCreator);
+
return NS_OK;
}
}
return NS_ERROR_NOT_AVAILABLE;
}
nsresult nsExternalHelperAppService::FillMIMEInfoForExtensionFromExtras(
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/nsIInternetConfigService.idl
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+#include "nsISupports.idl"
+
+interface nsIMIMEInfo;
+interface nsIURL;
+
+%{C++
+
+#include <Carbon/Carbon.h>
+
+#define NS_INTERNETCONFIGSERVICE_CONTRACTID \
+"@mozilla.org/mac/internet-config-service;1"
+
+%}
+
+native FSSpec(FSSpec);
+[ptr] native FSSpecPtr(FSSpec);
+
+[scriptable, uuid(38C37AA2-9F74-4B24-A70C-AC3AE4308210)]
+interface nsIInternetConfigService : nsISupports
+{
+ const unsigned long eICColor_WebBackgroundColour = 1;
+ const unsigned long eICColor_WebReadColor = 2;
+ const unsigned long eICColor_WebTextColor = 3;
+ const unsigned long eICColor_WebUnreadColor = 4;
+ const unsigned long eICBoolean_WebUnderlineLinks = 11;
+ const unsigned long eICString_WWWHomePage = 101;
+ const unsigned long eICString_WebSearchPagePrefs = 102;
+ const unsigned long eICString_MacSearchHost = 103;
+ const unsigned long eICString_FTPHost = 121;
+ const unsigned long eICBoolean_UsePassiveFTP = 122;
+ const unsigned long eICBoolean_UseFTPProxy = 123; const unsigned long eICString_FTPProxyUser = 124;
+ const unsigned long eICString_FTPProxyAccount = 125; const unsigned long eICString_FTPProxyHost = 126;
+ const unsigned long eICString_FTPProxyPassword = 127;
+ const unsigned long eICBoolean_UseHTTPProxy = 130; const unsigned long eICString_HTTPProxyHost = 131;
+ const unsigned long eICString_LDAPSearchbase = 201; const unsigned long eICString_LDAPServer = 202;
+ const unsigned long eICString_SMTPHost = 221;
+ const unsigned long eICString_Email = 222;
+ const unsigned long eICString_MailAccount = 223; const unsigned long eICString_MailPassword = 224;
+ const unsigned long eICText_MailHeaders = 225; const unsigned long eICText_Signature = 226;
+ const unsigned long eICBoolean_NewMailDialog = 231;
+ const unsigned long eICBoolean_NewMailFlashIcon = 232;
+ const unsigned long eICBoolean_NewMailPlaySound = 233; const unsigned long eICString_NewMailSoundName = 234;
+ const unsigned long eICString_NNTPHost = 241;
+ const unsigned long eICString_NewsAuthUsername = 242; const unsigned long eICString_NewsAuthPassword = 243;
+ const unsigned long eICText_NewsHeaders = 244;
+ const unsigned long eICString_InfoMacPreferred = 245;
+ const unsigned long eICString_Organization = 251; const unsigned long eICString_RealName = 252;
+ const unsigned long eICText_SnailMailAddress = 253;
+ const unsigned long eICString_QuotingString = 254;
+ const unsigned long eICString_GopherHost = 301;
+ const unsigned long eICBoolean_UseGopherProxy = 302; const unsigned long eICString_GopherProxy = 303;
+ const unsigned long eICBoolean_UseSocks = 321; const unsigned long eICString_SocksHost = 322;
+ const unsigned long eICString_TelnetHost = 331;
+ const unsigned long eICString_IRCHost = 341;
+ const unsigned long eICString_NTPHost = 351;
+ const unsigned long eICString_WAISGateway = 381;
+ const unsigned long eICString_FingerHost = 382; const unsigned long eICText_Plan = 383;
+ const unsigned long eICString_WhoisHost = 384;
+ const unsigned long eICString_PhHost = 385;
+ const unsigned long eICString_ArchiePreferred = 386;
+ const unsigned long eICString_UMichPreferred = 391;
+
+ const unsigned long eIICMapFlag_BinaryMask = 1; /* file should be transfered in binary as opposed to text mode*/
+ const unsigned long eIICMapFlag_ResourceForkMask = 2; /* the resource fork of the file is significant*/
+ const unsigned long eIICMapFlag_DataForkMask = 4; /* the data fork of the file is significant*/
+ const unsigned long eIICMapFlag_PostMask = 8; /* post process using post fields*/
+ const unsigned long eIICMapFlag_NotIncomingMask = 16; /* ignore this mapping for incoming files*/
+ const unsigned long eIICMapFlag_NotOutgoingMask = 32; /* ignore this mapping for outgoing files*/
+
+
+ void launchURL(in string url);
+
+ boolean hasMappingForMIMEType(in string mimetype);
+
+ boolean hasProtocolHandler(in string protocol);
+
+ // pass in a mime type or a file extension.....
+ void fillInMIMEInfo(in string mimetype, in string aFileExtension, out nsIMIMEInfo mimeinfo);
+
+ void getMIMEInfoFromExtension(in string aFileExt, out nsIMIMEInfo mimeinfo);
+
+ void getMIMEInfoFromTypeCreator(in PRUint32 aType, in PRUint32 aCreator, in string aFileExt, out nsIMIMEInfo mimeInfo);
+
+ ACString getString(in unsigned long keyenum);
+
+ unsigned long getColor(in unsigned long keyenum);
+
+ boolean getBoolean(in unsigned long keyenum);
+};
--- a/uriloader/exthandler/nsMIMEInfoImpl.cpp
+++ b/uriloader/exthandler/nsMIMEInfoImpl.cpp
@@ -58,37 +58,43 @@ NS_INTERFACE_MAP_BEGIN(nsMIMEInfoBase)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMIMEInfo, mClass == eMIMEInfo)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHandlerInfo)
NS_INTERFACE_MAP_END_THREADSAFE
// nsMIMEInfoImpl methods
// Constructors for a MIME handler.
nsMIMEInfoBase::nsMIMEInfoBase(const char *aMIMEType) :
+ mMacType(0),
+ mMacCreator(0),
mType(aMIMEType),
mClass(eMIMEInfo),
mPreferredAction(nsIMIMEInfo::saveToDisk),
mAlwaysAskBeforeHandling(PR_TRUE)
{
}
nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aMIMEType) :
+ mMacType(0),
+ mMacCreator(0),
mType(aMIMEType),
mClass(eMIMEInfo),
mPreferredAction(nsIMIMEInfo::saveToDisk),
mAlwaysAskBeforeHandling(PR_TRUE)
{
}
// Constructor for a handler that lets the caller specify whether this is a
// MIME handler or a protocol handler. In the long run, these will be distinct
// classes (f.e. nsMIMEInfo and nsProtocolInfo), but for now we reuse this class
// for both and distinguish between the two kinds of handlers via the aClass
// argument to this method, which can be either eMIMEInfo or eProtocolInfo.
nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aType, HandlerClass aClass) :
+ mMacType(0),
+ mMacCreator(0),
mType(aType),
mClass(aClass),
mPreferredAction(nsIMIMEInfo::saveToDisk),
mAlwaysAskBeforeHandling(PR_TRUE)
{
}
nsMIMEInfoBase::~nsMIMEInfoBase()
@@ -205,16 +211,52 @@ nsMIMEInfoBase::Equals(nsIMIMEInfo *aMIM
if (NS_FAILED(rv)) return rv;
*_retval = mType.Equals(type);
return NS_OK;
}
NS_IMETHODIMP
+nsMIMEInfoBase::GetMacType(PRUint32 *aMacType)
+{
+ *aMacType = mMacType;
+
+ if (!mMacType)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoBase::SetMacType(PRUint32 aMacType)
+{
+ mMacType = aMacType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoBase::GetMacCreator(PRUint32 *aMacCreator)
+{
+ *aMacCreator = mMacCreator;
+
+ if (!mMacCreator)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoBase::SetMacCreator(PRUint32 aMacCreator)
+{
+ mMacCreator = aMacCreator;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsMIMEInfoBase::SetFileExtensions(const nsACString& aExtensions)
{
mExtensions.Clear();
nsCString extList( aExtensions );
PRInt32 breakLocation = -1;
while ( (breakLocation= extList.FindChar(',') )!= -1)
{
@@ -366,16 +408,19 @@ nsMIMEInfoBase::LaunchWithURI(nsIURI* aU
}
void
nsMIMEInfoBase::CopyBasicDataTo(nsMIMEInfoBase* aOther)
{
aOther->mType = mType;
aOther->mDefaultAppDescription = mDefaultAppDescription;
aOther->mExtensions = mExtensions;
+
+ aOther->mMacType = mMacType;
+ aOther->mMacCreator = mMacCreator;
}
/* static */
nsresult
nsMIMEInfoBase::LaunchWithIProcess(nsIFile* aApp, const nsCString& aArg)
{
NS_ASSERTION(aApp, "Unexpected null pointer, fix caller");
--- a/uriloader/exthandler/nsMIMEInfoImpl.h
+++ b/uriloader/exthandler/nsMIMEInfoImpl.h
@@ -74,16 +74,20 @@ class nsMIMEInfoBase : public nsIMIMEInf
NS_IMETHOD ExtensionExists(const nsACString & aExtension, PRBool *_retval);
NS_IMETHOD AppendExtension(const nsACString & aExtension);
NS_IMETHOD GetPrimaryExtension(nsACString & aPrimaryExtension);
NS_IMETHOD SetPrimaryExtension(const nsACString & aPrimaryExtension);
NS_IMETHOD GetType(nsACString & aType);
NS_IMETHOD GetMIMEType(nsACString & aMIMEType);
NS_IMETHOD GetDescription(nsAString & aDescription);
NS_IMETHOD SetDescription(const nsAString & aDescription);
+ 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 * *aPreferredAppHandler);
NS_IMETHOD SetPreferredApplicationHandler(nsIHandlerApp * aPreferredAppHandler);
NS_IMETHOD GetPossibleApplicationHandlers(nsIMutableArray * *aPossibleAppHandlers);
NS_IMETHOD GetDefaultDescription(nsAString & aDefaultDescription);
NS_IMETHOD LaunchWithFile(nsIFile *aFile);
NS_IMETHOD LaunchWithURI(nsIURI *aURI,
nsIInterfaceRequestor *aWindowContext);
@@ -159,16 +163,17 @@ class nsMIMEInfoBase : public nsIMIMEInf
* @param aFile the associated nsILocalFile (out param)
*/
static NS_HIDDEN_(nsresult) GetLocalFileFromURI(nsIURI *aURI,
nsILocalFile **aFile);
// member variables
nsTArray<nsCString> mExtensions; ///< array of file extensions associated w/ this MIME obj
nsString mDescription; ///< human readable description
+ PRUint32 mMacType, mMacCreator; ///< Mac file type and creator
nsCString mType;
HandlerClass mClass;
nsCOMPtr<nsIHandlerApp> mPreferredApplication;
nsCOMPtr<nsIMutableArray> mPossibleApplications;
nsHandlerInfoAction mPreferredAction; ///< preferred action to associate with this type
nsString mPreferredAppDescription;
nsString mDefaultAppDescription;
PRBool mAlwaysAskBeforeHandling;
--- a/widget/src/cocoa/nsLookAndFeel.mm
+++ b/widget/src/cocoa/nsLookAndFeel.mm
@@ -33,16 +33,17 @@
* 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 "nsLookAndFeel.h"
#include "nsObjCExceptions.h"
+#include "nsIInternetConfigService.h"
#include "nsIServiceManager.h"
#include "nsNativeThemeColors.h"
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel()
{
@@ -61,17 +62,27 @@ static nscolor GetColorFromNSColor(NSCol
}
nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor)
{
nsresult res = NS_OK;
switch (aID) {
case eColor_WindowBackground:
- aColor = NS_RGB(0xff,0xff,0xff);
+ {
+ nsCOMPtr<nsIInternetConfigService> icService_wb (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+ if (icService_wb) {
+ res = icService_wb->GetColor(nsIInternetConfigService::eICColor_WebBackgroundColour, &aColor);
+ if (NS_SUCCEEDED(res))
+ return res;
+ }
+
+ aColor = NS_RGB(0xff,0xff,0xff); // default to white if we didn't find it in internet config
+ res = NS_OK;
+ }
break;
case eColor_WindowForeground:
aColor = NS_RGB(0x00,0x00,0x00);
break;
case eColor_WidgetBackground:
aColor = NS_RGB(0xdd,0xdd,0xdd);
break;
case eColor_WidgetForeground:
@@ -87,18 +98,27 @@ nsresult nsLookAndFeel::NativeGetColor(c
aColor = NS_RGB(0xa0,0xa0,0xa0);
break;
case eColor_Widget3DShadow:
aColor = NS_RGB(0x40,0x40,0x40);
break;
case eColor_TextBackground:
aColor = NS_RGB(0xff,0xff,0xff);
break;
- case eColor_TextForeground:
+ case eColor_TextForeground:
+ {
+ nsCOMPtr<nsIInternetConfigService> icService_tf (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+ if (icService_tf) {
+ res = icService_tf->GetColor(nsIInternetConfigService::eICColor_WebTextColor, &aColor);
+ if (NS_SUCCEEDED(res))
+ return res;
+ }
aColor = NS_RGB(0x00,0x00,0x00);
+ res = NS_OK;
+ }
break;
case eColor_TextSelectBackground:
res = GetMacBrushColor(kThemeBrushPrimaryHighlightColor, aColor, NS_RGB(0x00,0x00,0x00));
break;
case eColor_highlight: // CSS2 color
res = GetMacBrushColor(kThemeBrushAlternatePrimaryHighlightColor, aColor, NS_RGB(0x33,0x6F,0xCB));
break;
case eColor__moz_menuhover: