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.

     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

mercurial