Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef mozilla_EventListenerManager_h_
8 : #define mozilla_EventListenerManager_h_
9 :
10 : #include "mozilla/BasicEvents.h"
11 : #include "mozilla/dom/EventListenerBinding.h"
12 : #include "mozilla/JSEventHandler.h"
13 : #include "mozilla/MemoryReporting.h"
14 : #include "nsCOMPtr.h"
15 : #include "nsCycleCollectionParticipant.h"
16 : #include "nsGkAtoms.h"
17 : #include "nsIDOMEventListener.h"
18 : #include "nsTObserverArray.h"
19 :
20 : class nsIDocShell;
21 : class nsIDOMEvent;
22 : class nsIEventListenerInfo;
23 : class nsPIDOMWindowInner;
24 : class JSTracer;
25 :
26 : struct EventTypeData;
27 :
28 : template<class T> class nsCOMArray;
29 :
30 : namespace mozilla {
31 :
32 : class ELMCreationDetector;
33 : class EventListenerManager;
34 :
35 : namespace dom {
36 : class EventTarget;
37 : class Element;
38 : } // namespace dom
39 :
40 : typedef dom::CallbackObjectHolder<dom::EventListener,
41 : nsIDOMEventListener> EventListenerHolder;
42 :
43 : struct EventListenerFlags
44 : {
45 : friend class EventListenerManager;
46 : private:
47 : // If mListenerIsJSListener is true, the listener is implemented by JS.
48 : // Otherwise, it's implemented by native code or JS but it's wrapped.
49 : bool mListenerIsJSListener : 1;
50 :
51 : public:
52 : // If mCapture is true, it means the listener captures the event. Otherwise,
53 : // it's listening at bubbling phase.
54 : bool mCapture : 1;
55 : // If mInSystemGroup is true, the listener is listening to the events in the
56 : // system group.
57 : bool mInSystemGroup : 1;
58 : // If mAllowUntrustedEvents is true, the listener is listening to the
59 : // untrusted events too.
60 : bool mAllowUntrustedEvents : 1;
61 : // If mPassive is true, the listener will not be calling preventDefault on the
62 : // event. (If it does call preventDefault, we should ignore it).
63 : bool mPassive : 1;
64 : // If mOnce is true, the listener will be removed from the manager before it
65 : // is invoked, so that it would only be invoked once.
66 : bool mOnce : 1;
67 :
68 4190 : EventListenerFlags() :
69 : mListenerIsJSListener(false),
70 : mCapture(false), mInSystemGroup(false), mAllowUntrustedEvents(false),
71 4190 : mPassive(false), mOnce(false)
72 : {
73 4190 : }
74 :
75 15092 : bool EqualsForAddition(const EventListenerFlags& aOther) const
76 : {
77 24485 : return (mCapture == aOther.mCapture &&
78 16763 : mInSystemGroup == aOther.mInSystemGroup &&
79 29832 : mListenerIsJSListener == aOther.mListenerIsJSListener &&
80 22462 : mAllowUntrustedEvents == aOther.mAllowUntrustedEvents);
81 : // Don't compare mPassive or mOnce
82 : }
83 :
84 173 : bool EqualsForRemoval(const EventListenerFlags& aOther) const
85 : {
86 341 : return (mCapture == aOther.mCapture &&
87 341 : mInSystemGroup == aOther.mInSystemGroup &&
88 341 : mListenerIsJSListener == aOther.mListenerIsJSListener);
89 : // Don't compare mAllowUntrustedEvents, mPassive, or mOnce
90 : }
91 : };
92 :
93 : inline EventListenerFlags TrustedEventsAtBubble()
94 : {
95 : EventListenerFlags flags;
96 : return flags;
97 : }
98 :
99 55 : inline EventListenerFlags TrustedEventsAtCapture()
100 : {
101 55 : EventListenerFlags flags;
102 55 : flags.mCapture = true;
103 55 : return flags;
104 : }
105 :
106 : inline EventListenerFlags AllEventsAtBubble()
107 : {
108 : EventListenerFlags flags;
109 : flags.mAllowUntrustedEvents = true;
110 : return flags;
111 : }
112 :
113 : inline EventListenerFlags AllEventsAtCapture()
114 : {
115 : EventListenerFlags flags;
116 : flags.mCapture = true;
117 : flags.mAllowUntrustedEvents = true;
118 : return flags;
119 : }
120 :
121 130 : inline EventListenerFlags TrustedEventsAtSystemGroupBubble()
122 : {
123 130 : EventListenerFlags flags;
124 130 : flags.mInSystemGroup = true;
125 130 : return flags;
126 : }
127 :
128 43 : inline EventListenerFlags TrustedEventsAtSystemGroupCapture()
129 : {
130 43 : EventListenerFlags flags;
131 43 : flags.mCapture = true;
132 43 : flags.mInSystemGroup = true;
133 43 : return flags;
134 : }
135 :
136 0 : inline EventListenerFlags AllEventsAtSystemGroupBubble()
137 : {
138 0 : EventListenerFlags flags;
139 0 : flags.mInSystemGroup = true;
140 0 : flags.mAllowUntrustedEvents = true;
141 0 : return flags;
142 : }
143 :
144 : inline EventListenerFlags AllEventsAtSystemGroupCapture()
145 : {
146 : EventListenerFlags flags;
147 : flags.mCapture = true;
148 : flags.mInSystemGroup = true;
149 : flags.mAllowUntrustedEvents = true;
150 : return flags;
151 : }
152 :
153 : class EventListenerManagerBase
154 : {
155 : protected:
156 : EventListenerManagerBase();
157 :
158 : EventMessage mNoListenerForEvent;
159 : uint16_t mMayHavePaintEventListener : 1;
160 : uint16_t mMayHaveMutationListeners : 1;
161 : uint16_t mMayHaveCapturingListeners : 1;
162 : uint16_t mMayHaveSystemGroupListeners : 1;
163 : uint16_t mMayHaveTouchEventListener : 1;
164 : uint16_t mMayHaveMouseEnterLeaveEventListener : 1;
165 : uint16_t mMayHavePointerEnterLeaveEventListener : 1;
166 : uint16_t mMayHaveKeyEventListener : 1;
167 : uint16_t mMayHaveInputOrCompositionEventListener : 1;
168 : uint16_t mMayHaveSelectionChangeEventListener : 1;
169 : uint16_t mClearingListeners : 1;
170 : uint16_t mIsMainThreadELM : 1;
171 : // uint16_t mUnused : 4;
172 : };
173 :
174 : /*
175 : * Event listener manager
176 : */
177 :
178 : class EventListenerManager final : public EventListenerManagerBase
179 : {
180 : ~EventListenerManager();
181 :
182 : public:
183 : struct Listener
184 : {
185 : EventListenerHolder mListener;
186 : nsCOMPtr<nsIAtom> mTypeAtom; // for the main thread
187 : nsString mTypeString; // for non-main-threads
188 : EventMessage mEventMessage;
189 :
190 : enum ListenerType : uint8_t
191 : {
192 : eNoListener,
193 : eNativeListener,
194 : eJSEventListener,
195 : eWrappedJSListener,
196 : eWebIDLListener,
197 : };
198 : ListenerType mListenerType;
199 :
200 : bool mListenerIsHandler : 1;
201 : bool mHandlerIsString : 1;
202 : bool mAllEvents : 1;
203 : bool mIsChrome : 1;
204 :
205 : EventListenerFlags mFlags;
206 :
207 170 : JSEventHandler* GetJSEventHandler() const
208 : {
209 192 : return (mListenerType == eJSEventListener) ?
210 22 : static_cast<JSEventHandler*>(mListener.GetXPCOMCallback()) :
211 170 : nullptr;
212 : }
213 :
214 1918 : Listener()
215 1918 : : mEventMessage(eVoidEvent)
216 : , mListenerType(eNoListener)
217 : , mListenerIsHandler(false)
218 : , mHandlerIsString(false)
219 : , mAllEvents(false)
220 1918 : , mIsChrome(false)
221 : {
222 1918 : }
223 :
224 1 : Listener(Listener&& aOther)
225 1 : : mListener(Move(aOther.mListener))
226 2 : , mTypeAtom(aOther.mTypeAtom.forget())
227 : , mTypeString(aOther.mTypeString)
228 1 : , mEventMessage(aOther.mEventMessage)
229 1 : , mListenerType(aOther.mListenerType)
230 1 : , mListenerIsHandler(aOther.mListenerIsHandler)
231 1 : , mHandlerIsString(aOther.mHandlerIsString)
232 1 : , mAllEvents(aOther.mAllEvents)
233 8 : , mIsChrome(aOther.mIsChrome)
234 : {
235 1 : aOther.mTypeString.Truncate();
236 1 : aOther.mEventMessage = eVoidEvent;
237 1 : aOther.mListenerType = eNoListener;
238 1 : aOther.mListenerIsHandler = false;
239 1 : aOther.mHandlerIsString = false;
240 1 : aOther.mAllEvents = false;
241 1 : aOther.mIsChrome = false;
242 1 : }
243 :
244 198 : ~Listener()
245 198 : {
246 198 : if ((mListenerType == eJSEventListener) && mListener) {
247 : static_cast<JSEventHandler*>(
248 4 : mListener.GetXPCOMCallback())->Disconnect();
249 : }
250 198 : }
251 :
252 347 : MOZ_ALWAYS_INLINE bool IsListening(const WidgetEvent* aEvent) const
253 : {
254 347 : if (mFlags.mInSystemGroup != aEvent->mFlags.mInSystemGroup) {
255 126 : return false;
256 : }
257 : // FIXME Should check !mFlags.mCapture when the event is in target
258 : // phase because capture phase event listeners should not be fired.
259 : // But it breaks at least <xul:dialog>'s buttons. Bug 235441.
260 548 : return ((mFlags.mCapture && aEvent->mFlags.mInCapturePhase) ||
261 571 : (!mFlags.mCapture && aEvent->mFlags.mInBubblingPhase));
262 : }
263 : };
264 :
265 : explicit EventListenerManager(dom::EventTarget* aTarget);
266 :
267 2991 : NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(EventListenerManager)
268 :
269 3216 : NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(EventListenerManager)
270 :
271 343 : void AddEventListener(const nsAString& aType,
272 : nsIDOMEventListener* aListener,
273 : bool aUseCapture,
274 : bool aWantsUntrusted)
275 : {
276 686 : AddEventListener(aType, EventListenerHolder(aListener),
277 343 : aUseCapture, aWantsUntrusted);
278 343 : }
279 177 : void AddEventListener(const nsAString& aType,
280 : dom::EventListener* aListener,
281 : const dom::AddEventListenerOptionsOrBoolean& aOptions,
282 : bool aWantsUntrusted)
283 : {
284 354 : AddEventListener(aType, EventListenerHolder(aListener),
285 177 : aOptions, aWantsUntrusted);
286 177 : }
287 100 : void RemoveEventListener(const nsAString& aType,
288 : nsIDOMEventListener* aListener,
289 : bool aUseCapture)
290 : {
291 100 : RemoveEventListener(aType, EventListenerHolder(aListener), aUseCapture);
292 100 : }
293 15 : void RemoveEventListener(const nsAString& aType,
294 : dom::EventListener* aListener,
295 : const dom::EventListenerOptionsOrBoolean& aOptions)
296 : {
297 15 : RemoveEventListener(aType, EventListenerHolder(aListener), aOptions);
298 15 : }
299 :
300 : void AddListenerForAllEvents(nsIDOMEventListener* aListener,
301 : bool aUseCapture,
302 : bool aWantsUntrusted,
303 : bool aSystemEventGroup);
304 : void RemoveListenerForAllEvents(nsIDOMEventListener* aListener,
305 : bool aUseCapture,
306 : bool aSystemEventGroup);
307 :
308 : /**
309 : * Sets events listeners of all types.
310 : * @param an event listener
311 : */
312 1022 : void AddEventListenerByType(nsIDOMEventListener *aListener,
313 : const nsAString& type,
314 : const EventListenerFlags& aFlags)
315 : {
316 1022 : AddEventListenerByType(EventListenerHolder(aListener), type, aFlags);
317 1022 : }
318 : void AddEventListenerByType(EventListenerHolder aListener,
319 : const nsAString& type,
320 : const EventListenerFlags& aFlags);
321 63 : void RemoveEventListenerByType(nsIDOMEventListener *aListener,
322 : const nsAString& type,
323 : const EventListenerFlags& aFlags)
324 : {
325 63 : RemoveEventListenerByType(EventListenerHolder(aListener), type, aFlags);
326 63 : }
327 : void RemoveEventListenerByType(EventListenerHolder aListener,
328 : const nsAString& type,
329 : const EventListenerFlags& aFlags);
330 :
331 : /**
332 : * Sets the current "inline" event listener for aName to be a
333 : * function compiled from aFunc if !aDeferCompilation. If
334 : * aDeferCompilation, then we assume that we can get the string from
335 : * mTarget later and compile lazily.
336 : *
337 : * aElement, if not null, is the element the string is associated with.
338 : */
339 : // XXXbz does that play correctly with nodes being adopted across
340 : // documents? Need to double-check the spec here.
341 : nsresult SetEventHandler(nsIAtom *aName,
342 : const nsAString& aFunc,
343 : bool aDeferCompilation,
344 : bool aPermitUntrustedEvents,
345 : dom::Element* aElement);
346 : /**
347 : * Remove the current "inline" event listener for aName.
348 : */
349 : void RemoveEventHandler(nsIAtom *aName, const nsAString& aTypeString);
350 :
351 2944 : void HandleEvent(nsPresContext* aPresContext,
352 : WidgetEvent* aEvent,
353 : nsIDOMEvent** aDOMEvent,
354 : dom::EventTarget* aCurrentTarget,
355 : nsEventStatus* aEventStatus)
356 : {
357 2944 : if (mListeners.IsEmpty() || aEvent->PropagationStopped()) {
358 6 : return;
359 : }
360 :
361 2938 : if (!mMayHaveCapturingListeners && !aEvent->mFlags.mInBubblingPhase) {
362 441 : return;
363 : }
364 :
365 2497 : if (!mMayHaveSystemGroupListeners && aEvent->mFlags.mInSystemGroup) {
366 458 : return;
367 : }
368 :
369 : // Check if we already know that there is no event listener for the event.
370 4612 : if (mNoListenerForEvent == aEvent->mMessage &&
371 1694 : (mNoListenerForEvent != eUnidentifiedEvent ||
372 360 : mNoListenerForEventAtom == aEvent->mSpecifiedEventType)) {
373 1239 : return;
374 : }
375 : HandleEventInternal(aPresContext, aEvent, aDOMEvent, aCurrentTarget,
376 800 : aEventStatus);
377 : }
378 :
379 : /**
380 : * Tells the event listener manager that its target (which owns it) is
381 : * no longer using it (and could go away).
382 : */
383 : void Disconnect();
384 :
385 : /**
386 : * Allows us to quickly determine if we have mutation listeners registered.
387 : */
388 : bool HasMutationListeners();
389 :
390 : /**
391 : * Allows us to quickly determine whether we have unload or beforeunload
392 : * listeners registered.
393 : */
394 : bool HasUnloadListeners();
395 :
396 : /**
397 : * Returns the mutation bits depending on which mutation listeners are
398 : * registered to this listener manager.
399 : * @note If a listener is an nsIDOMMutationListener, all possible mutation
400 : * event bits are returned. All bits are also returned if one of the
401 : * event listeners is registered to handle DOMSubtreeModified events.
402 : */
403 : uint32_t MutationListenerBits();
404 :
405 : /**
406 : * Returns true if there is at least one event listener for aEventName.
407 : */
408 : bool HasListenersFor(const nsAString& aEventName);
409 :
410 : /**
411 : * Returns true if there is at least one event listener for aEventNameWithOn.
412 : * Note that aEventNameWithOn must start with "on"!
413 : */
414 : bool HasListenersFor(nsIAtom* aEventNameWithOn);
415 :
416 : /**
417 : * Returns true if there is at least one event listener.
418 : */
419 : bool HasListeners();
420 :
421 : /**
422 : * Sets aList to the list of nsIEventListenerInfo objects representing the
423 : * listeners managed by this listener manager.
424 : */
425 : nsresult GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList);
426 :
427 : uint32_t GetIdentifierForEvent(nsIAtom* aEvent);
428 :
429 : static void Shutdown();
430 :
431 : /**
432 : * Returns true if there may be a paint event listener registered,
433 : * false if there definitely isn't.
434 : */
435 0 : bool MayHavePaintEventListener() { return mMayHavePaintEventListener; }
436 :
437 : /**
438 : * Returns true if there may be a touch event listener registered,
439 : * false if there definitely isn't.
440 : */
441 0 : bool MayHaveTouchEventListener() { return mMayHaveTouchEventListener; }
442 :
443 0 : bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; }
444 0 : bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; }
445 0 : bool MayHaveSelectionChangeEventListener() { return mMayHaveSelectionChangeEventListener; }
446 :
447 : /**
448 : * Returns true if there may be a key event listener (keydown, keypress,
449 : * or keyup) registered, or false if there definitely isn't.
450 : */
451 0 : bool MayHaveKeyEventListener() { return mMayHaveKeyEventListener; }
452 :
453 : /**
454 : * Returns true if there may be an advanced input event listener (input,
455 : * compositionstart, compositionupdate, or compositionend) registered,
456 : * or false if there definitely isn't.
457 : */
458 0 : bool MayHaveInputOrCompositionEventListener() { return mMayHaveInputOrCompositionEventListener; }
459 :
460 : size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
461 :
462 21 : uint32_t ListenerCount() const
463 : {
464 21 : return mListeners.Length();
465 : }
466 :
467 : void MarkForCC();
468 :
469 : void TraceListeners(JSTracer* aTrc);
470 :
471 0 : dom::EventTarget* GetTarget() { return mTarget; }
472 :
473 : bool HasUntrustedOrNonSystemGroupKeyEventListeners();
474 :
475 : bool HasApzAwareListeners();
476 : bool IsApzAwareListener(Listener* aListener);
477 : bool IsApzAwareEvent(nsIAtom* aEvent);
478 :
479 : protected:
480 : void HandleEventInternal(nsPresContext* aPresContext,
481 : WidgetEvent* aEvent,
482 : nsIDOMEvent** aDOMEvent,
483 : dom::EventTarget* aCurrentTarget,
484 : nsEventStatus* aEventStatus);
485 :
486 : nsresult HandleEventSubType(Listener* aListener,
487 : nsIDOMEvent* aDOMEvent,
488 : dom::EventTarget* aCurrentTarget);
489 :
490 : /**
491 : * If the given EventMessage has a legacy version that we support, then this
492 : * function returns that legacy version. Otherwise, this function simply
493 : * returns the passed-in EventMessage.
494 : */
495 : EventMessage GetLegacyEventMessage(EventMessage aEventMessage) const;
496 :
497 : void ProcessApzAwareEventListenerAdd();
498 :
499 : /**
500 : * Compile the "inline" event listener for aListener. The
501 : * body of the listener can be provided in aBody; if this is null we
502 : * will look for it on mTarget. If aBody is provided, aElement should be
503 : * as well; otherwise it will also be inferred from mTarget.
504 : */
505 : nsresult CompileEventHandlerInternal(Listener* aListener,
506 : const nsAString* aBody,
507 : dom::Element* aElement);
508 :
509 : /**
510 : * Find the Listener for the "inline" event listener for aTypeAtom.
511 : */
512 : Listener* FindEventHandler(EventMessage aEventMessage,
513 : nsIAtom* aTypeAtom,
514 : const nsAString& aTypeString);
515 :
516 : /**
517 : * Set the "inline" event listener for aName to aHandler. aHandler may be
518 : * have no actual handler set to indicate that we should lazily get and
519 : * compile the string for this listener, but in that case aContext and
520 : * aScopeGlobal must be non-null. Otherwise, aContext and aScopeGlobal are
521 : * allowed to be null.
522 : */
523 : Listener* SetEventHandlerInternal(nsIAtom* aName,
524 : const nsAString& aTypeString,
525 : const TypedEventHandler& aHandler,
526 : bool aPermitUntrustedEvents);
527 :
528 : bool IsDeviceType(EventMessage aEventMessage);
529 : void EnableDevice(EventMessage aEventMessage);
530 : void DisableDevice(EventMessage aEventMessage);
531 :
532 : public:
533 : /**
534 : * Set the "inline" event listener for aEventName to aHandler. If
535 : * aHandler is null, this will actually remove the event listener
536 : */
537 : void SetEventHandler(nsIAtom* aEventName,
538 : const nsAString& aTypeString,
539 : dom::EventHandlerNonNull* aHandler);
540 : void SetEventHandler(dom::OnErrorEventHandlerNonNull* aHandler);
541 : void SetEventHandler(dom::OnBeforeUnloadEventHandlerNonNull* aHandler);
542 :
543 : /**
544 : * Get the value of the "inline" event listener for aEventName.
545 : * This may cause lazy compilation if the listener is uncompiled.
546 : *
547 : * Note: It's the caller's responsibility to make sure to call the right one
548 : * of these methods. In particular, "onerror" events use
549 : * OnErrorEventHandlerNonNull for some event targets and EventHandlerNonNull
550 : * for others.
551 : */
552 0 : dom::EventHandlerNonNull* GetEventHandler(nsIAtom* aEventName,
553 : const nsAString& aTypeString)
554 : {
555 : const TypedEventHandler* typedHandler =
556 0 : GetTypedEventHandler(aEventName, aTypeString);
557 0 : return typedHandler ? typedHandler->NormalEventHandler() : nullptr;
558 : }
559 :
560 0 : dom::OnErrorEventHandlerNonNull* GetOnErrorEventHandler()
561 : {
562 0 : const TypedEventHandler* typedHandler = mIsMainThreadELM ?
563 0 : GetTypedEventHandler(nsGkAtoms::onerror, EmptyString()) :
564 0 : GetTypedEventHandler(nullptr, NS_LITERAL_STRING("error"));
565 0 : return typedHandler ? typedHandler->OnErrorEventHandler() : nullptr;
566 : }
567 :
568 0 : dom::OnBeforeUnloadEventHandlerNonNull* GetOnBeforeUnloadEventHandler()
569 : {
570 : const TypedEventHandler* typedHandler =
571 0 : GetTypedEventHandler(nsGkAtoms::onbeforeunload, EmptyString());
572 0 : return typedHandler ? typedHandler->OnBeforeUnloadEventHandler() : nullptr;
573 : }
574 :
575 : protected:
576 : /**
577 : * Helper method for implementing the various Get*EventHandler above. Will
578 : * return null if we don't have an event handler for this event name.
579 : */
580 : const TypedEventHandler* GetTypedEventHandler(nsIAtom* aEventName,
581 : const nsAString& aTypeString);
582 :
583 : void AddEventListener(const nsAString& aType,
584 : EventListenerHolder aListener,
585 : const dom::AddEventListenerOptionsOrBoolean& aOptions,
586 : bool aWantsUntrusted);
587 : void AddEventListener(const nsAString& aType,
588 : EventListenerHolder aListener,
589 : bool aUseCapture,
590 : bool aWantsUntrusted);
591 : void RemoveEventListener(const nsAString& aType,
592 : EventListenerHolder aListener,
593 : const dom::EventListenerOptionsOrBoolean& aOptions);
594 : void RemoveEventListener(const nsAString& aType,
595 : EventListenerHolder aListener,
596 : bool aUseCapture);
597 :
598 : void AddEventListenerInternal(EventListenerHolder aListener,
599 : EventMessage aEventMessage,
600 : nsIAtom* aTypeAtom,
601 : const nsAString& aTypeString,
602 : const EventListenerFlags& aFlags,
603 : bool aHandler = false,
604 : bool aAllEvents = false);
605 : void RemoveEventListenerInternal(EventListenerHolder aListener,
606 : EventMessage aEventMessage,
607 : nsIAtom* aUserType,
608 : const nsAString& aTypeString,
609 : const EventListenerFlags& aFlags,
610 : bool aAllEvents = false);
611 : void RemoveAllListeners();
612 : void NotifyEventListenerRemoved(nsIAtom* aUserType,
613 : const nsAString& aTypeString);
614 : const EventTypeData* GetTypeDataForIID(const nsIID& aIID);
615 : const EventTypeData* GetTypeDataForEventName(nsIAtom* aName);
616 : nsPIDOMWindowInner* GetInnerWindowForTarget();
617 : already_AddRefed<nsPIDOMWindowInner> GetTargetAsInnerWindow() const;
618 :
619 : bool ListenerCanHandle(const Listener* aListener,
620 : const WidgetEvent* aEvent,
621 : EventMessage aEventMessage) const;
622 :
623 : // BE AWARE, a lot of instances of EventListenerManager will be created.
624 : // Therefor, we need to keep this class compact. When you add integer
625 : // members, please add them to EventListemerManagerBase and check the size
626 : // at build time.
627 :
628 : already_AddRefed<nsIScriptGlobalObject>
629 : GetScriptGlobalAndDocument(nsIDocument** aDoc);
630 :
631 : nsAutoTObserverArray<Listener, 2> mListeners;
632 : dom::EventTarget* MOZ_NON_OWNING_REF mTarget;
633 : nsCOMPtr<nsIAtom> mNoListenerForEventAtom;
634 :
635 : friend class ELMCreationDetector;
636 : static uint32_t sMainThreadCreatedCount;
637 : };
638 :
639 : } // namespace mozilla
640 :
641 : /**
642 : * NS_AddSystemEventListener() is a helper function for implementing
643 : * EventTarget::AddSystemEventListener().
644 : */
645 : inline nsresult
646 352 : NS_AddSystemEventListener(mozilla::dom::EventTarget* aTarget,
647 : const nsAString& aType,
648 : nsIDOMEventListener *aListener,
649 : bool aUseCapture,
650 : bool aWantsUntrusted)
651 : {
652 : mozilla::EventListenerManager* listenerManager =
653 352 : aTarget->GetOrCreateListenerManager();
654 352 : NS_ENSURE_STATE(listenerManager);
655 352 : mozilla::EventListenerFlags flags;
656 352 : flags.mInSystemGroup = true;
657 352 : flags.mCapture = aUseCapture;
658 352 : flags.mAllowUntrustedEvents = aWantsUntrusted;
659 352 : listenerManager->AddEventListenerByType(aListener, aType, flags);
660 352 : return NS_OK;
661 : }
662 :
663 : #endif // mozilla_EventListenerManager_h_
|