LCOV - code coverage report
Current view: top level - widget - BasicEvents.h (source / functions) Hit Total Coverage
Test: output.info Lines: 242 454 53.3 %
Date: 2017-07-14 16:53:18 Functions: 55 111 49.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : #ifndef mozilla_BasicEvents_h__
       7             : #define mozilla_BasicEvents_h__
       8             : 
       9             : #include <stdint.h>
      10             : 
      11             : #include "mozilla/dom/EventTarget.h"
      12             : #include "mozilla/EventForwards.h"
      13             : #include "mozilla/TimeStamp.h"
      14             : #include "nsCOMPtr.h"
      15             : #include "nsIAtom.h"
      16             : #include "nsISupportsImpl.h"
      17             : #include "nsIWidget.h"
      18             : #include "nsString.h"
      19             : #include "Units.h"
      20             : 
      21             : #ifdef DEBUG
      22             : #include "nsXULAppAPI.h"
      23             : #endif // #ifdef DEBUG
      24             : 
      25             : namespace IPC {
      26             : template<typename T>
      27             : struct ParamTraits;
      28             : } // namespace IPC
      29             : 
      30             : namespace mozilla {
      31             : 
      32             : /******************************************************************************
      33             :  * mozilla::BaseEventFlags
      34             :  *
      35             :  * BaseEventFlags must be a POD struct for safe to use memcpy (including
      36             :  * in ParamTraits<BaseEventFlags>).  So don't make virtual methods, constructor,
      37             :  * destructor and operators.
      38             :  * This is necessary for VC which is NOT C++0x compiler.
      39             :  ******************************************************************************/
      40             : 
      41           0 : struct BaseEventFlags
      42             : {
      43             : public:
      44             :   // If mIsTrusted is true, the event is a trusted event.  Otherwise, it's
      45             :   // an untrusted event.
      46             :   bool    mIsTrusted : 1;
      47             :   // If mInBubblingPhase is true, the event is in bubbling phase or target
      48             :   // phase.
      49             :   bool    mInBubblingPhase : 1;
      50             :   // If mInCapturePhase is true, the event is in capture phase or target phase.
      51             :   bool    mInCapturePhase : 1;
      52             :   // If mInSystemGroup is true, the event is being dispatched in system group.
      53             :   bool    mInSystemGroup: 1;
      54             :   // If mCancelable is true, the event can be consumed.  I.e., calling
      55             :   // dom::Event::PreventDefault() can prevent the default action.
      56             :   bool    mCancelable : 1;
      57             :   // If mBubbles is true, the event can bubble.  Otherwise, cannot be handled
      58             :   // in bubbling phase.
      59             :   bool    mBubbles : 1;
      60             :   // If mPropagationStopped is true, dom::Event::StopPropagation() or
      61             :   // dom::Event::StopImmediatePropagation() has been called.
      62             :   bool    mPropagationStopped : 1;
      63             :   // If mImmediatePropagationStopped is true,
      64             :   // dom::Event::StopImmediatePropagation() has been called.
      65             :   // Note that mPropagationStopped must be true when this is true.
      66             :   bool    mImmediatePropagationStopped : 1;
      67             :   // If mDefaultPrevented is true, the event has been consumed.
      68             :   // E.g., dom::Event::PreventDefault() has been called or
      69             :   // the default action has been performed.
      70             :   bool    mDefaultPrevented : 1;
      71             :   // If mDefaultPreventedByContent is true, the event has been
      72             :   // consumed by content.
      73             :   // Note that mDefaultPrevented must be true when this is true.
      74             :   bool    mDefaultPreventedByContent : 1;
      75             :   // If mDefaultPreventedByChrome is true, the event has been
      76             :   // consumed by chrome.
      77             :   // Note that mDefaultPrevented must be true when this is true.
      78             :   bool    mDefaultPreventedByChrome : 1;
      79             :   // mMultipleActionsPrevented may be used when default handling don't want to
      80             :   // be prevented, but only one of the event targets should handle the event.
      81             :   // For example, when a <label> element is in another <label> element and
      82             :   // the first <label> element is clicked, that one may set this true.
      83             :   // Then, the second <label> element won't handle the event.
      84             :   bool    mMultipleActionsPrevented : 1;
      85             :   // If mIsBeingDispatched is true, the DOM event created from the event is
      86             :   // dispatching into the DOM tree and not completed.
      87             :   bool    mIsBeingDispatched : 1;
      88             :   // If mDispatchedAtLeastOnce is true, the event has been dispatched
      89             :   // as a DOM event and the dispatch has been completed.
      90             :   bool    mDispatchedAtLeastOnce : 1;
      91             :   // If mIsSynthesizedForTests is true, the event has been synthesized for
      92             :   // automated tests or something hacky approach of an add-on.
      93             :   bool    mIsSynthesizedForTests : 1;
      94             :   // If mExceptionWasRaised is true, one of the event handlers has raised an
      95             :   // exception.
      96             :   bool    mExceptionWasRaised : 1;
      97             :   // If mRetargetToNonNativeAnonymous is true and the target is in a non-native
      98             :   // native anonymous subtree, the event target is set to mOriginalTarget.
      99             :   bool    mRetargetToNonNativeAnonymous : 1;
     100             :   // If mNoContentDispatch is true, the event is never dispatched to the
     101             :   // event handlers which are added to the contents, onfoo attributes and
     102             :   // properties.  Note that this flag is ignored when
     103             :   // EventChainPreVisitor::mForceContentDispatch is set true.  For exapmle,
     104             :   // window and document object sets it true.  Therefore, web applications
     105             :   // can handle the event if they add event listeners to the window or the
     106             :   // document.
     107             :   // XXX This is an ancient and broken feature, don't use this for new bug
     108             :   //     as far as possible.
     109             :   bool    mNoContentDispatch : 1;
     110             :   // If mOnlyChromeDispatch is true, the event is dispatched to only chrome.
     111             :   bool    mOnlyChromeDispatch : 1;
     112             :   // Indicates if the key combination is reserved by chrome.  This is set by
     113             :   // MarkAsReservedByChrome().
     114             :   bool mIsReservedByChrome : 1;
     115             :   // If mOnlySystemGroupDispatchInContent is true, event listeners added to
     116             :   // the default group for non-chrome EventTarget won't be called.
     117             :   // Be aware, if this is true, EventDispatcher needs to check if each event
     118             :   // listener is added to chrome node, so, don't set this to true for the
     119             :   // events which are fired a lot of times like eMouseMove.
     120             :   bool    mOnlySystemGroupDispatchInContent : 1;
     121             :   // The event's action will be handled by APZ. The main thread should not
     122             :   // perform its associated action. This is currently only relevant for
     123             :   // wheel and touch events.
     124             :   bool mHandledByAPZ : 1;
     125             :   // True if the event is currently being handled by an event listener that
     126             :   // was registered as a passive listener.
     127             :   bool mInPassiveListener: 1;
     128             :   // If mComposed is true, the event fired by nodes in shadow DOM can cross the
     129             :   // boundary of shadow DOM and light DOM.
     130             :   bool mComposed : 1;
     131             :   // Similar to mComposed. Set it to true to allow events cross the boundary
     132             :   // between native non-anonymous content and native anonymouse content
     133             :   bool mComposedInNativeAnonymousContent : 1;
     134             :   // Set to true for events which are suppressed or delayed so that later a
     135             :   // DelayedEvent of it is dispatched. This is used when parent side process
     136             :   // the key event after content side, and may drop the event if the event
     137             :   // was suppressed or delayed in contents side.
     138             :   // It is also set to true for the events (in a DelayedInputEvent), which will
     139             :   // be dispatched afterwards.
     140             :   bool mIsSuppressedOrDelayed : 1;
     141             :   // Certain mouse events can be marked as positionless to return 0 from
     142             :   // coordinate related getters.
     143             :   bool mIsPositionless : 1;
     144             : 
     145             :   // Flags managing state of propagation between processes.
     146             :   // Note the the following flags shouldn't be referred directly.  Use utility
     147             :   // methods instead.
     148             : 
     149             :   // If mNoRemoteProcessDispatch is true, the event is not allowed to be sent
     150             :   // to remote process.
     151             :   bool mNoRemoteProcessDispatch : 1;
     152             :   // If mWantReplyFromContentProcess is true, the event will be redispatched
     153             :   // in the parent process after the content process has handled it. Useful
     154             :   // for when the parent process need the know first how the event was used
     155             :   // by content before handling it itself.
     156             :   bool mWantReplyFromContentProcess : 1;
     157             :   // If mPostedToRemoteProcess is true, the event has been posted to the
     158             :   // remote process (but it's not handled yet if it's not a duplicated event
     159             :   // instance).
     160             :   bool mPostedToRemoteProcess : 1;
     161             : 
     162             :   // If the event is being handled in target phase, returns true.
     163           0 :   inline bool InTargetPhase() const
     164             :   {
     165           0 :     return (mInBubblingPhase && mInCapturePhase);
     166             :   }
     167             : 
     168             :   /**
     169             :    * Helper methods for methods of DOM Event.
     170             :    */
     171           0 :   inline void StopPropagation()
     172             :   {
     173           0 :     mPropagationStopped = true;
     174           0 :   }
     175           0 :   inline void StopImmediatePropagation()
     176             :   {
     177           0 :     StopPropagation();
     178           0 :     mImmediatePropagationStopped = true;
     179           0 :   }
     180           0 :   inline void PreventDefault(bool aCalledByDefaultHandler = true)
     181             :   {
     182           0 :     if (!mCancelable) {
     183           0 :       return;
     184             :     }
     185           0 :     mDefaultPrevented = true;
     186             :     // Note that even if preventDefault() has already been called by chrome,
     187             :     // a call of preventDefault() by content needs to overwrite
     188             :     // mDefaultPreventedByContent to true because in such case, defaultPrevented
     189             :     // must be true when web apps check it after they call preventDefault().
     190           0 :     if (aCalledByDefaultHandler) {
     191           0 :       mDefaultPreventedByChrome = true;
     192             :     } else {
     193           0 :       mDefaultPreventedByContent = true;
     194             :     }
     195             :   }
     196             :   // This should be used only before dispatching events into the DOM tree.
     197           0 :   inline void PreventDefaultBeforeDispatch()
     198             :   {
     199           0 :     if (!mCancelable) {
     200           0 :       return;
     201             :     }
     202           0 :     mDefaultPrevented = true;
     203             :   }
     204        1616 :   inline bool DefaultPrevented() const
     205             :   {
     206        1616 :     return mDefaultPrevented;
     207             :   }
     208          12 :   inline bool DefaultPreventedByContent() const
     209             :   {
     210          12 :     MOZ_ASSERT(!mDefaultPreventedByContent || DefaultPrevented());
     211          12 :     return mDefaultPreventedByContent;
     212             :   }
     213        2070 :   inline bool IsTrusted() const
     214             :   {
     215        2070 :     return mIsTrusted;
     216             :   }
     217       14986 :   inline bool PropagationStopped() const
     218             :   {
     219       14986 :     return mPropagationStopped;
     220             :   }
     221             : 
     222             :   // Helper methods to access flags managing state of propagation between
     223             :   // processes.
     224             : 
     225             :   /**
     226             :    * Prevent to be dispatched to remote process.
     227             :    */
     228           2 :   inline void StopCrossProcessForwarding()
     229             :   {
     230           2 :     MOZ_ASSERT(!mPostedToRemoteProcess);
     231           2 :     mNoRemoteProcessDispatch = true;
     232           2 :     mWantReplyFromContentProcess = false;
     233           2 :   }
     234             :   /**
     235             :    * Return true if the event shouldn't be dispatched to remote process.
     236             :    */
     237          24 :   inline bool IsCrossProcessForwardingStopped() const
     238             :   {
     239          24 :     return mNoRemoteProcessDispatch;
     240             :   }
     241             :   /**
     242             :    * Mark the event as waiting reply from remote process.
     243             :    */
     244           0 :   inline void MarkAsWaitingReplyFromRemoteProcess()
     245             :   {
     246           0 :     MOZ_ASSERT(!mPostedToRemoteProcess);
     247             :     // When this is called, it means that event handlers in this process need
     248             :     // a reply from content in a remote process.  So, callers should stop
     249             :     // propagation in this process first.
     250           0 :     NS_ASSERTION(PropagationStopped(),
     251             :                  "Why didn't you stop propagation in this process?");
     252           0 :     mNoRemoteProcessDispatch = false;
     253           0 :     mWantReplyFromContentProcess = true;
     254           0 :   }
     255             :   /**
     256             :    * Return true if the event handler should wait reply event.  I.e., if this
     257             :    * returns true, any event handler should do nothing with the event.
     258             :    */
     259           0 :   inline bool IsWaitingReplyFromRemoteProcess() const
     260             :   {
     261           0 :     return !mNoRemoteProcessDispatch && mWantReplyFromContentProcess;
     262             :   }
     263             :   /**
     264             :    * Mark the event as already handled in the remote process.  This should be
     265             :    * called when initializing reply events.
     266             :    */
     267           0 :   inline void MarkAsHandledInRemoteProcess()
     268             :   {
     269           0 :     mNoRemoteProcessDispatch = true;
     270           0 :     mWantReplyFromContentProcess = true;
     271           0 :     mPostedToRemoteProcess = false;
     272           0 :   }
     273             :   /**
     274             :    * Return true if the event has already been handled in the remote process.
     275             :    */
     276             :   inline bool IsHandledInRemoteProcess() const
     277             :   {
     278             :     return mNoRemoteProcessDispatch && mWantReplyFromContentProcess;
     279             :   }
     280             :   /**
     281             :    * Return true if the event should be sent back to its parent process.
     282             :    */
     283           0 :   inline bool WantReplyFromContentProcess() const
     284             :   {
     285           0 :     MOZ_ASSERT(!XRE_IsParentProcess());
     286           0 :     return IsWaitingReplyFromRemoteProcess();
     287             :   }
     288             :   /**
     289             :    * Mark the event has already posted to a remote process.
     290             :    */
     291           6 :   inline void MarkAsPostedToRemoteProcess()
     292             :   {
     293           6 :     MOZ_ASSERT(!IsCrossProcessForwardingStopped());
     294           6 :     mPostedToRemoteProcess = true;
     295           6 :   }
     296             :   /**
     297             :    * Reset the cross process dispatching state.  This should be used when a
     298             :    * process receives the event because the state is in the sender.
     299             :    */
     300           6 :   inline void ResetCrossProcessDispatchingState()
     301             :   {
     302           6 :     MOZ_ASSERT(!IsCrossProcessForwardingStopped());
     303           6 :     mPostedToRemoteProcess = false;
     304           6 :   }
     305             :   /**
     306             :    * Return true if the event has been posted to a remote process.
     307             :    * Note that MarkAsPostedToRemoteProcess() is called by
     308             :    * ParamTraits<mozilla::WidgetEvent>.  Therefore, it *might* be possible
     309             :    * that posting the event failed even if this returns true.  But that must
     310             :    * really rare.  If that'd be problem for you, you should unmark this in
     311             :    * TabParent or somewhere.
     312             :    */
     313          18 :   inline bool HasBeenPostedToRemoteProcess() const
     314             :   {
     315          18 :     return mPostedToRemoteProcess;
     316             :   }
     317             :   /**
     318             :    * Mark the event is reserved by chrome.  I.e., shouldn't be dispatched to
     319             :    * content because it shouldn't be cancelable.
     320             :    */
     321           0 :   inline void MarkAsReservedByChrome()
     322             :   {
     323           0 :     MOZ_ASSERT(!mPostedToRemoteProcess);
     324           0 :     mIsReservedByChrome = true;
     325             :     // For reserved commands (such as Open New Tab), we don't need to wait for
     326             :     // the content to answer, neither to give a chance for content to override
     327             :     // its behavior.
     328           0 :     StopCrossProcessForwarding();
     329             :     // If the event is reserved by chrome, we shouldn't expose the event to
     330             :     // web contents because such events shouldn't be cancelable.  So, it's not
     331             :     // good behavior to fire such events but to ignore the defaultPrevented
     332             :     // attribute value in chrome.
     333           0 :     mOnlySystemGroupDispatchInContent = true;
     334           0 :   }
     335             :   /**
     336             :    * Return true if the event is reserved by chrome.
     337             :    */
     338           0 :   inline bool IsReservedByChrome() const
     339             :   {
     340           0 :     MOZ_ASSERT(!mIsReservedByChrome ||
     341             :                (IsCrossProcessForwardingStopped() &&
     342             :                 mOnlySystemGroupDispatchInContent));
     343           0 :     return mIsReservedByChrome;
     344             :   }
     345             : 
     346         590 :   inline void Clear()
     347             :   {
     348         590 :     SetRawFlags(0);
     349         590 :   }
     350             :   // Get if either the instance's bit or the aOther's bit is true, the
     351             :   // instance's bit becomes true.  In other words, this works like:
     352             :   // eventFlags |= aOther;
     353           0 :   inline void Union(const BaseEventFlags& aOther)
     354             :   {
     355           0 :     RawFlags rawFlags = GetRawFlags() | aOther.GetRawFlags();
     356           0 :     SetRawFlags(rawFlags);
     357           0 :   }
     358             : 
     359             : private:
     360             :   typedef uint32_t RawFlags;
     361             : 
     362         590 :   inline void SetRawFlags(RawFlags aRawFlags)
     363             :   {
     364             :     static_assert(sizeof(BaseEventFlags) <= sizeof(RawFlags),
     365             :       "mozilla::EventFlags must not be bigger than the RawFlags");
     366         590 :     memcpy(this, &aRawFlags, sizeof(BaseEventFlags));
     367         590 :   }
     368           0 :   inline RawFlags GetRawFlags() const
     369             :   {
     370           0 :     RawFlags result = 0;
     371           0 :     memcpy(&result, this, sizeof(BaseEventFlags));
     372           0 :     return result;
     373             :   }
     374             : };
     375             : 
     376             : /******************************************************************************
     377             :  * mozilla::EventFlags
     378             :  ******************************************************************************/
     379             : 
     380             : struct EventFlags : public BaseEventFlags
     381             : {
     382           0 :   EventFlags()
     383           0 :   {
     384           0 :     Clear();
     385           0 :   }
     386             : };
     387             : 
     388             : /******************************************************************************
     389             :  * mozilla::WidgetEventTime
     390             :  ******************************************************************************/
     391             : 
     392             : class WidgetEventTime
     393             : {
     394             : public:
     395             :   // Elapsed time, in milliseconds, from a platform-specific zero time
     396             :   // to the time the message was created
     397             :   uint64_t mTime;
     398             :   // Timestamp when the message was created. Set in parallel to 'time' until we
     399             :   // determine if it is safe to drop 'time' (see bug 77992).
     400             :   TimeStamp mTimeStamp;
     401             : 
     402         619 :   WidgetEventTime()
     403         619 :     : mTime(0)
     404         619 :     , mTimeStamp(TimeStamp::Now())
     405             :   {
     406         619 :   }
     407             : 
     408           6 :   WidgetEventTime(uint64_t aTime,
     409             :                   TimeStamp aTimeStamp)
     410           6 :     : mTime(aTime)
     411           6 :     , mTimeStamp(aTimeStamp)
     412             :   {
     413           6 :   }
     414             : 
     415          49 :   void AssignEventTime(const WidgetEventTime& aOther)
     416             :   {
     417          49 :     mTime = aOther.mTime;
     418          49 :     mTimeStamp = aOther.mTimeStamp;
     419          49 :   }
     420             : };
     421             : 
     422             : /******************************************************************************
     423             :  * mozilla::WidgetEvent
     424             :  ******************************************************************************/
     425             : 
     426          32 : class WidgetEvent : public WidgetEventTime
     427             : {
     428             : private:
     429         590 :   void SetDefaultCancelableAndBubbles()
     430             :   {
     431         590 :     switch (mClass) {
     432             :       case eEditorInputEventClass:
     433           0 :         mFlags.mCancelable = false;
     434           0 :         mFlags.mBubbles = mFlags.mIsTrusted;
     435           0 :         break;
     436             :       case eMouseEventClass:
     437          40 :         mFlags.mCancelable = (mMessage != eMouseEnter &&
     438          20 :                               mMessage != eMouseLeave);
     439          40 :         mFlags.mBubbles = (mMessage != eMouseEnter &&
     440          20 :                            mMessage != eMouseLeave);
     441          20 :         break;
     442             :       case ePointerEventClass:
     443           6 :         mFlags.mCancelable = (mMessage != ePointerEnter &&
     444           4 :                               mMessage != ePointerLeave &&
     445           4 :                               mMessage != ePointerCancel &&
     446           6 :                               mMessage != ePointerGotCapture &&
     447           2 :                               mMessage != ePointerLostCapture);
     448           4 :         mFlags.mBubbles = (mMessage != ePointerEnter &&
     449           2 :                            mMessage != ePointerLeave);
     450           2 :         break;
     451             :       case eDragEventClass:
     452           0 :         mFlags.mCancelable = (mMessage != eDragExit &&
     453           0 :                               mMessage != eDragLeave &&
     454           0 :                               mMessage != eDragEnd);
     455           0 :         mFlags.mBubbles = true;
     456           0 :         break;
     457             :       case eSMILTimeEventClass:
     458           0 :         mFlags.mCancelable = false;
     459           0 :         mFlags.mBubbles = false;
     460           0 :         break;
     461             :       case eTransitionEventClass:
     462             :       case eAnimationEventClass:
     463           8 :         mFlags.mCancelable = false;
     464           8 :         mFlags.mBubbles = true;
     465           8 :         break;
     466             :       case eCompositionEventClass:
     467             :         // XXX compositionstart is cancelable in draft of DOM3 Events.
     468             :         //     However, it doesn't make sense for us, we cannot cancel
     469             :         //     composition when we send compositionstart event.
     470           0 :         mFlags.mCancelable = false;
     471           0 :         mFlags.mBubbles = true;
     472           0 :         break;
     473             :       default:
     474         560 :         if (mMessage == eResize) {
     475          22 :           mFlags.mCancelable = false;
     476             :         } else {
     477         538 :           mFlags.mCancelable = true;
     478             :         }
     479         560 :         mFlags.mBubbles = true;
     480         560 :         break;
     481             :     }
     482         590 :   }
     483             : 
     484             : protected:
     485         590 :   WidgetEvent(bool aIsTrusted,
     486             :               EventMessage aMessage,
     487             :               EventClassID aEventClassID)
     488         590 :     : WidgetEventTime()
     489             :     , mClass(aEventClassID)
     490             :     , mMessage(aMessage)
     491             :     , mRefPoint(0, 0)
     492             :     , mLastRefPoint(0, 0)
     493             :     , mFocusSequenceNumber(0)
     494         590 :     , mSpecifiedEventType(nullptr)
     495             :   {
     496         590 :     MOZ_COUNT_CTOR(WidgetEvent);
     497         590 :     mFlags.Clear();
     498         590 :     mFlags.mIsTrusted = aIsTrusted;
     499         590 :     SetDefaultCancelableAndBubbles();
     500         590 :     SetDefaultComposed();
     501         590 :     SetDefaultComposedInNativeAnonymousContent();
     502         590 :   }
     503             : 
     504           6 :   WidgetEvent()
     505           6 :     : WidgetEventTime()
     506             :   {
     507           6 :     MOZ_COUNT_CTOR(WidgetEvent);
     508           6 :   }
     509             : 
     510             : public:
     511         513 :   WidgetEvent(bool aIsTrusted, EventMessage aMessage)
     512         513 :     : WidgetEvent(aIsTrusted, aMessage, eBasicEventClass)
     513             :   {
     514         513 :   }
     515             : 
     516         775 :   virtual ~WidgetEvent()
     517        1034 :   {
     518         517 :     MOZ_COUNT_DTOR(WidgetEvent);
     519        1033 :   }
     520             : 
     521          23 :   WidgetEvent(const WidgetEvent& aOther)
     522          23 :     : WidgetEventTime()
     523             :   {
     524          23 :     MOZ_COUNT_CTOR(WidgetEvent);
     525          23 :     *this = aOther;
     526          23 :   }
     527             : 
     528          11 :   virtual WidgetEvent* Duplicate() const
     529             :   {
     530          11 :     MOZ_ASSERT(mClass == eBasicEventClass,
     531             :                "Duplicate() must be overridden by sub class");
     532          11 :     WidgetEvent* result = new WidgetEvent(false, mMessage);
     533          11 :     result->AssignEventData(*this, true);
     534          11 :     result->mFlags = mFlags;
     535          11 :     return result;
     536             :   }
     537             : 
     538             :   EventClassID mClass;
     539             :   EventMessage mMessage;
     540             :   // Relative to the widget of the event, or if there is no widget then it is
     541             :   // in screen coordinates. Not modified by layout code.
     542             :   LayoutDeviceIntPoint mRefPoint;
     543             :   // The previous mRefPoint, if known, used to calculate mouse movement deltas.
     544             :   LayoutDeviceIntPoint mLastRefPoint;
     545             :   // The sequence number of the last potentially focus changing event handled
     546             :   // by APZ. This is used to track when that event has been processed by content,
     547             :   // and focus can be reconfirmed for async keyboard scrolling.
     548             :   uint64_t mFocusSequenceNumber;
     549             :   // See BaseEventFlags definition for the detail.
     550             :   BaseEventFlags mFlags;
     551             : 
     552             :   // If JS creates an event with unknown event type or known event type but
     553             :   // for different event interface, the event type is stored to this.
     554             :   // NOTE: This is always used if the instance is a WidgetCommandEvent instance.
     555             :   nsCOMPtr<nsIAtom> mSpecifiedEventType;
     556             : 
     557             :   // nsIAtom isn't available on non-main thread due to unsafe.  Therefore,
     558             :   // mSpecifiedEventTypeString is used instead of mSpecifiedEventType if
     559             :   // the event is created in non-main thread.
     560             :   nsString mSpecifiedEventTypeString;
     561             : 
     562             :   // Event targets, needed by DOM Events
     563             :   // Note that when you need event target for DOM event, you should use
     564             :   // Get*DOMEventTarget() instead of accessing these members directly.
     565             :   nsCOMPtr<dom::EventTarget> mTarget;
     566             :   nsCOMPtr<dom::EventTarget> mCurrentTarget;
     567             :   nsCOMPtr<dom::EventTarget> mOriginalTarget;
     568             : 
     569             :   dom::EventTarget* GetDOMEventTarget() const;
     570             :   dom::EventTarget* GetCurrentDOMEventTarget() const;
     571             :   dom::EventTarget* GetOriginalDOMEventTarget() const;
     572             : 
     573          43 :   void AssignEventData(const WidgetEvent& aEvent, bool aCopyTargets)
     574             :   {
     575             :     // mClass should be initialized with the constructor.
     576             :     // mMessage should be initialized with the constructor.
     577          43 :     mRefPoint = aEvent.mRefPoint;
     578             :     // mLastRefPoint doesn't need to be copied.
     579          43 :     mFocusSequenceNumber = aEvent.mFocusSequenceNumber;
     580          43 :     AssignEventTime(aEvent);
     581             :     // mFlags should be copied manually if it's necessary.
     582          43 :     mSpecifiedEventType = aEvent.mSpecifiedEventType;
     583             :     // mSpecifiedEventTypeString should be copied manually if it's necessary.
     584          43 :     mTarget = aCopyTargets ? aEvent.mTarget : nullptr;
     585          43 :     mCurrentTarget = aCopyTargets ? aEvent.mCurrentTarget : nullptr;
     586          43 :     mOriginalTarget = aCopyTargets ? aEvent.mOriginalTarget : nullptr;
     587          43 :   }
     588             : 
     589             :   /**
     590             :    * Helper methods for methods of DOM Event.
     591             :    */
     592           0 :   void StopPropagation() { mFlags.StopPropagation(); }
     593           0 :   void StopImmediatePropagation() { mFlags.StopImmediatePropagation(); }
     594           0 :   void PreventDefault(bool aCalledByDefaultHandler = true)
     595             :   {
     596             :     // Legacy mouse events shouldn't be prevented on ePointerDown by default
     597             :     // handlers.
     598           0 :     MOZ_RELEASE_ASSERT(!aCalledByDefaultHandler || mMessage != ePointerDown);
     599           0 :     mFlags.PreventDefault(aCalledByDefaultHandler);
     600           0 :   }
     601           0 :   void PreventDefaultBeforeDispatch() { mFlags.PreventDefaultBeforeDispatch(); }
     602        1616 :   bool DefaultPrevented() const { return mFlags.DefaultPrevented(); }
     603          12 :   bool DefaultPreventedByContent() const
     604             :   {
     605          12 :     return mFlags.DefaultPreventedByContent();
     606             :   }
     607        2070 :   bool IsTrusted() const { return mFlags.IsTrusted(); }
     608       14986 :   bool PropagationStopped() const { return mFlags.PropagationStopped(); }
     609             : 
     610             :   /**
     611             :    * Prevent to be dispatched to remote process.
     612             :    */
     613           2 :   inline void StopCrossProcessForwarding()
     614             :   {
     615           2 :     mFlags.StopCrossProcessForwarding();
     616           2 :   }
     617             :   /**
     618             :    * Return true if the event shouldn't be dispatched to remote process.
     619             :    */
     620          12 :   inline bool IsCrossProcessForwardingStopped() const
     621             :   {
     622          12 :     return mFlags.IsCrossProcessForwardingStopped();
     623             :   }
     624             :   /**
     625             :    * Mark the event as waiting reply from remote process.
     626             :    * Note that this also stops immediate propagation in current process.
     627             :    */
     628           0 :   inline void MarkAsWaitingReplyFromRemoteProcess()
     629             :   {
     630           0 :     mFlags.MarkAsWaitingReplyFromRemoteProcess();
     631           0 :   }
     632             :   /**
     633             :    * Return true if the event handler should wait reply event.  I.e., if this
     634             :    * returns true, any event handler should do nothing with the event.
     635             :    */
     636             :   inline bool IsWaitingReplyFromRemoteProcess() const
     637             :   {
     638             :     return mFlags.IsWaitingReplyFromRemoteProcess();
     639             :   }
     640             :   /**
     641             :    * Mark the event as already handled in the remote process.  This should be
     642             :    * called when initializing reply events.
     643             :    */
     644           0 :   inline void MarkAsHandledInRemoteProcess()
     645             :   {
     646           0 :     mFlags.MarkAsHandledInRemoteProcess();
     647           0 :   }
     648             :   /**
     649             :    * Return true if the event has already been handled in the remote process.
     650             :    * I.e., if this returns true, the event is a reply event.
     651             :    */
     652             :   inline bool IsHandledInRemoteProcess() const
     653             :   {
     654             :     return mFlags.IsHandledInRemoteProcess();
     655             :   }
     656             :   /**
     657             :    * Return true if the event should be sent back to its parent process.
     658             :    * So, usual event handlers shouldn't call this.
     659             :    */
     660           0 :   inline bool WantReplyFromContentProcess() const
     661             :   {
     662           0 :     return mFlags.WantReplyFromContentProcess();
     663             :   }
     664             :   /**
     665             :    * Mark the event has already posted to a remote process.
     666             :    */
     667           6 :   inline void MarkAsPostedToRemoteProcess()
     668             :   {
     669           6 :     mFlags.MarkAsPostedToRemoteProcess();
     670           6 :   }
     671             :   /**
     672             :    * Reset the cross process dispatching state.  This should be used when a
     673             :    * process receives the event because the state is in the sender.
     674             :    */
     675           6 :   inline void ResetCrossProcessDispatchingState()
     676             :   {
     677           6 :     mFlags.ResetCrossProcessDispatchingState();
     678           6 :   }
     679             :   /**
     680             :    * Return true if the event has been posted to a remote process.
     681             :    */
     682          18 :   inline bool HasBeenPostedToRemoteProcess() const
     683             :   {
     684          18 :     return mFlags.HasBeenPostedToRemoteProcess();
     685             :   }
     686             :   /**
     687             :    * Mark the event is reserved by chrome.  I.e., shouldn't be dispatched to
     688             :    * content because it shouldn't be cancelable.
     689             :    */
     690           0 :   inline void MarkAsReservedByChrome()
     691             :   {
     692           0 :     mFlags.MarkAsReservedByChrome();
     693           0 :   }
     694             :   /**
     695             :    * Return true if the event is reserved by chrome.
     696             :    */
     697           0 :   inline bool IsReservedByChrome() const
     698             :   {
     699           0 :     return mFlags.IsReservedByChrome();
     700             :   }
     701             : 
     702             :   /**
     703             :    * Utils for checking event types
     704             :    */
     705             : 
     706             :   /**
     707             :    * As*Event() returns the pointer of the instance only when the instance is
     708             :    * the class or one of its derived class.
     709             :    */
     710             : #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
     711             : #define NS_EVENT_CLASS(aPrefix, aName) \
     712             :   virtual aPrefix##aName* As##aName(); \
     713             :   const aPrefix##aName* As##aName() const;
     714             : 
     715             : #include "mozilla/EventClassList.h"
     716             : 
     717             : #undef NS_EVENT_CLASS
     718             : #undef NS_ROOT_EVENT_CLASS
     719             : 
     720             :   /**
     721             :    * Returns true if the event is a query content event.
     722             :    */
     723             :   bool IsQueryContentEvent() const;
     724             :   /**
     725             :    * Returns true if the event is a selection event.
     726             :    */
     727             :   bool IsSelectionEvent() const;
     728             :   /**
     729             :    * Returns true if the event is a content command event.
     730             :    */
     731             :   bool IsContentCommandEvent() const;
     732             :   /**
     733             :    * Returns true if the event is a native event deliverer event for plugin.
     734             :    */
     735             :   bool IsNativeEventDelivererForPlugin() const;
     736             : 
     737             :   /**
     738             :    * Returns true if the event mMessage is one of mouse events.
     739             :    */
     740             :   bool HasMouseEventMessage() const;
     741             :   /**
     742             :    * Returns true if the event mMessage is one of drag events.
     743             :    */
     744             :   bool HasDragEventMessage() const;
     745             :   /**
     746             :    * Returns true if the event mMessage is one of key events.
     747             :    */
     748             :   bool HasKeyEventMessage() const;
     749             :   /**
     750             :    * Returns true if the event mMessage is one of composition events or text
     751             :    * event.
     752             :    */
     753             :   bool HasIMEEventMessage() const;
     754             :   /**
     755             :    * Returns true if the event mMessage is one of plugin activation events.
     756             :    */
     757             :   bool HasPluginActivationEventMessage() const;
     758             : 
     759             :   /**
     760             :    * Returns true if the event can be sent to remote process.
     761             :    */
     762             :   bool CanBeSentToRemoteProcess() const;
     763             :   /**
     764             :    * Returns true if the event is native event deliverer event for plugin and
     765             :    * it should be retarted to focused document.
     766             :    */
     767             :   bool IsRetargetedNativeEventDelivererForPlugin() const;
     768             :   /**
     769             :    * Returns true if the event is native event deliverer event for plugin and
     770             :    * it should NOT be retarted to focused document.
     771             :    */
     772             :   bool IsNonRetargetedNativeEventDelivererForPlugin() const;
     773             :   /**
     774             :    * Returns true if the event is related to IME handling.  It includes
     775             :    * IME events, query content events and selection events.
     776             :    * Be careful when you use this.
     777             :    */
     778             :   bool IsIMERelatedEvent() const;
     779             : 
     780             :   /**
     781             :    * Whether the event should be handled by the frame of the mouse cursor
     782             :    * position or not.  When it should be handled there (e.g., the mouse events),
     783             :    * this returns true.
     784             :    */
     785             :   bool IsUsingCoordinates() const;
     786             :   /**
     787             :    * Whether the event should be handled by the focused DOM window in the
     788             :    * same top level window's or not.  E.g., key events, IME related events
     789             :    * (including the query content events, they are used in IME transaction)
     790             :    * should be handled by the (last) focused window rather than the dispatched
     791             :    * window.
     792             :    *
     793             :    * NOTE: Even if this returns true, the event isn't going to be handled by the
     794             :    * application level active DOM window which is on another top level window.
     795             :    * So, when the event is fired on a deactive window, the event is going to be
     796             :    * handled by the last focused DOM window in the last focused window.
     797             :    */
     798             :   bool IsTargetedAtFocusedWindow() const;
     799             :   /**
     800             :    * Whether the event should be handled by the focused content or not.  E.g.,
     801             :    * key events, IME related events and other input events which are not handled
     802             :    * by the frame of the mouse cursor position.
     803             :    *
     804             :    * NOTE: Even if this returns true, the event isn't going to be handled by the
     805             :    * application level active DOM window which is on another top level window.
     806             :    * So, when the event is fired on a deactive window, the event is going to be
     807             :    * handled by the last focused DOM element of the last focused DOM window in
     808             :    * the last focused window.
     809             :    */
     810             :   bool IsTargetedAtFocusedContent() const;
     811             :   /**
     812             :    * Whether the event should cause a DOM event.
     813             :    */
     814             :   bool IsAllowedToDispatchDOMEvent() const;
     815             :   /**
     816             :    * Whether the event should be dispatched in system group.
     817             :    */
     818             :   bool IsAllowedToDispatchInSystemGroup() const;
     819             :   /**
     820             :    * Initialize mComposed
     821             :    */
     822         887 :   void SetDefaultComposed()
     823             :   {
     824         887 :     switch (mClass) {
     825             :       case eCompositionEventClass:
     826           0 :         mFlags.mComposed = mMessage == eCompositionStart ||
     827           0 :                            mMessage == eCompositionUpdate ||
     828           0 :                            mMessage == eCompositionEnd;
     829           0 :         break;
     830             :       case eDragEventClass:
     831             :         // All drag & drop events are composed
     832           0 :         mFlags.mComposed = mMessage == eDrag || mMessage == eDragEnd ||
     833           0 :                            mMessage == eDragEnter || mMessage == eDragExit ||
     834           0 :                            mMessage == eDragLeave || mMessage == eDragOver ||
     835           0 :                            mMessage == eDragStart || mMessage == eDrop;
     836           0 :         break;
     837             :       case eEditorInputEventClass:
     838           0 :         mFlags.mComposed = mMessage == eEditorInput;
     839           0 :         break;
     840             :       case eFocusEventClass:
     841           8 :         mFlags.mComposed = mMessage == eBlur || mMessage == eFocus;
     842           8 :         break;
     843             :       case eKeyboardEventClass:
     844           0 :         mFlags.mComposed = mMessage == eKeyDown || mMessage == eKeyUp ||
     845           0 :                            mMessage == eKeyPress;
     846           0 :         break;
     847             :       case eMouseEventClass:
     848          60 :         mFlags.mComposed = mMessage == eMouseClick ||
     849          40 :                            mMessage == eMouseDoubleClick ||
     850          40 :                            mMessage == eMouseAuxClick ||
     851          60 :                            mMessage == eMouseDown || mMessage == eMouseUp ||
     852          60 :                            mMessage == eMouseEnter || mMessage == eMouseLeave ||
     853          57 :                            mMessage == eMouseOver || mMessage == eMouseOut ||
     854          44 :                            mMessage == eMouseMove || mMessage == eContextMenu;
     855          20 :         break;
     856             :       case ePointerEventClass:
     857             :         // All pointer events are composed
     858           6 :         mFlags.mComposed = mMessage == ePointerDown ||
     859           6 :                            mMessage == ePointerMove || mMessage == ePointerUp ||
     860           4 :                            mMessage == ePointerCancel ||
     861           3 :                            mMessage == ePointerOver ||
     862           1 :                            mMessage == ePointerOut ||
     863           0 :                            mMessage == ePointerEnter ||
     864           0 :                            mMessage == ePointerLeave ||
     865           2 :                            mMessage == ePointerGotCapture ||
     866           0 :                            mMessage == ePointerLostCapture;
     867           2 :         break;
     868             :       case eTouchEventClass:
     869             :         // All touch events are composed
     870           0 :         mFlags.mComposed = mMessage == eTouchStart || mMessage == eTouchEnd ||
     871           0 :                            mMessage == eTouchMove || mMessage == eTouchCancel;
     872           0 :         break;
     873             :       case eUIEventClass:
     874           0 :         mFlags.mComposed = mMessage == eLegacyDOMFocusIn ||
     875           0 :                            mMessage == eLegacyDOMFocusOut ||
     876           0 :                            mMessage == eLegacyDOMActivate;
     877           0 :         break;
     878             :       case eWheelEventClass:
     879             :         // All wheel events are composed
     880           0 :         mFlags.mComposed = mMessage == eWheel;
     881           0 :         break;
     882             :       default:
     883         857 :         mFlags.mComposed = false;
     884         857 :         break;
     885             :     }
     886         887 :   }
     887             : 
     888          17 :   void SetComposed(const nsAString& aEventTypeArg)
     889             :   {
     890          17 :     mFlags.mComposed = // composition events
     891          34 :                        aEventTypeArg.EqualsLiteral("compositionstart") ||
     892          34 :                        aEventTypeArg.EqualsLiteral("compositionupdate") ||
     893          34 :                        aEventTypeArg.EqualsLiteral("compositionend") ||
     894             :                        // drag and drop events
     895          34 :                        aEventTypeArg.EqualsLiteral("dragstart") ||
     896          34 :                        aEventTypeArg.EqualsLiteral("drag") ||
     897          34 :                        aEventTypeArg.EqualsLiteral("dragenter") ||
     898          34 :                        aEventTypeArg.EqualsLiteral("dragexit") ||
     899          34 :                        aEventTypeArg.EqualsLiteral("dragleave") ||
     900          34 :                        aEventTypeArg.EqualsLiteral("dragover") ||
     901          34 :                        aEventTypeArg.EqualsLiteral("drop") ||
     902          34 :                        aEventTypeArg.EqualsLiteral("dropend") ||
     903             :                        // editor input events
     904          34 :                        aEventTypeArg.EqualsLiteral("input") ||
     905          34 :                        aEventTypeArg.EqualsLiteral("beforeinput") ||
     906             :                        // focus events
     907          34 :                        aEventTypeArg.EqualsLiteral("blur") ||
     908          34 :                        aEventTypeArg.EqualsLiteral("focus") ||
     909          34 :                        aEventTypeArg.EqualsLiteral("focusin") ||
     910          34 :                        aEventTypeArg.EqualsLiteral("focusout") ||
     911             :                        // keyboard events
     912          34 :                        aEventTypeArg.EqualsLiteral("keydown") ||
     913          34 :                        aEventTypeArg.EqualsLiteral("keyup") ||
     914          34 :                        aEventTypeArg.EqualsLiteral("keypress") ||
     915             :                        // mouse events
     916          34 :                        aEventTypeArg.EqualsLiteral("click") ||
     917          34 :                        aEventTypeArg.EqualsLiteral("dblclick") ||
     918          34 :                        aEventTypeArg.EqualsLiteral("mousedown") ||
     919          34 :                        aEventTypeArg.EqualsLiteral("mouseup") ||
     920          34 :                        aEventTypeArg.EqualsLiteral("mouseenter") ||
     921          34 :                        aEventTypeArg.EqualsLiteral("mouseleave") ||
     922          34 :                        aEventTypeArg.EqualsLiteral("mouseover") ||
     923          34 :                        aEventTypeArg.EqualsLiteral("mouseout") ||
     924          34 :                        aEventTypeArg.EqualsLiteral("mousemove") ||
     925          34 :                        aEventTypeArg.EqualsLiteral("contextmenu") ||
     926             :                        // pointer events
     927          34 :                        aEventTypeArg.EqualsLiteral("pointerdown") ||
     928          34 :                        aEventTypeArg.EqualsLiteral("pointermove") ||
     929          34 :                        aEventTypeArg.EqualsLiteral("pointerup") ||
     930          34 :                        aEventTypeArg.EqualsLiteral("pointercancel") ||
     931          34 :                        aEventTypeArg.EqualsLiteral("pointerover") ||
     932          34 :                        aEventTypeArg.EqualsLiteral("pointerout") ||
     933          34 :                        aEventTypeArg.EqualsLiteral("pointerenter") ||
     934          34 :                        aEventTypeArg.EqualsLiteral("pointerleave") ||
     935          34 :                        aEventTypeArg.EqualsLiteral("gotpointercapture") ||
     936          34 :                        aEventTypeArg.EqualsLiteral("lostpointercapture") ||
     937             :                        // touch events
     938          34 :                        aEventTypeArg.EqualsLiteral("touchstart") ||
     939          34 :                        aEventTypeArg.EqualsLiteral("touchend") ||
     940          34 :                        aEventTypeArg.EqualsLiteral("touchmove") ||
     941          34 :                        aEventTypeArg.EqualsLiteral("touchcancel") ||
     942             :                        // UI legacy events
     943          34 :                        aEventTypeArg.EqualsLiteral("DOMFocusIn") ||
     944          34 :                        aEventTypeArg.EqualsLiteral("DOMFocusOut") ||
     945          51 :                        aEventTypeArg.EqualsLiteral("DOMActivate") ||
     946             :                        // wheel events
     947          17 :                        aEventTypeArg.EqualsLiteral("wheel");
     948          17 :   }
     949             : 
     950          36 :   void SetComposed(bool aComposed)
     951             :   {
     952          36 :     mFlags.mComposed = aComposed;
     953          36 :   }
     954             : 
     955         904 :   void SetDefaultComposedInNativeAnonymousContent()
     956             :   {
     957             :     // For compatibility concerns, we set mComposedInNativeAnonymousContent to
     958             :     // false for those events we want to stop propagation.
     959             :     //
     960             :     // nsVideoFrame may create anonymous image element which fires eLoad,
     961             :     // eLoadStart, eLoadEnd, eLoadError. We don't want these events cross
     962             :     // the boundary of NAC
     963        2636 :     mFlags.mComposedInNativeAnonymousContent = mMessage != eLoad &&
     964        1650 :                                                mMessage != eLoadStart &&
     965        2542 :                                                mMessage != eLoadEnd &&
     966         816 :                                                mMessage != eLoadError;
     967         904 :   }
     968             : };
     969             : 
     970             : /******************************************************************************
     971             :  * mozilla::NativeEventData
     972             :  *
     973             :  * WidgetGUIEvent's mPluginEvent member used to be a void* pointer,
     974             :  * used to reference external, OS-specific data structures.
     975             :  *
     976             :  * That void* pointer wasn't serializable by itself, causing
     977             :  * certain plugin events not to function in e10s. See bug 586656.
     978             :  *
     979             :  * To make this serializable, we changed this void* pointer into
     980             :  * a proper buffer, and copy these external data structures into this
     981             :  * buffer.
     982             :  *
     983             :  * That buffer is NativeEventData::mBuffer below.
     984             :  *
     985             :  * We wrap this in that NativeEventData class providing operators to
     986             :  * be compatible with existing code that was written around
     987             :  * the old void* field.
     988             :  ******************************************************************************/
     989             : 
     990         184 : class NativeEventData final
     991             : {
     992             :   nsTArray<uint8_t> mBuffer;
     993             : 
     994             :   friend struct IPC::ParamTraits<mozilla::NativeEventData>;
     995             : 
     996             : public:
     997             : 
     998           0 :   explicit operator bool() const
     999             :   {
    1000           0 :     return !mBuffer.IsEmpty();
    1001             :   }
    1002             : 
    1003             :   template<typename T>
    1004           0 :   explicit operator const T*() const
    1005             :   {
    1006           0 :     return mBuffer.IsEmpty()
    1007           0 :            ? nullptr
    1008           0 :            : reinterpret_cast<const T*>(mBuffer.Elements());
    1009             :   }
    1010             : 
    1011             :   template <typename T>
    1012           0 :   void Copy(const T& other)
    1013             :   {
    1014             :     static_assert(!mozilla::IsPointer<T>::value, "Don't want a pointer!");
    1015           0 :     mBuffer.SetLength(sizeof(T));
    1016           0 :     memcpy(mBuffer.Elements(), &other, mBuffer.Length());
    1017           0 :   }
    1018             : 
    1019           0 :   void Clear()
    1020             :   {
    1021           0 :     mBuffer.Clear();
    1022           0 :   }
    1023             : };
    1024             : 
    1025             : /******************************************************************************
    1026             :  * mozilla::WidgetGUIEvent
    1027             :  ******************************************************************************/
    1028             : 
    1029          85 : class WidgetGUIEvent : public WidgetEvent
    1030             : {
    1031             : protected:
    1032          69 :   WidgetGUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
    1033             :                  EventClassID aEventClassID)
    1034          69 :     : WidgetEvent(aIsTrusted, aMessage, aEventClassID)
    1035          69 :     , mWidget(aWidget)
    1036             :   {
    1037          69 :   }
    1038             : 
    1039           6 :   WidgetGUIEvent()
    1040           6 :   {
    1041           6 :   }
    1042             : 
    1043             : public:
    1044         121 :   virtual WidgetGUIEvent* AsGUIEvent() override { return this; }
    1045             : 
    1046           0 :   WidgetGUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
    1047           0 :     : WidgetEvent(aIsTrusted, aMessage, eGUIEventClass)
    1048           0 :     , mWidget(aWidget)
    1049             :   {
    1050           0 :   }
    1051             : 
    1052           0 :   virtual WidgetEvent* Duplicate() const override
    1053             :   {
    1054           0 :     MOZ_ASSERT(mClass == eGUIEventClass,
    1055             :                "Duplicate() must be overridden by sub class");
    1056             :     // Not copying widget, it is a weak reference.
    1057           0 :     WidgetGUIEvent* result = new WidgetGUIEvent(false, mMessage, nullptr);
    1058           0 :     result->AssignGUIEventData(*this, true);
    1059           0 :     result->mFlags = mFlags;
    1060           0 :     return result;
    1061             :   }
    1062             : 
    1063             :   // Originator of the event
    1064             :   nsCOMPtr<nsIWidget> mWidget;
    1065             : 
    1066             :   /*
    1067             :    * Ideally though, we wouldn't allow arbitrary reinterpret_cast'ing here;
    1068             :    * instead, we would at least store type information here so that
    1069             :    * this class can't be used to reinterpret one structure type into another.
    1070             :    * We can also wonder if it would be possible to properly extend
    1071             :    * WidgetGUIEvent and other Event classes to remove the need for this
    1072             :    * mPluginEvent field.
    1073             :    */
    1074             :   typedef NativeEventData PluginEvent;
    1075             : 
    1076             :   // Event for NPAPI plugin
    1077             :   PluginEvent mPluginEvent;
    1078             : 
    1079          18 :   void AssignGUIEventData(const WidgetGUIEvent& aEvent, bool aCopyTargets)
    1080             :   {
    1081          18 :     AssignEventData(aEvent, aCopyTargets);
    1082             : 
    1083             :     // widget should be initialized with the constructor.
    1084             : 
    1085          18 :     mPluginEvent = aEvent.mPluginEvent;
    1086          18 :   }
    1087             : };
    1088             : 
    1089             : /******************************************************************************
    1090             :  * mozilla::Modifier
    1091             :  *
    1092             :  * All modifier keys should be defined here.  This is used for managing
    1093             :  * modifier states for DOM Level 3 or later.
    1094             :  ******************************************************************************/
    1095             : 
    1096             : enum Modifier
    1097             : {
    1098             :   MODIFIER_NONE       = 0x0000,
    1099             :   MODIFIER_ALT        = 0x0001,
    1100             :   MODIFIER_ALTGRAPH   = 0x0002,
    1101             :   MODIFIER_CAPSLOCK   = 0x0004,
    1102             :   MODIFIER_CONTROL    = 0x0008,
    1103             :   MODIFIER_FN         = 0x0010,
    1104             :   MODIFIER_FNLOCK     = 0x0020,
    1105             :   MODIFIER_META       = 0x0040,
    1106             :   MODIFIER_NUMLOCK    = 0x0080,
    1107             :   MODIFIER_SCROLLLOCK = 0x0100,
    1108             :   MODIFIER_SHIFT      = 0x0200,
    1109             :   MODIFIER_SYMBOL     = 0x0400,
    1110             :   MODIFIER_SYMBOLLOCK = 0x0800,
    1111             :   MODIFIER_OS         = 0x1000
    1112             : };
    1113             : 
    1114             : /******************************************************************************
    1115             :  * Modifier key names.
    1116             :  ******************************************************************************/
    1117             : 
    1118             : #define NS_DOM_KEYNAME_ALT        "Alt"
    1119             : #define NS_DOM_KEYNAME_ALTGRAPH   "AltGraph"
    1120             : #define NS_DOM_KEYNAME_CAPSLOCK   "CapsLock"
    1121             : #define NS_DOM_KEYNAME_CONTROL    "Control"
    1122             : #define NS_DOM_KEYNAME_FN         "Fn"
    1123             : #define NS_DOM_KEYNAME_FNLOCK     "FnLock"
    1124             : #define NS_DOM_KEYNAME_META       "Meta"
    1125             : #define NS_DOM_KEYNAME_NUMLOCK    "NumLock"
    1126             : #define NS_DOM_KEYNAME_SCROLLLOCK "ScrollLock"
    1127             : #define NS_DOM_KEYNAME_SHIFT      "Shift"
    1128             : #define NS_DOM_KEYNAME_SYMBOL     "Symbol"
    1129             : #define NS_DOM_KEYNAME_SYMBOLLOCK "SymbolLock"
    1130             : #define NS_DOM_KEYNAME_OS         "OS"
    1131             : 
    1132             : /******************************************************************************
    1133             :  * mozilla::Modifiers
    1134             :  ******************************************************************************/
    1135             : 
    1136             : typedef uint16_t Modifiers;
    1137             : 
    1138             : class MOZ_STACK_CLASS GetModifiersName final : public nsAutoCString
    1139             : {
    1140             : public:
    1141             :   explicit GetModifiersName(Modifiers aModifiers)
    1142             :   {
    1143             :     if (aModifiers & MODIFIER_ALT) {
    1144             :       AssignLiteral(NS_DOM_KEYNAME_ALT);
    1145             :     }
    1146             :     if (aModifiers & MODIFIER_ALTGRAPH) {
    1147             :       MaybeAppendSeparator();
    1148             :       AppendLiteral(NS_DOM_KEYNAME_ALTGRAPH);
    1149             :     }
    1150             :     if (aModifiers & MODIFIER_CAPSLOCK) {
    1151             :       MaybeAppendSeparator();
    1152             :       AppendLiteral(NS_DOM_KEYNAME_CAPSLOCK);
    1153             :     }
    1154             :     if (aModifiers & MODIFIER_CONTROL) {
    1155             :       MaybeAppendSeparator();
    1156             :       AppendLiteral(NS_DOM_KEYNAME_CONTROL);
    1157             :     }
    1158             :     if (aModifiers & MODIFIER_FN) {
    1159             :       MaybeAppendSeparator();
    1160             :       AppendLiteral(NS_DOM_KEYNAME_FN);
    1161             :     }
    1162             :     if (aModifiers & MODIFIER_FNLOCK) {
    1163             :       MaybeAppendSeparator();
    1164             :       AppendLiteral(NS_DOM_KEYNAME_FNLOCK);
    1165             :     }
    1166             :     if (aModifiers & MODIFIER_META) {
    1167             :       MaybeAppendSeparator();
    1168             :       AppendLiteral(NS_DOM_KEYNAME_META);
    1169             :     }
    1170             :     if (aModifiers & MODIFIER_NUMLOCK) {
    1171             :       MaybeAppendSeparator();
    1172             :       AppendLiteral(NS_DOM_KEYNAME_NUMLOCK);
    1173             :     }
    1174             :     if (aModifiers & MODIFIER_SCROLLLOCK) {
    1175             :       MaybeAppendSeparator();
    1176             :       AppendLiteral(NS_DOM_KEYNAME_SCROLLLOCK);
    1177             :     }
    1178             :     if (aModifiers & MODIFIER_SHIFT) {
    1179             :       MaybeAppendSeparator();
    1180             :       AppendLiteral(NS_DOM_KEYNAME_SHIFT);
    1181             :     }
    1182             :     if (aModifiers & MODIFIER_SYMBOL) {
    1183             :       MaybeAppendSeparator();
    1184             :       AppendLiteral(NS_DOM_KEYNAME_SYMBOL);
    1185             :     }
    1186             :     if (aModifiers & MODIFIER_SYMBOLLOCK) {
    1187             :       MaybeAppendSeparator();
    1188             :       AppendLiteral(NS_DOM_KEYNAME_SYMBOLLOCK);
    1189             :     }
    1190             :     if (aModifiers & MODIFIER_OS) {
    1191             :       MaybeAppendSeparator();
    1192             :       AppendLiteral(NS_DOM_KEYNAME_OS);
    1193             :     }
    1194             :     if (IsEmpty()) {
    1195             :       AssignLiteral("none");
    1196             :     }
    1197             :   }
    1198             : 
    1199             : private:
    1200             :   void MaybeAppendSeparator()
    1201             :   {
    1202             :     if (!IsEmpty()) {
    1203             :       AppendLiteral(" | ");
    1204             :     }
    1205             :   }
    1206             : };
    1207             : 
    1208             : /******************************************************************************
    1209             :  * mozilla::WidgetInputEvent
    1210             :  ******************************************************************************/
    1211             : 
    1212          46 : class WidgetInputEvent : public WidgetGUIEvent
    1213             : {
    1214             : protected:
    1215          22 :   WidgetInputEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
    1216             :                    EventClassID aEventClassID)
    1217          22 :     : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, aEventClassID)
    1218          22 :     , mModifiers(0)
    1219             :   {
    1220          22 :   }
    1221             : 
    1222           6 :   WidgetInputEvent()
    1223           6 :     : mModifiers(0)
    1224             :   {
    1225           6 :   }
    1226             : 
    1227             : public:
    1228          10 :   virtual WidgetInputEvent* AsInputEvent() override { return this; }
    1229             : 
    1230           0 :   WidgetInputEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
    1231           0 :     : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eInputEventClass)
    1232           0 :     , mModifiers(0)
    1233             :   {
    1234           0 :   }
    1235             : 
    1236           0 :   virtual WidgetEvent* Duplicate() const override
    1237             :   {
    1238           0 :     MOZ_ASSERT(mClass == eInputEventClass,
    1239             :                "Duplicate() must be overridden by sub class");
    1240             :     // Not copying widget, it is a weak reference.
    1241           0 :     WidgetInputEvent* result = new WidgetInputEvent(false, mMessage, nullptr);
    1242           0 :     result->AssignInputEventData(*this, true);
    1243           0 :     result->mFlags = mFlags;
    1244           0 :     return result;
    1245             :   }
    1246             : 
    1247             : 
    1248             :   /**
    1249             :    * Returns a modifier of "Accel" virtual modifier which is used for shortcut
    1250             :    * key.
    1251             :    */
    1252             :   static Modifier AccelModifier();
    1253             : 
    1254             :   /**
    1255             :    * GetModifier() returns a modifier flag which is activated by aDOMKeyName.
    1256             :    */
    1257             :   static Modifier GetModifier(const nsAString& aDOMKeyName);
    1258             : 
    1259             :   // true indicates the accel key on the environment is down
    1260           0 :   bool IsAccel() const
    1261             :   {
    1262           0 :     return ((mModifiers & AccelModifier()) != 0);
    1263             :   }
    1264             : 
    1265             :   // true indicates the shift key is down
    1266           0 :   bool IsShift() const
    1267             :   {
    1268           0 :     return ((mModifiers & MODIFIER_SHIFT) != 0);
    1269             :   }
    1270             :   // true indicates the control key is down
    1271           0 :   bool IsControl() const
    1272             :   {
    1273           0 :     return ((mModifiers & MODIFIER_CONTROL) != 0);
    1274             :   }
    1275             :   // true indicates the alt key is down
    1276           0 :   bool IsAlt() const
    1277             :   {
    1278           0 :     return ((mModifiers & MODIFIER_ALT) != 0);
    1279             :   }
    1280             :   // true indicates the meta key is down (or, on Mac, the Command key)
    1281           0 :   bool IsMeta() const
    1282             :   {
    1283           0 :     return ((mModifiers & MODIFIER_META) != 0);
    1284             :   }
    1285             :   // true indicates the win key is down on Windows. Or the Super or Hyper key
    1286             :   // is down on Linux.
    1287           0 :   bool IsOS() const
    1288             :   {
    1289           0 :     return ((mModifiers & MODIFIER_OS) != 0);
    1290             :   }
    1291             :   // true indicates the alt graph key is down
    1292             :   // NOTE: on Mac, the option key press causes both IsAlt() and IsAltGrpah()
    1293             :   //       return true.
    1294           0 :   bool IsAltGraph() const
    1295             :   {
    1296           0 :     return ((mModifiers & MODIFIER_ALTGRAPH) != 0);
    1297             :   }
    1298             :   // true indicates the CapLock LED is turn on.
    1299           0 :   bool IsCapsLocked() const
    1300             :   {
    1301           0 :     return ((mModifiers & MODIFIER_CAPSLOCK) != 0);
    1302             :   }
    1303             :   // true indicates the NumLock LED is turn on.
    1304           0 :   bool IsNumLocked() const
    1305             :   {
    1306           0 :     return ((mModifiers & MODIFIER_NUMLOCK) != 0);
    1307             :   }
    1308             :   // true indicates the ScrollLock LED is turn on.
    1309           0 :   bool IsScrollLocked() const
    1310             :   {
    1311           0 :     return ((mModifiers & MODIFIER_SCROLLLOCK) != 0);
    1312             :   }
    1313             : 
    1314             :   // true indicates the Fn key is down, but this is not supported by native
    1315             :   // key event on any platform.
    1316           0 :   bool IsFn() const
    1317             :   {
    1318           0 :     return ((mModifiers & MODIFIER_FN) != 0);
    1319             :   }
    1320             :   // true indicates the FnLock LED is turn on, but we don't know such
    1321             :   // keyboards nor platforms.
    1322           0 :   bool IsFnLocked() const
    1323             :   {
    1324           0 :     return ((mModifiers & MODIFIER_FNLOCK) != 0);
    1325             :   }
    1326             :   // true indicates the Symbol is down, but this is not supported by native
    1327             :   // key event on any platforms.
    1328           0 :   bool IsSymbol() const
    1329             :   {
    1330           0 :     return ((mModifiers & MODIFIER_SYMBOL) != 0);
    1331             :   }
    1332             :   // true indicates the SymbolLock LED is turn on, but we don't know such
    1333             :   // keyboards nor platforms.
    1334           0 :   bool IsSymbolLocked() const
    1335             :   {
    1336           0 :     return ((mModifiers & MODIFIER_SYMBOLLOCK) != 0);
    1337             :   }
    1338             : 
    1339           0 :   void InitBasicModifiers(bool aCtrlKey,
    1340             :                           bool aAltKey,
    1341             :                           bool aShiftKey,
    1342             :                           bool aMetaKey)
    1343             :   {
    1344           0 :     mModifiers = 0;
    1345           0 :     if (aCtrlKey) {
    1346           0 :       mModifiers |= MODIFIER_CONTROL;
    1347             :     }
    1348           0 :     if (aAltKey) {
    1349           0 :       mModifiers |= MODIFIER_ALT;
    1350             :     }
    1351           0 :     if (aShiftKey) {
    1352           0 :       mModifiers |= MODIFIER_SHIFT;
    1353             :     }
    1354           0 :     if (aMetaKey) {
    1355           0 :       mModifiers |= MODIFIER_META;
    1356             :     }
    1357           0 :   }
    1358             : 
    1359             :   Modifiers mModifiers;
    1360             : 
    1361          10 :   void AssignInputEventData(const WidgetInputEvent& aEvent, bool aCopyTargets)
    1362             :   {
    1363          10 :     AssignGUIEventData(aEvent, aCopyTargets);
    1364             : 
    1365          10 :     mModifiers = aEvent.mModifiers;
    1366          10 :   }
    1367             : };
    1368             : 
    1369             : /******************************************************************************
    1370             :  * mozilla::InternalUIEvent
    1371             :  *
    1372             :  * XXX Why this inherits WidgetGUIEvent rather than WidgetEvent?
    1373             :  ******************************************************************************/
    1374             : 
    1375           8 : class InternalUIEvent : public WidgetGUIEvent
    1376             : {
    1377             : protected:
    1378             :   InternalUIEvent()
    1379             :     : mDetail(0)
    1380             :     , mCausedByUntrustedEvent(false)
    1381             :   {
    1382             :   }
    1383             : 
    1384           0 :   InternalUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
    1385             :                   EventClassID aEventClassID)
    1386           0 :     : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, aEventClassID)
    1387             :     , mDetail(0)
    1388           0 :     , mCausedByUntrustedEvent(false)
    1389             :   {
    1390           0 :   }
    1391             : 
    1392           8 :   InternalUIEvent(bool aIsTrusted, EventMessage aMessage,
    1393             :                   EventClassID aEventClassID)
    1394           8 :     : WidgetGUIEvent(aIsTrusted, aMessage, nullptr, aEventClassID)
    1395             :     , mDetail(0)
    1396           8 :     , mCausedByUntrustedEvent(false)
    1397             :   {
    1398           8 :   }
    1399             : 
    1400             : public:
    1401           0 :   virtual InternalUIEvent* AsUIEvent() override { return this; }
    1402             : 
    1403             :   /**
    1404             :    * If the UIEvent is caused by another event (e.g., click event),
    1405             :    * aEventCausesThisEvent should be the event.  If there is no such event,
    1406             :    * this should be nullptr.
    1407             :    */
    1408           0 :   InternalUIEvent(bool aIsTrusted, EventMessage aMessage,
    1409             :                   const WidgetEvent* aEventCausesThisEvent)
    1410           0 :     : WidgetGUIEvent(aIsTrusted, aMessage, nullptr, eUIEventClass)
    1411             :     , mDetail(0)
    1412             :     , mCausedByUntrustedEvent(
    1413           0 :         aEventCausesThisEvent && !aEventCausesThisEvent->IsTrusted())
    1414             :   {
    1415           0 :   }
    1416             : 
    1417           0 :   virtual WidgetEvent* Duplicate() const override
    1418             :   {
    1419           0 :     MOZ_ASSERT(mClass == eUIEventClass,
    1420             :                "Duplicate() must be overridden by sub class");
    1421           0 :     InternalUIEvent* result = new InternalUIEvent(false, mMessage, nullptr);
    1422           0 :     result->AssignUIEventData(*this, true);
    1423           0 :     result->mFlags = mFlags;
    1424           0 :     return result;
    1425             :   }
    1426             : 
    1427             :   int32_t mDetail;
    1428             :   // mCausedByUntrustedEvent is true if the event is caused by untrusted event.
    1429             :   bool mCausedByUntrustedEvent;
    1430             : 
    1431             :   // If you check the event is a trusted event and NOT caused by an untrusted
    1432             :   // event, IsTrustable() returns what you expected.
    1433           0 :   bool IsTrustable() const
    1434             :   {
    1435           0 :     return IsTrusted() && !mCausedByUntrustedEvent;
    1436             :   }
    1437             : 
    1438           0 :   void AssignUIEventData(const InternalUIEvent& aEvent, bool aCopyTargets)
    1439             :   {
    1440           0 :     AssignGUIEventData(aEvent, aCopyTargets);
    1441             : 
    1442           0 :     mDetail = aEvent.mDetail;
    1443           0 :     mCausedByUntrustedEvent = aEvent.mCausedByUntrustedEvent;
    1444           0 :   }
    1445             : };
    1446             : 
    1447             : } // namespace mozilla
    1448             : 
    1449             : #endif // mozilla_BasicEvents_h__

Generated by: LCOV version 1.13