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