source: trunk/third/mozilla/xpfe/bootstrap/nsDocLoadObserver.cpp @ 19518

Revision 19518, 5.7 KB checked in by rbasch, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19517, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Netscape Public License
6 * Version 1.1 (the "License"); you may not use this file except in
7 * compliance with the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/NPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is Mozilla Communicator client code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *  Simon Fraser <sfraser@netscape.com>
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the NPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the NPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39#include "nsCOMPtr.h"
40#include "nsError.h"
41#include "nsIObserverService.h"
42#include "nsIServiceManager.h"
43#include "nsString.h"
44#include "nsReadableUtils.h"
45#include "nsAEUtils.h"
46#include "nsAESpyglassSuiteHandler.h"
47
48#include "nsDocLoadObserver.h"
49
50nsDocLoadObserver::nsDocLoadObserver()
51:       mRegistered(PR_FALSE)
52{
53}
54
55nsDocLoadObserver::~nsDocLoadObserver()
56{
57}
58
59
60NS_IMPL_ISUPPORTS1(nsDocLoadObserver, nsIObserver)
61
62void nsDocLoadObserver::Register()
63{
64        if (!mRegistered)
65        {
66                nsresult rv;
67                nsCOMPtr<nsIObserverService> anObserverService = do_GetService("@mozilla.org/observer-service;1", &rv);
68                if (NS_SUCCEEDED(rv))
69                {
70                        if (NS_SUCCEEDED(anObserverService->AddObserver(this, "EndDocumentLoad", PR_FALSE)))
71                        {
72                                mRegistered = PR_TRUE;
73                        }
74                }
75        }
76}
77
78void nsDocLoadObserver::Unregister()
79{
80        if (mRegistered)
81        {
82                nsresult rv;
83                nsCOMPtr<nsIObserverService> anObserverService = do_GetService("@mozilla.org/observer-service;1", &rv);
84                if (NS_SUCCEEDED(rv))
85                {
86                        if (NS_SUCCEEDED(anObserverService->RemoveObserver(this,
87                                "EndDocumentLoad")))
88                        {
89                                mRegistered = PR_FALSE;
90                        }
91                }
92        }
93}
94
95void nsDocLoadObserver::AddEchoRequester(OSType appSignature)
96{
97  // make sure an application is only in the list once
98  mEchoRequesters.RemoveElement((void*)appSignature);
99 
100        mEchoRequesters.AppendElement((void*)appSignature);
101        Register();     // ensure we are registered
102}
103
104void nsDocLoadObserver::RemoveEchoRequester(OSType appSignature)
105{
106        mEchoRequesters.RemoveElement((void*)appSignature);
107        if (mEchoRequesters.Count() == 0)
108          Unregister();
109}
110
111NS_IMETHODIMP nsDocLoadObserver::Observe(nsISupports* /*aSubject*/,
112                const char* /*aTopic*/, const PRUnichar* someData)
113{
114        // we need a URL to forward
115        if (!someData)
116                return NS_ERROR_NULL_POINTER;
117
118        // are there any echo requesters to notify?
119        if (mEchoRequesters.Count() == 0)
120                return NS_OK;
121
122        // create the descriptor for identifying this application
123        StAEDesc from;
124        const OSType mozz = 'MOZZ';
125        if (noErr != ::AECreateDesc(typeType, &mozz, sizeof(mozz), &from))
126                return NS_ERROR_UNEXPECTED;
127
128        // create the descriptor for the URL
129        nsString urlText(someData);
130        char* urlString = ToNewCString(urlText);
131
132        StAEDesc url;
133        OSErr err = ::AECreateDesc(typeChar, urlString, urlText.Length(), &url);
134        nsMemory::Free(urlString);
135        if (err != noErr)
136                return NS_ERROR_UNEXPECTED;
137
138        // keep track of any invalid requesters and remove them when we're done
139        nsVoidArray requestersToRemove;
140       
141        PRInt32         numRequesters = mEchoRequesters.Count();
142       
143        // now notify all the echo requesters
144        for (PRInt32 i = 0; i < numRequesters; i ++)
145        {
146                // specify the address of the requester
147                StAEDesc targetAddress;
148                const OSType target = (OSType)mEchoRequesters.ElementAt(i);
149                if (noErr != ::AECreateDesc(typeApplSignature, &target, sizeof(target), &targetAddress))
150                        return NS_ERROR_UNEXPECTED;
151
152                // create the event
153                AppleEvent sendEvent;
154                err = ::AECreateAppleEvent(AESpyglassSuiteHandler::kSpyglassSendSignature,
155                                AESpyglassSuiteHandler::kSendURLEchoEvent,
156                                &targetAddress, kAutoGenerateReturnID, kAnyTransactionID, &sendEvent);
157                if (noErr != err)
158                {       // this target is no longer available
159                        requestersToRemove.AppendElement((void *)target);
160                        continue;
161                }
162
163                // attach our signature - to let the requester know who we are
164                err = ::AEPutParamDesc(&sendEvent, keyOriginalAddressAttr, &from);
165                NS_ASSERTION(noErr == err, "AEPutParamDesc");
166
167                // attach the new URL
168                err = ::AEPutParamDesc(&sendEvent, keyDirectObject, &url);
169                NS_ASSERTION(noErr == err, "AEPutParamDesc");
170               
171                // send it
172                AppleEvent reply;
173                err = ::AESend(&sendEvent, &reply, kAENoReply, kAENormalPriority, 180, NULL, NULL);
174                NS_ASSERTION(noErr == err, "AESend");
175                ::AEDisposeDesc(&sendEvent);
176        }
177
178        // now remove unresponsive requestors
179        for (PRInt32 i = 0; i < requestersToRemove.Count(); i ++)
180        {
181                OSType  thisRequester = (OSType)requestersToRemove.ElementAt(i);
182                mEchoRequesters.RemoveElement((void *)thisRequester);
183        }
184       
185        return NS_OK;
186}
Note: See TracBrowser for help on using the repository browser.