First Checked In.

git-svn-id: svn://10.0.0.236/trunk@71831 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
sfraser%netscape.com 2000-06-09 00:11:45 +00:00
parent 727c3c9fb8
commit f649ab93aa
2 changed files with 245 additions and 0 deletions

View File

@ -0,0 +1,169 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Simon Fraser <sfraser@netscape.com>
*/
#include "nsCOMPtr.h"
#include "nsError.h"
#include "nsIObserverService.h"
#include "nsIServiceManager.h"
#include "nsString2.h"
#include "nsAEUtils.h"
#include "nsAESpyglassSuiteHandler.h"
#include "nsDocLoadObserver.h"
nsDocLoadObserver::nsDocLoadObserver()
: mRegistered(PR_FALSE)
{
NS_INIT_ISUPPORTS();
}
nsDocLoadObserver::~nsDocLoadObserver()
{
}
NS_IMPL_ISUPPORTS1(nsDocLoadObserver, nsIObserver)
void nsDocLoadObserver::Register()
{
if (!mRegistered)
{
nsresult rv;
nsCOMPtr<nsIObserverService> anObserverService = do_GetService(NS_OBSERVERSERVICE_PROGID, &rv);
if (NS_SUCCEEDED(rv))
{
if (NS_SUCCEEDED(anObserverService->AddObserver(this,
NS_ConvertASCIItoUCS2("EndDocumentLoad").GetUnicode())))
{
mRegistered = PR_TRUE;
}
}
}
}
void nsDocLoadObserver::Unregister()
{
if (mRegistered)
{
nsresult rv;
nsCOMPtr<nsIObserverService> anObserverService = do_GetService(NS_OBSERVERSERVICE_PROGID, &rv);
if (NS_SUCCEEDED(rv))
{
if (NS_SUCCEEDED(anObserverService->RemoveObserver(this,
NS_ConvertASCIItoUCS2("EndDocumentLoad").GetUnicode())))
{
mRegistered = PR_FALSE;
}
}
}
}
void nsDocLoadObserver::AddEchoRequester(OSType appSignature)
{
mEchoRequesters.AppendElement((void*)appSignature);
Register(); // ensure we are registered
}
void nsDocLoadObserver::RemoveEchoRequester(OSType appSignature)
{
mEchoRequesters.RemoveElement((void*)appSignature);
if (mEchoRequesters.Count() == 0)
Unregister();
}
NS_IMETHODIMP nsDocLoadObserver::Observe(nsISupports* /*aSubject*/,
const PRUnichar* /*aTopic*/, const PRUnichar* someData)
{
// we need a URL to forward
if (!someData)
return NS_ERROR_NULL_POINTER;
// are there any echo requesters to notify?
if (mEchoRequesters.Count() == 0)
return NS_OK;
// create the descriptor for identifying this application
StAEDesc from;
const OSType mozz = 'MOZZ';
if (noErr != ::AECreateDesc(typeType, &mozz, sizeof(mozz), &from))
return NS_ERROR_UNEXPECTED;
// create the descriptor for the URL
nsString urlText(someData);
char* urlString = urlText.ToNewCString();
StAEDesc url;
OSErr err = ::AECreateDesc(typeChar, urlString, urlText.Length(), &url);
nsMemory::Free(urlString);
if (err != noErr)
return NS_ERROR_UNEXPECTED;
// keep track of any invalid requesters and remove them when we're done
nsVoidArray requestersToRemove;
PRInt32 numRequesters = mEchoRequesters.Count();
// now notify all the echo requesters
for (PRInt32 i = 0; i < numRequesters; i ++)
{
// specify the address of the requester
StAEDesc targetAddress;
const OSType target = (OSType)mEchoRequesters.ElementAt(i);
if (noErr != ::AECreateDesc(typeApplSignature, &target, sizeof(target), &targetAddress))
return NS_ERROR_UNEXPECTED;
// create the event
AppleEvent sendEvent;
err = ::AECreateAppleEvent(AESpyglassSuiteHandler::kSpyglassSendSignature,
AESpyglassSuiteHandler::kSendURLEchoEvent,
&targetAddress, kAutoGenerateReturnID, kAnyTransactionID, &sendEvent);
if (noErr != err)
{ // this target is no longer available
requestersToRemove.AppendElement((void *)target);
continue;
}
// attach our signature - to let the requester know who we are
err = ::AEPutParamDesc(&sendEvent, keyOriginalAddressAttr, &from);
NS_ASSERTION(noErr == err, "AEPutParamDesc");
// attach the new URL
err = ::AEPutParamDesc(&sendEvent, keyDirectObject, &url);
NS_ASSERTION(noErr == err, "AEPutParamDesc");
// send it
AppleEvent reply;
err = ::AESend(&sendEvent, &reply, kAENoReply, kAENormalPriority, 180, NULL, NULL);
NS_ASSERTION(noErr == err, "AESend");
::AEDisposeDesc(&sendEvent);
}
// now remove unresponsive requestors
for (PRInt32 i = 0; i < requestersToRemove.Count(); i ++)
{
OSType thisRequester = (OSType)requestersToRemove.ElementAt(i);
mEchoRequesters.RemoveElement((void *)thisRequester);
}
return NS_OK;
}

View File

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Simon Fraser <sfraser@netscape.com>
*/
#ifndef nsDocLoadObserver_h_
#define nsDocLoadObserver_h_
#include "nsIObserver.h"
#include <MacTypes.h>
#include "nsVoidArray.h"
/*----------------------------------------------------------------------------
nsDocLoadObserver
The nsDocLoadObserver is a singleton object that registers for
'EndDocumentLoad' events from the Mozilla browser. It maintains a set of
'echo requesters'. When the observer receives an event notification, it
forwards the event to all echo requesters. If the forward fails (most
likely because the application is no longer in memory), the echo requester
is automatically removed from the set.
Usage:
nsDocLoadObserver& observer = nsDocLoadObserver::Instance();
observer.Register();
observer.AddEchoRequester('App1');
observer.AddEchoRequester('App2');
----------------------------------------------------------------------------*/
class nsDocLoadObserver : public nsIObserver
{
public:
nsDocLoadObserver();
virtual ~nsDocLoadObserver();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
// add an application to be notified when an 'EndDocumentLoad' has occurred
void AddEchoRequester(OSType appSignature);
void RemoveEchoRequester(OSType appSignature);
protected:
// register the observer with the nsIObserverService. After this object
// has been successfully registered, this method will simply return
// immediately.
void Register();
void Unregister();
private:
// 'true' if this handler has been successfully registered with the nsIObserverService
PRBool mRegistered;
nsVoidArray mEchoRequesters;
};
#endif // nsDocLoadObserver_h_