bug 263546: move external protocol warning down a level, r=jsr,sr=darin

This commit is contained in:
dveditz%cruzio.com 2004-10-25 07:46:01 +00:00
parent b0a51a539c
commit 430d42c69d
19 changed files with 277 additions and 207 deletions

View File

@ -191,7 +191,6 @@ pref("privacy.popups.policy", 1);
pref("privacy.popups.usecustom", true);
pref("privacy.popups.firstTime", true);
pref("network.protocols.useSystemDefaults", false); // set to true if user links should use system default handlers
pref("network.cookie.cookieBehavior", 0); // cookies enabled
pref("network.cookie.enableForCurrentSessionOnly", false);
@ -240,8 +239,16 @@ pref("signon.rememberSignons", true);
pref("signon.expireMasterPassword", false);
pref("signon.SignonFileName", "signons.txt");
// We want to make sure mail URLs are handled externally...
pref("network.protocol-handler.external.mailto", true); // for mail
pref("network.protocol-handler.external.news" , true); // for news
pref("network.protocol-handler.external.news", true); // for news
pref("network.protocol-handler.external.snews", true); // for secure news
pref("network.protocol-handler.external.nntp", true); // also news
// ...without warning dialogs
pref("network.protocol-handler.warn-external.mailto", false);
pref("network.protocol-handler.warn-external.news", false);
pref("network.protocol-handler.warn-external.snews", false);
pref("network.protocol-handler.warn-external.nntp", false);
// By default, all protocol handlers are exposed. This means that
// the browser will respond to openURL commands for all URL types.
@ -249,6 +256,9 @@ pref("network.protocol-handler.external.news" , true); // for news
// failing over to the system handlers.
pref("network.protocol-handler.expose-all", true);
pref("network.protocol-handler.expose.mailto", false);
pref("network.protocol-handler.expose.news", false);
pref("network.protocol-handler.expose.snews", false);
pref("network.protocol-handler.expose.nntp", false);
// Default security warning dialogs to show once.
pref("security.warn_entering_secure.show_once", true);

View File

@ -536,7 +536,6 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
nsIDocShell** aDocShell,
nsIRequest** aRequest)
{
PRBool earlyReturn = PR_FALSE;
{
// defer to an external protocol handler if necessary...
nsCOMPtr<nsIExternalProtocolService> extProtService = do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
@ -549,17 +548,11 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
PRBool isExposed;
nsresult rv = extProtService->IsExposedProtocol(scheme.get(), &isExposed);
if (NS_SUCCEEDED(rv) && !isExposed) {
rv = extProtService->LoadUrl(aURI);
if (NS_SUCCEEDED(rv))
earlyReturn = PR_TRUE;
else
NS_WARNING("failed to launch external protocol handler");
return extProtService->LoadUrl(aURI);
}
}
}
}
if (earlyReturn)
return NS_OK;
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);

View File

@ -100,19 +100,20 @@ pref("image.animation_mode", "normal");
// prevents necko connecting to ports 1-5 unless the protocol
// overrides.
// Default action for unlisted external protocol handlers
pref("network.protocol-handler.external-default", true); // OK to load
pref("network.protocol-handler.warn-external-default", true); // warn before load
// Prevent using external protocol handlers for these schemes
pref("network.protocol-handler.external.hcp", false);
pref("network.protocol-handler.external.vbscript", false);
pref("network.protocol-handler.external.javascript", false);
pref("network.protocol-handler.external.data", false);
pref("network.protocol-handler.external.ms-help", false);
pref("network.protocol-handler.external.vnd.ms.radio", false);
pref("network.protocol-handler.external.help", false);
pref("network.protocol-handler.external.disk", false);
// Default action for unlisted external protocol handlers
// 0 == never load, 1 == always load, 2 == ask the user
pref("network.protocol-handler.external-default", 2);
// An exposed protocol handler is one that can be used in all contexts. A
// non-exposed protocol handler is one that can only be used internally by the
// application. For example, a non-exposed protocol would not be loaded by the

