mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-13 18:27:35 +00:00
Bug 43583; implement new helper app launch confirmation dialog interface; r=mcafee@netscape.com
This commit is contained in:
parent
a044cab1f4
commit
c6639ebe6c
@ -21,6 +21,7 @@
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
#include "nsIUnkContentTypeHandler.h"
|
||||
#include "nsIHelperAppLauncherDialog.h"
|
||||
|
||||
#include "nsIAppShellComponentImpl.h"
|
||||
|
||||
@ -32,12 +33,15 @@
|
||||
#include "nsIStreamObserver.h"
|
||||
#include "nsIHTTPChannel.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIExternalHelperAppService.h"
|
||||
|
||||
// {42770B50-03E9-11d3-8068-00600811A9C3}
|
||||
#define NS_UNKNOWNCONTENTTYPEHANDLER_CID \
|
||||
{ 0x42770b50, 0x3e9, 0x11d3, { 0x80, 0x68, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
|
||||
|
||||
class nsUnknownContentTypeHandler : public nsIUnknownContentTypeHandler,
|
||||
public nsIHelperAppLauncherDialog,
|
||||
public nsAppShellComponentImpl {
|
||||
public:
|
||||
NS_DEFINE_STATIC_CID_ACCESSOR( NS_UNKNOWNCONTENTTYPEHANDLER_CID );
|
||||
@ -58,8 +62,20 @@ public:
|
||||
// This class implements the nsIUnknownContentTypeHandler interface functions.
|
||||
NS_DECL_NSIUNKNOWNCONTENTTYPEHANDLER
|
||||
|
||||
// This class implements the nsIHelperAppLauncherDialog interface functions.
|
||||
NS_DECL_NSIHELPERAPPLAUNCHERDIALOG
|
||||
|
||||
private:
|
||||
nsInstanceCounter mInstanceCounter;
|
||||
|
||||
// Module stuff.
|
||||
static NS_METHOD CreateComponent( nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
void **aResult );
|
||||
static nsUnknownContentTypeHandler *mInstance;
|
||||
|
||||
public:
|
||||
static nsModuleComponentInfo components[];
|
||||
}; // nsUnknownContentTypeHandler
|
||||
|
||||
// HandleUnknownContentType (from nsIUnknownContentTypeHandler) implementation.
|
||||
@ -161,8 +177,350 @@ nsUnknownContentTypeHandler::HandleUnknownContentType( nsIChannel *aChannel,
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Show the helper app launch confirmation dialog as instructed.
|
||||
NS_IMETHODIMP
|
||||
nsUnknownContentTypeHandler::Show( nsIHelperAppLauncher *aLauncher, nsISupports *aContext ) {
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
// Get parent window (from context).
|
||||
nsCOMPtr<nsIDOMWindow> parent( do_GetInterface( aContext ) );
|
||||
if ( parent ) {
|
||||
// Get JS context from parent window.
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface( parent, &rv );
|
||||
if ( NS_SUCCEEDED( rv ) && sgo ) {
|
||||
nsCOMPtr<nsIScriptContext> context;
|
||||
sgo->GetContext( getter_AddRefs( context ) );
|
||||
if ( context ) {
|
||||
// Get native context.
|
||||
JSContext *jsContext = (JSContext*)context->GetNativeContext();
|
||||
if ( jsContext ) {
|
||||
// Set up window.arguments[0]...
|
||||
void *stackPtr;
|
||||
jsval *argv = JS_PushArguments( jsContext,
|
||||
&stackPtr,
|
||||
"sss%ip",
|
||||
"chrome://global/content/helperAppLauncher.xul",
|
||||
"_blank",
|
||||
"chrome",
|
||||
(const nsIID*)(&NS_GET_IID(nsIHelperAppLauncher)),
|
||||
(nsISupports*)aLauncher );
|
||||
if ( argv ) {
|
||||
// Open the dialog.
|
||||
nsCOMPtr<nsIDOMWindow> dialog;
|
||||
rv = parent->OpenDialog( jsContext, argv, 6, getter_AddRefs( dialog ) );
|
||||
// Pop arguments.
|
||||
JS_PopArguments( jsContext, stackPtr );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnknownContentTypeHandler::CreateComponent( nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
void **aResult ) {
|
||||
if ( !aResult ) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
if ( aOuter ) {
|
||||
*aResult = nsnull;
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
if (mInstance == nsnull) {
|
||||
mInstance = new nsUnknownContentTypeHandler();
|
||||
}
|
||||
|
||||
if ( mInstance == nsnull )
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = mInstance->QueryInterface( aIID, aResult );
|
||||
if ( NS_FAILED(rv) ) {
|
||||
*aResult = nsnull;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsUnknownContentTypeHandler* nsUnknownContentTypeHandler::mInstance = nsnull;
|
||||
|
||||
nsModuleComponentInfo nsUnknownContentTypeHandler::components[] = {
|
||||
{ NS_IUNKNOWNCONTENTTYPEHANDLER_CLASSNAME,
|
||||
NS_UNKNOWNCONTENTTYPEHANDLER_CID,
|
||||
NS_IUNKNOWNCONTENTTYPEHANDLER_PROGID,
|
||||
nsUnknownContentTypeHandler::CreateComponent },
|
||||
{ NS_IHELPERAPPLAUNCHERDLG_CLASSNAME,
|
||||
NS_UNKNOWNCONTENTTYPEHANDLER_CID,
|
||||
NS_IHELPERAPPLAUNCHERDLG_PROGID,
|
||||
nsUnknownContentTypeHandler::CreateComponent },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE( "nsUnknownContentTypeHandler", nsUnknownContentTypeHandler::components )
|
||||
|
||||
#if 0
|
||||
// Generate base nsIAppShellComponent implementation.
|
||||
NS_IMPL_IAPPSHELLCOMPONENT( nsUnknownContentTypeHandler,
|
||||
nsIUnknownContentTypeHandler,
|
||||
NS_IUNKNOWNCONTENTTYPEHANDLER_PROGID,
|
||||
0 )
|
||||
#else
|
||||
|
||||
// XXX Cut/paste subset of nsIAppShellComponentImpl.h (just what we need).
|
||||
|
||||
// These make the macro source compile appropriately.
|
||||
#define className nsUnknownContentTypeHandler
|
||||
#define interfaceName nsIUnknownContentTypeHandler
|
||||
#define progId NS_IUNKNOWNCONTENTTYPEHANDLER_PROGID
|
||||
|
||||
/* Define instance counter implementation stuff. */
|
||||
NS_DEFINE_MODULE_INSTANCE_COUNTER()
|
||||
/* Define component globals. */
|
||||
NS_DEFINE_COMPONENT_GLOBALS()
|
||||
/* Component's implementation of Initialize. */
|
||||
NS_IMETHODIMP
|
||||
className::Initialize( nsIAppShellService *anAppShell,
|
||||
nsICmdLineService *aCmdLineService ) {
|
||||
nsresult rv = NS_OK;
|
||||
mAppShell = anAppShell;
|
||||
mCmdLine = aCmdLineService;
|
||||
if ( Is_Service() ) {
|
||||
rv = nsServiceManager::RegisterService( progId, (interfaceName*)this );
|
||||
}
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
rv = DoInitialization();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
/* Component's implementation of Shutdown. */
|
||||
NS_IMETHODIMP
|
||||
className::Shutdown() {
|
||||
nsresult rv = NS_OK;
|
||||
if ( Is_Service() ) {
|
||||
rv = nsServiceManager::UnregisterService( progId );
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
/* nsISupports Implementation for the class */
|
||||
NS_IMPL_ADDREF( className );
|
||||
NS_IMPL_RELEASE( className );
|
||||
/* QueryInterface implementation for this class. */
|
||||
NS_IMETHODIMP
|
||||
className::QueryInterface( REFNSIID anIID, void **anInstancePtr ) {
|
||||
nsresult rv = NS_OK;
|
||||
/* Check for place to return result. */
|
||||
if ( !anInstancePtr ) {
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
} else {
|
||||
/* Initialize result. */
|
||||
*anInstancePtr = 0;
|
||||
/* Check for IIDs we support and cast this appropriately. */
|
||||
if ( 0 ) {
|
||||
} else if ( anIID.Equals( NS_GET_IID(interfaceName) ) ) {
|
||||
*anInstancePtr = (void*) this;
|
||||
NS_ADDREF_THIS();
|
||||
} else if ( anIID.Equals( NS_GET_IID(nsIHelperAppLauncherDialog) ) ) {
|
||||
*anInstancePtr = (void*) (nsIHelperAppLauncherDialog*)this;
|
||||
NS_ADDREF_THIS();
|
||||
} else if ( anIID.Equals( NS_GET_IID(nsIAppShellComponent) ) ) {
|
||||
*anInstancePtr = (void*) ( (nsIAppShellComponent*)this );
|
||||
NS_ADDREF_THIS();
|
||||
} else if ( anIID.Equals( NS_GET_IID(nsISupports) ) ) {
|
||||
*anInstancePtr = (void*) ( (nsISupports*) (interfaceName*)this );
|
||||
NS_ADDREF_THIS();
|
||||
} else {
|
||||
/* Not an interface we support. */
|
||||
rv = NS_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
#if 0
|
||||
/* Factory class */
|
||||
struct className##Factory : public nsIFactory {
|
||||
/* ctor/dtor */
|
||||
className##Factory() {
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
virtual ~className##Factory() {
|
||||
}
|
||||
/* This class implements the nsISupports interface functions. */
|
||||
NS_DECL_ISUPPORTS
|
||||
/* nsIFactory methods */
|
||||
NS_IMETHOD CreateInstance( nsISupports *aOuter,
|
||||
const nsIID &aIID,
|
||||
void **aResult );
|
||||
NS_IMETHOD LockFactory( PRBool aLock );
|
||||
private:
|
||||
nsInstanceCounter instanceCounter;
|
||||
};
|
||||
/* nsISupports interface implementation for the factory. */
|
||||
NS_IMPL_ADDREF( className##Factory )
|
||||
NS_IMPL_RELEASE( className##Factory )
|
||||
NS_IMETHODIMP
|
||||
className##Factory::QueryInterface( const nsIID &anIID, void **aResult ) {
|
||||
nsresult rv = NS_OK;
|
||||
if ( aResult ) {
|
||||
*aResult = 0;
|
||||
if ( 0 ) {
|
||||
} else if ( anIID.Equals( NS_GET_IID(nsIFactory) ) ) {
|
||||
*aResult = (void*) (nsIFactory*)this;
|
||||
NS_ADDREF_THIS();
|
||||
} else if ( anIID.Equals( NS_GET_IID(nsISupports) ) ) {
|
||||
*aResult = (void*) (nsISupports*) (interfaceName*)this;
|
||||
NS_ADDREF_THIS();
|
||||
} else {
|
||||
rv = NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
} else {
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
/* Factory's CreateInstance implementation */
|
||||
NS_IMETHODIMP
|
||||
className##Factory::CreateInstance( nsISupports *anOuter,
|
||||
const nsIID &anIID,
|
||||
void* *aResult ) {
|
||||
nsresult rv = NS_OK;
|
||||
if ( aResult ) {
|
||||
/* Allocate new find component object. */
|
||||
className *component = new className();
|
||||
if ( component ) {
|
||||
/* Allocated OK, do query interface to get proper */
|
||||
/* pointer and increment refcount. */
|
||||
rv = component->QueryInterface( anIID, aResult );
|
||||
if ( NS_FAILED( rv ) ) {
|
||||
/* refcount still at zero, delete it here. */
|
||||
delete component;
|
||||
}
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
/* Factory's LockFactory implementation */
|
||||
NS_IMETHODIMP
|
||||
className##Factory::LockFactory(PRBool aLock) {
|
||||
return nsInstanceCounter::LockFactory( aLock );
|
||||
}
|
||||
class className##Module : public nsIModule {
|
||||
public:
|
||||
className##Module() {
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
virtual ~className##Module() {
|
||||
}
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMODULE
|
||||
};
|
||||
NS_IMPL_ISUPPORTS1(className##Module, nsIModule)
|
||||
/* NSRegisterSelf implementation */
|
||||
NS_IMETHODIMP
|
||||
className##Module::RegisterSelf(nsIComponentManager *compMgr,
|
||||
nsIFile* aPath,
|
||||
const char *registryLocation,
|
||||
const char *componentType)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
/* WARNING: Dont remember service manager. */
|
||||
/* Get the component manager service. */
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
/* Register our component. */
|
||||
rv = compMgr->RegisterComponentSpec( className::GetCID(), #className,
|
||||
progId, aPath, PR_TRUE, PR_TRUE );
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
DEBUG_PRINTF( PR_STDOUT, #className " registration successfuln" );
|
||||
if ( autoInit ) {
|
||||
/* Add to appshell component list. */
|
||||
nsIRegistry *registry;
|
||||
rv = nsServiceManager::GetService( NS_REGISTRY_PROGID,
|
||||
NS_GET_IID(nsIRegistry),
|
||||
(nsISupports**)®istry );
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
|
||||
char buffer[256];
|
||||
char *cidString = className::GetCID().ToString();
|
||||
PR_snprintf( buffer, sizeof buffer, "%s/%s",
|
||||
NS_IAPPSHELLCOMPONENT_KEY,
|
||||
cidString ? cidString : "unknown" );
|
||||
delete [] cidString;
|
||||
nsRegistryKey key;
|
||||
rv = registry->AddSubtree( nsIRegistry::Common, buffer, &key );
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
DEBUG_PRINTF( PR_STDOUT, #className " added to appshell component listn" );
|
||||
} else {
|
||||
DEBUG_PRINTF( PR_STDOUT, #className " not added to appshell component list, rv=0x%Xn", (int)rv );
|
||||
}
|
||||
} else {
|
||||
DEBUG_PRINTF( PR_STDOUT, #className " not added to appshell component list, rv=0x%Xn", (int)rv );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DEBUG_PRINTF( PR_STDOUT, #className " registration failed, RegisterComponent rv=0x%Xn", (int)rv );
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/* UnregisterSelf implementation */
|
||||
NS_IMETHODIMP
|
||||
className##Module::UnregisterSelf( nsIComponentManager *compMgr,
|
||||
nsIFile* aPath,
|
||||
const char *registryLocation) {
|
||||
nsresult rv = NS_OK;
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
DEBUG_PRINTF( PR_STDOUT, #className " registration failed, GetService rv=0x%Xn", (int)rv );
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Unregister our component. */
|
||||
rv = compMgr->UnregisterComponentSpec( className::GetCID(), aPath);
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
DEBUG_PRINTF( PR_STDOUT, #className " unregistration successfuln" );
|
||||
} else {
|
||||
DEBUG_PRINTF( PR_STDOUT, #className " unregistration failed, UnregisterComponent rv=0x%Xn", (int)rv );
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/* GetFactory implementation */
|
||||
NS_IMETHODIMP
|
||||
className##Module::GetClassObject( nsIComponentManager *compMgr,
|
||||
const nsCID &aClass,
|
||||
const nsIID &aIID,
|
||||
void **aFactory ) {
|
||||
nsresult rv = NS_OK;
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
if ( aFactory ) {
|
||||
className##Factory *factory = new className##Factory();
|
||||
if ( factory ) {
|
||||
NS_ADDREF(factory);
|
||||
rv = factory->QueryInterface( aIID, (void**)aFactory );
|
||||
NS_RELEASE(factory);
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
className##Module::CanUnload( nsIComponentManager*, PRBool* canUnload) {
|
||||
if (!canUnload) return NS_ERROR_NULL_POINTER;
|
||||
*canUnload = nsInstanceCounter::CanUnload();
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
NS_IMPL_IAPPSHELLCOMPONENTIMPL_CTORDTOR( className )
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user