hurl.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:27k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include <string.h>
- #include <stdio.h>
- #ifndef _MAC_MACHO
- #include <InternetConfig.h>
- #endif
- #include "hxtypes.h"
- #include "hxcom.h" /* IUnknown */
- #include "ihxpckts.h" /* IHXBuffer */
- #include "platform/mac/hurl.h"
- #include "hxwintyp.h"
- #if defined(_CARBON) || defined(_MAC_UNIX)
- #include "platform/mac/mac_pref_cf.h"
- #ifndef _MAC_UNIX
- #include "filespecutils.h"
- #include "MoreFilesX.h"
- #endif
- static BOOL LaunchMacBrowserCarbon(const char* pURL, IHXPreferences* pPrefs, BOOL bBringToFront, BOOL bNewWindow);
- static BOOL GetPreferredBrowser(IHXPreferences* pPrefs, FSRef *outBrowserFSRef, OSType *outBrowserSignature);
- static void MakeHurlJavascriptURL(const char * pszURL, const char * pszWindowName,
- BOOL bSetPosition, const HXxPoint& ptWindowPos, const HXxSize& sizeWindow, CHXString& outStrURL, BOOL bUseNewJavascriptWindow);
- #else
- #include "mac_pref.h"
- #endif // _CARBON
- // Stuff for using ODOCs instead of OpenURL for Unicode UTF-8 URLs because IE 5.2 and Netscape can't
- // deal with UTF8 in URLs; we'll send ODOCs instead of OpenURL events in those cases
- Boolean IsLocalFileURLAPotentialProblemBecauseOfPercentEncodedUTF8Chars(const char *pURL);
- BOOL MakeOpenDocumentsEventFromURL(OSType appSignature, const char* pURL, AEDesc *theAppleEventPtr, Boolean bNewWindow);
- #include "platform/mac/hx_moreprocesses.h"
- #ifndef _MAC_UNIX
- #include "hx_morefiles.h"
- #include "fullpathname.h"
- #include "hxinternetconfigutils.h"
- #endif
- #include "hxresult.h"
- #include "hxprefs.h"
- const DescType kWebBrowserSuite = 'WWW!';
- const DescType kOpenUrlEventID = 'OURL';
- const DescType kOpenUrlWindowID = 'WIND';
- const DescType kCloseAllWindowsEventID = 'CLSA';
- const OSType MSIE_CREATOR = 'MSIE';
- const OSType NETSCAPE_CREATOR = 'MOSS';
- const OSType MOZILLA_CREATOR = 'MOZZ';
- const OSType AOL_CREATOR = 'AOp3';
- const OSType OMNIWEB_CREATOR = 'OWEB';
- const OSType ICAB_CREATOR = 'iCAB';
- const OSType CHIMERA_CREATOR = 'CHIM';
- const OSType OPERA_CREATOR = 'OPRA';
- const OSType SAFARI_CREATOR = 'sfri';
-
- const OSType MOSAIC_CREATOR = 'MOS!';
- const OSType MOSAIC_BrowserSuite = 'mos!';
- const OSType MOSAIC_OpenUrlEventID = 'ourl';
- // if there's no default browser signature that we can determine from HX prefs or from InternetConfig,
- // we'll look for one in this list, in this order
- static OSType BrowserCreators[]
- = { SAFARI_CREATOR, MSIE_CREATOR, NETSCAPE_CREATOR, MOZILLA_CREATOR, AOL_CREATOR,
- OMNIWEB_CREATOR, ICAB_CREATOR, CHIMERA_CREATOR, OPERA_CREATOR, 0 }; // what's Opera? Any others?
- /********************************************************************
- LaunchMacBrowserWithURL
-
- ********************************************************************/
- BOOL LaunchMacBrowserWithURL(const char* pURL, IHXPreferences* pPrefs)
- {
- const BOOL bBringToFront = TRUE;
-
- return LaunchMacBrowserWithURLOrdered(pURL, pPrefs, bBringToFront);
- }
- BOOL LaunchMacBrowserWithURLOrdered(const char* pURL, IHXPreferences* pPrefs, BOOL bBringToFront)
- {
- const BOOL bExistingWindow = FALSE;
-
- return LaunchMacBrowserWithURLWindowParam(pURL, pPrefs, bBringToFront, bExistingWindow);
- }
- BOOL LaunchMacBrowserTargetingWindow(const char* pURL, IHXPreferences* pPrefs, BOOL bBringToFront,
- const char* pTargetWindowName, BOOL bUseNewJavascriptWindow)
- {
- // if bUseNewJavascriptWindow is false, then we won't make a new window for the javascript to execute in;
- // on some browsers, this will make the javascript fail to execute if no windows are open.
-
- const BOOL kDontSetPosition = FALSE;
- HXxPoint ptUnset = { 0, 0 };
- HXxSize szUnset = { 0, 0 };
- CHXString strNewURL;
-
- MakeHurlJavascriptURL(pURL, pTargetWindowName, kDontSetPosition, ptUnset, szUnset, strNewURL, bUseNewJavascriptWindow);
- if (strNewURL.IsEmpty())
- {
- check(!"LaunchMacBrowserTargetingWindow could not make Javascript URL");
- strNewURL = pURL;
- }
-
- // we make a new window since the Javascript will blow away the existing window
- return LaunchMacBrowserWithURLWindowParam(strNewURL, pPrefs, bBringToFront, bUseNewJavascriptWindow);
- }
- BOOL LaunchMacBrowserWithURLWindowParam(const char* pURL, IHXPreferences* pPrefs, BOOL bBringToFront, BOOL bNewWindow)
- {
- #if defined(_CARBON) || defined(_MAC_UNIX)
- return LaunchMacBrowserCarbon(pURL, pPrefs, bBringToFront, bNewWindow);
- #else
-
- OSErr theErr = noErr;
- CPBusyCursor busyCursor;
-
- Size urlLen = ::strlen(pURL);
- Boolean launched = FALSE;
-
- // Check to see if the default browser is running, otherwise launch it.
- // Then send it an openURL event.
- OSType defaultBrowser = 'PNst';
- IHXBuffer* pBuffer = NULL;
- Boolean bICStarted = HXInternetConfigMac::StartUsingIC();
- if (pPrefs)
- {
- if (HXR_OK == pPrefs->ReadPref("PreferredBrowser", pBuffer))
- {
- const char* theBrowserFilePath = (const char*) pBuffer->GetBuffer();
- if (theBrowserFilePath)
- {
- FInfo applFinderInfo;
- FSSpec spec;
- if (noErr == FSSpecFromPathName(theBrowserFilePath, &spec))
- {
- if (noErr == FSpGetFInfo(&spec, &applFinderInfo))
- {
- defaultBrowser = applFinderInfo.fdCreator;
- }
- }
- }
- pBuffer->Release();
- }
- }
- /* get Preferred Browser from InternetConfig unless either
- InternetConfig isn't linked in, System 8.1, OR
- Preferences dictate a specific browser. */
- if (defaultBrowser == 'PNst')
- {
- if (ICStart) // not linked with IC for some reason - pre Sys 8.1?
- {
- unsigned char *kDontCareBrowserName = NULL;
-
- OSStatus err = HXInternetConfigMac::GetHTTPHelper(&defaultBrowser, kDontCareBrowserName);
- }
- else
- {
- defaultBrowser = NETSCAPE_CREATOR;
- }
- }
-
- OSType openBrowser = 0;
- FSSpec cachedDefaultBrowserSpec;
- {
-
- // check if any browser is already running
- if (CheckForApplicationRunning(NETSCAPE_CREATOR))
- openBrowser = NETSCAPE_CREATOR;
- else if (CheckForApplicationRunning(MSIE_CREATOR))
- openBrowser = MSIE_CREATOR;
- else if (CheckForApplicationRunning(AOL_CREATOR))
- openBrowser = AOL_CREATOR;
- if (!openBrowser)
- {
- short volindex=1;
- short vRefNum=0;
-
- // Look through all volumes for the default browser application.
- while (GetVRefnumFromIndex(volindex,&vRefNum))
- {
- short fileindex=0;
- while (noErr==HX_FSpGetAppSpecFromDesktop(defaultBrowser,fileindex,
- vRefNum,&cachedDefaultBrowserSpec))
- {
- FInfo finfo;
- FSpGetFInfo(&cachedDefaultBrowserSpec,&finfo);
- if (finfo.fdType=='APPL')
- {
- AppleEvent theEvent;
-
- //do this at idle time! don't want to launch app at interrupt time
- if (MakeOpenURLEvent(defaultBrowser, pURL, &theEvent, bNewWindow))
- {
- ProcessSerialNumber* kDontCareAboutPSN = NULL;
- short launchFlags;
-
- if (bBringToFront)
- {
- launchFlags = (launchContinue | launchNoFileFlags);
- }
- else
- {
- launchFlags = (launchContinue | launchNoFileFlags | launchDontSwitch);
- }
- theErr = FSpLaunchApplicationWithParamsAndFlags(&cachedDefaultBrowserSpec, &theEvent,
- kDontCareAboutPSN, launchFlags);
- if (theErr == noErr)
- {
- launched = TRUE;
- }
-
- (void) AEDisposeDesc(&theEvent);
- }
-
- }//if
- else
- {
- fileindex++;
- continue;
- }//else
- break;
- }//while
-
- if (launched) break;
- volindex++;
- }//while
- }//if
-
- if( !launched && openBrowser)
- {
- const BOOL bAsync = TRUE;
- launched = SendOpenURLOrdered(openBrowser,pURL, bAsync, bBringToFront, bNewWindow);
- }
-
-
- if ( bICStarted && !launched )
- {
- theErr = HXInternetConfigMac::LaunchURL(pURL);
-
- launched = (theErr == noErr);
- }
- goto CleanUp;
- }//if
- CleanUp:
- if (bICStarted)
- {
- HXInternetConfigMac::StopUsingIC();
- }
-
- return (launched);
-
- #endif // !defined _CARBON
- }
- BOOL SendOpenURL(OSType appSignature, const char* pURL, BOOL async)
- {
- const BOOL bBringToFront = TRUE;
-
- return SendOpenURLOrdered(appSignature, pURL, async, bBringToFront);
- }
- BOOL SendOpenURLOrdered(OSType appSignature, const char* pURL, BOOL async, BOOL bBringToFront, BOOL bNewWindow)
- {
- AEDesc theAppleEvent;
- AEDesc outAEReply;
- OSErr err;
-
- if (MakeOpenURLEvent(appSignature, pURL, &theAppleEvent, bNewWindow))
- {
- if (async)
- {
- err = AESend (&theAppleEvent, &outAEReply,
- kAENoReply + kAEDontRecord, kAEHighPriority, kNoTimeOut, nil, nil);
- }
- else
- {
- err = AESend (&theAppleEvent, &outAEReply,
- kAEWaitReply+kAEDontRecord, kAEHighPriority, kNoTimeOut,nil,nil);
- AEDisposeDesc(&outAEReply);
- }
-
- if (bBringToFront)
- {
- ActivateApplication(appSignature);
- }
-
- (void) AEDisposeDesc(&theAppleEvent);
- }
- else
- {
- err = -1;
- }
- return (err == noErr);
- }
- BOOL SendOpenURLSync(OSType appSignature, const char* pURL)
- {
- return SendOpenURL(appSignature,pURL,false);
- }//SendOpenURLSync
- BOOL SendOpenURLAsync(OSType appSignature, const char* pURL)
- {
- return SendOpenURL(appSignature,pURL,true);
- }//SendOpenURLASync
- // MakeOpenURLEvent
- //
- // The caller is responsible for disposing of theAppleEventPtr allocated by this routine
- BOOL MakeOpenURLEvent(OSType appSignature, const char* pURL, AEDesc *theAppleEventPtr, Boolean bNewWindow)
- {
- if (IsLocalFileURLAPotentialProblemBecauseOfPercentEncodedUTF8Chars(pURL))
- {
- // for local file URLs which have UTF8 characters in them encoded as % hex,
- // we use an ODOC event instead of the OpenURL event since IE 5.2 and Netscape 6.?
- // can't handle the UTF8 URLs
- return MakeOpenDocumentsEventFromURL(appSignature, pURL, theAppleEventPtr, bNewWindow);
- }
-
- AEDesc target;
- OSErr err;
- AEEventClass eventClass;
- AEEventID eventID;
-
- if (MOSAIC_CREATOR == appSignature)
- {
- eventClass = MOSAIC_BrowserSuite;
- eventID = MOSAIC_OpenUrlEventID;
- }
- else
- {
- eventClass = kWebBrowserSuite;
- eventID = kOpenUrlEventID;
- }
- // Create an application signature address.
- err = AECreateDesc(typeApplSignature, &appSignature, sizeof(OSType), &target);
- require_noerr(err, CreateDescFailed);
-
- // Create the Apple event
- err = AECreateAppleEvent(eventClass, eventID, &target,
- kAutoGenerateReturnID, kAnyTransactionID, theAppleEventPtr);
- require_noerr(err, AECreateAppleEventFailed);
-
- // Add the URL as the direct object
- err = AEPutParamPtr(theAppleEventPtr, keyDirectObject, typeChar, pURL, strlen(pURL));
- require_noerr(err, CouldntPutDirectObject);
-
- {
- // Add the targetted window parameter
- const long kSameWindow = -1, kNewWindow = 0;
-
- long window = bNewWindow ? kNewWindow : kSameWindow;
-
- err = AEPutParamPtr(theAppleEventPtr, kOpenUrlWindowID, typeLongInteger, &window, sizeof(window));
- require_noerr(err, CouldntPutWindow);
-
- (void) AEDisposeDesc(&target);
- return TRUE;
- }
- // error handling: reverse-order cleanup
- CouldntPutWindow:
- CouldntPutDirectObject:
- (void) AEDisposeDesc(theAppleEventPtr);
- AECreateAppleEventFailed:
- (void) AEDisposeDesc(&target);
- CreateDescFailed:
-
- return FALSE;
- }
- BOOL MakeOpenDocumentsEventFromURL(OSType appSignature, const char* pURL, AEDesc *theAppleEventPtr, Boolean bNewWindow)
- {
-
- #ifdef _MAC_UNIX
- HX_ASSERT("unimplemented" == NULL);
- #else
- AEDesc target;
- OSErr err;
- AliasHandle alias = NULL;
- CHXFileSpecifier fileSpec;
- FSRef fileRef;
-
- theAppleEventPtr->dataHandle = NULL;
- target.dataHandle = NULL;
-
- fileSpec.SetFromURL(pURL);
- require(CHXFileSpecUtils::FileExists(fileSpec), bail);
-
- fileRef = (FSRef) fileSpec;
-
- // Create an application signature address.
- err = AECreateDesc(typeApplSignature, &appSignature, sizeof(OSType), &target);
- require_noerr(err, bail);
-
- // Create the Apple event
- err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &target,
- kAutoGenerateReturnID, kAnyTransactionID, theAppleEventPtr);
- require_noerr(err, bail);
-
- // Add an alias as the direct object
- err = FSNewAlias(NULL, &fileRef, &alias);
- require_noerr(err, bail);
-
- err = AEPutParamPtr(theAppleEventPtr, keyDirectObject, typeAlias, *alias, ::GetHandleSize((Handle) alias));
- require_noerr(err, bail);
-
- (void) AEDisposeDesc(&target);
- DisposeHandle((Handle) alias);
- return TRUE;
- // error handling: reverse-order cleanup
- bail:
- if (theAppleEventPtr->dataHandle) (void) AEDisposeDesc(theAppleEventPtr);
- if (target.dataHandle) (void) AEDisposeDesc(&target);
- if (alias) DisposeHandle((Handle) alias);
-
- return FALSE;
- #endif
- }
- #if defined(_CARBON) || defined(_MAC_UNIX)
- BOOL GetPreferredOrSystemBrowser(IHXPreferences* pPrefs, FSRef *outBrowserFSRef, OSType *outBrowserSignature)
- {
- #ifdef _MAC_UNIX
- HX_ASSERT("GetPreferredOrSystemBrowser unimplemented" == NULL);
- #else
- FSRef browserFSRef;
- OSType defaultBrowserSignature;
- BOOL bSuccess;
-
- ZeroInit(&browserFSRef);
-
- bSuccess = GetPreferredBrowser(pPrefs, &browserFSRef, &defaultBrowserSignature);
- if (!bSuccess)
- {
- // there isn't a preferred browser in prefs; get one from InternetConfig, or else look
- // for any of our known browsers
-
- unsigned char *kDontCareBrowserName = NULL;
- OSErr err;
-
- err = HXInternetConfigMac::GetHTTPHelper(&defaultBrowserSignature, kDontCareBrowserName);
- if (err == noErr)
- {
- err = GetApplicationFSRefFromSignature(defaultBrowserSignature, &browserFSRef);
- }
-
- if (err != noErr)
- {
- defaultBrowserSignature = NETSCAPE_CREATOR;
- for (int idx = 0; BrowserCreators[idx] != 0; idx++)
- {
- if (noErr == GetApplicationFSRefFromSignature(BrowserCreators[idx], &browserFSRef))
- {
- defaultBrowserSignature = BrowserCreators[idx];
- break;
- }
- }
- }
- if (err == noErr)
- {
- bSuccess = TRUE;
- }
- }
-
- if (outBrowserSignature) *outBrowserSignature = defaultBrowserSignature;
- if (outBrowserFSRef) *outBrowserFSRef = browserFSRef;
-
- return bSuccess;
- #endif
- }
- BOOL GetPreferredBrowser(IHXPreferences* pPrefs, FSRef *outBrowserFSRef, OSType *outBrowserSignature)
- {
- #ifdef _MAC_UNIX
- HX_ASSERT("GetPreferredBrowser unimplemented" == NULL);
- #else
- HX_RESULT res;
- OSStatus err;
- const char* theBrowserPref;
- FinderInfo fileInfo;
- IHXBuffer* pBuffer = NULL;
-
- check(outBrowserFSRef != NULL && outBrowserSignature != NULL);
-
- require_nonnull_quiet(pPrefs, NoPrefsAvailable);
-
- res = pPrefs->ReadPref("PreferredBrowser", pBuffer);
- require_quiet(SUCCEEDED(res), CantGetPreferredBrowser);
-
- theBrowserPref = (const char*) pBuffer->GetBuffer();
- require_nonnull(theBrowserPref, CantGetPrefFromBuffer);
-
- require_quiet(strlen(theBrowserPref) > 1, NoBrowserSet);
-
- if (strlen(theBrowserPref) == 4)
- {
- // the pref is an OSType
- *outBrowserSignature = *(OSType *) theBrowserPref;
-
- err = GetApplicationFSRefFromSignature(*outBrowserSignature, outBrowserFSRef);
- require_noerr_quiet(err, CantGetBrowserFSRef);
- }
- else
- {
- // the pref is a persistent file spec or a path
- CHXFileSpecifier browserSpec;
-
- (void) browserSpec.SetFromPersistentString(theBrowserPref);
- require(browserSpec.IsSet(), CantMakeBrowserSpec);
-
- *outBrowserFSRef = (FSRef) browserSpec;
-
- err = FSGetFinderInfo(outBrowserFSRef, &fileInfo, NULL, NULL);
- require_noerr_quiet(err, CantGetBrowserType);
-
- *outBrowserSignature = fileInfo.file.fileCreator;
- }
-
- HX_RELEASE(pBuffer);
- return TRUE;
- CantGetBrowserType:
- CantGetAppRef:
- CantMakeBrowserSpec:
- CantGetBrowserFSRef:
- NoBrowserSet:
- CantGetPrefFromBuffer:
- HX_RELEASE(pBuffer);
- CantGetPreferredBrowser:
- NoPrefsAvailable:
- return FALSE;
- #endif
- }
- static BOOL LaunchMacBrowserCarbon(const char* pURL, IHXPreferences* pPrefs, BOOL bBringToFront, BOOL bNewWindow)
- {
- #ifdef _MAC_UNIX
- HX_ASSERT("LaunchMacBrowserCarbon unimplemented" == NULL);
- #else
- FSRef browserFSRef;
- //BOOL bSuccess;
- OSType defaultBrowserSignature;
- OSType openBrowserSignature;
- OSStatus err;
- BOOL bLaunched;
- int idx;
- bLaunched = FALSE;
-
- // get the preferred browser from prefs, if it's available; otherwise, find some other browser
- // to default to
-
- defaultBrowserSignature = 0;
- ZeroInit(&browserFSRef);
-
- GetPreferredOrSystemBrowser(pPrefs, &browserFSRef, &defaultBrowserSignature);
-
- // see if the preferred browser, or any other, is running
- openBrowserSignature = 0;
- if (CheckForApplicationRunning(defaultBrowserSignature))
- {
- openBrowserSignature = defaultBrowserSignature;
- }
- else
- {
- for (idx = 0; BrowserCreators[idx] != 0; idx++)
- {
- if (CheckForApplicationRunning(BrowserCreators[idx]))
- {
- openBrowserSignature = BrowserCreators[idx];
- break;
- }
- }
- }
-
- // CZ 10/29/02 - if a browser is running and the current app is that browser
- // then we must be running the embedded player
- // in this case don't force the browser to come to the front
- // ie. a hurl from the embedded player shouldn't bring the browser to the front
-
- if (GetCurrentAppSignature() == openBrowserSignature)
- {
- bBringToFront = FALSE;
- }
-
- // GR 10/1/02 Nasty hack: Netscape 6 and 7 can't deal with URLs in standard OS X format, so
- // for that browser and for local URLs only, we'll make a bogus old-style file:/// URL
- // by taking a full path and replacing colons with slashes
-
- CHXString strNetscapeLocalURL;
- if (openBrowserSignature == 'MOSS' || (openBrowserSignature == 0 && defaultBrowserSignature == 'MOSS'))
- {
- CHXFileSpecifier fileSpec;
-
- fileSpec.SetFromURL(pURL);
- if (fileSpec.IsSet())
- {
- CHXString strPathMunge = fileSpec.GetPathName();
- for (int idx = 0; idx < strPathMunge.GetLength(); idx++)
- {
- if (strPathMunge[idx] == ':') strPathMunge.SetAt(idx, '/');
- else if (strPathMunge[idx] == '/') strPathMunge.SetAt(idx, ':');
- }
- strPathMunge.FindAndReplace(" ", "%20", TRUE);
-
- strNetscapeLocalURL = "file:///";
- strNetscapeLocalURL += strPathMunge;
- pURL = (const char *) strNetscapeLocalURL;
- }
- }
-
- // try to send the URL via an Apple event to an open browser
- if (openBrowserSignature)
- {
- const BOOL bAsync = TRUE;
-
- bLaunched = SendOpenURLOrdered(openBrowserSignature, pURL, bAsync, bBringToFront, bNewWindow);
- }
-
- // if necessary, launch a browser
- if (!bLaunched)
- {
- if (IsRunningNativeOnMacOSX())
- {
- CHXFileSpecifier tempSpec;
- if (IsLocalFileURLAPotentialProblemBecauseOfPercentEncodedUTF8Chars(pURL))
- {
- // we handle the UTF8 problem only with local files; avoid the problem
- // by opening file document directly instead of using a temp file
- tempSpec.SetFromURL(pURL);
- }
- else
- {
- // Is OS X we can't pass an Apple event with the launch (can we?), so we'll make a document to
- // open which redirects to the real page
-
- // make a temp file with the redirect to the real URL; we do this for network URLs
- // or for local URLs that don't have UTF-8
-
- CHXDirSpecifier tempDirSpec;
- CHXString strRedirect;
- const BOOL kReplaceExistingTempFile = TRUE;
-
- strRedirect = "<HEAD>n<META HTTP-EQUIV="refresh" CONTENT="0;URL=";
- strRedirect += pURL;
- strRedirect += "">n</HEAD>n";
-
- // make a file spec for a temp file, create the file and open it,
- // and write the redirect into the file
-
- tempDirSpec = CHXFileSpecUtils::MacFindFolder(kOnAppropriateDisk, kChewableItemsFolderType);
- tempSpec = CHXFileSpecUtils::GetUniqueTempFileSpec(tempDirSpec, "HX_hurl_%.html", "%");
- check(tempSpec.IsSet());
-
- err = CHXFileSpecUtils::WriteTextFile(tempSpec, strRedirect, kReplaceExistingTempFile);
- check_noerr(err);
- }
-
- // launch the browser with that temp file
-
- if (err == noErr)
- {
- LSLaunchFSRefSpec launchSpec;
-
- ZeroInit(&launchSpec);
- launchSpec.appRef = &browserFSRef;
- launchSpec.numDocs = 1;
- launchSpec.itemRefs = (FSRef *) tempSpec;
- launchSpec.launchFlags = kLSLaunchDefaults | (bBringToFront ? 0 : kLSLaunchDontSwitch);
-
- err = LSOpenFromRefSpec(&launchSpec, NULL); // NULL -> don't care about FSRef of launched app
- }
- if (err == noErr)
- {
- bLaunched = TRUE;
- }
-
- }
- else
- {
- // OS 9 launch
- AppleEvent theEvent;
- if (MakeOpenURLEvent(defaultBrowserSignature, pURL, &theEvent, bNewWindow))
- {
- ProcessSerialNumber* kDontCareAboutPSN = NULL;
- short launchFlags;
- FSSpec appSpec;
-
- launchFlags = (launchContinue | launchNoFileFlags);
- if (!bBringToFront)
- {
- launchFlags |= launchDontSwitch;
- }
-
- err = FindApplicationBySignature(defaultBrowserSignature, &appSpec);
-
- if (err == noErr)
- {
- err = FSpLaunchApplicationWithParamsAndFlags(&appSpec, &theEvent,
- kDontCareAboutPSN, launchFlags);
- }
- if (err == noErr)
- {
- bLaunched = TRUE;
- }
-
- (void) AEDisposeDesc(&theEvent);
- }
- }
- }
-
- // last ditch effort is to rely on InternetConfig
- if (!bLaunched)
- {
- err = HXInternetConfigMac::LaunchURL(pURL);
- if (err == noErr)
- {
- bLaunched = TRUE;
- }
- }
-
- return bLaunched;
- #endif
- }
- Boolean IsLocalFileURLAPotentialProblemBecauseOfPercentEncodedUTF8Chars(const char *pURL)
- {
- // In Mac OS X, 8-bit characters become %-encoded Unicode in the URL, like
- // this:
- // folder