View File

@ -436,10 +436,15 @@ pref("image.animation_mode", "normal");
// prevents necko connecting to ports 1-5 unless the protocol
// overrides.
// Default action for unlisted external protocol handlers
pref("network.protocol-handler.external-default", true); // OK to load
pref("network.protocol-handler.warn-external-default", true); // warn before load
// Prevent using external protocol handlers for these schemes
pref("network.protocol-handler.external.hcp", false);
pref("network.protocol-handler.external.vbscript", false);
pref("network.protocol-handler.external.javascript", false);
pref("network.protocol-handler.external.data", false);
pref("network.protocol-handler.external.ms-help", false);
pref("network.protocol-handler.external.shell", false);
pref("network.protocol-handler.external.vnd.ms.radio", false);
@ -448,10 +453,6 @@ pref("network.protocol-handler.external.disk", false);
pref("network.protocol-handler.external.disks", false);
pref("network.protocol-handler.external.afp", false);
// Default action for unlisted external protocol handlers
// 0 == never load, 1 == always load, 2 == ask the user
pref("network.protocol-handler.external-default", 2);
// An exposed protocol handler is one that can be used in all contexts. A
// non-exposed protocol handler is one that can only be used internally by the
// application. For example, a non-exposed protocol would not be loaded by the

View File

@ -76,6 +76,7 @@ REQUIRES = xpcom \
intl \
uconv \
docshell \
windowwatcher \
$(NULL)
ifdef MOZ_PHOENIX

View File

