Bug 1025824 - Fix mHwcLayerMap handling r=sushil
[gecko.git] / dom / events / EventListenerService.cpp
blob22fe980edaecb6e860c7ff3d0428c814794a897d
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "EventListenerService.h"
7 #ifdef MOZ_JSDEBUGGER
8 #include "jsdIDebuggerService.h"
9 #endif
10 #include "mozilla/BasicEvents.h"
11 #include "mozilla/EventDispatcher.h"
12 #include "mozilla/EventListenerManager.h"
13 #include "mozilla/JSEventHandler.h"
14 #include "mozilla/Maybe.h"
15 #include "nsCOMArray.h"
16 #include "nsCxPusher.h"
17 #include "nsDOMClassInfoID.h"
18 #include "nsIXPConnect.h"
19 #include "nsJSUtils.h"
20 #include "nsMemory.h"
21 #include "nsServiceManagerUtils.h"
23 namespace mozilla {
25 using namespace dom;
27 /******************************************************************************
28 * mozilla::EventListenerInfo
29 ******************************************************************************/
31 NS_IMPL_CYCLE_COLLECTION(EventListenerInfo, mListener)
33 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(EventListenerInfo)
34 NS_INTERFACE_MAP_ENTRY(nsIEventListenerInfo)
35 NS_INTERFACE_MAP_ENTRY(nsISupports)
36 NS_INTERFACE_MAP_END
38 NS_IMPL_CYCLE_COLLECTING_ADDREF(EventListenerInfo)
39 NS_IMPL_CYCLE_COLLECTING_RELEASE(EventListenerInfo)
41 NS_IMETHODIMP
42 EventListenerInfo::GetType(nsAString& aType)
44 aType = mType;
45 return NS_OK;
48 NS_IMETHODIMP
49 EventListenerInfo::GetCapturing(bool* aCapturing)
51 *aCapturing = mCapturing;
52 return NS_OK;
55 NS_IMETHODIMP
56 EventListenerInfo::GetAllowsUntrusted(bool* aAllowsUntrusted)
58 *aAllowsUntrusted = mAllowsUntrusted;
59 return NS_OK;
62 NS_IMETHODIMP
63 EventListenerInfo::GetInSystemEventGroup(bool* aInSystemEventGroup)
65 *aInSystemEventGroup = mInSystemEventGroup;
66 return NS_OK;
69 NS_IMETHODIMP
70 EventListenerInfo::GetListenerObject(JSContext* aCx,
71 JS::MutableHandle<JS::Value> aObject)
73 Maybe<JSAutoCompartment> ac;
74 GetJSVal(aCx, ac, aObject);
75 return NS_OK;
78 /******************************************************************************
79 * mozilla::EventListenerService
80 ******************************************************************************/
82 NS_IMPL_ISUPPORTS(EventListenerService, nsIEventListenerService)
84 bool
85 EventListenerInfo::GetJSVal(JSContext* aCx,
86 Maybe<JSAutoCompartment>& aAc,
87 JS::MutableHandle<JS::Value> aJSVal)
89 aJSVal.setNull();
90 nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(mListener);
91 if (wrappedJS) {
92 JS::Rooted<JSObject*> object(aCx, wrappedJS->GetJSObject());
93 if (!object) {
94 return false;
96 aAc.construct(aCx, object);
97 aJSVal.setObject(*object);
98 return true;
101 nsCOMPtr<JSEventHandler> jsHandler = do_QueryInterface(mListener);
102 if (jsHandler && jsHandler->GetTypedEventHandler().HasEventHandler()) {
103 JS::Handle<JSObject*> handler =
104 jsHandler->GetTypedEventHandler().Ptr()->Callable();
105 if (handler) {
106 aAc.construct(aCx, handler);
107 aJSVal.setObject(*handler);
108 return true;
111 return false;
114 NS_IMETHODIMP
115 EventListenerInfo::ToSource(nsAString& aResult)
117 aResult.SetIsVoid(true);
119 AutoSafeJSContext cx;
120 Maybe<JSAutoCompartment> ac;
121 JS::Rooted<JS::Value> v(cx);
122 if (GetJSVal(cx, ac, &v)) {
123 JSString* str = JS_ValueToSource(cx, v);
124 if (str) {
125 nsDependentJSString depStr;
126 if (depStr.init(cx, str)) {
127 aResult.Assign(depStr);
131 return NS_OK;
134 NS_IMETHODIMP
135 EventListenerInfo::GetDebugObject(nsISupports** aRetVal)
137 *aRetVal = nullptr;
139 #ifdef MOZ_JSDEBUGGER
140 nsresult rv = NS_OK;
141 nsCOMPtr<jsdIDebuggerService> jsd =
142 do_GetService("@mozilla.org/js/jsd/debugger-service;1", &rv);
143 NS_ENSURE_SUCCESS(rv, NS_OK);
145 bool isOn = false;
146 jsd->GetIsOn(&isOn);
147 NS_ENSURE_TRUE(isOn, NS_OK);
149 AutoSafeJSContext cx;
150 Maybe<JSAutoCompartment> ac;
151 JS::Rooted<JS::Value> v(cx);
152 if (GetJSVal(cx, ac, &v)) {
153 nsCOMPtr<jsdIValue> jsdValue;
154 rv = jsd->WrapValue(v, getter_AddRefs(jsdValue));
155 NS_ENSURE_SUCCESS(rv, rv);
156 jsdValue.forget(aRetVal);
158 #endif
160 return NS_OK;
163 NS_IMETHODIMP
164 EventListenerService::GetListenerInfoFor(nsIDOMEventTarget* aEventTarget,
165 uint32_t* aCount,
166 nsIEventListenerInfo*** aOutArray)
168 NS_ENSURE_ARG_POINTER(aEventTarget);
169 *aCount = 0;
170 *aOutArray = nullptr;
171 nsCOMArray<nsIEventListenerInfo> listenerInfos;
173 nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aEventTarget);
174 NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
176 EventListenerManager* elm = eventTarget->GetExistingListenerManager();
177 if (elm) {
178 elm->GetListenerInfo(&listenerInfos);
181 int32_t count = listenerInfos.Count();
182 if (count == 0) {
183 return NS_OK;
186 *aOutArray =
187 static_cast<nsIEventListenerInfo**>(
188 nsMemory::Alloc(sizeof(nsIEventListenerInfo*) * count));
189 NS_ENSURE_TRUE(*aOutArray, NS_ERROR_OUT_OF_MEMORY);
191 for (int32_t i = 0; i < count; ++i) {
192 NS_ADDREF((*aOutArray)[i] = listenerInfos[i]);
194 *aCount = count;
195 return NS_OK;
198 NS_IMETHODIMP
199 EventListenerService::GetEventTargetChainFor(nsIDOMEventTarget* aEventTarget,
200 uint32_t* aCount,
201 nsIDOMEventTarget*** aOutArray)
203 *aCount = 0;
204 *aOutArray = nullptr;
205 NS_ENSURE_ARG(aEventTarget);
206 WidgetEvent event(true, NS_EVENT_NULL);
207 nsCOMArray<EventTarget> targets;
208 nsresult rv = EventDispatcher::Dispatch(aEventTarget, nullptr, &event,
209 nullptr, nullptr, nullptr, &targets);
210 NS_ENSURE_SUCCESS(rv, rv);
211 int32_t count = targets.Count();
212 if (count == 0) {
213 return NS_OK;
216 *aOutArray =
217 static_cast<nsIDOMEventTarget**>(
218 nsMemory::Alloc(sizeof(nsIDOMEventTarget*) * count));
219 NS_ENSURE_TRUE(*aOutArray, NS_ERROR_OUT_OF_MEMORY);
221 for (int32_t i = 0; i < count; ++i) {
222 NS_ADDREF((*aOutArray)[i] = targets[i]);
224 *aCount = count;
226 return NS_OK;
229 NS_IMETHODIMP
230 EventListenerService::HasListenersFor(nsIDOMEventTarget* aEventTarget,
231 const nsAString& aType,
232 bool* aRetVal)
234 nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aEventTarget);
235 NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
237 EventListenerManager* elm = eventTarget->GetExistingListenerManager();
238 *aRetVal = elm && elm->HasListenersFor(aType);
239 return NS_OK;
242 NS_IMETHODIMP
243 EventListenerService::AddSystemEventListener(nsIDOMEventTarget *aTarget,
244 const nsAString& aType,
245 nsIDOMEventListener* aListener,
246 bool aUseCapture)
248 NS_PRECONDITION(aTarget, "Missing target");
249 NS_PRECONDITION(aListener, "Missing listener");
251 nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
252 NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
254 EventListenerManager* manager = eventTarget->GetOrCreateListenerManager();
255 NS_ENSURE_STATE(manager);
257 EventListenerFlags flags =
258 aUseCapture ? TrustedEventsAtSystemGroupCapture() :
259 TrustedEventsAtSystemGroupBubble();
260 manager->AddEventListenerByType(aListener, aType, flags);
261 return NS_OK;
264 NS_IMETHODIMP
265 EventListenerService::RemoveSystemEventListener(nsIDOMEventTarget *aTarget,
266 const nsAString& aType,
267 nsIDOMEventListener* aListener,
268 bool aUseCapture)
270 NS_PRECONDITION(aTarget, "Missing target");
271 NS_PRECONDITION(aListener, "Missing listener");
273 nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
274 NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
276 EventListenerManager* manager = eventTarget->GetExistingListenerManager();
277 if (manager) {
278 EventListenerFlags flags =
279 aUseCapture ? TrustedEventsAtSystemGroupCapture() :
280 TrustedEventsAtSystemGroupBubble();
281 manager->RemoveEventListenerByType(aListener, aType, flags);
284 return NS_OK;
287 NS_IMETHODIMP
288 EventListenerService::AddListenerForAllEvents(nsIDOMEventTarget* aTarget,
289 nsIDOMEventListener* aListener,
290 bool aUseCapture,
291 bool aWantsUntrusted,
292 bool aSystemEventGroup)
294 NS_ENSURE_STATE(aTarget && aListener);
296 nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
297 NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
299 EventListenerManager* manager = eventTarget->GetOrCreateListenerManager();
300 NS_ENSURE_STATE(manager);
301 manager->AddListenerForAllEvents(aListener, aUseCapture, aWantsUntrusted,
302 aSystemEventGroup);
303 return NS_OK;
306 NS_IMETHODIMP
307 EventListenerService::RemoveListenerForAllEvents(nsIDOMEventTarget* aTarget,
308 nsIDOMEventListener* aListener,
309 bool aUseCapture,
310 bool aSystemEventGroup)
312 NS_ENSURE_STATE(aTarget && aListener);
314 nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(aTarget);
315 NS_ENSURE_TRUE(eventTarget, NS_ERROR_NO_INTERFACE);
317 EventListenerManager* manager = eventTarget->GetExistingListenerManager();
318 if (manager) {
319 manager->RemoveListenerForAllEvents(aListener, aUseCapture, aSystemEventGroup);
321 return NS_OK;
324 } // namespace mozilla
326 nsresult
327 NS_NewEventListenerService(nsIEventListenerService** aResult)
329 *aResult = new mozilla::EventListenerService();
330 NS_ADDREF(*aResult);
331 return NS_OK;