Bug 1776680 [wpt PR 34603] - [@container] Test invalidation of font-relative units...
[gecko.git] / dom / events / EventDispatcher.h
blob9a9a0f2361f864e80a4f67426adad7baace8422a
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 #ifdef MOZILLA_INTERNAL_API
8 # ifndef mozilla_EventDispatcher_h_
9 # define mozilla_EventDispatcher_h_
11 # include "mozilla/dom/BindingDeclarations.h"
12 # include "mozilla/dom/Touch.h"
13 # include "mozilla/EventForwards.h"
14 # include "mozilla/Maybe.h"
15 # include "nsCOMPtr.h"
16 # include "nsTArray.h"
18 // Microsoft's API Name hackery sucks
19 # undef CreateEvent
21 class nsIContent;
22 class nsPresContext;
24 template <class E>
25 class nsCOMArray;
27 namespace mozilla {
28 namespace dom {
29 class Event;
30 class EventTarget;
31 } // namespace dom
33 /**
34 * About event dispatching:
35 * When either EventDispatcher::Dispatch or
36 * EventDispatcher::DispatchDOMEvent is called an event target chain is
37 * created. EventDispatcher creates the chain by calling GetEventTargetParent
38 * on each event target and the creation continues until either the mCanHandle
39 * member of the EventChainPreVisitor object is false or the mParentTarget
40 * does not point to a new target. The event target chain is created in the
41 * heap.
43 * If the event needs retargeting, mEventTargetAtParent must be set in
44 * GetEventTargetParent.
46 * The capture, target and bubble phases of the event dispatch are handled
47 * by iterating through the event target chain. Iteration happens twice,
48 * first for the default event group and then for the system event group.
49 * While dispatching the event for the system event group PostHandleEvent
50 * is called right after calling event listener for the current event target.
53 class MOZ_STACK_CLASS EventChainVisitor {
54 public:
55 // For making creators of this class instances guarantee the lifetime of
56 // aPresContext, this needs to be marked as MOZ_CAN_RUN_SCRIPT.
57 MOZ_CAN_RUN_SCRIPT
58 EventChainVisitor(nsPresContext* aPresContext, WidgetEvent* aEvent,
59 dom::Event* aDOMEvent,
60 nsEventStatus aEventStatus = nsEventStatus_eIgnore)
61 : mPresContext(aPresContext),
62 mEvent(aEvent),
63 mDOMEvent(aDOMEvent),
64 mEventStatus(aEventStatus),
65 mItemFlags(0) {}
67 /**
68 * The prescontext, possibly nullptr.
69 * Note that the lifetime of mPresContext is guaranteed by the creators.
71 MOZ_KNOWN_LIVE nsPresContext* const mPresContext;
73 /**
74 * The WidgetEvent which is being dispatched. Never nullptr.
76 WidgetEvent* const mEvent;
78 /**
79 * The DOM Event assiciated with the mEvent. Possibly nullptr if a DOM Event
80 * is not (yet) created.
82 dom::Event* mDOMEvent;
84 /**
85 * The status of the event.
86 * @see nsEventStatus.h
88 nsEventStatus mEventStatus;
90 /**
91 * Bits for items in the event target chain.
92 * Set in GetEventTargetParent() and used in PostHandleEvent().
94 * @note These bits are different for each item in the event target chain.
95 * It is up to the Pre/PostHandleEvent implementation to decide how to
96 * use these bits.
98 * @note Using uint16_t because that is used also in EventTargetChainItem.
100 uint16_t mItemFlags;
103 * Data for items in the event target chain.
104 * Set in GetEventTargetParent() and used in PostHandleEvent().
106 * @note This data is different for each item in the event target chain.
107 * It is up to the Pre/PostHandleEvent implementation to decide how to
108 * use this.
110 nsCOMPtr<nsISupports> mItemData;
113 class MOZ_STACK_CLASS EventChainPreVisitor final : public EventChainVisitor {
114 public:
115 MOZ_CAN_RUN_SCRIPT
116 EventChainPreVisitor(nsPresContext* aPresContext, WidgetEvent* aEvent,
117 dom::Event* aDOMEvent, nsEventStatus aEventStatus,
118 bool aIsInAnon,
119 dom::EventTarget* aTargetInKnownToBeHandledScope)
120 : EventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus),
121 mCanHandle(true),
122 mAutomaticChromeDispatch(true),
123 mForceContentDispatch(false),
124 mRelatedTargetIsInAnon(false),
125 mOriginalTargetIsInAnon(aIsInAnon),
126 mWantsWillHandleEvent(false),
127 mMayHaveListenerManager(true),
128 mWantsPreHandleEvent(false),
129 mRootOfClosedTree(false),
130 mItemInShadowTree(false),
131 mParentIsSlotInClosedTree(false),
132 mParentIsChromeHandler(false),
133 mRelatedTargetRetargetedInCurrentScope(false),
134 mIgnoreBecauseOfShadowDOM(false),
135 mParentTarget(nullptr),
136 mEventTargetAtParent(nullptr),
137 mRetargetedRelatedTarget(nullptr),
138 mTargetInKnownToBeHandledScope(aTargetInKnownToBeHandledScope) {}
140 void Reset() {
141 mItemFlags = 0;
142 mItemData = nullptr;
143 mCanHandle = true;
144 mAutomaticChromeDispatch = true;
145 mForceContentDispatch = false;
146 mWantsWillHandleEvent = false;
147 mMayHaveListenerManager = true;
148 mWantsPreHandleEvent = false;
149 mRootOfClosedTree = false;
150 mItemInShadowTree = false;
151 mParentIsSlotInClosedTree = false;
152 mParentIsChromeHandler = false;
153 // Note, we don't clear mRelatedTargetRetargetedInCurrentScope explicitly,
154 // since it is used during event path creation to indicate whether
155 // relatedTarget may need to be retargeted.
156 mIgnoreBecauseOfShadowDOM = false;
157 mParentTarget = nullptr;
158 mEventTargetAtParent = nullptr;
159 mRetargetedRelatedTarget = nullptr;
160 mRetargetedTouchTargets.reset();
163 dom::EventTarget* GetParentTarget() { return mParentTarget; }
165 void SetParentTarget(dom::EventTarget* aParentTarget, bool aIsChromeHandler) {
166 mParentTarget = aParentTarget;
167 if (mParentTarget) {
168 mParentIsChromeHandler = aIsChromeHandler;
172 void IgnoreCurrentTargetBecauseOfShadowDOMRetargeting() {
173 mCanHandle = false;
174 mIgnoreBecauseOfShadowDOM = true;
175 SetParentTarget(nullptr, false);
176 mEventTargetAtParent = nullptr;
180 * Member that must be set in GetEventTargetParent by event targets. If set to
181 * false, indicates that this event target will not be handling the event and
182 * construction of the event target chain is complete. The target that sets
183 * mCanHandle to false is NOT included in the event target chain.
185 bool mCanHandle;
188 * If mCanHandle is false and mAutomaticChromeDispatch is also false
189 * event will not be dispatched to the chrome event handler.
191 bool mAutomaticChromeDispatch;
194 * If mForceContentDispatch is set to true,
195 * content dispatching is not disabled for this event target.
196 * FIXME! This is here for backward compatibility. Bug 329119
198 bool mForceContentDispatch;
201 * true if it is known that related target is or is a descendant of an
202 * element which is anonymous for events.
204 bool mRelatedTargetIsInAnon;
207 * true if the original target of the event is inside anonymous content.
208 * This is set before calling GetEventTargetParent on event targets.
210 bool mOriginalTargetIsInAnon;
213 * Whether or not EventTarget::WillHandleEvent will be
214 * called. Default is false;
216 bool mWantsWillHandleEvent;
219 * If it is known that the current target doesn't have a listener manager
220 * when GetEventTargetParent is called, set this to false.
222 bool mMayHaveListenerManager;
225 * Whether or not EventTarget::PreHandleEvent will be called. Default is
226 * false;
228 bool mWantsPreHandleEvent;
231 * True if the current target is either closed ShadowRoot or root of
232 * chrome only access tree (for example native anonymous content).
234 bool mRootOfClosedTree;
237 * If target is node and its root is a shadow root.
238 * https://dom.spec.whatwg.org/#event-path-item-in-shadow-tree
240 bool mItemInShadowTree;
243 * True if mParentTarget is HTMLSlotElement in a closed shadow tree and the
244 * current target is assigned to that slot.
246 bool mParentIsSlotInClosedTree;
249 * True if mParentTarget is a chrome handler in the event path.
251 bool mParentIsChromeHandler;
254 * True if event's related target has been already retargeted in the
255 * current 'scope'. This should be set to false initially and whenever
256 * event path creation crosses shadow boundary.
258 bool mRelatedTargetRetargetedInCurrentScope;
261 * True if Shadow DOM relatedTarget retargeting causes the current item
262 * to not show up in the event path.
264 bool mIgnoreBecauseOfShadowDOM;
266 private:
268 * Parent item in the event target chain.
270 dom::EventTarget* mParentTarget;
272 public:
274 * If the event needs to be retargeted, this is the event target,
275 * which should be used when the event is handled at mParentTarget.
277 dom::EventTarget* mEventTargetAtParent;
280 * If the related target of the event needs to be retargeted, set this
281 * to a new EventTarget.
283 dom::EventTarget* mRetargetedRelatedTarget;
286 * If mEvent is a WidgetTouchEvent and its mTouches needs retargeting,
287 * set the targets to this array. The array should contain one entry per
288 * each object in WidgetTouchEvent::mTouches.
290 mozilla::Maybe<nsTArray<RefPtr<dom::EventTarget>>> mRetargetedTouchTargets;
293 * Set to the value of mEvent->mTarget of the previous scope in case of
294 * Shadow DOM or such, and if there is no anonymous content this just points
295 * to the initial target.
297 dom::EventTarget* mTargetInKnownToBeHandledScope;
300 class MOZ_STACK_CLASS EventChainPostVisitor final
301 : public mozilla::EventChainVisitor {
302 public:
303 // Note that for making guarantee the lifetime of mPresContext and mDOMEvent,
304 // creators should guarantee that aOther won't be deleted while the instance
305 // of this class is alive.
306 MOZ_CAN_RUN_SCRIPT
307 explicit EventChainPostVisitor(EventChainVisitor& aOther)
308 : EventChainVisitor(aOther.mPresContext, aOther.mEvent,
309 MOZ_KnownLive(aOther.mDOMEvent),
310 aOther.mEventStatus) {}
314 * If an EventDispatchingCallback object is passed to Dispatch,
315 * its HandleEvent method is called after handling the default event group,
316 * before handling the system event group.
317 * This is used in PresShell.
319 class MOZ_STACK_CLASS EventDispatchingCallback {
320 public:
321 MOZ_CAN_RUN_SCRIPT
322 virtual void HandleEvent(EventChainPostVisitor& aVisitor) = 0;
326 * The generic class for event dispatching.
327 * Must not be used outside Gecko!
329 class EventDispatcher {
330 public:
332 * aTarget should QI to EventTarget.
333 * If the target of aEvent is set before calling this method, the target of
334 * aEvent is used as the target (unless there is event
335 * retargeting) and the originalTarget of the DOM Event.
336 * aTarget is always used as the starting point for constructing the event
337 * target chain, no matter what the value of aEvent->mTarget is.
338 * In other words, aEvent->mTarget is only a property of the event and it has
339 * nothing to do with the construction of the event target chain.
340 * Neither aTarget nor aEvent is allowed to be nullptr.
342 * If aTargets is non-null, event target chain will be created, but
343 * event won't be handled. In this case aEvent->mMessage should be
344 * eVoidEvent.
345 * @note Use this method when dispatching a WidgetEvent.
347 MOZ_CAN_RUN_SCRIPT static nsresult Dispatch(
348 nsISupports* aTarget, nsPresContext* aPresContext, WidgetEvent* aEvent,
349 dom::Event* aDOMEvent = nullptr, nsEventStatus* aEventStatus = nullptr,
350 EventDispatchingCallback* aCallback = nullptr,
351 nsTArray<dom::EventTarget*>* aTargets = nullptr);
354 * Dispatches an event.
355 * If aDOMEvent is not nullptr, it is used for dispatching
356 * (aEvent can then be nullptr) and (if aDOMEvent is not |trusted| already),
357 * the |trusted| flag is set if the caller uses the system principal.
358 * Otherwise this works like EventDispatcher::Dispatch.
359 * @note Use this method when dispatching a dom::Event.
361 MOZ_CAN_RUN_SCRIPT static nsresult DispatchDOMEvent(
362 nsISupports* aTarget, WidgetEvent* aEvent, dom::Event* aDOMEvent,
363 nsPresContext* aPresContext, nsEventStatus* aEventStatus);
366 * Creates a DOM Event. Returns null if the event type is unsupported.
368 static already_AddRefed<dom::Event> CreateEvent(
369 dom::EventTarget* aOwner, nsPresContext* aPresContext,
370 WidgetEvent* aEvent, const nsAString& aEventType,
371 dom::CallerType aCallerType = dom::CallerType::System);
373 static void GetComposedPathFor(WidgetEvent* aEvent,
374 nsTArray<RefPtr<dom::EventTarget>>& aPath);
377 * Called at shutting down.
379 static void Shutdown();
382 } // namespace mozilla
384 # endif // mozilla_EventDispatcher_h_
385 #endif