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"
8 #include "jsdIDebuggerService.h"
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"
21 #include "nsServiceManagerUtils.h"
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
)
38 NS_IMPL_CYCLE_COLLECTING_ADDREF(EventListenerInfo
)
39 NS_IMPL_CYCLE_COLLECTING_RELEASE(EventListenerInfo
)
42 EventListenerInfo::GetType(nsAString
& aType
)
49 EventListenerInfo::GetCapturing(bool* aCapturing
)
51 *aCapturing
= mCapturing
;
56 EventListenerInfo::GetAllowsUntrusted(bool* aAllowsUntrusted
)
58 *aAllowsUntrusted
= mAllowsUntrusted
;
63 EventListenerInfo::GetInSystemEventGroup(bool* aInSystemEventGroup
)
65 *aInSystemEventGroup
= mInSystemEventGroup
;
70 EventListenerInfo::GetListenerObject(JSContext
* aCx
,
71 JS::MutableHandle
<JS::Value
> aObject
)
73 Maybe
<JSAutoCompartment
> ac
;
74 GetJSVal(aCx
, ac
, aObject
);
78 /******************************************************************************
79 * mozilla::EventListenerService
80 ******************************************************************************/
82 NS_IMPL_ISUPPORTS(EventListenerService
, nsIEventListenerService
)
85 EventListenerInfo::GetJSVal(JSContext
* aCx
,
86 Maybe
<JSAutoCompartment
>& aAc
,
87 JS::MutableHandle
<JS::Value
> aJSVal
)
90 nsCOMPtr
<nsIXPConnectWrappedJS
> wrappedJS
= do_QueryInterface(mListener
);
92 JS::Rooted
<JSObject
*> object(aCx
, wrappedJS
->GetJSObject());
96 aAc
.construct(aCx
, object
);
97 aJSVal
.setObject(*object
);
101 nsCOMPtr
<JSEventHandler
> jsHandler
= do_QueryInterface(mListener
);
102 if (jsHandler
&& jsHandler
->GetTypedEventHandler().HasEventHandler()) {
103 JS::Handle
<JSObject
*> handler
=
104 jsHandler
->GetTypedEventHandler().Ptr()->Callable();
106 aAc
.construct(aCx
, handler
);
107 aJSVal
.setObject(*handler
);
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
);
125 nsDependentJSString depStr
;
126 if (depStr
.init(cx
, str
)) {
127 aResult
.Assign(depStr
);
135 EventListenerInfo::GetDebugObject(nsISupports
** aRetVal
)
139 #ifdef MOZ_JSDEBUGGER
141 nsCOMPtr
<jsdIDebuggerService
> jsd
=
142 do_GetService("@mozilla.org/js/jsd/debugger-service;1", &rv
);
143 NS_ENSURE_SUCCESS(rv
, NS_OK
);
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
);
164 EventListenerService::GetListenerInfoFor(nsIDOMEventTarget
* aEventTarget
,
166 nsIEventListenerInfo
*** aOutArray
)
168 NS_ENSURE_ARG_POINTER(aEventTarget
);
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();
178 elm
->GetListenerInfo(&listenerInfos
);
181 int32_t count
= listenerInfos
.Count();
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
]);
199 EventListenerService::GetEventTargetChainFor(nsIDOMEventTarget
* aEventTarget
,
201 nsIDOMEventTarget
*** aOutArray
)
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();
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
]);
230 EventListenerService::HasListenersFor(nsIDOMEventTarget
* aEventTarget
,
231 const nsAString
& aType
,
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
);
243 EventListenerService::AddSystemEventListener(nsIDOMEventTarget
*aTarget
,
244 const nsAString
& aType
,
245 nsIDOMEventListener
* aListener
,
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
);
265 EventListenerService::RemoveSystemEventListener(nsIDOMEventTarget
*aTarget
,
266 const nsAString
& aType
,
267 nsIDOMEventListener
* aListener
,
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();
278 EventListenerFlags flags
=
279 aUseCapture
? TrustedEventsAtSystemGroupCapture() :
280 TrustedEventsAtSystemGroupBubble();
281 manager
->RemoveEventListenerByType(aListener
, aType
, flags
);
288 EventListenerService::AddListenerForAllEvents(nsIDOMEventTarget
* aTarget
,
289 nsIDOMEventListener
* aListener
,
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
,
307 EventListenerService::RemoveListenerForAllEvents(nsIDOMEventTarget
* aTarget
,
308 nsIDOMEventListener
* aListener
,
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();
319 manager
->RemoveListenerForAllEvents(aListener
, aUseCapture
, aSystemEventGroup
);
324 } // namespace mozilla
327 NS_NewEventListenerService(nsIEventListenerService
** aResult
)
329 *aResult
= new mozilla::EventListenerService();