Bug 458160 - Enable downloadable .otf fonts under Windows. r=roc, sr=vlad.
[wine-gecko.git] / dom / src / threads / nsDOMWorkerMessageHandler.cpp
blob953b158051b3121241003633a06a81ff47dcef3a
1 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
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.
15 * The Original Code is Web Workers.
17 * The Initial Developer of the Original Code is
18 * Mozilla Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 2008
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Ben Turner <bent.mozilla@gmail.com> (Original Author)
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 MPL, 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 MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsDOMWorkerMessageHandler.h"
41 #include "nsIDOMEvent.h"
42 #include "nsIXPConnect.h"
44 #include "nsContentUtils.h"
46 #include "nsDOMThreadService.h"
47 #include "nsDOMWorkerEvents.h"
49 NS_IMPL_THREADSAFE_ADDREF(nsDOMWorkerEventListenerBase)
50 NS_IMPL_THREADSAFE_RELEASE(nsDOMWorkerEventListenerBase)
52 nsresult
53 nsDOMWorkerWeakEventListener::Init(nsIDOMEventListener* aListener)
55 NS_ENSURE_ARG_POINTER(aListener);
57 nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS(do_QueryInterface(aListener));
58 NS_ENSURE_TRUE(wrappedJS, NS_NOINTERFACE);
60 JSObject* obj;
61 nsresult rv = wrappedJS->GetJSObject(&obj);
62 NS_ENSURE_SUCCESS(rv, rv);
64 mObj = obj;
66 return NS_OK;
69 already_AddRefed<nsIDOMEventListener>
70 nsDOMWorkerWeakEventListener::GetListener()
72 JSContext* cx = nsDOMThreadService::GetCurrentContext();
73 NS_ENSURE_TRUE(cx, nsnull);
75 nsIXPConnect* xpc = nsContentUtils::XPConnect();
77 nsCOMPtr<nsIDOMEventListener> listener;
78 nsresult rv = xpc->WrapJS(cx, mObj, NS_GET_IID(nsIDOMEventListener),
79 getter_AddRefs(listener));
80 NS_ENSURE_SUCCESS(rv, nsnull);
82 return listener.forget();
85 nsDOMWorkerWrappedWeakEventListener::
86 nsDOMWorkerWrappedWeakEventListener(nsDOMWorkerWeakEventListener* aInner)
87 : mInner(aInner)
89 NS_ASSERTION(aInner, "Null pointer!");
92 NS_IMPL_THREADSAFE_ISUPPORTS2(nsDOMWorkerMessageHandler,
93 nsIDOMEventTarget,
94 nsIClassInfo)
96 NS_IMPL_CI_INTERFACE_GETTER1(nsDOMWorkerMessageHandler,
97 nsIDOMEventTarget)
99 NS_IMPL_THREADSAFE_DOM_CI(nsDOMWorkerMessageHandler)
101 const nsDOMWorkerMessageHandler::ListenerCollection*
102 nsDOMWorkerMessageHandler::GetListenerCollection(const nsAString& aType) const
104 PRUint32 count = mCollections.Length();
105 for (PRUint32 index = 0; index < count; index++) {
106 const ListenerCollection& collection = mCollections[index];
107 if (collection.type.Equals(aType)) {
108 return &collection;
111 return nsnull;
114 void
115 nsDOMWorkerMessageHandler::GetListenersForType(const nsAString& aType,
116 ListenerArray& _retval) const
118 _retval.Clear();
120 const ListenerCollection* collection = GetListenerCollection(aType);
121 if (collection) {
122 PRUint32 count = collection->listeners.Length();
124 if (!_retval.SetLength(count)) {
125 NS_WARNING("Out of memory!");
126 return;
129 for (PRUint32 index = 0; index < count; index++) {
130 nsCOMPtr<nsIDOMEventListener> listener =
131 collection->listeners[index]->GetListener();
132 _retval[index].swap(listener);
137 nsresult
138 nsDOMWorkerMessageHandler::SetOnXListener(const nsAString& aType,
139 nsIDOMEventListener* aListener)
141 nsRefPtr<nsDOMWorkerWrappedWeakEventListener> wrappedListener;
143 ListenerCollection* collection =
144 const_cast<ListenerCollection*>(GetListenerCollection(aType));
146 #ifdef DEBUG
147 PRBool removed;
148 #endif
150 if (collection) {
151 wrappedListener.swap(collection->onXListener);
152 if (wrappedListener) {
153 #ifdef DEBUG
154 removed =
155 #endif
156 collection->listeners.RemoveElement(wrappedListener);
157 NS_ASSERTION(removed, "Element wasn't in the list!");
161 if (!aListener) {
162 if (collection && !collection->listeners.Length()) {
163 #ifdef DEBUG
164 removed =
165 #endif
166 mCollections.RemoveElement(*collection);
167 NS_ASSERTION(removed, "Element wasn't in the list!");
169 return NS_OK;
172 nsRefPtr<nsDOMWorkerWeakEventListener> weakListener =
173 new nsDOMWorkerWeakEventListener();
174 NS_ENSURE_TRUE(weakListener, NS_ERROR_OUT_OF_MEMORY);
176 nsresult rv = weakListener->Init(aListener);
177 NS_ENSURE_SUCCESS(rv, rv);
179 wrappedListener = new nsDOMWorkerWrappedWeakEventListener(weakListener);
180 NS_ENSURE_TRUE(wrappedListener, NS_ERROR_OUT_OF_MEMORY);
182 if (!collection) {
183 collection = mCollections.AppendElement(aType);
184 NS_ENSURE_TRUE(collection, NS_ERROR_OUT_OF_MEMORY);
187 WeakListener* newListener =
188 collection->listeners.AppendElement(wrappedListener);
189 NS_ENSURE_TRUE(newListener, NS_ERROR_OUT_OF_MEMORY);
191 wrappedListener.swap(collection->onXListener);
192 return NS_OK;
195 already_AddRefed<nsIDOMEventListener>
196 nsDOMWorkerMessageHandler::GetOnXListener(const nsAString& aType) const
198 const ListenerCollection* collection = GetListenerCollection(aType);
199 if (collection && collection->onXListener) {
200 return collection->onXListener->GetListener();
203 return nsnull;
206 void
207 nsDOMWorkerMessageHandler::ClearListeners(const nsAString& aType)
209 PRUint32 count = mCollections.Length();
210 for (PRUint32 index = 0; index < count; index++) {
211 if (mCollections[index].type.Equals(aType)) {
212 mCollections.RemoveElementAt(index);
213 return;
218 PRBool
219 nsDOMWorkerMessageHandler::HasListeners(const nsAString& aType)
221 const ListenerCollection* collection = GetListenerCollection(aType);
222 return collection && collection->listeners.Length();
225 void
226 nsDOMWorkerMessageHandler::ClearAllListeners()
228 mCollections.Clear();
231 void
232 nsDOMWorkerMessageHandler::Trace(JSTracer* aTracer)
234 PRUint32 cCount = mCollections.Length();
235 for (PRUint32 cIndex = 0; cIndex < cCount; cIndex++) {
236 const ListenerCollection& collection = mCollections[cIndex];
237 PRUint32 lCount = collection.listeners.Length();
238 for (PRUint32 lIndex = 0; lIndex < lCount; lIndex++) {
239 JSObject* obj = collection.listeners[lIndex]->GetJSObject();
240 NS_ASSERTION(obj, "Null object!");
241 JS_SET_TRACING_DETAILS(aTracer, nsnull, this, 0);
242 JS_CallTracer(aTracer, obj, JSTRACE_OBJECT);
248 * See nsIDOMEventTarget
250 NS_IMETHODIMP
251 nsDOMWorkerMessageHandler::AddEventListener(const nsAString& aType,
252 nsIDOMEventListener* aListener,
253 PRBool aUseCapture)
255 ListenerCollection* collection =
256 const_cast<ListenerCollection*>(GetListenerCollection(aType));
258 if (!collection) {
259 collection = mCollections.AppendElement(aType);
260 NS_ENSURE_TRUE(collection, NS_ERROR_OUT_OF_MEMORY);
263 nsRefPtr<nsDOMWorkerWeakEventListener> weakListener =
264 new nsDOMWorkerWeakEventListener();
265 NS_ENSURE_TRUE(weakListener, NS_ERROR_OUT_OF_MEMORY);
267 nsresult rv = weakListener->Init(aListener);
268 NS_ENSURE_SUCCESS(rv, rv);
270 WeakListener* newListener = collection->listeners.AppendElement(weakListener);
271 NS_ENSURE_TRUE(newListener, NS_ERROR_OUT_OF_MEMORY);
273 return NS_OK;
277 * See nsIDOMEventTarget
279 NS_IMETHODIMP
280 nsDOMWorkerMessageHandler::RemoveEventListener(const nsAString& aType,
281 nsIDOMEventListener* aListener,
282 PRBool aUseCapture)
284 ListenerCollection* collection =
285 const_cast<ListenerCollection*>(GetListenerCollection(aType));
287 if (collection) {
288 PRUint32 count = collection->listeners.Length();
289 for (PRUint32 index = 0; index < count; index++) {
290 WeakListener& weakListener = collection->listeners[index];
291 if (weakListener == collection->onXListener) {
292 continue;
294 nsCOMPtr<nsIDOMEventListener> listener = weakListener->GetListener();
295 if (listener == aListener) {
296 collection->listeners.RemoveElementAt(index);
297 break;
301 if (!collection->listeners.Length()) {
302 #ifdef DEBUG
303 PRBool removed =
304 #endif
305 mCollections.RemoveElement(*collection);
306 NS_ASSERTION(removed, "Somehow this wasn't in the list!");
310 return NS_OK;
314 * See nsIDOMEventTarget
316 NS_IMETHODIMP
317 nsDOMWorkerMessageHandler::DispatchEvent(nsIDOMEvent* aEvent,
318 PRBool* _retval)
320 NS_ENSURE_ARG_POINTER(aEvent);
322 nsCOMPtr<nsIDOMWorkerPrivateEvent> event;
324 if (_retval) {
325 event = do_QueryInterface(aEvent);
326 if (!event) {
327 event = new nsDOMWorkerPrivateEvent(aEvent);
328 NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
330 aEvent = event;
333 nsAutoString type;
334 nsresult rv = aEvent->GetType(type);
335 NS_ENSURE_SUCCESS(rv, rv);
337 nsAutoTArray<Listener, 10> listeners;
338 GetListenersForType(type, listeners);
340 PRUint32 count = listeners.Length();
341 for (PRUint32 index = 0; index < count; index++) {
342 const Listener& listener = listeners[index];
343 NS_ASSERTION(listener, "Null listener in array!");
345 listener->HandleEvent(aEvent);
348 if (_retval) {
349 *_retval = event->PreventDefaultCalled();
352 return NS_OK;