dom/events/EventDispatcher.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial