123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifdef MOZILLA_INTERNAL_API
- #ifndef mozilla_EventDispatcher_h_
- #define mozilla_EventDispatcher_h_
- #include "mozilla/EventForwards.h"
- #include "nsCOMPtr.h"
- #include "nsTArray.h"
- // Microsoft's API Name hackery sucks
- #undef CreateEvent
- class nsIContent;
- class nsIDOMEvent;
- class nsPresContext;
- template<class E> class nsCOMArray;
- namespace mozilla {
- namespace dom {
- class Event;
- class EventTarget;
- } // namespace dom
- /**
- * About event dispatching:
- * When either EventDispatcher::Dispatch or
- * EventDispatcher::DispatchDOMEvent is called an event target chain is
- * created. EventDispatcher creates the chain by calling GetEventTargetParent
- * on each event target and the creation continues until either the mCanHandle
- * member of the EventChainPreVisitor object is false or the mParentTarget
- * does not point to a new target. The event target chain is created in the
- * heap.
- *
- * If the event needs retargeting, mEventTargetAtParent must be set in
- * GetEventTargetParent.
- *
- * The capture, target and bubble phases of the event dispatch are handled
- * by iterating through the event target chain. Iteration happens twice,
- * first for the default event group and then for the system event group.
- * While dispatching the event for the system event group PostHandleEvent
- * is called right after calling event listener for the current event target.
- */
- class EventChainVisitor
- {
- public:
- EventChainVisitor(nsPresContext* aPresContext,
- WidgetEvent* aEvent,
- nsIDOMEvent* aDOMEvent,
- nsEventStatus aEventStatus = nsEventStatus_eIgnore)
- : mPresContext(aPresContext)
- , mEvent(aEvent)
- , mDOMEvent(aDOMEvent)
- , mEventStatus(aEventStatus)
- , mItemFlags(0)
- {
- }
- /**
- * The prescontext, possibly nullptr.
- */
- nsPresContext* const mPresContext;
- /**
- * The WidgetEvent which is being dispatched. Never nullptr.
- */
- WidgetEvent* const mEvent;
- /**
- * The DOM Event assiciated with the mEvent. Possibly nullptr if a DOM Event
- * is not (yet) created.
- */
- nsIDOMEvent* mDOMEvent;
- /**
- * The status of the event.
- * @see nsEventStatus.h
- */
- nsEventStatus mEventStatus;
- /**
- * Bits for items in the event target chain.
- * Set in GetEventTargetParent() and used in PostHandleEvent().
- *
- * @note These bits are different for each item in the event target chain.
- * It is up to the Pre/PostHandleEvent implementation to decide how to
- * use these bits.
- *
- * @note Using uint16_t because that is used also in EventTargetChainItem.
- */
- uint16_t mItemFlags;
- /**
- * Data for items in the event target chain.
- * Set in GetEventTargetParent() and used in PostHandleEvent().
- *
- * @note This data is different for each item in the event target chain.
- * It is up to the Pre/PostHandleEvent implementation to decide how to
- * use this.
- */
- nsCOMPtr<nsISupports> mItemData;
- };
- class EventChainPreVisitor : public EventChainVisitor
- {
- public:
- EventChainPreVisitor(nsPresContext* aPresContext,
- WidgetEvent* aEvent,
- nsIDOMEvent* aDOMEvent,
- nsEventStatus aEventStatus,
- bool aIsInAnon)
- : EventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus)
- , mCanHandle(true)
- , mAutomaticChromeDispatch(true)
- , mForceContentDispatch(false)
- , mRelatedTargetIsInAnon(false)
- , mOriginalTargetIsInAnon(aIsInAnon)
- , mWantsWillHandleEvent(false)
- , mMayHaveListenerManager(true)
- , mWantsPreHandleEvent(false)
- , mRootOfClosedTree(false)
- , mParentIsSlotInClosedTree(false)
- , mParentIsChromeHandler(false)
- , mParentTarget(nullptr)
- , mEventTargetAtParent(nullptr)
- {
- }
- void Reset()
- {
- mItemFlags = 0;
- mItemData = nullptr;
- mCanHandle = true;
- mAutomaticChromeDispatch = true;
- mForceContentDispatch = false;
- mWantsWillHandleEvent = false;
- mMayHaveListenerManager = true;
- mWantsPreHandleEvent = false;
- mRootOfClosedTree = false;
- mParentIsSlotInClosedTree = false;
- mParentIsChromeHandler = false;
- mParentTarget = nullptr;
- mEventTargetAtParent = nullptr;
- }
- dom::EventTarget* GetParentTarget()
- {
- return mParentTarget;
- }
- void SetParentTarget(dom::EventTarget* aParentTarget, bool aIsChromeHandler)
- {
- mParentTarget = aParentTarget;
- if (mParentTarget) {
- mParentIsChromeHandler = aIsChromeHandler;
- }
- }
- /**
- * Member that must be set in GetEventTargetParent by event targets. If set to
- * false, indicates that this event target will not be handling the event and
- * construction of the event target chain is complete. The target that sets
- * mCanHandle to false is NOT included in the event target chain.
- */
- bool mCanHandle;
- /**
- * If mCanHandle is false and mAutomaticChromeDispatch is also false
- * event will not be dispatched to the chrome event handler.
- */
- bool mAutomaticChromeDispatch;
- /**
- * If mForceContentDispatch is set to true,
- * content dispatching is not disabled for this event target.
- * FIXME! This is here for backward compatibility. Bug 329119
- */
- bool mForceContentDispatch;
- /**
- * true if it is known that related target is or is a descendant of an
- * element which is anonymous for events.
- */
- bool mRelatedTargetIsInAnon;
- /**
- * true if the original target of the event is inside anonymous content.
- * This is set before calling GetEventTargetParent on event targets.
- */
- bool mOriginalTargetIsInAnon;
- /**
- * Whether or not nsIDOMEventTarget::WillHandleEvent will be
- * called. Default is false;
- */
- bool mWantsWillHandleEvent;
- /**
- * If it is known that the current target doesn't have a listener manager
- * when GetEventTargetParent is called, set this to false.
- */
- bool mMayHaveListenerManager;
- /**
- * Whether or not nsIDOMEventTarget::PreHandleEvent will be called. Default is
- * false;
- */
- bool mWantsPreHandleEvent;
- /**
- * True if the current target is either closed ShadowRoot or root of
- * chrome only access tree (for example native anonymous content).
- */
- bool mRootOfClosedTree;
- /**
- * True if mParentTarget is HTMLSlotElement in a closed shadow tree and the
- * current target is assigned to that slot.
- */
- bool mParentIsSlotInClosedTree;
- /**
- * True if mParentTarget is a chrome handler in the event path.
- */
- bool mParentIsChromeHandler;
- private:
- /**
- * Parent item in the event target chain.
- */
- dom::EventTarget* mParentTarget;
- public:
- /**
- * If the event needs to be retargeted, this is the event target,
- * which should be used when the event is handled at mParentTarget.
- */
- dom::EventTarget* mEventTargetAtParent;
- };
- class EventChainPostVisitor : public mozilla::EventChainVisitor
- {
- public:
- explicit EventChainPostVisitor(EventChainVisitor& aOther)
- : EventChainVisitor(aOther.mPresContext, aOther.mEvent,
- aOther.mDOMEvent, aOther.mEventStatus)
- {
- }
- };
- /**
- * If an EventDispatchingCallback object is passed to Dispatch,
- * its HandleEvent method is called after handling the default event group,
- * before handling the system event group.
- * This is used in nsPresShell.
- */
- class MOZ_STACK_CLASS EventDispatchingCallback
- {
- public:
- virtual void HandleEvent(EventChainPostVisitor& aVisitor) = 0;
- };
- /**
- * The generic class for event dispatching.
- * Must not be used outside Gecko!
- */
- class EventDispatcher
- {
- public:
- /**
- * aTarget should QI to EventTarget.
- * If the target of aEvent is set before calling this method, the target of
- * aEvent is used as the target (unless there is event
- * retargeting) and the originalTarget of the DOM Event.
- * aTarget is always used as the starting point for constructing the event
- * target chain, no matter what the value of aEvent->mTarget is.
- * In other words, aEvent->mTarget is only a property of the event and it has
- * nothing to do with the construction of the event target chain.
- * Neither aTarget nor aEvent is allowed to be nullptr.
- *
- * If aTargets is non-null, event target chain will be created, but
- * event won't be handled. In this case aEvent->mMessage should be
- * eVoidEvent.
- * @note Use this method when dispatching a WidgetEvent.
- */
- static nsresult Dispatch(nsISupports* aTarget,
- nsPresContext* aPresContext,
- WidgetEvent* aEvent,
- nsIDOMEvent* aDOMEvent = nullptr,
- nsEventStatus* aEventStatus = nullptr,
- EventDispatchingCallback* aCallback = nullptr,
- nsTArray<dom::EventTarget*>* aTargets = nullptr);
- /**
- * Dispatches an event.
- * If aDOMEvent is not nullptr, it is used for dispatching
- * (aEvent can then be nullptr) and (if aDOMEvent is not |trusted| already),
- * the |trusted| flag is set based on the UniversalXPConnect capability.
- * Otherwise this works like EventDispatcher::Dispatch.
- * @note Use this method when dispatching nsIDOMEvent.
- */
- static nsresult DispatchDOMEvent(nsISupports* aTarget,
- WidgetEvent* aEvent,
- nsIDOMEvent* aDOMEvent,
- nsPresContext* aPresContext,
- nsEventStatus* aEventStatus);
- /**
- * Creates a DOM Event. Returns null if the event type is unsupported.
- */
- static already_AddRefed<dom::Event> CreateEvent(dom::EventTarget* aOwner,
- nsPresContext* aPresContext,
- WidgetEvent* aEvent,
- const nsAString& aEventType);
- static void GetComposedPathFor(WidgetEvent* aEvent,
- nsTArray<RefPtr<dom::EventTarget>>& aPath);
- /**
- * Called at shutting down.
- */
- static void Shutdown();
- };
- } // namespace mozilla
- #endif // mozilla_EventDispatcher_h_
- #endif
|