1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/events/EventListenerManager.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,579 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef mozilla_EventListenerManager_h_ 1.10 +#define mozilla_EventListenerManager_h_ 1.11 + 1.12 +#include "mozilla/BasicEvents.h" 1.13 +#include "mozilla/dom/EventListenerBinding.h" 1.14 +#include "mozilla/JSEventHandler.h" 1.15 +#include "mozilla/MemoryReporting.h" 1.16 +#include "nsCOMPtr.h" 1.17 +#include "nsCycleCollectionParticipant.h" 1.18 +#include "nsGkAtoms.h" 1.19 +#include "nsIDOMEventListener.h" 1.20 +#include "nsTObserverArray.h" 1.21 + 1.22 +class nsIDOMEvent; 1.23 +class nsIEventListenerInfo; 1.24 +class nsIScriptContext; 1.25 +class nsPIDOMWindow; 1.26 + 1.27 +struct EventTypeData; 1.28 + 1.29 +template<class T> class nsCOMArray; 1.30 + 1.31 +namespace mozilla { 1.32 + 1.33 +class ELMCreationDetector; 1.34 +class EventListenerManager; 1.35 + 1.36 +namespace dom { 1.37 +class EventTarget; 1.38 +class Element; 1.39 +} // namespace dom 1.40 + 1.41 +typedef dom::CallbackObjectHolder<dom::EventListener, 1.42 + nsIDOMEventListener> EventListenerHolder; 1.43 + 1.44 +struct EventListenerFlags 1.45 +{ 1.46 + friend class EventListenerManager; 1.47 +private: 1.48 + // If mListenerIsJSListener is true, the listener is implemented by JS. 1.49 + // Otherwise, it's implemented by native code or JS but it's wrapped. 1.50 + bool mListenerIsJSListener : 1; 1.51 + 1.52 +public: 1.53 + // If mCapture is true, it means the listener captures the event. Otherwise, 1.54 + // it's listening at bubbling phase. 1.55 + bool mCapture : 1; 1.56 + // If mInSystemGroup is true, the listener is listening to the events in the 1.57 + // system group. 1.58 + bool mInSystemGroup : 1; 1.59 + // If mAllowUntrustedEvents is true, the listener is listening to the 1.60 + // untrusted events too. 1.61 + bool mAllowUntrustedEvents : 1; 1.62 + 1.63 + EventListenerFlags() : 1.64 + mListenerIsJSListener(false), 1.65 + mCapture(false), mInSystemGroup(false), mAllowUntrustedEvents(false) 1.66 + { 1.67 + } 1.68 + 1.69 + bool Equals(const EventListenerFlags& aOther) const 1.70 + { 1.71 + return (mCapture == aOther.mCapture && 1.72 + mInSystemGroup == aOther.mInSystemGroup && 1.73 + mListenerIsJSListener == aOther.mListenerIsJSListener && 1.74 + mAllowUntrustedEvents == aOther.mAllowUntrustedEvents); 1.75 + } 1.76 + 1.77 + bool EqualsIgnoringTrustness(const EventListenerFlags& aOther) const 1.78 + { 1.79 + return (mCapture == aOther.mCapture && 1.80 + mInSystemGroup == aOther.mInSystemGroup && 1.81 + mListenerIsJSListener == aOther.mListenerIsJSListener); 1.82 + } 1.83 + 1.84 + bool operator==(const EventListenerFlags& aOther) const 1.85 + { 1.86 + return Equals(aOther); 1.87 + } 1.88 +}; 1.89 + 1.90 +inline EventListenerFlags TrustedEventsAtBubble() 1.91 +{ 1.92 + EventListenerFlags flags; 1.93 + return flags; 1.94 +} 1.95 + 1.96 +inline EventListenerFlags TrustedEventsAtCapture() 1.97 +{ 1.98 + EventListenerFlags flags; 1.99 + flags.mCapture = true; 1.100 + return flags; 1.101 +} 1.102 + 1.103 +inline EventListenerFlags AllEventsAtBubbe() 1.104 +{ 1.105 + EventListenerFlags flags; 1.106 + flags.mAllowUntrustedEvents = true; 1.107 + return flags; 1.108 +} 1.109 + 1.110 +inline EventListenerFlags AllEventsAtCapture() 1.111 +{ 1.112 + EventListenerFlags flags; 1.113 + flags.mCapture = true; 1.114 + flags.mAllowUntrustedEvents = true; 1.115 + return flags; 1.116 +} 1.117 + 1.118 +inline EventListenerFlags TrustedEventsAtSystemGroupBubble() 1.119 +{ 1.120 + EventListenerFlags flags; 1.121 + flags.mInSystemGroup = true; 1.122 + return flags; 1.123 +} 1.124 + 1.125 +inline EventListenerFlags TrustedEventsAtSystemGroupCapture() 1.126 +{ 1.127 + EventListenerFlags flags; 1.128 + flags.mCapture = true; 1.129 + flags.mInSystemGroup = true; 1.130 + return flags; 1.131 +} 1.132 + 1.133 +inline EventListenerFlags AllEventsAtSystemGroupBubble() 1.134 +{ 1.135 + EventListenerFlags flags; 1.136 + flags.mInSystemGroup = true; 1.137 + flags.mAllowUntrustedEvents = true; 1.138 + return flags; 1.139 +} 1.140 + 1.141 +inline EventListenerFlags AllEventsAtSystemGroupCapture() 1.142 +{ 1.143 + EventListenerFlags flags; 1.144 + flags.mCapture = true; 1.145 + flags.mInSystemGroup = true; 1.146 + flags.mAllowUntrustedEvents = true; 1.147 + return flags; 1.148 +} 1.149 + 1.150 +/* 1.151 + * Event listener manager 1.152 + */ 1.153 + 1.154 +class EventListenerManager MOZ_FINAL 1.155 +{ 1.156 +public: 1.157 + struct Listener 1.158 + { 1.159 + EventListenerHolder mListener; 1.160 + nsCOMPtr<nsIAtom> mTypeAtom; // for the main thread 1.161 + nsString mTypeString; // for non-main-threads 1.162 + uint16_t mEventType; 1.163 + 1.164 + enum ListenerType MOZ_ENUM_TYPE(uint8_t) 1.165 + { 1.166 + eNativeListener = 0, 1.167 + eJSEventListener, 1.168 + eWrappedJSListener, 1.169 + eWebIDLListener, 1.170 + eListenerTypeCount 1.171 + }; 1.172 + uint8_t mListenerType; 1.173 + 1.174 + bool mListenerIsHandler : 1; 1.175 + bool mHandlerIsString : 1; 1.176 + bool mAllEvents : 1; 1.177 + 1.178 + EventListenerFlags mFlags; 1.179 + 1.180 + JSEventHandler* GetJSEventHandler() const 1.181 + { 1.182 + return (mListenerType == eJSEventListener) ? 1.183 + static_cast<JSEventHandler*>(mListener.GetXPCOMCallback()) : 1.184 + nullptr; 1.185 + } 1.186 + 1.187 + Listener() 1.188 + { 1.189 + MOZ_ASSERT(sizeof(mListenerType) == 1); 1.190 + MOZ_ASSERT(eListenerTypeCount < 255); 1.191 + } 1.192 + 1.193 + ~Listener() 1.194 + { 1.195 + if ((mListenerType == eJSEventListener) && mListener) { 1.196 + static_cast<JSEventHandler*>( 1.197 + mListener.GetXPCOMCallback())->Disconnect(); 1.198 + } 1.199 + } 1.200 + 1.201 + MOZ_ALWAYS_INLINE bool IsListening(const WidgetEvent* aEvent) const 1.202 + { 1.203 + if (mFlags.mInSystemGroup != aEvent->mFlags.mInSystemGroup) { 1.204 + return false; 1.205 + } 1.206 + // FIXME Should check !mFlags.mCapture when the event is in target 1.207 + // phase because capture phase event listeners should not be fired. 1.208 + // But it breaks at least <xul:dialog>'s buttons. Bug 235441. 1.209 + return ((mFlags.mCapture && aEvent->mFlags.mInCapturePhase) || 1.210 + (!mFlags.mCapture && aEvent->mFlags.mInBubblingPhase)); 1.211 + } 1.212 + }; 1.213 + 1.214 + EventListenerManager(dom::EventTarget* aTarget); 1.215 + virtual ~EventListenerManager(); 1.216 + 1.217 + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(EventListenerManager) 1.218 + 1.219 + NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(EventListenerManager) 1.220 + 1.221 + void AddEventListener(const nsAString& aType, 1.222 + nsIDOMEventListener* aListener, 1.223 + bool aUseCapture, 1.224 + bool aWantsUntrusted) 1.225 + { 1.226 + EventListenerHolder holder(aListener); 1.227 + AddEventListener(aType, holder, aUseCapture, aWantsUntrusted); 1.228 + } 1.229 + void AddEventListener(const nsAString& aType, 1.230 + dom::EventListener* aListener, 1.231 + bool aUseCapture, 1.232 + bool aWantsUntrusted) 1.233 + { 1.234 + EventListenerHolder holder(aListener); 1.235 + AddEventListener(aType, holder, aUseCapture, aWantsUntrusted); 1.236 + } 1.237 + void RemoveEventListener(const nsAString& aType, 1.238 + nsIDOMEventListener* aListener, 1.239 + bool aUseCapture) 1.240 + { 1.241 + EventListenerHolder holder(aListener); 1.242 + RemoveEventListener(aType, holder, aUseCapture); 1.243 + } 1.244 + void RemoveEventListener(const nsAString& aType, 1.245 + dom::EventListener* aListener, 1.246 + bool aUseCapture) 1.247 + { 1.248 + EventListenerHolder holder(aListener); 1.249 + RemoveEventListener(aType, holder, aUseCapture); 1.250 + } 1.251 + 1.252 + void AddListenerForAllEvents(nsIDOMEventListener* aListener, 1.253 + bool aUseCapture, 1.254 + bool aWantsUntrusted, 1.255 + bool aSystemEventGroup); 1.256 + void RemoveListenerForAllEvents(nsIDOMEventListener* aListener, 1.257 + bool aUseCapture, 1.258 + bool aSystemEventGroup); 1.259 + 1.260 + /** 1.261 + * Sets events listeners of all types. 1.262 + * @param an event listener 1.263 + */ 1.264 + void AddEventListenerByType(nsIDOMEventListener *aListener, 1.265 + const nsAString& type, 1.266 + const EventListenerFlags& aFlags) 1.267 + { 1.268 + EventListenerHolder holder(aListener); 1.269 + AddEventListenerByType(holder, type, aFlags); 1.270 + } 1.271 + void AddEventListenerByType(const EventListenerHolder& aListener, 1.272 + const nsAString& type, 1.273 + const EventListenerFlags& aFlags); 1.274 + void RemoveEventListenerByType(nsIDOMEventListener *aListener, 1.275 + const nsAString& type, 1.276 + const EventListenerFlags& aFlags) 1.277 + { 1.278 + EventListenerHolder holder(aListener); 1.279 + RemoveEventListenerByType(holder, type, aFlags); 1.280 + } 1.281 + void RemoveEventListenerByType(const EventListenerHolder& aListener, 1.282 + const nsAString& type, 1.283 + const EventListenerFlags& aFlags); 1.284 + 1.285 + /** 1.286 + * Sets the current "inline" event listener for aName to be a 1.287 + * function compiled from aFunc if !aDeferCompilation. If 1.288 + * aDeferCompilation, then we assume that we can get the string from 1.289 + * mTarget later and compile lazily. 1.290 + * 1.291 + * aElement, if not null, is the element the string is associated with. 1.292 + */ 1.293 + // XXXbz does that play correctly with nodes being adopted across 1.294 + // documents? Need to double-check the spec here. 1.295 + nsresult SetEventHandler(nsIAtom *aName, 1.296 + const nsAString& aFunc, 1.297 + uint32_t aLanguage, 1.298 + bool aDeferCompilation, 1.299 + bool aPermitUntrustedEvents, 1.300 + dom::Element* aElement); 1.301 + /** 1.302 + * Remove the current "inline" event listener for aName. 1.303 + */ 1.304 + void RemoveEventHandler(nsIAtom *aName, const nsAString& aTypeString); 1.305 + 1.306 + void HandleEvent(nsPresContext* aPresContext, 1.307 + WidgetEvent* aEvent, 1.308 + nsIDOMEvent** aDOMEvent, 1.309 + dom::EventTarget* aCurrentTarget, 1.310 + nsEventStatus* aEventStatus) 1.311 + { 1.312 + if (mListeners.IsEmpty() || aEvent->mFlags.mPropagationStopped) { 1.313 + return; 1.314 + } 1.315 + 1.316 + if (!mMayHaveCapturingListeners && !aEvent->mFlags.mInBubblingPhase) { 1.317 + return; 1.318 + } 1.319 + 1.320 + if (!mMayHaveSystemGroupListeners && aEvent->mFlags.mInSystemGroup) { 1.321 + return; 1.322 + } 1.323 + 1.324 + // Check if we already know that there is no event listener for the event. 1.325 + if (mNoListenerForEvent == aEvent->message && 1.326 + (mNoListenerForEvent != NS_USER_DEFINED_EVENT || 1.327 + mNoListenerForEventAtom == aEvent->userType)) { 1.328 + return; 1.329 + } 1.330 + HandleEventInternal(aPresContext, aEvent, aDOMEvent, aCurrentTarget, 1.331 + aEventStatus); 1.332 + } 1.333 + 1.334 + /** 1.335 + * Tells the event listener manager that its target (which owns it) is 1.336 + * no longer using it (and could go away). 1.337 + */ 1.338 + void Disconnect(); 1.339 + 1.340 + /** 1.341 + * Allows us to quickly determine if we have mutation listeners registered. 1.342 + */ 1.343 + bool HasMutationListeners(); 1.344 + 1.345 + /** 1.346 + * Allows us to quickly determine whether we have unload or beforeunload 1.347 + * listeners registered. 1.348 + */ 1.349 + bool HasUnloadListeners(); 1.350 + 1.351 + /** 1.352 + * Returns the mutation bits depending on which mutation listeners are 1.353 + * registered to this listener manager. 1.354 + * @note If a listener is an nsIDOMMutationListener, all possible mutation 1.355 + * event bits are returned. All bits are also returned if one of the 1.356 + * event listeners is registered to handle DOMSubtreeModified events. 1.357 + */ 1.358 + uint32_t MutationListenerBits(); 1.359 + 1.360 + /** 1.361 + * Returns true if there is at least one event listener for aEventName. 1.362 + */ 1.363 + bool HasListenersFor(const nsAString& aEventName); 1.364 + 1.365 + /** 1.366 + * Returns true if there is at least one event listener for aEventNameWithOn. 1.367 + * Note that aEventNameWithOn must start with "on"! 1.368 + */ 1.369 + bool HasListenersFor(nsIAtom* aEventNameWithOn); 1.370 + 1.371 + /** 1.372 + * Returns true if there is at least one event listener. 1.373 + */ 1.374 + bool HasListeners(); 1.375 + 1.376 + /** 1.377 + * Sets aList to the list of nsIEventListenerInfo objects representing the 1.378 + * listeners managed by this listener manager. 1.379 + */ 1.380 + nsresult GetListenerInfo(nsCOMArray<nsIEventListenerInfo>* aList); 1.381 + 1.382 + uint32_t GetIdentifierForEvent(nsIAtom* aEvent); 1.383 + 1.384 + static void Shutdown(); 1.385 + 1.386 + /** 1.387 + * Returns true if there may be a paint event listener registered, 1.388 + * false if there definitely isn't. 1.389 + */ 1.390 + bool MayHavePaintEventListener() { return mMayHavePaintEventListener; } 1.391 + 1.392 + /** 1.393 + * Returns true if there may be a touch event listener registered, 1.394 + * false if there definitely isn't. 1.395 + */ 1.396 + bool MayHaveTouchEventListener() { return mMayHaveTouchEventListener; } 1.397 + 1.398 + bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; } 1.399 + bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; } 1.400 + 1.401 + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; 1.402 + 1.403 + uint32_t ListenerCount() const 1.404 + { 1.405 + return mListeners.Length(); 1.406 + } 1.407 + 1.408 + void MarkForCC(); 1.409 + 1.410 + dom::EventTarget* GetTarget() { return mTarget; } 1.411 + 1.412 +protected: 1.413 + void HandleEventInternal(nsPresContext* aPresContext, 1.414 + WidgetEvent* aEvent, 1.415 + nsIDOMEvent** aDOMEvent, 1.416 + dom::EventTarget* aCurrentTarget, 1.417 + nsEventStatus* aEventStatus); 1.418 + 1.419 + nsresult HandleEventSubType(Listener* aListener, 1.420 + nsIDOMEvent* aDOMEvent, 1.421 + dom::EventTarget* aCurrentTarget); 1.422 + 1.423 + /** 1.424 + * Compile the "inline" event listener for aListener. The 1.425 + * body of the listener can be provided in aBody; if this is null we 1.426 + * will look for it on mTarget. If aBody is provided, aElement should be 1.427 + * as well; otherwise it will also be inferred from mTarget. 1.428 + */ 1.429 + nsresult CompileEventHandlerInternal(Listener* aListener, 1.430 + const nsAString* aBody, 1.431 + dom::Element* aElement); 1.432 + 1.433 + /** 1.434 + * Find the Listener for the "inline" event listener for aTypeAtom. 1.435 + */ 1.436 + Listener* FindEventHandler(uint32_t aEventType, 1.437 + nsIAtom* aTypeAtom, 1.438 + const nsAString& aTypeString); 1.439 + 1.440 + /** 1.441 + * Set the "inline" event listener for aName to aHandler. aHandler may be 1.442 + * have no actual handler set to indicate that we should lazily get and 1.443 + * compile the string for this listener, but in that case aContext and 1.444 + * aScopeGlobal must be non-null. Otherwise, aContext and aScopeGlobal are 1.445 + * allowed to be null. 1.446 + */ 1.447 + Listener* SetEventHandlerInternal(nsIAtom* aName, 1.448 + const nsAString& aTypeString, 1.449 + const TypedEventHandler& aHandler, 1.450 + bool aPermitUntrustedEvents); 1.451 + 1.452 + bool IsDeviceType(uint32_t aType); 1.453 + void EnableDevice(uint32_t aType); 1.454 + void DisableDevice(uint32_t aType); 1.455 + 1.456 +public: 1.457 + /** 1.458 + * Set the "inline" event listener for aEventName to aHandler. If 1.459 + * aHandler is null, this will actually remove the event listener 1.460 + */ 1.461 + void SetEventHandler(nsIAtom* aEventName, 1.462 + const nsAString& aTypeString, 1.463 + dom::EventHandlerNonNull* aHandler); 1.464 + void SetEventHandler(dom::OnErrorEventHandlerNonNull* aHandler); 1.465 + void SetEventHandler(dom::OnBeforeUnloadEventHandlerNonNull* aHandler); 1.466 + 1.467 + /** 1.468 + * Get the value of the "inline" event listener for aEventName. 1.469 + * This may cause lazy compilation if the listener is uncompiled. 1.470 + * 1.471 + * Note: It's the caller's responsibility to make sure to call the right one 1.472 + * of these methods. In particular, "onerror" events use 1.473 + * OnErrorEventHandlerNonNull for some event targets and EventHandlerNonNull 1.474 + * for others. 1.475 + */ 1.476 + dom::EventHandlerNonNull* GetEventHandler(nsIAtom* aEventName, 1.477 + const nsAString& aTypeString) 1.478 + { 1.479 + const TypedEventHandler* typedHandler = 1.480 + GetTypedEventHandler(aEventName, aTypeString); 1.481 + return typedHandler ? typedHandler->NormalEventHandler() : nullptr; 1.482 + } 1.483 + 1.484 + dom::OnErrorEventHandlerNonNull* GetOnErrorEventHandler() 1.485 + { 1.486 + const TypedEventHandler* typedHandler = mIsMainThreadELM ? 1.487 + GetTypedEventHandler(nsGkAtoms::onerror, EmptyString()) : 1.488 + GetTypedEventHandler(nullptr, NS_LITERAL_STRING("error")); 1.489 + return typedHandler ? typedHandler->OnErrorEventHandler() : nullptr; 1.490 + } 1.491 + 1.492 + dom::OnBeforeUnloadEventHandlerNonNull* GetOnBeforeUnloadEventHandler() 1.493 + { 1.494 + const TypedEventHandler* typedHandler = 1.495 + GetTypedEventHandler(nsGkAtoms::onbeforeunload, EmptyString()); 1.496 + return typedHandler ? typedHandler->OnBeforeUnloadEventHandler() : nullptr; 1.497 + } 1.498 + 1.499 +protected: 1.500 + /** 1.501 + * Helper method for implementing the various Get*EventHandler above. Will 1.502 + * return null if we don't have an event handler for this event name. 1.503 + */ 1.504 + const TypedEventHandler* GetTypedEventHandler(nsIAtom* aEventName, 1.505 + const nsAString& aTypeString); 1.506 + 1.507 + void AddEventListener(const nsAString& aType, 1.508 + const EventListenerHolder& aListener, 1.509 + bool aUseCapture, 1.510 + bool aWantsUntrusted); 1.511 + void RemoveEventListener(const nsAString& aType, 1.512 + const EventListenerHolder& aListener, 1.513 + bool aUseCapture); 1.514 + 1.515 + void AddEventListenerInternal(const EventListenerHolder& aListener, 1.516 + uint32_t aType, 1.517 + nsIAtom* aTypeAtom, 1.518 + const nsAString& aTypeString, 1.519 + const EventListenerFlags& aFlags, 1.520 + bool aHandler = false, 1.521 + bool aAllEvents = false); 1.522 + void RemoveEventListenerInternal(const EventListenerHolder& aListener, 1.523 + uint32_t aType, 1.524 + nsIAtom* aUserType, 1.525 + const nsAString& aTypeString, 1.526 + const EventListenerFlags& aFlags, 1.527 + bool aAllEvents = false); 1.528 + void RemoveAllListeners(); 1.529 + const EventTypeData* GetTypeDataForIID(const nsIID& aIID); 1.530 + const EventTypeData* GetTypeDataForEventName(nsIAtom* aName); 1.531 + nsPIDOMWindow* GetInnerWindowForTarget(); 1.532 + already_AddRefed<nsPIDOMWindow> GetTargetAsInnerWindow() const; 1.533 + 1.534 + bool ListenerCanHandle(Listener* aListener, WidgetEvent* aEvent); 1.535 + 1.536 + already_AddRefed<nsIScriptGlobalObject> 1.537 + GetScriptGlobalAndDocument(nsIDocument** aDoc); 1.538 + 1.539 + uint32_t mMayHavePaintEventListener : 1; 1.540 + uint32_t mMayHaveMutationListeners : 1; 1.541 + uint32_t mMayHaveCapturingListeners : 1; 1.542 + uint32_t mMayHaveSystemGroupListeners : 1; 1.543 + uint32_t mMayHaveTouchEventListener : 1; 1.544 + uint32_t mMayHaveMouseEnterLeaveEventListener : 1; 1.545 + uint32_t mMayHavePointerEnterLeaveEventListener : 1; 1.546 + uint32_t mClearingListeners : 1; 1.547 + uint32_t mIsMainThreadELM : 1; 1.548 + uint32_t mNoListenerForEvent : 23; 1.549 + 1.550 + nsAutoTObserverArray<Listener, 2> mListeners; 1.551 + dom::EventTarget* mTarget; // WEAK 1.552 + nsCOMPtr<nsIAtom> mNoListenerForEventAtom; 1.553 + 1.554 + friend class ELMCreationDetector; 1.555 + static uint32_t sMainThreadCreatedCount; 1.556 +}; 1.557 + 1.558 +} // namespace mozilla 1.559 + 1.560 +/** 1.561 + * NS_AddSystemEventListener() is a helper function for implementing 1.562 + * EventTarget::AddSystemEventListener(). 1.563 + */ 1.564 +inline nsresult 1.565 +NS_AddSystemEventListener(mozilla::dom::EventTarget* aTarget, 1.566 + const nsAString& aType, 1.567 + nsIDOMEventListener *aListener, 1.568 + bool aUseCapture, 1.569 + bool aWantsUntrusted) 1.570 +{ 1.571 + mozilla::EventListenerManager* listenerManager = 1.572 + aTarget->GetOrCreateListenerManager(); 1.573 + NS_ENSURE_STATE(listenerManager); 1.574 + mozilla::EventListenerFlags flags; 1.575 + flags.mInSystemGroup = true; 1.576 + flags.mCapture = aUseCapture; 1.577 + flags.mAllowUntrustedEvents = aWantsUntrusted; 1.578 + listenerManager->AddEventListenerByType(aListener, aType, flags); 1.579 + return NS_OK; 1.580 +} 1.581 + 1.582 +#endif // mozilla_EventListenerManager_h_