Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifdef MOZILLA_INTERNAL_API
7 #ifndef mozilla_EventDispatcher_h_
8 #define mozilla_EventDispatcher_h_
10 #include "mozilla/EventForwards.h"
11 #include "nsCOMPtr.h"
13 // Microsoft's API Name hackery sucks
14 #undef CreateEvent
16 class nsIDOMEvent;
17 class nsIScriptGlobalObject;
18 class nsPresContext;
20 template<class E> class nsCOMArray;
22 namespace mozilla {
23 namespace dom {
24 class EventTarget;
25 } // namespace dom
27 /**
28 * About event dispatching:
29 * When either EventDispatcher::Dispatch or
30 * EventDispatcher::DispatchDOMEvent is called an event target chain is
31 * created. EventDispatcher creates the chain by calling PreHandleEvent
32 * on each event target and the creation continues until either the mCanHandle
33 * member of the EventChainPreVisitor object is false or the mParentTarget
34 * does not point to a new target. The event target chain is created in the
35 * heap.
36 *
37 * If the event needs retargeting, mEventTargetAtParent must be set in
38 * PreHandleEvent.
39 *
40 * The capture, target and bubble phases of the event dispatch are handled
41 * by iterating through the event target chain. Iteration happens twice,
42 * first for the default event group and then for the system event group.
43 * While dispatching the event for the system event group PostHandleEvent
44 * is called right after calling event listener for the current event target.
45 */
47 class EventChainVisitor
48 {
49 public:
50 EventChainVisitor(nsPresContext* aPresContext,
51 WidgetEvent* aEvent,
52 nsIDOMEvent* aDOMEvent,
53 nsEventStatus aEventStatus = nsEventStatus_eIgnore)
54 : mPresContext(aPresContext)
55 , mEvent(aEvent)
56 , mDOMEvent(aDOMEvent)
57 , mEventStatus(aEventStatus)
58 , mItemFlags(0)
59 {
60 }
62 /**
63 * The prescontext, possibly nullptr.
64 */
65 nsPresContext* const mPresContext;
67 /**
68 * The WidgetEvent which is being dispatched. Never nullptr.
69 */
70 WidgetEvent* const mEvent;
72 /**
73 * The DOM Event assiciated with the mEvent. Possibly nullptr if a DOM Event
74 * is not (yet) created.
75 */
76 nsIDOMEvent* mDOMEvent;
78 /**
79 * The status of the event.
80 * @see nsEventStatus.h
81 */
82 nsEventStatus mEventStatus;
84 /**
85 * Bits for items in the event target chain.
86 * Set in PreHandleEvent() and used in PostHandleEvent().
87 *
88 * @note These bits are different for each item in the event target chain.
89 * It is up to the Pre/PostHandleEvent implementation to decide how to
90 * use these bits.
91 *
92 * @note Using uint16_t because that is used also in EventTargetChainItem.
93 */
94 uint16_t mItemFlags;
96 /**
97 * Data for items in the event target chain.
98 * Set in PreHandleEvent() and used in PostHandleEvent().
99 *
100 * @note This data is different for each item in the event target chain.
101 * It is up to the Pre/PostHandleEvent implementation to decide how to
102 * use this.
103 */
104 nsCOMPtr<nsISupports> mItemData;
105 };
107 class EventChainPreVisitor : public EventChainVisitor
108 {
109 public:
110 EventChainPreVisitor(nsPresContext* aPresContext,
111 WidgetEvent* aEvent,
112 nsIDOMEvent* aDOMEvent,
113 nsEventStatus aEventStatus,
114 bool aIsInAnon)
115 : EventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus)
116 , mCanHandle(true)
117 , mAutomaticChromeDispatch(true)
118 , mForceContentDispatch(false)
119 , mRelatedTargetIsInAnon(false)
120 , mOriginalTargetIsInAnon(aIsInAnon)
121 , mWantsWillHandleEvent(false)
122 , mMayHaveListenerManager(true)
123 , mParentTarget(nullptr)
124 , mEventTargetAtParent(nullptr)
125 {
126 }
128 void Reset()
129 {
130 mItemFlags = 0;
131 mItemData = nullptr;
132 mCanHandle = true;
133 mAutomaticChromeDispatch = true;
134 mForceContentDispatch = false;
135 mWantsWillHandleEvent = false;
136 mMayHaveListenerManager = true;
137 mParentTarget = nullptr;
138 mEventTargetAtParent = nullptr;
139 }
141 /**
142 * Member that must be set in PreHandleEvent by event targets. If set to false,
143 * indicates that this event target will not be handling the event and
144 * construction of the event target chain is complete. The target that sets
145 * mCanHandle to false is NOT included in the event target chain.
146 */
147 bool mCanHandle;
149 /**
150 * If mCanHandle is false and mAutomaticChromeDispatch is also false
151 * event will not be dispatched to the chrome event handler.
152 */
153 bool mAutomaticChromeDispatch;
155 /**
156 * If mForceContentDispatch is set to true,
157 * content dispatching is not disabled for this event target.
158 * FIXME! This is here for backward compatibility. Bug 329119
159 */
160 bool mForceContentDispatch;
162 /**
163 * true if it is known that related target is or is a descendant of an
164 * element which is anonymous for events.
165 */
166 bool mRelatedTargetIsInAnon;
168 /**
169 * true if the original target of the event is inside anonymous content.
170 * This is set before calling PreHandleEvent on event targets.
171 */
172 bool mOriginalTargetIsInAnon;
174 /**
175 * Whether or not nsIDOMEventTarget::WillHandleEvent will be
176 * called. Default is false;
177 */
178 bool mWantsWillHandleEvent;
180 /**
181 * If it is known that the current target doesn't have a listener manager
182 * when PreHandleEvent is called, set this to false.
183 */
184 bool mMayHaveListenerManager;
186 /**
187 * Parent item in the event target chain.
188 */
189 dom::EventTarget* mParentTarget;
191 /**
192 * If the event needs to be retargeted, this is the event target,
193 * which should be used when the event is handled at mParentTarget.
194 */
195 dom::EventTarget* mEventTargetAtParent;
196 };
198 class EventChainPostVisitor : public mozilla::EventChainVisitor
199 {
200 public:
201 EventChainPostVisitor(EventChainVisitor& aOther)
202 : EventChainVisitor(aOther.mPresContext, aOther.mEvent,
203 aOther.mDOMEvent, aOther.mEventStatus)
204 {
205 }
206 };
208 /**
209 * If an EventDispatchingCallback object is passed to Dispatch,
210 * its HandleEvent method is called after handling the default event group,
211 * before handling the system event group.
212 * This is used in nsPresShell.
213 */
214 class MOZ_STACK_CLASS EventDispatchingCallback
215 {
216 public:
217 virtual void HandleEvent(EventChainPostVisitor& aVisitor) = 0;
218 };
220 /**
221 * The generic class for event dispatching.
222 * Must not be used outside Gecko!
223 */
224 class EventDispatcher
225 {
226 public:
227 /**
228 * aTarget should QI to EventTarget.
229 * If the target of aEvent is set before calling this method, the target of
230 * aEvent is used as the target (unless there is event
231 * retargeting) and the originalTarget of the DOM Event.
232 * aTarget is always used as the starting point for constructing the event
233 * target chain, no matter what the value of aEvent->target is.
234 * In other words, aEvent->target is only a property of the event and it has
235 * nothing to do with the construction of the event target chain.
236 * Neither aTarget nor aEvent is allowed to be nullptr.
237 *
238 * If aTargets is non-null, event target chain will be created, but
239 * event won't be handled. In this case aEvent->message should be
240 * NS_EVENT_NULL.
241 * @note Use this method when dispatching a WidgetEvent.
242 */
243 static nsresult Dispatch(nsISupports* aTarget,
244 nsPresContext* aPresContext,
245 WidgetEvent* aEvent,
246 nsIDOMEvent* aDOMEvent = nullptr,
247 nsEventStatus* aEventStatus = nullptr,
248 EventDispatchingCallback* aCallback = nullptr,
249 nsCOMArray<dom::EventTarget>* aTargets = nullptr);
251 /**
252 * Dispatches an event.
253 * If aDOMEvent is not nullptr, it is used for dispatching
254 * (aEvent can then be nullptr) and (if aDOMEvent is not |trusted| already),
255 * the |trusted| flag is set based on the UniversalXPConnect capability.
256 * Otherwise this works like EventDispatcher::Dispatch.
257 * @note Use this method when dispatching nsIDOMEvent.
258 */
259 static nsresult DispatchDOMEvent(nsISupports* aTarget,
260 WidgetEvent* aEvent,
261 nsIDOMEvent* aDOMEvent,
262 nsPresContext* aPresContext,
263 nsEventStatus* aEventStatus);
265 /**
266 * Creates a DOM Event.
267 */
268 static nsresult CreateEvent(dom::EventTarget* aOwner,
269 nsPresContext* aPresContext,
270 WidgetEvent* aEvent,
271 const nsAString& aEventType,
272 nsIDOMEvent** aDOMEvent);
274 /**
275 * Called at shutting down.
276 */
277 static void Shutdown();
278 };
280 } // namespace mozilla
282 #endif // mozilla_EventDispatcher_h_
283 #endif