1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Olli Pettay (Olli.Pettay@helsinki.fi)
19 : * Portions created by the Initial Developer are Copyright (C) 2006
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifdef MOZILLA_INTERNAL_API
39 : #ifndef nsEventDispatcher_h___
40 : #define nsEventDispatcher_h___
41 :
42 : #include "nsCOMPtr.h"
43 : #include "nsEvent.h"
44 :
45 : class nsIContent;
46 : class nsIDocument;
47 : class nsPresContext;
48 : class nsIDOMEvent;
49 : class nsIScriptGlobalObject;
50 : class nsIDOMEventTarget;
51 : class nsEventTargetChainItem;
52 : template<class E> class nsCOMArray;
53 :
54 : /**
55 : * About event dispatching:
56 : * When either nsEventDispatcher::Dispatch or
57 : * nsEventDispatcher::DispatchDOMEvent is called an event target chain is
58 : * created. nsEventDispatcher creates the chain by calling PreHandleEvent
59 : * on each event target and the creation continues until either the mCanHandle
60 : * member of the nsEventChainPreVisitor object is false or the mParentTarget
61 : * does not point to a new target. The event target chain is created in the
62 : * heap.
63 : *
64 : * If the event needs retargeting, mEventTargetAtParent must be set in
65 : * PreHandleEvent.
66 : *
67 : * The capture, target and bubble phases of the event dispatch are handled
68 : * by iterating through the event target chain. Iteration happens twice,
69 : * first for the default event group and then for the system event group.
70 : * While dispatching the event for the system event group PostHandleEvent
71 : * is called right after calling event listener for the current event target.
72 : */
73 :
74 32762 : class nsEventChainVisitor {
75 : public:
76 32762 : nsEventChainVisitor(nsPresContext* aPresContext,
77 : nsEvent* aEvent,
78 : nsIDOMEvent* aDOMEvent,
79 : nsEventStatus aEventStatus = nsEventStatus_eIgnore)
80 : : mPresContext(aPresContext), mEvent(aEvent), mDOMEvent(aDOMEvent),
81 32762 : mEventStatus(aEventStatus), mItemFlags(0)
82 32762 : {}
83 :
84 : /**
85 : * The prescontext, possibly nsnull.
86 : */
87 : nsPresContext* const mPresContext;
88 :
89 : /**
90 : * The nsEvent which is being dispatched. Never nsnull.
91 : */
92 : nsEvent* const mEvent;
93 :
94 : /**
95 : * The DOM Event assiciated with the mEvent. Possibly nsnull if a DOM Event
96 : * is not (yet) created.
97 : */
98 : nsIDOMEvent* mDOMEvent;
99 :
100 : /**
101 : * The status of the event.
102 : * @see nsEventStatus.h
103 : */
104 : nsEventStatus mEventStatus;
105 :
106 : /**
107 : * Bits for items in the event target chain.
108 : * Set in PreHandleEvent() and used in PostHandleEvent().
109 : *
110 : * @note These bits are different for each item in the event target chain.
111 : * It is up to the Pre/PostHandleEvent implementation to decide how to
112 : * use these bits.
113 : *
114 : * @note Using PRUint16 because that is used also in nsEventTargetChainItem.
115 : */
116 : PRUint16 mItemFlags;
117 :
118 : /**
119 : * Data for items in the event target chain.
120 : * Set in PreHandleEvent() and used in PostHandleEvent().
121 : *
122 : * @note This data is different for each item in the event target chain.
123 : * It is up to the Pre/PostHandleEvent implementation to decide how to
124 : * use this.
125 : */
126 : nsCOMPtr<nsISupports> mItemData;
127 : };
128 :
129 16381 : class nsEventChainPreVisitor : public nsEventChainVisitor {
130 : public:
131 16381 : nsEventChainPreVisitor(nsPresContext* aPresContext,
132 : nsEvent* aEvent,
133 : nsIDOMEvent* aDOMEvent,
134 : nsEventStatus aEventStatus,
135 : bool aIsInAnon)
136 : : nsEventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus),
137 : mCanHandle(true), mForceContentDispatch(false),
138 : mRelatedTargetIsInAnon(false), mOriginalTargetIsInAnon(aIsInAnon),
139 : mWantsWillHandleEvent(false), mMayHaveListenerManager(true),
140 16381 : mParentTarget(nsnull), mEventTargetAtParent(nsnull) {}
141 :
142 25419 : void Reset() {
143 25419 : mItemFlags = 0;
144 25419 : mItemData = nsnull;
145 25419 : mCanHandle = true;
146 25419 : mForceContentDispatch = false;
147 25419 : mWantsWillHandleEvent = false;
148 25419 : mMayHaveListenerManager = true;
149 25419 : mParentTarget = nsnull;
150 25419 : mEventTargetAtParent = nsnull;
151 25419 : }
152 :
153 : /**
154 : * Member that must be set in PreHandleEvent by event targets. If set to false,
155 : * indicates that this event target will not be handling the event and
156 : * construction of the event target chain is complete. The target that sets
157 : * mCanHandle to false is NOT included in the event target chain.
158 : */
159 : bool mCanHandle;
160 :
161 : /**
162 : * If mForceContentDispatch is set to true,
163 : * content dispatching is not disabled for this event target.
164 : * FIXME! This is here for backward compatibility. Bug 329119
165 : */
166 : bool mForceContentDispatch;
167 :
168 : /**
169 : * true if it is known that related target is or is a descendant of an
170 : * element which is anonymous for events.
171 : */
172 : bool mRelatedTargetIsInAnon;
173 :
174 : /**
175 : * true if the original target of the event is inside anonymous content.
176 : * This is set before calling PreHandleEvent on event targets.
177 : */
178 : bool mOriginalTargetIsInAnon;
179 :
180 : /**
181 : * Whether or not nsIDOMEventTarget::WillHandleEvent will be
182 : * called. Default is false;
183 : */
184 : bool mWantsWillHandleEvent;
185 :
186 : /**
187 : * If it is known that the current target doesn't have a listener manager
188 : * when PreHandleEvent is called, set this to false.
189 : */
190 : bool mMayHaveListenerManager;
191 :
192 : /**
193 : * Parent item in the event target chain.
194 : */
195 : nsIDOMEventTarget* mParentTarget;
196 :
197 : /**
198 : * If the event needs to be retargeted, this is the event target,
199 : * which should be used when the event is handled at mParentTarget.
200 : */
201 : nsIDOMEventTarget* mEventTargetAtParent;
202 : };
203 :
204 16381 : class nsEventChainPostVisitor : public nsEventChainVisitor {
205 : public:
206 16381 : nsEventChainPostVisitor(nsEventChainVisitor& aOther)
207 : : nsEventChainVisitor(aOther.mPresContext, aOther.mEvent, aOther.mDOMEvent,
208 16381 : aOther.mEventStatus)
209 16381 : {}
210 : };
211 :
212 : /**
213 : * If an nsDispatchingCallback object is passed to Dispatch,
214 : * its HandleEvent method is called after handling the default event group,
215 : * before handling the system event group.
216 : * This is used in nsPresShell.
217 : */
218 0 : class NS_STACK_CLASS nsDispatchingCallback {
219 : public:
220 : virtual void HandleEvent(nsEventChainPostVisitor& aVisitor) = 0;
221 : };
222 :
223 : /**
224 : * The generic class for event dispatching.
225 : * Must not be used outside Gecko!
226 : */
227 : class nsEventDispatcher
228 : {
229 : public:
230 : /**
231 : * aTarget should QI to nsIDOMEventTarget.
232 : * If the target of aEvent is set before calling this method, the target of
233 : * aEvent is used as the target (unless there is event
234 : * retargeting) and the originalTarget of the DOM Event.
235 : * aTarget is always used as the starting point for constructing the event
236 : * target chain, no matter what the value of aEvent->target is.
237 : * In other words, aEvent->target is only a property of the event and it has
238 : * nothing to do with the construction of the event target chain.
239 : * Neither aTarget nor aEvent is allowed to be nsnull.
240 : *
241 : * If aTargets is non-null, event target chain will be created, but
242 : * event won't be handled. In this case aEvent->message should be
243 : * NS_EVENT_TYPE_NULL.
244 : * @note Use this method when dispatching an nsEvent.
245 : */
246 : static nsresult Dispatch(nsISupports* aTarget,
247 : nsPresContext* aPresContext,
248 : nsEvent* aEvent,
249 : nsIDOMEvent* aDOMEvent = nsnull,
250 : nsEventStatus* aEventStatus = nsnull,
251 : nsDispatchingCallback* aCallback = nsnull,
252 : nsCOMArray<nsIDOMEventTarget>* aTargets = nsnull);
253 :
254 : /**
255 : * Dispatches an event.
256 : * If aDOMEvent is not nsnull, it is used for dispatching
257 : * (aEvent can then be nsnull) and (if aDOMEvent is not |trusted| already),
258 : * the |trusted| flag is set based on the UniversalXPConnect capability.
259 : * Otherwise this works like nsEventDispatcher::Dispatch.
260 : * @note Use this method when dispatching nsIDOMEvent.
261 : */
262 : static nsresult DispatchDOMEvent(nsISupports* aTarget,
263 : nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
264 : nsPresContext* aPresContext,
265 : nsEventStatus* aEventStatus);
266 :
267 : /**
268 : * Creates a DOM Event.
269 : */
270 : static nsresult CreateEvent(nsPresContext* aPresContext,
271 : nsEvent* aEvent,
272 : const nsAString& aEventType,
273 : nsIDOMEvent** aDOMEvent);
274 :
275 : };
276 :
277 : #endif
278 : #endif
|