EventTarget.h (20301B)
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_dom_EventTarget_h_ 8 #define mozilla_dom_EventTarget_h_ 9 10 #include "mozilla/dom/Nullable.h" 11 #include "nsAtom.h" 12 #include "nsISupports.h" 13 #include "nsWrapperCache.h" 14 15 class nsIDOMEventListener; 16 class nsIGlobalObject; 17 class nsINode; 18 class nsPIDOMWindowInner; 19 class nsPIDOMWindowOuter; 20 class nsPIWindowRoot; 21 class nsScreen; 22 23 namespace mozilla { 24 25 class AsyncEventDispatcher; 26 class ErrorResult; 27 class EventChainPostVisitor; 28 class EventChainPreVisitor; 29 class EventChainVisitor; 30 class EventListenerManager; 31 32 namespace dom { 33 34 class AddEventListenerOptionsOrBoolean; 35 class Event; 36 class EventListener; 37 class EventListenerOptionsOrBoolean; 38 class EventHandlerNonNull; 39 class GlobalObject; 40 class Navigation; 41 class WindowProxyHolder; 42 enum class CallerType : uint32_t; 43 enum class EventCallbackDebuggerNotificationType : uint8_t; 44 45 // IID for the dom::EventTarget interface 46 #define NS_EVENTTARGET_IID \ 47 {0xde651c36, 0x0053, 0x4c67, {0xb1, 0x3d, 0x67, 0xb9, 0x40, 0xfc, 0x82, 0xe4}} 48 49 class EventTarget : public nsISupports, public nsWrapperCache { 50 public: 51 NS_INLINE_DECL_STATIC_IID(NS_EVENTTARGET_IID) 52 53 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 54 55 void SetIsOnMainThread() { 56 MOZ_ASSERT(NS_IsMainThread()); 57 mRefCnt.SetIsOnMainThread(); 58 } 59 60 #ifndef NS_BUILD_REFCNT_LOGGING 61 MozExternalRefCountType NonVirtualAddRef(); 62 MozExternalRefCountType NonVirtualRelease(); 63 #endif 64 65 // WebIDL API 66 static already_AddRefed<EventTarget> Constructor(const GlobalObject& aGlobal, 67 ErrorResult& aRv); 68 void AddEventListener(const nsAString& aType, EventListener* aCallback, 69 const AddEventListenerOptionsOrBoolean& aOptions, 70 const Nullable<bool>& aWantsUntrusted); 71 void RemoveEventListener(const nsAString& aType, EventListener* aCallback, 72 const EventListenerOptionsOrBoolean& aOptions); 73 74 protected: 75 /** 76 * This method allows addition of event listeners represented by 77 * nsIDOMEventListener, with almost the same semantics as the 78 * standard AddEventListener. The one difference is that it just 79 * has a "use capture" boolean, not an EventListenerOptions. 80 */ 81 nsresult AddEventListener(const nsAString& aType, 82 nsIDOMEventListener* aListener, bool aUseCapture, 83 const Nullable<bool>& aWantsUntrusted); 84 85 public: 86 /** 87 * Helper methods to make the nsIDOMEventListener version of 88 * AddEventListener simpler to call for consumers. 89 */ 90 nsresult AddEventListener(const nsAString& aType, 91 nsIDOMEventListener* aListener, bool aUseCapture) { 92 return AddEventListener(aType, aListener, aUseCapture, Nullable<bool>()); 93 } 94 nsresult AddEventListener(const nsAString& aType, 95 nsIDOMEventListener* aListener, bool aUseCapture, 96 bool aWantsUntrusted) { 97 return AddEventListener(aType, aListener, aUseCapture, 98 Nullable<bool>(aWantsUntrusted)); 99 } 100 101 /** 102 * This method allows the removal of event listeners represented by 103 * nsIDOMEventListener from the event target, with the same semantics as the 104 * standard RemoveEventListener. 105 */ 106 void RemoveEventListener(const nsAString& aType, 107 nsIDOMEventListener* aListener, bool aUseCapture); 108 /** 109 * RemoveSystemEventListener() should be used if you have used 110 * AddSystemEventListener(). 111 */ 112 void RemoveSystemEventListener(const nsAString& aType, 113 nsIDOMEventListener* aListener, 114 bool aUseCapture); 115 116 /** 117 * Add a system event listener with the default wantsUntrusted value. 118 */ 119 nsresult AddSystemEventListener(const nsAString& aType, 120 nsIDOMEventListener* aListener, 121 bool aUseCapture) { 122 return AddSystemEventListener(aType, aListener, aUseCapture, 123 Nullable<bool>()); 124 } 125 126 /** 127 * Add a system event listener with the given wantsUntrusted value. 128 */ 129 nsresult AddSystemEventListener(const nsAString& aType, 130 nsIDOMEventListener* aListener, 131 bool aUseCapture, bool aWantsUntrusted) { 132 return AddSystemEventListener(aType, aListener, aUseCapture, 133 Nullable<bool>(aWantsUntrusted)); 134 } 135 136 virtual bool IsNode() const { return false; } 137 inline nsINode* GetAsNode(); 138 inline const nsINode* GetAsNode() const; 139 inline nsINode* AsNode(); 140 inline const nsINode* AsNode() const; 141 142 virtual bool IsNavigation() const { return false; } 143 inline Navigation* GetAsNavigation(); 144 inline const Navigation* GetAsNavigation() const; 145 inline Navigation* AsNavigation(); 146 inline const Navigation* AsNavigation() const; 147 148 virtual bool IsScreen() const { return false; } 149 inline nsScreen* GetAsScreen(); 150 inline const nsScreen* GetAsScreen() const; 151 inline nsScreen* AsScreen(); 152 inline const nsScreen* AsScreen() const; 153 154 virtual bool IsInnerWindow() const { return false; } 155 virtual bool IsOuterWindow() const { return false; } 156 virtual bool IsRootWindow() const { return false; } 157 nsPIDOMWindowInner* GetAsInnerWindow(); 158 const nsPIDOMWindowInner* GetAsInnerWindow() const; 159 nsPIDOMWindowOuter* GetAsOuterWindow(); 160 const nsPIDOMWindowOuter* GetAsOuterWindow() const; 161 inline nsPIWindowRoot* GetAsWindowRoot(); 162 inline const nsPIWindowRoot* GetAsWindowRoot() const; 163 nsPIDOMWindowInner* AsInnerWindow(); 164 const nsPIDOMWindowInner* AsInnerWindow() const; 165 nsPIDOMWindowOuter* AsOuterWindow(); 166 const nsPIDOMWindowOuter* AsOuterWindow() const; 167 inline nsPIWindowRoot* AsWindowRoot(); 168 inline const nsPIWindowRoot* AsWindowRoot() const; 169 170 /** 171 * Returns the EventTarget object which should be used as the target 172 * of DOMEvents. 173 * Usually |this| is returned, but for example Window (inner windw) returns 174 * the WindowProxy (outer window). 175 */ 176 virtual EventTarget* GetTargetForDOMEvent() { return this; }; 177 178 /** 179 * Returns the EventTarget object which should be used as the target 180 * of the event and when constructing event target chain. 181 * Usually |this| is returned, but for example WindowProxy (outer window) 182 * returns the Window (inner window). 183 */ 184 virtual EventTarget* GetTargetForEventTargetChain() { return this; } 185 186 /** 187 * The most general DispatchEvent method. This is the one the bindings call. 188 */ 189 // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230) 190 MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual bool DispatchEvent(Event& aEvent, 191 CallerType aCallerType, 192 ErrorResult& aRv) = 0; 193 194 /** 195 * A version of DispatchEvent you can use if you really don't care whether it 196 * succeeds or not and whether default is prevented or not. 197 */ 198 // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230) 199 MOZ_CAN_RUN_SCRIPT_BOUNDARY void DispatchEvent(Event& aEvent); 200 201 /** 202 * A version of DispatchEvent you can use if you really don't care whether 203 * default is prevented or not. 204 */ 205 // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230) 206 MOZ_CAN_RUN_SCRIPT_BOUNDARY void DispatchEvent(Event& aEvent, 207 ErrorResult& aRv); 208 209 nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); } 210 211 // Note, this takes the type in onfoo form! 212 EventHandlerNonNull* GetEventHandler(const nsAString& aType) { 213 RefPtr<nsAtom> type = NS_Atomize(aType); 214 return GetEventHandler(type); 215 } 216 217 // Note, this takes the type in onfoo form! 218 void SetEventHandler(const nsAString& aType, EventHandlerNonNull* aHandler, 219 ErrorResult& rv); 220 221 // For an event 'foo' aType will be 'onfoo'. 222 virtual void EventListenerAdded(nsAtom* aType) {} 223 224 // For an event 'foo' aType will be 'onfoo'. 225 virtual void EventListenerRemoved(nsAtom* aType) {} 226 227 // Returns an outer window that corresponds to the inner window this event 228 // target is associated with. Will return null if the inner window is not the 229 // current inner or if there is no window around at all. 230 Nullable<WindowProxyHolder> GetOwnerGlobalForBindings(); 231 virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindingsInternal() = 0; 232 233 // The global object this event target is associated with, if any. 234 // This may be an inner window or some other global object. This 235 // will never be an outer window. 236 virtual nsIGlobalObject* GetOwnerGlobal() const = 0; 237 238 /** 239 * Get the event listener manager, creating it if it does not already exist. 240 */ 241 virtual EventListenerManager* GetOrCreateListenerManager() = 0; 242 243 /** 244 * Get the event listener manager, returning null if it does not already 245 * exist. 246 */ 247 virtual EventListenerManager* GetExistingListenerManager() const = 0; 248 249 virtual Maybe<EventCallbackDebuggerNotificationType> 250 GetDebuggerNotificationType() const { 251 return Nothing(); 252 } 253 254 // Called from AsyncEventDispatcher to notify it is running. 255 virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) {} 256 257 // Used by APZ to determine whether this event target has non-chrome event 258 // listeners for untrusted key events. 259 bool HasNonSystemGroupListenersForUntrustedKeyEvents() const; 260 261 // Used by APZ to determine whether this event target has non-chrome and 262 // non-passive event listeners for untrusted key events. 263 bool HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents() const; 264 265 virtual bool IsApzAware() const; 266 267 /** 268 * Called before the capture phase of the event flow. 269 * This is used to create the event target chain and implementations 270 * should set the necessary members of EventChainPreVisitor. 271 * At least aVisitor.mCanHandle must be set, 272 * usually also aVisitor.mParentTarget if mCanHandle is true. 273 * mCanHandle says that this object can handle the aVisitor.mEvent event and 274 * the mParentTarget is the possible parent object for the event target chain. 275 * @see EventDispatcher.h for more documentation about aVisitor. 276 * 277 * @param aVisitor the visitor object which is used to create the 278 * event target chain for event dispatching. 279 * 280 * @note Only EventDispatcher should call this method. 281 */ 282 virtual void GetEventTargetParent(EventChainPreVisitor& aVisitor) = 0; 283 284 /** 285 * Called on the activation target during dispatch of activation events. 286 * https://dom.spec.whatwg.org/#eventtarget-legacy-pre-activation-behavior 287 */ 288 virtual void LegacyPreActivationBehavior(EventChainVisitor& aVisitor) {} 289 290 /** 291 * Called on the activation target during dispatch of activation events. 292 * https://dom.spec.whatwg.org/#eventtarget-activation-behavior 293 */ 294 MOZ_CAN_RUN_SCRIPT 295 virtual void ActivationBehavior(EventChainPostVisitor& aVisitor) {} 296 297 /** 298 * Called on the activation target during dispatch of activation events. 299 * https://dom.spec.whatwg.org/#eventtarget-legacy-canceled-activation-behavior 300 */ 301 virtual void LegacyCanceledActivationBehavior( 302 EventChainPostVisitor& aVisitor) {} 303 304 /** 305 * Called before the capture phase of the event flow and after event target 306 * chain creation. This is used to handle things that must be executed before 307 * dispatching the event to DOM. 308 */ 309 virtual nsresult PreHandleEvent(EventChainVisitor& aVisitor) { return NS_OK; } 310 311 /** 312 * If EventChainPreVisitor.mWantsWillHandleEvent is set true, 313 * called just before possible event handlers on this object will be called. 314 */ 315 virtual void WillHandleEvent(EventChainPostVisitor& aVisitor) {} 316 317 /** 318 * Called after the bubble phase of the system event group. 319 * The default handling of the event should happen here. 320 * @param aVisitor the visitor object which is used during post handling. 321 * 322 * @see EventDispatcher.h for documentation about aVisitor. 323 * @note Only EventDispatcher should call this method. 324 */ 325 MOZ_CAN_RUN_SCRIPT 326 virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) = 0; 327 328 protected: 329 EventHandlerNonNull* GetEventHandler(nsAtom* aType); 330 void SetEventHandler(nsAtom* aType, EventHandlerNonNull* aHandler); 331 332 /** 333 * Hook for AddEventListener that allows it to compute the right 334 * wantsUntrusted boolean when one is not provided. If this returns failure, 335 * the listener will not be added. 336 * 337 * This hook will NOT be called unless aWantsUntrusted is null in 338 * AddEventListener. If you need to take action when event listeners are 339 * added, use EventListenerAdded. Especially because not all event listener 340 * additions go through AddEventListener! 341 */ 342 virtual bool ComputeDefaultWantsUntrusted(ErrorResult& aRv) = 0; 343 344 /** 345 * A method to compute the right wantsUntrusted value for AddEventListener. 346 * This will call the above hook as needed. 347 * 348 * If aOptions is non-null, and it contains a value for mWantUntrusted, that 349 * value takes precedence over aWantsUntrusted. 350 */ 351 bool ComputeWantsUntrusted(const Nullable<bool>& aWantsUntrusted, 352 const AddEventListenerOptionsOrBoolean* aOptions, 353 ErrorResult& aRv); 354 355 /** 356 * addSystemEventListener() adds an event listener of aType to the system 357 * group. Typically, core code should use the system group for listening to 358 * content (i.e., non-chrome) element's events. If core code uses 359 * EventTarget::AddEventListener for a content node, it means 360 * that the listener cannot listen to the event when web content calls 361 * stopPropagation() of the event. 362 * 363 * @param aType An event name you're going to handle. 364 * @param aListener An event listener. 365 * @param aUseCapture true if you want to listen the event in capturing 366 * phase. Otherwise, false. 367 * @param aWantsUntrusted true if you want to handle untrusted events. 368 * false if not. 369 * Null if you want the default behavior. 370 */ 371 nsresult AddSystemEventListener(const nsAString& aType, 372 nsIDOMEventListener* aListener, 373 bool aUseCapture, 374 const Nullable<bool>& aWantsUntrusted); 375 }; 376 377 #define NS_IMPL_FROMEVENTTARGET_GENERIC(_class, _check, _const) \ 378 template <typename T> \ 379 static auto FromEventTarget(_const T& aEventTarget) \ 380 -> decltype(static_cast<_const _class*>(&aEventTarget)) { \ 381 return aEventTarget._check ? static_cast<_const _class*>(&aEventTarget) \ 382 : nullptr; \ 383 } \ 384 template <typename T> \ 385 static _const _class* FromEventTarget(_const T* aEventTarget) { \ 386 MOZ_DIAGNOSTIC_ASSERT(aEventTarget); \ 387 return FromEventTarget(*aEventTarget); \ 388 } \ 389 template <typename T> \ 390 static _const _class* FromEventTargetOrNull(_const T* aEventTarget) { \ 391 return aEventTarget ? FromEventTarget(*aEventTarget) : nullptr; \ 392 } 393 394 #define NS_IMPL_FROMEVENTTARGET_HELPER(_class, _check) \ 395 NS_IMPL_FROMEVENTTARGET_GENERIC(_class, _check, ) \ 396 NS_IMPL_FROMEVENTTARGET_GENERIC(_class, _check, const) \ 397 template <typename T> \ 398 static _class* FromEventTarget(T&& aEventTarget) { \ 399 MOZ_DIAGNOSTIC_ASSERT(!!aEventTarget); \ 400 /* We need the double-cast in case aEventTarget is a smartptr. Those */ \ 401 /* can cast to superclasses of the type they're templated on, */ \ 402 /* but not directly to subclasses. */ \ 403 return aEventTarget->_check \ 404 ? static_cast<_class*>(static_cast<EventTarget*>(aEventTarget)) \ 405 : nullptr; \ 406 } \ 407 template <typename T> \ 408 static _class* FromEventTargetOrNull(T&& aEventTarget) { \ 409 return aEventTarget ? FromEventTarget(aEventTarget) : nullptr; \ 410 } 411 412 // Unfortunately, nsPIDOMWindowInner and nsPIDOMWindowOuter do not inherit 413 // EventTarget directly, but they are public interfaces which should have 414 // these helper methods. Therefore, we cannot cast from EventTarget to 415 // the interfaces in their header file. That's the reason why we cannot use 416 // the zero cost casts nor decltype for the template methods which take a 417 // reference. 418 #define NS_IMPL_FROMEVENTTARGET_GENERIC_WITH_GETTER(_class, _getter, _const) \ 419 static _const _class* FromEventTarget( \ 420 _const mozilla::dom::EventTarget& aEventTarget) { \ 421 return aEventTarget._getter; \ 422 } \ 423 template <typename T> \ 424 static _const _class* FromEventTarget(_const T* aEventTarget) { \ 425 return aEventTarget->_getter; \ 426 } \ 427 template <typename T> \ 428 static _const _class* FromEventTargetOrNull(_const T* aEventTarget) { \ 429 return aEventTarget ? aEventTarget->_getter : nullptr; \ 430 } 431 432 #define NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER_INNER(_class, _getter) \ 433 template <typename T> \ 434 static _class* FromEventTarget(T&& aEventTarget) { \ 435 return aEventTarget->_getter; \ 436 } \ 437 template <typename T> \ 438 static _class* FromEventTargetOrNull(T&& aEventTarget) { \ 439 return aEventTarget ? aEventTarget->_getter : nullptr; \ 440 } 441 442 #define NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER(_class, _getter) \ 443 NS_IMPL_FROMEVENTTARGET_GENERIC_WITH_GETTER(_class, _getter, ) \ 444 NS_IMPL_FROMEVENTTARGET_GENERIC_WITH_GETTER(_class, _getter, const) \ 445 NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER_INNER(_class, _getter) 446 447 } // namespace dom 448 } // namespace mozilla 449 450 #ifdef NS_BUILD_REFCNT_LOGGING 451 # define NON_VIRTUAL_ADDREF_RELEASE(class_) /* Nothing */ 452 #else 453 # define NON_VIRTUAL_ADDREF_RELEASE(class_) \ 454 namespace mozilla { \ 455 template <> \ 456 class RefPtrTraits<class_> { \ 457 public: \ 458 static void Release(class_* aObject) { aObject->NonVirtualRelease(); } \ 459 static void AddRef(class_* aObject) { aObject->NonVirtualAddRef(); } \ 460 }; \ 461 } 462 463 #endif 464 465 NON_VIRTUAL_ADDREF_RELEASE(mozilla::dom::EventTarget) 466 467 #endif // mozilla_dom_EventTarget_h_