1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/events/EventDispatcher.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,283 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifdef MOZILLA_INTERNAL_API 1.10 +#ifndef mozilla_EventDispatcher_h_ 1.11 +#define mozilla_EventDispatcher_h_ 1.12 + 1.13 +#include "mozilla/EventForwards.h" 1.14 +#include "nsCOMPtr.h" 1.15 + 1.16 +// Microsoft's API Name hackery sucks 1.17 +#undef CreateEvent 1.18 + 1.19 +class nsIDOMEvent; 1.20 +class nsIScriptGlobalObject; 1.21 +class nsPresContext; 1.22 + 1.23 +template<class E> class nsCOMArray; 1.24 + 1.25 +namespace mozilla { 1.26 +namespace dom { 1.27 +class EventTarget; 1.28 +} // namespace dom 1.29 + 1.30 +/** 1.31 + * About event dispatching: 1.32 + * When either EventDispatcher::Dispatch or 1.33 + * EventDispatcher::DispatchDOMEvent is called an event target chain is 1.34 + * created. EventDispatcher creates the chain by calling PreHandleEvent 1.35 + * on each event target and the creation continues until either the mCanHandle 1.36 + * member of the EventChainPreVisitor object is false or the mParentTarget 1.37 + * does not point to a new target. The event target chain is created in the 1.38 + * heap. 1.39 + * 1.40 + * If the event needs retargeting, mEventTargetAtParent must be set in 1.41 + * PreHandleEvent. 1.42 + * 1.43 + * The capture, target and bubble phases of the event dispatch are handled 1.44 + * by iterating through the event target chain. Iteration happens twice, 1.45 + * first for the default event group and then for the system event group. 1.46 + * While dispatching the event for the system event group PostHandleEvent 1.47 + * is called right after calling event listener for the current event target. 1.48 + */ 1.49 + 1.50 +class EventChainVisitor 1.51 +{ 1.52 +public: 1.53 + EventChainVisitor(nsPresContext* aPresContext, 1.54 + WidgetEvent* aEvent, 1.55 + nsIDOMEvent* aDOMEvent, 1.56 + nsEventStatus aEventStatus = nsEventStatus_eIgnore) 1.57 + : mPresContext(aPresContext) 1.58 + , mEvent(aEvent) 1.59 + , mDOMEvent(aDOMEvent) 1.60 + , mEventStatus(aEventStatus) 1.61 + , mItemFlags(0) 1.62 + { 1.63 + } 1.64 + 1.65 + /** 1.66 + * The prescontext, possibly nullptr. 1.67 + */ 1.68 + nsPresContext* const mPresContext; 1.69 + 1.70 + /** 1.71 + * The WidgetEvent which is being dispatched. Never nullptr. 1.72 + */ 1.73 + WidgetEvent* const mEvent; 1.74 + 1.75 + /** 1.76 + * The DOM Event assiciated with the mEvent. Possibly nullptr if a DOM Event 1.77 + * is not (yet) created. 1.78 + */ 1.79 + nsIDOMEvent* mDOMEvent; 1.80 + 1.81 + /** 1.82 + * The status of the event. 1.83 + * @see nsEventStatus.h 1.84 + */ 1.85 + nsEventStatus mEventStatus; 1.86 + 1.87 + /** 1.88 + * Bits for items in the event target chain. 1.89 + * Set in PreHandleEvent() and used in PostHandleEvent(). 1.90 + * 1.91 + * @note These bits are different for each item in the event target chain. 1.92 + * It is up to the Pre/PostHandleEvent implementation to decide how to 1.93 + * use these bits. 1.94 + * 1.95 + * @note Using uint16_t because that is used also in EventTargetChainItem. 1.96 + */ 1.97 + uint16_t mItemFlags; 1.98 + 1.99 + /** 1.100 + * Data for items in the event target chain. 1.101 + * Set in PreHandleEvent() and used in PostHandleEvent(). 1.102 + * 1.103 + * @note This data is different for each item in the event target chain. 1.104 + * It is up to the Pre/PostHandleEvent implementation to decide how to 1.105 + * use this. 1.106 + */ 1.107 + nsCOMPtr<nsISupports> mItemData; 1.108 +}; 1.109 + 1.110 +class EventChainPreVisitor : public EventChainVisitor 1.111 +{ 1.112 +public: 1.113 + EventChainPreVisitor(nsPresContext* aPresContext, 1.114 + WidgetEvent* aEvent, 1.115 + nsIDOMEvent* aDOMEvent, 1.116 + nsEventStatus aEventStatus, 1.117 + bool aIsInAnon) 1.118 + : EventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus) 1.119 + , mCanHandle(true) 1.120 + , mAutomaticChromeDispatch(true) 1.121 + , mForceContentDispatch(false) 1.122 + , mRelatedTargetIsInAnon(false) 1.123 + , mOriginalTargetIsInAnon(aIsInAnon) 1.124 + , mWantsWillHandleEvent(false) 1.125 + , mMayHaveListenerManager(true) 1.126 + , mParentTarget(nullptr) 1.127 + , mEventTargetAtParent(nullptr) 1.128 + { 1.129 + } 1.130 + 1.131 + void Reset() 1.132 + { 1.133 + mItemFlags = 0; 1.134 + mItemData = nullptr; 1.135 + mCanHandle = true; 1.136 + mAutomaticChromeDispatch = true; 1.137 + mForceContentDispatch = false; 1.138 + mWantsWillHandleEvent = false; 1.139 + mMayHaveListenerManager = true; 1.140 + mParentTarget = nullptr; 1.141 + mEventTargetAtParent = nullptr; 1.142 + } 1.143 + 1.144 + /** 1.145 + * Member that must be set in PreHandleEvent by event targets. If set to false, 1.146 + * indicates that this event target will not be handling the event and 1.147 + * construction of the event target chain is complete. The target that sets 1.148 + * mCanHandle to false is NOT included in the event target chain. 1.149 + */ 1.150 + bool mCanHandle; 1.151 + 1.152 + /** 1.153 + * If mCanHandle is false and mAutomaticChromeDispatch is also false 1.154 + * event will not be dispatched to the chrome event handler. 1.155 + */ 1.156 + bool mAutomaticChromeDispatch; 1.157 + 1.158 + /** 1.159 + * If mForceContentDispatch is set to true, 1.160 + * content dispatching is not disabled for this event target. 1.161 + * FIXME! This is here for backward compatibility. Bug 329119 1.162 + */ 1.163 + bool mForceContentDispatch; 1.164 + 1.165 + /** 1.166 + * true if it is known that related target is or is a descendant of an 1.167 + * element which is anonymous for events. 1.168 + */ 1.169 + bool mRelatedTargetIsInAnon; 1.170 + 1.171 + /** 1.172 + * true if the original target of the event is inside anonymous content. 1.173 + * This is set before calling PreHandleEvent on event targets. 1.174 + */ 1.175 + bool mOriginalTargetIsInAnon; 1.176 + 1.177 + /** 1.178 + * Whether or not nsIDOMEventTarget::WillHandleEvent will be 1.179 + * called. Default is false; 1.180 + */ 1.181 + bool mWantsWillHandleEvent; 1.182 + 1.183 + /** 1.184 + * If it is known that the current target doesn't have a listener manager 1.185 + * when PreHandleEvent is called, set this to false. 1.186 + */ 1.187 + bool mMayHaveListenerManager; 1.188 + 1.189 + /** 1.190 + * Parent item in the event target chain. 1.191 + */ 1.192 + dom::EventTarget* mParentTarget; 1.193 + 1.194 + /** 1.195 + * If the event needs to be retargeted, this is the event target, 1.196 + * which should be used when the event is handled at mParentTarget. 1.197 + */ 1.198 + dom::EventTarget* mEventTargetAtParent; 1.199 +}; 1.200 + 1.201 +class EventChainPostVisitor : public mozilla::EventChainVisitor 1.202 +{ 1.203 +public: 1.204 + EventChainPostVisitor(EventChainVisitor& aOther) 1.205 + : EventChainVisitor(aOther.mPresContext, aOther.mEvent, 1.206 + aOther.mDOMEvent, aOther.mEventStatus) 1.207 + { 1.208 + } 1.209 +}; 1.210 + 1.211 +/** 1.212 + * If an EventDispatchingCallback object is passed to Dispatch, 1.213 + * its HandleEvent method is called after handling the default event group, 1.214 + * before handling the system event group. 1.215 + * This is used in nsPresShell. 1.216 + */ 1.217 +class MOZ_STACK_CLASS EventDispatchingCallback 1.218 +{ 1.219 +public: 1.220 + virtual void HandleEvent(EventChainPostVisitor& aVisitor) = 0; 1.221 +}; 1.222 + 1.223 +/** 1.224 + * The generic class for event dispatching. 1.225 + * Must not be used outside Gecko! 1.226 + */ 1.227 +class EventDispatcher 1.228 +{ 1.229 +public: 1.230 + /** 1.231 + * aTarget should QI to EventTarget. 1.232 + * If the target of aEvent is set before calling this method, the target of 1.233 + * aEvent is used as the target (unless there is event 1.234 + * retargeting) and the originalTarget of the DOM Event. 1.235 + * aTarget is always used as the starting point for constructing the event 1.236 + * target chain, no matter what the value of aEvent->target is. 1.237 + * In other words, aEvent->target is only a property of the event and it has 1.238 + * nothing to do with the construction of the event target chain. 1.239 + * Neither aTarget nor aEvent is allowed to be nullptr. 1.240 + * 1.241 + * If aTargets is non-null, event target chain will be created, but 1.242 + * event won't be handled. In this case aEvent->message should be 1.243 + * NS_EVENT_NULL. 1.244 + * @note Use this method when dispatching a WidgetEvent. 1.245 + */ 1.246 + static nsresult Dispatch(nsISupports* aTarget, 1.247 + nsPresContext* aPresContext, 1.248 + WidgetEvent* aEvent, 1.249 + nsIDOMEvent* aDOMEvent = nullptr, 1.250 + nsEventStatus* aEventStatus = nullptr, 1.251 + EventDispatchingCallback* aCallback = nullptr, 1.252 + nsCOMArray<dom::EventTarget>* aTargets = nullptr); 1.253 + 1.254 + /** 1.255 + * Dispatches an event. 1.256 + * If aDOMEvent is not nullptr, it is used for dispatching 1.257 + * (aEvent can then be nullptr) and (if aDOMEvent is not |trusted| already), 1.258 + * the |trusted| flag is set based on the UniversalXPConnect capability. 1.259 + * Otherwise this works like EventDispatcher::Dispatch. 1.260 + * @note Use this method when dispatching nsIDOMEvent. 1.261 + */ 1.262 + static nsresult DispatchDOMEvent(nsISupports* aTarget, 1.263 + WidgetEvent* aEvent, 1.264 + nsIDOMEvent* aDOMEvent, 1.265 + nsPresContext* aPresContext, 1.266 + nsEventStatus* aEventStatus); 1.267 + 1.268 + /** 1.269 + * Creates a DOM Event. 1.270 + */ 1.271 + static nsresult CreateEvent(dom::EventTarget* aOwner, 1.272 + nsPresContext* aPresContext, 1.273 + WidgetEvent* aEvent, 1.274 + const nsAString& aEventType, 1.275 + nsIDOMEvent** aDOMEvent); 1.276 + 1.277 + /** 1.278 + * Called at shutting down. 1.279 + */ 1.280 + static void Shutdown(); 1.281 +}; 1.282 + 1.283 +} // namespace mozilla 1.284 + 1.285 +#endif // mozilla_EventDispatcher_h_ 1.286 +#endif