LCOV - code coverage report
Current view: top level - dom/events - EventDispatcher.h (source / functions) Hit Total Coverage
Test: output.info Lines: 28 28 100.0 %
Date: 2017-07-14 16:53:18 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13