@ -81,7 +81,7 @@ NS_IMETHODIMP nsOSHelperAppService::ExternalProtocolHandlerExists(const char * a
return NS_OK;
}
NS_IMETHODIMP nsOSHelperAppService::LoadUrl(nsIURI * aURL)
nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
{
LOG(("-- nsOSHelperAppService::LoadUrl\n"));
nsresult rv = NS_OK;

View File

@ -57,7 +57,7 @@ public:
// override nsIExternalProtocolService methods
NS_IMETHOD ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
NS_IMETHOD LoadUrl(nsIURI * aURL);
nsresult LoadUriInternal(nsIURI * aURL);
// GetFileTokenForPath must be implemented by each platform.
// platformAppPath --> a platform specific path to an application that we got out of the

View File

@ -118,7 +118,7 @@ NS_IMETHODIMP nsOSHelperAppService::ExternalProtocolHandlerExists(const char * a
return rv;
}
NS_IMETHODIMP nsOSHelperAppService::LoadUrl(nsIURI * aURL)
nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
{
nsCAutoString url;
nsresult rv = NS_ERROR_FAILURE;

View File

@ -56,7 +56,7 @@ public:
// override nsIExternalProtocolService methods
NS_IMETHOD ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
NS_IMETHOD LoadUrl(nsIURI * aURL);
nsresult LoadUriInternal(nsIURI * aURL);
// method overrides --> used to hook the mime service into internet config....
NS_IMETHOD GetFromTypeAndExtension(const nsACString& aType, const nsACString& aFileExt, nsIMIMEInfo ** aMIMEInfo);

View File

@ -102,6 +102,7 @@
#include "nsIMIMEHeaderParam.h"
#include "nsIPrefService.h"
#include "nsIWindowWatcher.h"
#include "nsIGlobalHistory.h" // to mark downloads as visited
@ -1063,8 +1064,211 @@ NS_IMETHODIMP nsExternalHelperAppService::IsExposedProtocol(const char * aProtoc
NS_IMETHODIMP nsExternalHelperAppService::LoadUrl(nsIURI * aURL)
{
// this method should only be implemented by each OS specific implementation of this service.
return NS_ERROR_NOT_IMPLEMENTED;
return LoadURI(aURL, nsnull);
}
// nsExternalHelperAppService::LoadURI() may now pose a confirm dialog
// that existing callers aren't expecting. We must do it on an event
// callback to make sure we don't hang someone up.
struct extLoadRequest : PLEvent {
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIPrompt> prompt;
};
void *PR_CALLBACK
nsExternalHelperAppService::handleExternalLoadEvent(PLEvent *event)
{
extLoadRequest* req = NS_STATIC_CAST(extLoadRequest*, event);
if (req && sSrv && sSrv->isExternalLoadOK(req->uri, req->prompt))
sSrv->LoadUriInternal(req->uri);
return nsnull;
}
static void PR_CALLBACK destroyExternalLoadEvent(PLEvent *event)
{
delete NS_STATIC_CAST(extLoadRequest*, event);
}
NS_IMETHODIMP nsExternalHelperAppService::LoadURI(nsIURI * aURL, nsIPrompt * aPrompt)
{
// post external load event
nsCOMPtr<nsIEventQueue> eventQ;
nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ));
if (NS_FAILED(rv))
return rv;
extLoadRequest *event = new extLoadRequest;
if (!event)
return NS_ERROR_OUT_OF_MEMORY;
event->uri = aURL;
event->prompt = aPrompt;
PL_InitEvent(event, nsnull, handleExternalLoadEvent, destroyExternalLoadEvent);
rv = eventQ->PostEvent(event);
if (NS_FAILED(rv))
PL_DestroyEvent(event);
return rv;
}
// helper routines used by LoadURI to check whether we're allowed
// to load external schemes and whether or not to warn the user
static const char kExternalProtocolPrefPrefix[] = "network.protocol-handler.external.";
static const char kExternalProtocolDefaultPref[] = "network.protocol-handler.external-default";
static const char kExternalWarningPrefPrefix[] = "network.protocol-handler.warn-external.";
static const char kExternalWarningDefaultPref[] = "network.protocol-handler.warn-external-default";
PRBool nsExternalHelperAppService::isExternalLoadOK(nsIURI* aURL, nsIPrompt* aPrompt)
{
if (!aURL)
return PR_FALSE;
nsCAutoString scheme;
aURL->GetScheme(scheme);
if (scheme.IsEmpty())
return PR_FALSE; // must have a scheme
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (!prefs)
return PR_FALSE; // deny if we can't check prefs
// Deny load if the prefs say to do so
nsCAutoString externalPref(kExternalProtocolPrefPrefix);
externalPref += scheme;
PRBool allowLoad = PR_FALSE;
nsresult rv = prefs->GetBoolPref(externalPref.get(), &allowLoad);
if (NS_FAILED(rv))
{
// no scheme-specific value, check the default
rv = prefs->GetBoolPref(kExternalProtocolDefaultPref, &allowLoad);
}
if (NS_FAILED(rv) || !allowLoad)
return PR_FALSE; // explicitly denied or missing default pref
// allowLoad is now true. See whether we have to ask the user
nsCAutoString warningPref(kExternalWarningPrefPrefix);
warningPref += scheme;
PRBool warn = PR_TRUE;
rv = prefs->GetBoolPref(warningPref.get(), &warn);
if (NS_FAILED(rv))
{
// no scheme-specific value, check the default
rv = prefs->GetBoolPref(kExternalWarningDefaultPref, &warn);
}
if (NS_FAILED(rv) || warn)
{
// explicit "warn" setting or missing default pref:
// we must ask the user before loading this type externally
PRBool remember = PR_FALSE;
allowLoad = promptForScheme(aURL, aPrompt, &remember);
if (remember)
{
if (allowLoad)
// suppress future warnings for this scheme
prefs->SetBoolPref(warningPref.get(), PR_FALSE);
else
// prevent externally loading this scheme in the future
prefs->SetBoolPref(externalPref.get(), PR_FALSE);
}
}
return allowLoad;
}
PRBool nsExternalHelperAppService::promptForScheme(nsIURI* aURI,
nsIPrompt* aPrompt,
PRBool *aRemember)
{
// if no prompt passed in get one from the windowwatcher
nsCOMPtr<nsIPrompt> prompt(aPrompt);
if (!prompt)
{
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
if (wwatch)
wwatch->GetNewPrompter(0, getter_AddRefs(prompt));
}
if (!prompt) {
NS_ERROR("No prompt to warn user about external load, denying");
return PR_FALSE; // told to warn but no prompt: deny
}
// load the strings we need
nsCOMPtr<nsIStringBundleService> sbSvc(do_GetService(NS_STRINGBUNDLE_CONTRACTID));
if (!sbSvc) {
NS_ERROR("Couldn't load StringBundleService");
return PR_FALSE;
}
nsCOMPtr<nsIStringBundle> appstrings;
nsresult rv = sbSvc->CreateBundle("chrome://global/locale/appstrings.properties",
getter_AddRefs(appstrings));
if (NS_FAILED(rv) || !appstrings) {
NS_ERROR("Failed to create appstrings.properties bundle");
return PR_FALSE;
}
nsCAutoString spec;
aURI->GetSpec(spec);
NS_ConvertUTF8toUTF16 uri(spec);
nsCAutoString asciischeme;
aURI->GetScheme(asciischeme);
NS_ConvertUTF8toUTF16 scheme(asciischeme);
nsXPIDLString desc;
GetApplicationDescription(asciischeme, desc);
nsXPIDLString title;
appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolTitle").get(),
getter_Copies(title));
nsXPIDLString checkMsg;
appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolChkMsg").get(),
getter_Copies(checkMsg));
nsXPIDLString launchBtn;
appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolLaunchBtn").get(),
getter_Copies(launchBtn));
if (desc.IsEmpty())
appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolUnknown").get(),
getter_Copies(desc));
nsXPIDLString message;
const PRUnichar* msgArgs[] = { scheme.get(), uri.get(), desc.get() };
appstrings->FormatStringFromName(NS_LITERAL_STRING("externalProtocolPrompt").get(),
msgArgs,
NS_ARRAY_LENGTH(msgArgs),
getter_Copies(message));
if (scheme.IsEmpty() || uri.IsEmpty() || title.IsEmpty() ||
checkMsg.IsEmpty() || launchBtn.IsEmpty() || message.IsEmpty() ||
desc.IsEmpty())
return PR_FALSE;
// all pieces assembled, now we can pose the dialog
PRInt32 choice = 1; // assume "cancel" in case of failure
rv = prompt->ConfirmEx(title.get(), message.get(),
nsIPrompt::BUTTON_DELAY_ENABLE +
nsIPrompt::BUTTON_POS_1_DEFAULT +
(nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) +
(nsIPrompt::BUTTON_TITLE_CANCEL * nsIPrompt::BUTTON_POS_1),
launchBtn.get(), 0, 0, checkMsg.get(),
aRemember, &choice);
if (NS_SUCCEEDED(rv) && choice == 0)
return PR_TRUE;
return PR_FALSE;
}
NS_IMETHODIMP nsExternalHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
@ -1811,6 +2015,11 @@ nsresult nsExternalAppHandler::ExecuteDesiredAction()
// XXX Put progress dialog in barber-pole mode
// and change text to say "Copying from:".
rv = MoveFile(mFinalFileDestination);
if (NS_SUCCEEDED(rv) && action == nsIMIMEInfo::saveToDisk)
{
nsCOMPtr<nsILocalFile> destfile(do_QueryInterface(mFinalFileDestination));
sSrv->FixFilePermissions(destfile);
}
}
// Notify dialog that download is complete.
@ -1990,7 +2199,6 @@ nsresult nsExternalAppHandler::MoveFile(nsIFile * aNewFileLocation)
if (directoryLocation)
{
rv = mTempFile->MoveToNative(directoryLocation, fileName);
sSrv->FixFilePermissions(fileToUse);
}
if (NS_FAILED(rv))
{

View File

@ -70,6 +70,8 @@
#include "nsIObserver.h"
#include "nsCOMArray.h"
#include "nsWeakReference.h"
#include "nsIPrompt.h"
#include "nsEventQueueUtils.h"
class nsExternalAppHandler;
class nsIMIMEInfo;
@ -309,6 +311,16 @@ protected:
* Array for the files that should be deleted
*/
nsCOMArray<nsILocalFile> mTemporaryFilesList;
/**
* OS-specific loading of external URLs
*/
virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI * aURL) = 0;
NS_HIDDEN_(PRBool) isExternalLoadOK(nsIURI* aURI, nsIPrompt* aPrompt);
NS_HIDDEN_(PRBool) promptForScheme(nsIURI* aURI, nsIPrompt* aPrompt, PRBool *aRemember);
// friend event handler that accesses the external loading functions
static void *PR_CALLBACK handleExternalLoadEvent(PLEvent *event);
};
/**

View File

@ -61,7 +61,6 @@
#include "nsIExternalProtocolService.h"
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
static const char kExternalProtocolPrefPrefix[] = "network.protocol-handler.external.";
@ -83,15 +82,14 @@ public:
nsresult SetURI(nsIURI*);
private:
nsresult OpenURL();
private:
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIURI> mOriginalURI;
nsresult mStatus;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
PRBool PromptForScheme(nsIURI *aURI);
};
NS_IMPL_THREADSAFE_ADDREF(nsExtProtocolChannel)
@ -168,158 +166,29 @@ nsresult nsExtProtocolChannel::SetURI(nsIURI* aURI)
return NS_OK;
}
PRBool nsExtProtocolChannel::PromptForScheme(nsIURI* aURI)
{
// deny the load if we aren't able to ask but prefs say we should
nsCAutoString scheme;
nsresult rv = aURI->GetScheme(scheme);
if (!mCallbacks) {
NS_WARNING("Notification Callbacks not set!");
return PR_FALSE;
}
nsCOMPtr<nsIPrompt> prompt = do_GetInterface(mCallbacks);
if (!prompt) {
NS_WARNING("No prompt interface on channel");
return PR_FALSE;
}
nsCOMPtr<nsIStringBundleService> sbSvc(do_GetService(NS_STRINGBUNDLE_CONTRACTID));
if (!sbSvc) {
NS_WARNING("Couldn't load StringBundleService");
return PR_FALSE;
}
nsXPIDLString desc;
nsCOMPtr<nsIExternalProtocolService> extProtService (do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
if (extProtService)
extProtService->GetApplicationDescription(scheme, desc);
nsCOMPtr<nsIStringBundle> appstrings;
rv = sbSvc->CreateBundle("chrome://global/locale/appstrings.properties",
getter_AddRefs(appstrings));
if (NS_FAILED(rv) || !appstrings) {
NS_WARNING("Failed to create appstrings.properties bundle");
return PR_FALSE;
}
nsCAutoString spec;
aURI->GetSpec(spec);
NS_ConvertUTF8toUTF16 uri(spec);
NS_ConvertUTF8toUTF16 utf16scheme(scheme);
nsXPIDLString title;
appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolTitle").get(),
getter_Copies(title));
nsXPIDLString checkMsg;
appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolChkMsg").get(),
getter_Copies(checkMsg));
nsXPIDLString launchBtn;
appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolLaunchBtn").get(),
getter_Copies(launchBtn));
if (desc.IsEmpty())
appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolUnknown").get(),
getter_Copies(desc));
nsXPIDLString message;
const PRUnichar* msgArgs[] = { utf16scheme.get(), uri.get(), desc.get() };
appstrings->FormatStringFromName(NS_LITERAL_STRING("externalProtocolPrompt").get(),
msgArgs,
NS_ARRAY_LENGTH(msgArgs),
getter_Copies(message));
if (utf16scheme.IsEmpty() || uri.IsEmpty() || title.IsEmpty() ||
checkMsg.IsEmpty() || launchBtn.IsEmpty() || message.IsEmpty() ||
desc.IsEmpty())
return PR_FALSE;
// all pieces assembled, now we can pose the dialog
PRBool allowLoad = PR_FALSE;
PRBool remember = PR_FALSE;
PRInt32 choice = 1; // assume "cancel" in case of failure
rv = prompt->ConfirmEx(title.get(), message.get(),
nsIPrompt::BUTTON_DELAY_ENABLE +
nsIPrompt::BUTTON_POS_1_DEFAULT +
(nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) +
(nsIPrompt::BUTTON_TITLE_CANCEL * nsIPrompt::BUTTON_POS_1),
launchBtn.get(), 0, 0, checkMsg.get(),
&remember, &choice);
if (NS_SUCCEEDED(rv))
{
if (choice == 0)
allowLoad = PR_TRUE;
if (remember)
{
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (prefs)
{
nsCAutoString prefname(kExternalProtocolPrefPrefix);
prefname += scheme;
prefs->SetBoolPref(prefname.get(), allowLoad);
}
}
}
return allowLoad;
}
nsresult nsExtProtocolChannel::OpenURL()
{
nsCOMPtr<nsIExternalProtocolService> extProtService (do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
nsCAutoString urlScheme;
mUrl->GetScheme(urlScheme);
if (extProtService)
{
#ifdef DEBUG
nsCAutoString urlScheme;
mUrl->GetScheme(urlScheme);
PRBool haveHandler = PR_FALSE;
extProtService->ExternalProtocolHandlerExists(urlScheme.get(), &haveHandler);
NS_ASSERTION(haveHandler, "Why do we have a channel for this url if we don't support the protocol?");
#endif
// Check that it's OK to hand this scheme off to the OS
PRBool allowLoad = PR_FALSE;
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (prefs)
// get an nsIPrompt from the channel if we can
nsCOMPtr<nsIPrompt> prompt;
if (mCallbacks)
{
// check whether it's explicitly approved or denied in prefs
nsCAutoString schemePref(kExternalProtocolPrefPrefix);
schemePref += urlScheme;
nsresult rv = prefs->GetBoolPref(schemePref.get(), &allowLoad);
if (NS_FAILED(rv))
{
// scheme not explicitly listed, what is the default action?
const PRInt32 kExternalProtocolNever = 0;
const PRInt32 kExternalProtocolAlways = 1;
const PRInt32 kExternalProtocolAsk = 2;
PRInt32 externalDefault = kExternalProtocolAsk;
prefs->GetIntPref("network.protocol-handler.external-default",
&externalDefault);
if (externalDefault == kExternalProtocolAlways)
{
// original behavior -- just do it
allowLoad = PR_TRUE;
}
else if (externalDefault == kExternalProtocolAsk)
{
allowLoad = PromptForScheme(mUrl);
}
}
mCallbacks->GetInterface(NS_GET_IID(nsIPrompt), getter_AddRefs(prompt));
}
if (allowLoad)
return extProtService->LoadUrl(mUrl);
return extProtService->LoadURI(mUrl, prompt);
}
return NS_ERROR_FAILURE;
}
@ -329,44 +198,9 @@ NS_IMETHODIMP nsExtProtocolChannel::Open(nsIInputStream **_retval)
return NS_ERROR_NO_CONTENT; // force caller to abort.
}
static void *PR_CALLBACK handleExtProtoEvent(PLEvent *event)
{
nsExtProtocolChannel *channel =
NS_STATIC_CAST(nsExtProtocolChannel*, PL_GetEventOwner(event));
NS_ASSERTION(channel, "Where has the channel gone?");
channel->OpenURL();
return nsnull;
}
static void PR_CALLBACK destroyExtProtoEvent(PLEvent *event)
{
nsExtProtocolChannel *channel =
NS_STATIC_CAST(nsExtProtocolChannel*, PL_GetEventOwner(event));
NS_ASSERTION(channel, "Where has the channel gone?");
NS_RELEASE(channel);
delete event;
}
NS_IMETHODIMP nsExtProtocolChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
{
nsCOMPtr<nsIEventQueue> eventQ;
nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(eventQ));
if (NS_FAILED(rv))
return rv;
PLEvent *event = new PLEvent;
if (event)
{
NS_ADDREF_THIS();
PL_InitEvent(event, this, handleExtProtoEvent, destroyExtProtoEvent);
rv = eventQ->PostEvent(event);
if (NS_FAILED(rv))
PL_DestroyEvent(event);
}
OpenURL();
return NS_ERROR_NO_CONTENT; // force caller to abort.
}

View File

@ -41,6 +41,7 @@
interface nsIURI;
interface nsIFile;
interface nsIPrompt;
/**
* The external protocol service is used for finding and launching
@ -78,6 +79,15 @@ interface nsIExternalProtocolService : nsISupports
*/
void loadUrl (in nsIURI aURL);
/**
* Used to load a URI via an external application. Might prompt the user for
* permission to load the external application. Replaces loadUrl()
*
* @param aURI The URI to load
* @param aPrompt If null we grab one from windowwatcher if we need it
*/
void loadURI(in nsIURI aURI, in nsIPrompt aPrompt);
/**
* Gets a human-readable description for the application responsible for
* handling a specific protocol.
@ -91,4 +101,4 @@ interface nsIExternalProtocolService : nsISupports
* possible to get a description for it.
*/
AString getApplicationDescription(in AUTF8String aScheme);
};
};

View File

@ -1158,7 +1158,7 @@ NS_IMETHODIMP nsOSHelperAppService::ExternalProtocolHandlerExists(const char * a
return NS_OK;
}
NS_IMETHODIMP nsOSHelperAppService::LoadUrl(nsIURI * aURL)
nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
{
LOG(("-- nsOSHelperAppService::LoadUrl\n"));
nsCOMPtr<nsIPref> thePrefsService(do_GetService(NS_PREF_CONTRACTID));

View File

@ -65,7 +65,7 @@ public:
// override nsIExternalProtocolService methods
NS_IMETHOD ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
NS_IMETHOD LoadUrl(nsIURI * aURL);
nsresult LoadUriInternal(nsIURI * aURL);
protected:
already_AddRefed<nsMIMEInfoOS2> GetFromType(const nsCString& aMimeType);

View File

@ -1258,7 +1258,7 @@ NS_IMETHODIMP nsOSHelperAppService::ExternalProtocolHandlerExists(const char * a
return NS_OK;
}
NS_IMETHODIMP nsOSHelperAppService::LoadUrl(nsIURI * aURI)
nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURI)
{
// Gets a string pref network.protocol-handler.app.<scheme>
// and executes it

View File

@ -64,7 +64,7 @@ public:
// override nsIExternalProtocolService methods
NS_IMETHOD ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
NS_IMETHOD LoadUrl(nsIURI * aURL);
nsresult LoadUriInternal(nsIURI * aURL);
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
// GetFileTokenForPath must be implemented by each platform.

View File

@ -224,7 +224,7 @@ NS_IMETHODIMP nsOSHelperAppService::ExternalProtocolHandlerExists(const char * a
// this implementation was pretty much copied verbatime from Tony Robinson's code in nsExternalProtocolWin.cpp
NS_IMETHODIMP nsOSHelperAppService::LoadUrl(nsIURI * aURL)
nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
{
nsresult rv = NS_OK;

View File

@ -59,7 +59,7 @@ public:
// override nsIExternalProtocolService methods
NS_IMETHOD ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
NS_IMETHOD LoadUrl(nsIURI * aURL);
nsresult LoadUriInternal(nsIURI * aURL);
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
// method overrides for windows registry look up steps....