1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_BasicEvents_h__
7 #define mozilla_BasicEvents_h__
10 #include <type_traits>
12 #include "mozilla/EventForwards.h"
13 #include "mozilla/TimeStamp.h"
14 #include "mozilla/dom/EventTarget.h"
15 #include "mozilla/layers/LayersTypes.h"
18 #include "nsISupportsImpl.h"
19 #include "nsIWidget.h"
24 # include "nsXULAppAPI.h"
25 #endif // #ifdef DEBUG
36 class EventTargetChainItem
;
38 enum class CrossProcessForwarding
{
39 // eStop prevents the event to be sent to remote process.
41 // eAllow keeps current state of the event whether it's sent to remote
42 // process. In other words, eAllow does NOT mean that making the event
43 // sent to remote process when IsCrossProcessForwardingStopped() returns
48 /******************************************************************************
49 * mozilla::BaseEventFlags
51 * BaseEventFlags must be a POD struct for safe to use memcpy (including
52 * in ParamTraits<BaseEventFlags>). So don't make virtual methods, constructor,
53 * destructor and operators.
54 * This is necessary for VC which is NOT C++0x compiler.
55 ******************************************************************************/
57 struct BaseEventFlags
{
59 // If mIsTrusted is true, the event is a trusted event. Otherwise, it's
60 // an untrusted event.
62 // If mInBubblingPhase is true, the event is in bubbling phase or target
64 bool mInBubblingPhase
: 1;
65 // If mInCapturePhase is true, the event is in capture phase or target phase.
66 bool mInCapturePhase
: 1;
67 // If mInTargetPhase is true, the event is in target phase.
68 bool mInTargetPhase
: 1;
69 // If mInSystemGroup is true, the event is being dispatched in system group.
70 bool mInSystemGroup
: 1;
71 // If mCancelable is true, the event can be consumed. I.e., calling
72 // dom::Event::PreventDefault() can prevent the default action.
74 // If mBubbles is true, the event can bubble. Otherwise, cannot be handled
77 // If mPropagationStopped is true, dom::Event::StopPropagation() or
78 // dom::Event::StopImmediatePropagation() has been called.
79 bool mPropagationStopped
: 1;
80 // If mImmediatePropagationStopped is true,
81 // dom::Event::StopImmediatePropagation() has been called.
82 // Note that mPropagationStopped must be true when this is true.
83 bool mImmediatePropagationStopped
: 1;
84 // If mDefaultPrevented is true, the event has been consumed.
85 // E.g., dom::Event::PreventDefault() has been called or
86 // the default action has been performed.
87 bool mDefaultPrevented
: 1;
88 // If mDefaultPreventedByContent is true, the event has been
89 // consumed by content.
90 // Note that mDefaultPrevented must be true when this is true.
91 bool mDefaultPreventedByContent
: 1;
92 // If mDefaultPreventedByChrome is true, the event has been
93 // consumed by chrome.
94 // Note that mDefaultPrevented must be true when this is true.
95 bool mDefaultPreventedByChrome
: 1;
96 // mMultipleActionsPrevented may be used when default handling don't want to
97 // be prevented, but only one of the event targets should handle the event.
98 // For example, when a <label> element is in another <label> element and
99 // the first <label> element is clicked, that one may set this true.
100 // Then, the second <label> element won't handle the event.
101 bool mMultipleActionsPrevented
: 1;
102 // Similar to above but expected to be used during PreHandleEvent phase.
103 bool mMultiplePreActionsPrevented
: 1;
104 // If mIsBeingDispatched is true, the DOM event created from the event is
105 // dispatching into the DOM tree and not completed.
106 bool mIsBeingDispatched
: 1;
107 // If mDispatchedAtLeastOnce is true, the event has been dispatched
108 // as a DOM event and the dispatch has been completed in the process.
109 // So, this is false even if the event has already been dispatched
110 // in another process.
111 bool mDispatchedAtLeastOnce
: 1;
112 // If mIsSynthesizedForTests is true, the event has been synthesized for
113 // automated tests or something hacky approach of an add-on.
114 bool mIsSynthesizedForTests
: 1;
115 // If mExceptionWasRaised is true, one of the event handlers has raised an
117 bool mExceptionWasRaised
: 1;
118 // If mRetargetToNonNativeAnonymous is true and the target is in a non-native
119 // native anonymous subtree, the event target is set to mOriginalTarget.
120 bool mRetargetToNonNativeAnonymous
: 1;
121 // If mNoContentDispatch is true, the event is never dispatched to the
122 // event handlers which are added to the contents, onfoo attributes and
123 // properties. Note that this flag is ignored when
124 // EventChainPreVisitor::mForceContentDispatch is set true. For exapmle,
125 // window and document object sets it true. Therefore, web applications
126 // can handle the event if they add event listeners to the window or the
128 // XXX This is an ancient and broken feature, don't use this for new bug
129 // as far as possible.
130 bool mNoContentDispatch
: 1;
131 // If mOnlyChromeDispatch is true, the event is dispatched to only chrome.
132 bool mOnlyChromeDispatch
: 1;
133 // Indicates if the key combination is reserved by chrome. This is set by
134 // MarkAsReservedByChrome().
135 bool mIsReservedByChrome
: 1;
136 // If mOnlySystemGroupDispatchInContent is true, event listeners added to
137 // the default group for non-chrome EventTarget won't be called.
138 // Be aware, if this is true, EventDispatcher needs to check if each event
139 // listener is added to chrome node, so, don't set this to true for the
140 // events which are fired a lot of times like eMouseMove.
141 bool mOnlySystemGroupDispatchInContent
: 1;
142 // If mOnlySystemGroupDispatch is true, the event will be dispatched only to
143 // event listeners added in the system group.
144 bool mOnlySystemGroupDispatch
: 1;
145 // The event's action will be handled by APZ. The main thread should not
146 // perform its associated action.
147 bool mHandledByAPZ
: 1;
148 // True if the event is currently being handled by an event listener that
149 // was registered as a passive listener.
150 bool mInPassiveListener
: 1;
151 // If mComposed is true, the event fired by nodes in shadow DOM can cross the
152 // boundary of shadow DOM and light DOM.
154 // Similar to mComposed. Set it to true to allow events cross the boundary
155 // between native non-anonymous content and native anonymouse content
156 bool mComposedInNativeAnonymousContent
: 1;
157 // Set to true for events which are suppressed or delayed so that later a
158 // DelayedEvent of it is dispatched. This is used when parent side process
159 // the key event after content side, and may drop the event if the event
160 // was suppressed or delayed in contents side.
161 // It is also set to true for the events (in a DelayedInputEvent), which will
162 // be dispatched afterwards.
163 bool mIsSuppressedOrDelayed
: 1;
164 // Certain mouse events can be marked as positionless to return 0 from
165 // coordinate related getters.
166 bool mIsPositionless
: 1;
168 // Flags managing state of propagation between processes.
169 // Note the the following flags shouldn't be referred directly. Use utility
172 // If mNoRemoteProcessDispatch is true, the event is not allowed to be sent
173 // to remote process.
174 bool mNoRemoteProcessDispatch
: 1;
175 // If mWantReplyFromContentProcess is true, the event will be redispatched
176 // in the parent process after the content process has handled it. Useful
177 // for when the parent process need the know first how the event was used
178 // by content before handling it itself.
179 bool mWantReplyFromContentProcess
: 1;
180 // If mPostedToRemoteProcess is true, the event has been posted to the
181 // remote process (but it's not handled yet if it's not a duplicated event
183 bool mPostedToRemoteProcess
: 1;
184 // If mCameFromAnotherProcess is true, the event came from another process.
185 bool mCameFromAnotherProcess
: 1;
188 * Helper methods for methods of DOM Event.
190 inline void StopPropagation() { mPropagationStopped
= true; }
191 inline void StopImmediatePropagation() {
193 mImmediatePropagationStopped
= true;
195 inline void PreventDefault(bool aCalledByDefaultHandler
= true) {
199 mDefaultPrevented
= true;
200 // Note that even if preventDefault() has already been called by chrome,
201 // a call of preventDefault() by content needs to overwrite
202 // mDefaultPreventedByContent to true because in such case, defaultPrevented
203 // must be true when web apps check it after they call preventDefault().
204 if (aCalledByDefaultHandler
) {
205 StopCrossProcessForwarding();
206 mDefaultPreventedByChrome
= true;
208 mDefaultPreventedByContent
= true;
211 // This should be used only before dispatching events into the DOM tree.
212 inline void PreventDefaultBeforeDispatch(
213 CrossProcessForwarding aCrossProcessForwarding
) {
217 mDefaultPrevented
= true;
218 if (aCrossProcessForwarding
== CrossProcessForwarding::eStop
) {
219 StopCrossProcessForwarding();
222 inline bool DefaultPrevented() const { return mDefaultPrevented
; }
223 inline bool DefaultPreventedByContent() const {
224 MOZ_ASSERT(!mDefaultPreventedByContent
|| DefaultPrevented());
225 return mDefaultPreventedByContent
;
227 inline bool IsTrusted() const { return mIsTrusted
; }
228 inline bool PropagationStopped() const { return mPropagationStopped
; }
230 // Helper methods to access flags managing state of propagation between
234 * Prevent to be dispatched to remote process.
236 inline void StopCrossProcessForwarding() {
237 MOZ_ASSERT(!mPostedToRemoteProcess
);
238 mNoRemoteProcessDispatch
= true;
239 mWantReplyFromContentProcess
= false;
242 * Return true if the event shouldn't be dispatched to remote process.
244 inline bool IsCrossProcessForwardingStopped() const {
245 return mNoRemoteProcessDispatch
;
248 * Mark the event as waiting reply from remote process.
249 * If the caller needs to win other keyboard event handlers in chrome,
250 * the caller should call StopPropagation() too.
251 * Otherwise, if the caller just needs to know if the event is consumed by
252 * either content or chrome, it should just call this because the event
253 * may be reserved by chrome and it needs to be dispatched into the DOM
254 * tree in chrome for checking if it's reserved before being sent to any
257 inline void MarkAsWaitingReplyFromRemoteProcess() {
258 MOZ_ASSERT(!mPostedToRemoteProcess
);
259 mNoRemoteProcessDispatch
= false;
260 mWantReplyFromContentProcess
= true;
263 * Reset "waiting reply from remote process" state. This is useful when
264 * you dispatch a copy of an event coming from different process.
266 inline void ResetWaitingReplyFromRemoteProcessState() {
267 if (IsWaitingReplyFromRemoteProcess()) {
268 // FYI: mWantReplyFromContentProcess is also used for indicating
269 // "handled in remote process" state. Therefore, only when
270 // IsWaitingReplyFromRemoteProcess() returns true, this should
272 mWantReplyFromContentProcess
= false;
276 * Return true if the event handler should wait reply event. I.e., if this
277 * returns true, any event handler should do nothing with the event.
279 inline bool IsWaitingReplyFromRemoteProcess() const {
280 return !mNoRemoteProcessDispatch
&& mWantReplyFromContentProcess
;
283 * Mark the event as already handled in the remote process. This should be
284 * called when initializing reply events.
286 inline void MarkAsHandledInRemoteProcess() {
287 mNoRemoteProcessDispatch
= true;
288 mWantReplyFromContentProcess
= true;
289 mPostedToRemoteProcess
= false;
292 * Return true if the event has already been handled in the remote process.
294 inline bool IsHandledInRemoteProcess() const {
295 return mNoRemoteProcessDispatch
&& mWantReplyFromContentProcess
;
298 * Return true if the event should be sent back to its parent process.
300 inline bool WantReplyFromContentProcess() const {
301 MOZ_ASSERT(!XRE_IsParentProcess());
302 return IsWaitingReplyFromRemoteProcess();
305 * Mark the event has already posted to a remote process.
307 inline void MarkAsPostedToRemoteProcess() {
308 MOZ_ASSERT(!IsCrossProcessForwardingStopped());
309 mPostedToRemoteProcess
= true;
312 * Reset the cross process dispatching state. This should be used when a
313 * process receives the event because the state is in the sender.
315 inline void ResetCrossProcessDispatchingState() {
316 MOZ_ASSERT(!IsCrossProcessForwardingStopped());
317 mPostedToRemoteProcess
= false;
318 // Ignore propagation state in the remote process if it's marked as
319 // "waiting reply from remote process" because the process needs to
320 // stop propagation in the process until receiving a reply event.
321 // Note that the propagation stopped flag is important for the reply event
322 // handler in the main process because it's used for making whether it's
323 // ignored by the remote process or not.
324 if (!XRE_IsParentProcess() && IsWaitingReplyFromRemoteProcess()) {
325 mPropagationStopped
= mImmediatePropagationStopped
= false;
327 // mDispatchedAtLeastOnce indicates the state in current process.
328 mDispatchedAtLeastOnce
= false;
331 * Return true if the event has been posted to a remote process.
332 * Note that MarkAsPostedToRemoteProcess() is called by
333 * ParamTraits<mozilla::WidgetEvent>. Therefore, it *might* be possible
334 * that posting the event failed even if this returns true. But that must
335 * really rare. If that'd be problem for you, you should unmark this in
336 * BrowserParent or somewhere.
338 inline bool HasBeenPostedToRemoteProcess() const {
339 return mPostedToRemoteProcess
;
342 * Return true if the event came from another process.
344 inline bool CameFromAnotherProcess() const { return mCameFromAnotherProcess
; }
346 * Mark the event as coming from another process.
348 inline void MarkAsComingFromAnotherProcess() {
349 mCameFromAnotherProcess
= true;
352 * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to
353 * content because it shouldn't be cancelable.
355 inline void MarkAsReservedByChrome() {
356 MOZ_ASSERT(!mPostedToRemoteProcess
);
357 mIsReservedByChrome
= true;
358 // For reserved commands (such as Open New Tab), we don't need to wait for
359 // the content to answer, neither to give a chance for content to override
361 StopCrossProcessForwarding();
362 // If the event is reserved by chrome, we shouldn't expose the event to
363 // web contents because such events shouldn't be cancelable. So, it's not
364 // good behavior to fire such events but to ignore the defaultPrevented
365 // attribute value in chrome.
366 mOnlySystemGroupDispatchInContent
= true;
369 * Return true if the event is reserved by chrome.
371 inline bool IsReservedByChrome() const {
372 MOZ_ASSERT(!mIsReservedByChrome
|| (IsCrossProcessForwardingStopped() &&
373 mOnlySystemGroupDispatchInContent
));
374 return mIsReservedByChrome
;
377 inline void Clear() { SetRawFlags(0); }
378 // Get if either the instance's bit or the aOther's bit is true, the
379 // instance's bit becomes true. In other words, this works like:
380 // eventFlags |= aOther;
381 inline void Union(const BaseEventFlags
& aOther
) {
382 RawFlags rawFlags
= GetRawFlags() | aOther
.GetRawFlags();
383 SetRawFlags(rawFlags
);
387 typedef uint64_t RawFlags
;
389 inline void SetRawFlags(RawFlags aRawFlags
) {
390 static_assert(sizeof(BaseEventFlags
) <= sizeof(RawFlags
),
391 "mozilla::EventFlags must not be bigger than the RawFlags");
392 memcpy(this, &aRawFlags
, sizeof(BaseEventFlags
));
394 inline RawFlags
GetRawFlags() const {
396 memcpy(&result
, this, sizeof(BaseEventFlags
));
401 /******************************************************************************
402 * mozilla::EventFlags
403 ******************************************************************************/
405 struct EventFlags
: public BaseEventFlags
{
406 EventFlags() { Clear(); }
409 /******************************************************************************
410 * mozilla::WidgetEventTime
411 ******************************************************************************/
413 class WidgetEventTime
{
415 // Timestamp when the message was created.
416 TimeStamp mTimeStamp
;
418 WidgetEventTime() : mTimeStamp(TimeStamp::Now()) {}
420 explicit WidgetEventTime(TimeStamp aTimeStamp
) : mTimeStamp(aTimeStamp
) {}
422 void AssignEventTime(const WidgetEventTime
& aOther
) {
423 mTimeStamp
= aOther
.mTimeStamp
;
427 /******************************************************************************
428 * mozilla::WidgetEvent
429 ******************************************************************************/
431 class WidgetEvent
: public WidgetEventTime
{
433 void SetDefaultCancelableAndBubbles() {
435 case eEditorInputEventClass
:
436 mFlags
.mCancelable
= false;
437 mFlags
.mBubbles
= mFlags
.mIsTrusted
;
439 case eMouseEventClass
:
441 (mMessage
!= eMouseEnter
&& mMessage
!= eMouseLeave
);
442 mFlags
.mBubbles
= (mMessage
!= eMouseEnter
&& mMessage
!= eMouseLeave
);
444 case ePointerEventClass
:
446 (mMessage
!= ePointerEnter
&& mMessage
!= ePointerLeave
&&
447 mMessage
!= ePointerCancel
&& mMessage
!= ePointerGotCapture
&&
448 mMessage
!= ePointerLostCapture
);
450 (mMessage
!= ePointerEnter
&& mMessage
!= ePointerLeave
);
452 case eDragEventClass
:
453 mFlags
.mCancelable
= (mMessage
!= eDragExit
&& mMessage
!= eDragLeave
&&
454 mMessage
!= eDragEnd
);
455 mFlags
.mBubbles
= true;
457 case eSMILTimeEventClass
:
458 mFlags
.mCancelable
= false;
459 mFlags
.mBubbles
= false;
461 case eTransitionEventClass
:
462 case eAnimationEventClass
:
463 mFlags
.mCancelable
= false;
464 mFlags
.mBubbles
= true;
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 mFlags
.mCancelable
= false;
471 mFlags
.mBubbles
= true;
474 if (mMessage
== eResize
|| mMessage
== eMozVisualResize
||
475 mMessage
== eMozVisualScroll
|| mMessage
== eEditorInput
||
476 mMessage
== eFormSelect
) {
477 mFlags
.mCancelable
= false;
479 mFlags
.mCancelable
= true;
481 mFlags
.mBubbles
= true;
487 WidgetEvent(bool aIsTrusted
, EventMessage aMessage
,
488 EventClassID aEventClassID
)
490 mClass(aEventClassID
),
494 mFocusSequenceNumber(0),
495 mSpecifiedEventType(nullptr),
497 mLayersId(layers::LayersId
{0}) {
498 MOZ_COUNT_CTOR(WidgetEvent
);
500 mFlags
.mIsTrusted
= aIsTrusted
;
501 SetDefaultCancelableAndBubbles();
502 SetDefaultComposed();
503 SetDefaultComposedInNativeAnonymousContent();
506 WidgetEvent() : WidgetEventTime(), mPath(nullptr) {
507 MOZ_COUNT_CTOR(WidgetEvent
);
511 WidgetEvent(bool aIsTrusted
, EventMessage aMessage
)
512 : WidgetEvent(aIsTrusted
, aMessage
, eBasicEventClass
) {}
514 MOZ_COUNTED_DTOR_VIRTUAL(WidgetEvent
)
516 WidgetEvent(const WidgetEvent
& aOther
) : WidgetEventTime() {
517 MOZ_COUNT_CTOR(WidgetEvent
);
520 WidgetEvent
& operator=(const WidgetEvent
& aOther
) = default;
522 WidgetEvent(WidgetEvent
&& aOther
)
523 : WidgetEventTime(std::move(aOther
)),
524 mClass(aOther
.mClass
),
525 mMessage(aOther
.mMessage
),
526 mRefPoint(std::move(aOther
.mRefPoint
)),
527 mLastRefPoint(std::move(aOther
.mLastRefPoint
)),
528 mFocusSequenceNumber(aOther
.mFocusSequenceNumber
),
529 mFlags(std::move(aOther
.mFlags
)),
530 mSpecifiedEventType(std::move(aOther
.mSpecifiedEventType
)),
531 mSpecifiedEventTypeString(std::move(aOther
.mSpecifiedEventTypeString
)),
532 mTarget(std::move(aOther
.mTarget
)),
533 mCurrentTarget(std::move(aOther
.mCurrentTarget
)),
534 mOriginalTarget(std::move(aOther
.mOriginalTarget
)),
535 mRelatedTarget(std::move(aOther
.mRelatedTarget
)),
536 mOriginalRelatedTarget(std::move(aOther
.mOriginalRelatedTarget
)),
537 mPath(std::move(aOther
.mPath
)) {
538 MOZ_COUNT_CTOR(WidgetEvent
);
540 WidgetEvent
& operator=(WidgetEvent
&& aOther
) = default;
542 virtual WidgetEvent
* Duplicate() const {
543 MOZ_ASSERT(mClass
== eBasicEventClass
,
544 "Duplicate() must be overridden by sub class");
545 WidgetEvent
* result
= new WidgetEvent(false, mMessage
);
546 result
->AssignEventData(*this, true);
547 result
->mFlags
= mFlags
;
552 EventMessage mMessage
;
553 // Relative to the widget of the event, or if there is no widget then it is
554 // in screen coordinates. Not modified by layout code.
555 // This is in visual coordinates, i.e. the correct RelativeTo value that
556 // expresses what this is relative to is `{viewportFrame, Visual}`, where
557 // `viewportFrame` is the viewport frame of the widget's root document.
558 LayoutDeviceIntPoint mRefPoint
;
559 // The previous mRefPoint, if known, used to calculate mouse movement deltas.
560 LayoutDeviceIntPoint mLastRefPoint
;
561 // The sequence number of the last potentially focus changing event handled
562 // by APZ. This is used to track when that event has been processed by
563 // content, and focus can be reconfirmed for async keyboard scrolling.
564 uint64_t mFocusSequenceNumber
;
565 // See BaseEventFlags definition for the detail.
566 BaseEventFlags mFlags
;
568 // If JS creates an event with unknown event type or known event type but
569 // for different event interface, the event type is stored to this.
570 // NOTE: This is always used if the instance is a WidgetCommandEvent instance
571 // or "input" event is dispatched with dom::Event class.
572 RefPtr
<nsAtom
> mSpecifiedEventType
;
574 // nsAtom isn't available on non-main thread due to unsafe. Therefore,
575 // mSpecifiedEventTypeString is used instead of mSpecifiedEventType if
576 // the event is created in non-main thread.
577 nsString mSpecifiedEventTypeString
;
579 // Event targets, needed by DOM Events
580 // Note that when you need event target for DOM event, you should use
581 // Get*DOMEventTarget() instead of accessing these members directly.
582 nsCOMPtr
<dom::EventTarget
> mTarget
;
583 nsCOMPtr
<dom::EventTarget
> mCurrentTarget
;
584 nsCOMPtr
<dom::EventTarget
> mOriginalTarget
;
586 /// The possible related target
587 nsCOMPtr
<dom::EventTarget
> mRelatedTarget
;
588 nsCOMPtr
<dom::EventTarget
> mOriginalRelatedTarget
;
590 nsTArray
<EventTargetChainItem
>* mPath
;
592 // The LayersId of the content process that this event should be
593 // dispatched to. This field is only used in the chrome process
594 // and doesn't get remoted to child processes.
595 layers::LayersId mLayersId
;
597 dom::EventTarget
* GetDOMEventTarget() const;
598 dom::EventTarget
* GetCurrentDOMEventTarget() const;
599 dom::EventTarget
* GetOriginalDOMEventTarget() const;
601 void AssignEventData(const WidgetEvent
& aEvent
, bool aCopyTargets
) {
602 // mClass should be initialized with the constructor.
603 // mMessage should be initialized with the constructor.
604 mRefPoint
= aEvent
.mRefPoint
;
605 // mLastRefPoint doesn't need to be copied.
606 mFocusSequenceNumber
= aEvent
.mFocusSequenceNumber
;
607 // mLayersId intentionally not copied, since it's not used within content
608 AssignEventTime(aEvent
);
609 // mFlags should be copied manually if it's necessary.
610 mSpecifiedEventType
= aEvent
.mSpecifiedEventType
;
611 // mSpecifiedEventTypeString should be copied manually if it's necessary.
612 mTarget
= aCopyTargets
? aEvent
.mTarget
: nullptr;
613 mCurrentTarget
= aCopyTargets
? aEvent
.mCurrentTarget
: nullptr;
614 mOriginalTarget
= aCopyTargets
? aEvent
.mOriginalTarget
: nullptr;
615 mRelatedTarget
= aCopyTargets
? aEvent
.mRelatedTarget
: nullptr;
616 mOriginalRelatedTarget
=
617 aCopyTargets
? aEvent
.mOriginalRelatedTarget
: nullptr;
621 * Helper methods for methods of DOM Event.
623 void StopPropagation() { mFlags
.StopPropagation(); }
624 void StopImmediatePropagation() { mFlags
.StopImmediatePropagation(); }
625 void PreventDefault(bool aCalledByDefaultHandler
= true,
626 nsIPrincipal
* aPrincipal
= nullptr);
628 void PreventDefaultBeforeDispatch(
629 CrossProcessForwarding aCrossProcessForwarding
) {
630 mFlags
.PreventDefaultBeforeDispatch(aCrossProcessForwarding
);
632 bool DefaultPrevented() const { return mFlags
.DefaultPrevented(); }
633 bool DefaultPreventedByContent() const {
634 return mFlags
.DefaultPreventedByContent();
636 bool IsTrusted() const { return mFlags
.IsTrusted(); }
637 bool PropagationStopped() const { return mFlags
.PropagationStopped(); }
640 * Prevent to be dispatched to remote process.
642 inline void StopCrossProcessForwarding() {
643 mFlags
.StopCrossProcessForwarding();
646 * Return true if the event shouldn't be dispatched to remote process.
648 inline bool IsCrossProcessForwardingStopped() const {
649 return mFlags
.IsCrossProcessForwardingStopped();
652 * Mark the event as waiting reply from remote process.
653 * Note that this also stops immediate propagation in current process.
655 inline void MarkAsWaitingReplyFromRemoteProcess() {
656 mFlags
.MarkAsWaitingReplyFromRemoteProcess();
659 * Reset "waiting reply from remote process" state. This is useful when
660 * you dispatch a copy of an event coming from different process.
662 inline void ResetWaitingReplyFromRemoteProcessState() {
663 mFlags
.ResetWaitingReplyFromRemoteProcessState();
666 * Return true if the event handler should wait reply event. I.e., if this
667 * returns true, any event handler should do nothing with the event.
669 inline bool IsWaitingReplyFromRemoteProcess() const {
670 return mFlags
.IsWaitingReplyFromRemoteProcess();
673 * Mark the event as already handled in the remote process. This should be
674 * called when initializing reply events.
676 inline void MarkAsHandledInRemoteProcess() {
677 mFlags
.MarkAsHandledInRemoteProcess();
680 * Return true if the event has already been handled in the remote process.
681 * I.e., if this returns true, the event is a reply event.
683 inline bool IsHandledInRemoteProcess() const {
684 return mFlags
.IsHandledInRemoteProcess();
687 * Return true if the event should be sent back to its parent process.
688 * So, usual event handlers shouldn't call this.
690 inline bool WantReplyFromContentProcess() const {
691 return mFlags
.WantReplyFromContentProcess();
694 * Mark the event has already posted to a remote process.
696 inline void MarkAsPostedToRemoteProcess() {
697 mFlags
.MarkAsPostedToRemoteProcess();
700 * Reset the cross process dispatching state. This should be used when a
701 * process receives the event because the state is in the sender.
703 inline void ResetCrossProcessDispatchingState() {
704 mFlags
.ResetCrossProcessDispatchingState();
707 * Return true if the event has been posted to a remote process.
709 inline bool HasBeenPostedToRemoteProcess() const {
710 return mFlags
.HasBeenPostedToRemoteProcess();
713 * Return true if the event came from another process.
715 inline bool CameFromAnotherProcess() const {
716 return mFlags
.CameFromAnotherProcess();
719 * Mark the event as coming from another process.
721 inline void MarkAsComingFromAnotherProcess() {
722 mFlags
.MarkAsComingFromAnotherProcess();
725 * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to
726 * content because it shouldn't be cancelable.
728 inline void MarkAsReservedByChrome() { mFlags
.MarkAsReservedByChrome(); }
730 * Return true if the event is reserved by chrome.
732 inline bool IsReservedByChrome() const { return mFlags
.IsReservedByChrome(); }
735 * Utils for checking event types
739 * As*Event() returns the pointer of the instance only when the instance is
740 * the class or one of its derived class.
742 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
743 #define NS_EVENT_CLASS(aPrefix, aName) \
744 virtual aPrefix##aName* As##aName(); \
745 const aPrefix##aName* As##aName() const;
747 #include "mozilla/EventClassList.h"
749 #undef NS_EVENT_CLASS
750 #undef NS_ROOT_EVENT_CLASS
753 * Returns true if the event is a query content event.
755 bool IsQueryContentEvent() const;
757 * Returns true if the event is a selection event.
759 bool IsSelectionEvent() const;
761 * Returns true if the event is a content command event.
763 bool IsContentCommandEvent() const;
766 * Returns true if the event mMessage is one of mouse events.
768 bool HasMouseEventMessage() const;
770 * Returns true if the event mMessage is one of drag events.
772 bool HasDragEventMessage() const;
774 * Returns true if aMessage or mMessage is one of key events.
776 static bool IsKeyEventMessage(EventMessage aMessage
);
777 bool HasKeyEventMessage() const { return IsKeyEventMessage(mMessage
); }
779 * Returns true if the event mMessage is one of composition events or text
782 bool HasIMEEventMessage() const;
785 * Returns true if the event can be sent to remote process.
787 bool CanBeSentToRemoteProcess() const;
789 * Returns true if the original target is a remote process and the event
790 * will be posted to the remote process later.
792 bool WillBeSentToRemoteProcess() const;
794 * Returns true if the event is related to IME handling. It includes
795 * IME events, query content events and selection events.
796 * Be careful when you use this.
798 bool IsIMERelatedEvent() const;
801 * Whether the event should be handled by the frame of the mouse cursor
802 * position or not. When it should be handled there (e.g., the mouse events),
805 bool IsUsingCoordinates() const;
807 * Whether the event should be handled by the focused DOM window in the
808 * same top level window's or not. E.g., key events, IME related events
809 * (including the query content events, they are used in IME transaction)
810 * should be handled by the (last) focused window rather than the dispatched
813 * NOTE: Even if this returns true, the event isn't going to be handled by the
814 * application level active DOM window which is on another top level window.
815 * So, when the event is fired on a deactive window, the event is going to be
816 * handled by the last focused DOM window in the last focused window.
818 bool IsTargetedAtFocusedWindow() const;
820 * Whether the event should be handled by the focused content or not. E.g.,
821 * key events, IME related events and other input events which are not handled
822 * by the frame of the mouse cursor position.
824 * NOTE: Even if this returns true, the event isn't going to be handled by the
825 * application level active DOM window which is on another top level window.
826 * So, when the event is fired on a deactive window, the event is going to be
827 * handled by the last focused DOM element of the last focused DOM window in
828 * the last focused window.
830 bool IsTargetedAtFocusedContent() const;
832 * Whether the event should cause a DOM event.
834 bool IsAllowedToDispatchDOMEvent() const;
836 * Whether the event should be dispatched in system group.
838 bool IsAllowedToDispatchInSystemGroup() const;
840 * Whether the event should be blocked for fingerprinting resistance.
842 bool IsBlockedForFingerprintingResistance() const;
844 * Whether the event handler can flush pending notifications or not.
846 bool AllowFlushingPendingNotifications() const;
848 * Initialize mComposed
850 void SetDefaultComposed() {
852 case eClipboardEventClass
:
853 mFlags
.mComposed
= true;
855 case eCompositionEventClass
:
857 mMessage
== eCompositionStart
|| mMessage
== eCompositionUpdate
||
858 mMessage
== eCompositionChange
|| mMessage
== eCompositionEnd
;
860 case eDragEventClass
:
861 // All drag & drop events are composed
862 mFlags
.mComposed
= mMessage
== eDrag
|| mMessage
== eDragEnd
||
863 mMessage
== eDragEnter
|| mMessage
== eDragExit
||
864 mMessage
== eDragLeave
|| mMessage
== eDragOver
||
865 mMessage
== eDragStart
|| mMessage
== eDrop
;
867 case eEditorInputEventClass
:
869 mMessage
== eEditorInput
|| mMessage
== eEditorBeforeInput
;
871 case eFocusEventClass
:
872 mFlags
.mComposed
= mMessage
== eBlur
|| mMessage
== eFocus
||
873 mMessage
== eFocusOut
|| mMessage
== eFocusIn
;
875 case eKeyboardEventClass
:
877 mMessage
== eKeyDown
|| mMessage
== eKeyUp
|| mMessage
== eKeyPress
;
879 case eMouseEventClass
:
881 mMessage
== eMouseClick
|| mMessage
== eMouseDoubleClick
||
882 mMessage
== eMouseAuxClick
|| mMessage
== eMouseDown
||
883 mMessage
== eMouseUp
|| mMessage
== eMouseOver
||
884 mMessage
== eMouseOut
|| mMessage
== eMouseMove
||
885 mMessage
== eContextMenu
|| mMessage
== eXULPopupShowing
||
886 mMessage
== eXULPopupHiding
|| mMessage
== eXULPopupShown
||
887 mMessage
== eXULPopupHidden
;
889 case ePointerEventClass
:
890 // All pointer events are composed
892 mMessage
== ePointerDown
|| mMessage
== ePointerMove
||
893 mMessage
== ePointerUp
|| mMessage
== ePointerCancel
||
894 mMessage
== ePointerOver
|| mMessage
== ePointerOut
||
895 mMessage
== ePointerGotCapture
|| mMessage
== ePointerLostCapture
;
897 case eTouchEventClass
:
898 // All touch events are composed
899 mFlags
.mComposed
= mMessage
== eTouchStart
|| mMessage
== eTouchEnd
||
900 mMessage
== eTouchMove
|| mMessage
== eTouchCancel
;
903 mFlags
.mComposed
= mMessage
== eLegacyDOMFocusIn
||
904 mMessage
== eLegacyDOMFocusOut
||
905 mMessage
== eLegacyDOMActivate
;
907 case eWheelEventClass
:
908 // All wheel events are composed
909 mFlags
.mComposed
= mMessage
== eWheel
;
911 case eMouseScrollEventClass
:
912 // Legacy mouse scroll events are composed too, for consistency with
914 mFlags
.mComposed
= mMessage
== eLegacyMouseLineOrPageScroll
||
915 mMessage
== eLegacyMousePixelScroll
;
918 mFlags
.mComposed
= false;
923 void SetComposed(const nsAString
& aEventTypeArg
) {
924 mFlags
.mComposed
= // composition events
925 aEventTypeArg
.EqualsLiteral("compositionstart") ||
926 aEventTypeArg
.EqualsLiteral("compositionupdate") ||
927 aEventTypeArg
.EqualsLiteral("compositionend") ||
928 aEventTypeArg
.EqualsLiteral("text") ||
929 // drag and drop events
930 aEventTypeArg
.EqualsLiteral("dragstart") ||
931 aEventTypeArg
.EqualsLiteral("drag") ||
932 aEventTypeArg
.EqualsLiteral("dragenter") ||
933 aEventTypeArg
.EqualsLiteral("dragexit") ||
934 aEventTypeArg
.EqualsLiteral("dragleave") ||
935 aEventTypeArg
.EqualsLiteral("dragover") ||
936 aEventTypeArg
.EqualsLiteral("drop") ||
937 aEventTypeArg
.EqualsLiteral("dropend") ||
938 // editor input events
939 aEventTypeArg
.EqualsLiteral("input") ||
940 aEventTypeArg
.EqualsLiteral("beforeinput") ||
942 aEventTypeArg
.EqualsLiteral("blur") ||
943 aEventTypeArg
.EqualsLiteral("focus") ||
944 aEventTypeArg
.EqualsLiteral("focusin") ||
945 aEventTypeArg
.EqualsLiteral("focusout") ||
947 aEventTypeArg
.EqualsLiteral("keydown") ||
948 aEventTypeArg
.EqualsLiteral("keyup") ||
949 aEventTypeArg
.EqualsLiteral("keypress") ||
951 aEventTypeArg
.EqualsLiteral("click") ||
952 aEventTypeArg
.EqualsLiteral("dblclick") ||
953 aEventTypeArg
.EqualsLiteral("mousedown") ||
954 aEventTypeArg
.EqualsLiteral("mouseup") ||
955 aEventTypeArg
.EqualsLiteral("mouseenter") ||
956 aEventTypeArg
.EqualsLiteral("mouseleave") ||
957 aEventTypeArg
.EqualsLiteral("mouseover") ||
958 aEventTypeArg
.EqualsLiteral("mouseout") ||
959 aEventTypeArg
.EqualsLiteral("mousemove") ||
960 aEventTypeArg
.EqualsLiteral("contextmenu") ||
962 aEventTypeArg
.EqualsLiteral("pointerdown") ||
963 aEventTypeArg
.EqualsLiteral("pointermove") ||
964 aEventTypeArg
.EqualsLiteral("pointerup") ||
965 aEventTypeArg
.EqualsLiteral("pointercancel") ||
966 aEventTypeArg
.EqualsLiteral("pointerover") ||
967 aEventTypeArg
.EqualsLiteral("pointerout") ||
968 aEventTypeArg
.EqualsLiteral("pointerenter") ||
969 aEventTypeArg
.EqualsLiteral("pointerleave") ||
970 aEventTypeArg
.EqualsLiteral("gotpointercapture") ||
971 aEventTypeArg
.EqualsLiteral("lostpointercapture") ||
973 aEventTypeArg
.EqualsLiteral("touchstart") ||
974 aEventTypeArg
.EqualsLiteral("touchend") ||
975 aEventTypeArg
.EqualsLiteral("touchmove") ||
976 aEventTypeArg
.EqualsLiteral("touchcancel") ||
978 aEventTypeArg
.EqualsLiteral("DOMFocusIn") ||
979 aEventTypeArg
.EqualsLiteral("DOMFocusOut") ||
980 aEventTypeArg
.EqualsLiteral("DOMActivate") ||
982 aEventTypeArg
.EqualsLiteral("wheel");
985 void SetComposed(bool aComposed
) { mFlags
.mComposed
= aComposed
; }
987 void SetDefaultComposedInNativeAnonymousContent() {
988 // For compatibility concerns, we set mComposedInNativeAnonymousContent to
989 // false for those events we want to stop propagation.
991 // nsVideoFrame may create anonymous image element which fires eLoad,
992 // eLoadStart, eLoadEnd, eLoadError. We don't want these events cross
993 // the boundary of NAC
994 mFlags
.mComposedInNativeAnonymousContent
=
995 mMessage
!= eLoad
&& mMessage
!= eLoadStart
&& mMessage
!= eLoadEnd
&&
996 mMessage
!= eLoadError
;
999 bool IsUserAction() const;
1002 /******************************************************************************
1003 * mozilla::WidgetGUIEvent
1004 ******************************************************************************/
1006 class WidgetGUIEvent
: public WidgetEvent
{
1008 WidgetGUIEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
1009 EventClassID aEventClassID
)
1010 : WidgetEvent(aIsTrusted
, aMessage
, aEventClassID
), mWidget(aWidget
) {}
1012 WidgetGUIEvent() = default;
1015 virtual WidgetGUIEvent
* AsGUIEvent() override
{ return this; }
1017 WidgetGUIEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
)
1018 : WidgetEvent(aIsTrusted
, aMessage
, eGUIEventClass
), mWidget(aWidget
) {}
1020 virtual WidgetEvent
* Duplicate() const override
{
1021 MOZ_ASSERT(mClass
== eGUIEventClass
,
1022 "Duplicate() must be overridden by sub class");
1023 // Not copying widget, it is a weak reference.
1024 WidgetGUIEvent
* result
= new WidgetGUIEvent(false, mMessage
, nullptr);
1025 result
->AssignGUIEventData(*this, true);
1026 result
->mFlags
= mFlags
;
1030 // Originator of the event
1031 nsCOMPtr
<nsIWidget
> mWidget
;
1033 void AssignGUIEventData(const WidgetGUIEvent
& aEvent
, bool aCopyTargets
) {
1034 AssignEventData(aEvent
, aCopyTargets
);
1035 // widget should be initialized with the constructor.
1039 /******************************************************************************
1042 * All modifier keys should be defined here. This is used for managing
1043 * modifier states for DOM Level 3 or later.
1044 ******************************************************************************/
1047 MODIFIER_NONE
= 0x0000,
1048 MODIFIER_ALT
= 0x0001,
1049 MODIFIER_ALTGRAPH
= 0x0002,
1050 MODIFIER_CAPSLOCK
= 0x0004,
1051 MODIFIER_CONTROL
= 0x0008,
1052 MODIFIER_FN
= 0x0010,
1053 MODIFIER_FNLOCK
= 0x0020,
1054 MODIFIER_META
= 0x0040,
1055 MODIFIER_NUMLOCK
= 0x0080,
1056 MODIFIER_SCROLLLOCK
= 0x0100,
1057 MODIFIER_SHIFT
= 0x0200,
1058 MODIFIER_SYMBOL
= 0x0400,
1059 MODIFIER_SYMBOLLOCK
= 0x0800,
1062 /******************************************************************************
1063 * Modifier key names.
1064 ******************************************************************************/
1066 #define NS_DOM_KEYNAME_ALT "Alt"
1067 #define NS_DOM_KEYNAME_ALTGRAPH "AltGraph"
1068 #define NS_DOM_KEYNAME_CAPSLOCK "CapsLock"
1069 #define NS_DOM_KEYNAME_CONTROL "Control"
1070 #define NS_DOM_KEYNAME_FN "Fn"
1071 #define NS_DOM_KEYNAME_FNLOCK "FnLock"
1072 #define NS_DOM_KEYNAME_META "Meta"
1073 #define NS_DOM_KEYNAME_NUMLOCK "NumLock"
1074 #define NS_DOM_KEYNAME_SCROLLLOCK "ScrollLock"
1075 #define NS_DOM_KEYNAME_SHIFT "Shift"
1076 #define NS_DOM_KEYNAME_SYMBOL "Symbol"
1077 #define NS_DOM_KEYNAME_SYMBOLLOCK "SymbolLock"
1078 #define NS_DOM_KEYNAME_OS "OS"
1080 /******************************************************************************
1081 * mozilla::Modifiers
1082 ******************************************************************************/
1084 typedef uint16_t Modifiers
;
1086 class MOZ_STACK_CLASS GetModifiersName final
: public nsAutoCString
{
1088 explicit GetModifiersName(Modifiers aModifiers
) {
1089 if (aModifiers
& MODIFIER_ALT
) {
1090 AssignLiteral(NS_DOM_KEYNAME_ALT
);
1092 if (aModifiers
& MODIFIER_ALTGRAPH
) {
1093 MaybeAppendSeparator();
1094 AppendLiteral(NS_DOM_KEYNAME_ALTGRAPH
);
1096 if (aModifiers
& MODIFIER_CAPSLOCK
) {
1097 MaybeAppendSeparator();
1098 AppendLiteral(NS_DOM_KEYNAME_CAPSLOCK
);
1100 if (aModifiers
& MODIFIER_CONTROL
) {
1101 MaybeAppendSeparator();
1102 AppendLiteral(NS_DOM_KEYNAME_CONTROL
);
1104 if (aModifiers
& MODIFIER_FN
) {
1105 MaybeAppendSeparator();
1106 AppendLiteral(NS_DOM_KEYNAME_FN
);
1108 if (aModifiers
& MODIFIER_FNLOCK
) {
1109 MaybeAppendSeparator();
1110 AppendLiteral(NS_DOM_KEYNAME_FNLOCK
);
1112 if (aModifiers
& MODIFIER_META
) {
1113 MaybeAppendSeparator();
1114 AppendLiteral(NS_DOM_KEYNAME_META
);
1116 if (aModifiers
& MODIFIER_NUMLOCK
) {
1117 MaybeAppendSeparator();
1118 AppendLiteral(NS_DOM_KEYNAME_NUMLOCK
);
1120 if (aModifiers
& MODIFIER_SCROLLLOCK
) {
1121 MaybeAppendSeparator();
1122 AppendLiteral(NS_DOM_KEYNAME_SCROLLLOCK
);
1124 if (aModifiers
& MODIFIER_SHIFT
) {
1125 MaybeAppendSeparator();
1126 AppendLiteral(NS_DOM_KEYNAME_SHIFT
);
1128 if (aModifiers
& MODIFIER_SYMBOL
) {
1129 MaybeAppendSeparator();
1130 AppendLiteral(NS_DOM_KEYNAME_SYMBOL
);
1132 if (aModifiers
& MODIFIER_SYMBOLLOCK
) {
1133 MaybeAppendSeparator();
1134 AppendLiteral(NS_DOM_KEYNAME_SYMBOLLOCK
);
1137 AssignLiteral("none");
1142 void MaybeAppendSeparator() {
1144 AppendLiteral(" | ");
1149 /******************************************************************************
1150 * mozilla::WidgetInputEvent
1151 ******************************************************************************/
1153 class WidgetInputEvent
: public WidgetGUIEvent
{
1155 WidgetInputEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
1156 EventClassID aEventClassID
)
1157 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, aEventClassID
),
1160 WidgetInputEvent() : mModifiers(0) {}
1163 virtual WidgetInputEvent
* AsInputEvent() override
{ return this; }
1165 WidgetInputEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
)
1166 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eInputEventClass
),
1169 virtual WidgetEvent
* Duplicate() const override
{
1170 MOZ_ASSERT(mClass
== eInputEventClass
,
1171 "Duplicate() must be overridden by sub class");
1172 // Not copying widget, it is a weak reference.
1173 WidgetInputEvent
* result
= new WidgetInputEvent(false, mMessage
, nullptr);
1174 result
->AssignInputEventData(*this, true);
1175 result
->mFlags
= mFlags
;
1180 * Returns a modifier of "Accel" virtual modifier which is used for shortcut
1183 static Modifier
AccelModifier();
1186 * GetModifier() returns a modifier flag which is activated by aDOMKeyName.
1188 static Modifier
GetModifier(const nsAString
& aDOMKeyName
);
1190 // true indicates the accel key on the environment is down
1191 bool IsAccel() const { return ((mModifiers
& AccelModifier()) != 0); }
1193 // true indicates the shift key is down
1194 bool IsShift() const { return ((mModifiers
& MODIFIER_SHIFT
) != 0); }
1195 // true indicates the control key is down
1196 bool IsControl() const { return ((mModifiers
& MODIFIER_CONTROL
) != 0); }
1197 // true indicates the alt key is down
1198 bool IsAlt() const { return ((mModifiers
& MODIFIER_ALT
) != 0); }
1199 // true indicates the meta key is down (Command key on macOS, Windows logo key
1200 // on Windows, Super/Hyper key on Linux, Meta key on Android).
1201 bool IsMeta() const { return ((mModifiers
& MODIFIER_META
) != 0); }
1202 // true indicates the alt graph key is down
1203 // NOTE: on Mac, the option key press causes both IsAlt() and IsAltGrpah()
1205 bool IsAltGraph() const { return ((mModifiers
& MODIFIER_ALTGRAPH
) != 0); }
1206 // true indicates the CapLock LED is turn on.
1207 bool IsCapsLocked() const { return ((mModifiers
& MODIFIER_CAPSLOCK
) != 0); }
1208 // true indicates the NumLock LED is turn on.
1209 bool IsNumLocked() const { return ((mModifiers
& MODIFIER_NUMLOCK
) != 0); }
1210 // true indicates the ScrollLock LED is turn on.
1211 bool IsScrollLocked() const {
1212 return ((mModifiers
& MODIFIER_SCROLLLOCK
) != 0);
1215 // true indicates the Fn key is down, but this is not supported by native
1216 // key event on any platform.
1217 bool IsFn() const { return ((mModifiers
& MODIFIER_FN
) != 0); }
1218 // true indicates the FnLock LED is turn on, but we don't know such
1219 // keyboards nor platforms.
1220 bool IsFnLocked() const { return ((mModifiers
& MODIFIER_FNLOCK
) != 0); }
1221 // true indicates the Symbol is down, but this is not supported by native
1222 // key event on any platforms.
1223 bool IsSymbol() const { return ((mModifiers
& MODIFIER_SYMBOL
) != 0); }
1224 // true indicates the SymbolLock LED is turn on, but we don't know such
1225 // keyboards nor platforms.
1226 bool IsSymbolLocked() const {
1227 return ((mModifiers
& MODIFIER_SYMBOLLOCK
) != 0);
1230 void InitBasicModifiers(bool aCtrlKey
, bool aAltKey
, bool aShiftKey
,
1234 mModifiers
|= MODIFIER_CONTROL
;
1237 mModifiers
|= MODIFIER_ALT
;
1240 mModifiers
|= MODIFIER_SHIFT
;
1243 mModifiers
|= MODIFIER_META
;
1247 Modifiers mModifiers
;
1249 void AssignInputEventData(const WidgetInputEvent
& aEvent
, bool aCopyTargets
) {
1250 AssignGUIEventData(aEvent
, aCopyTargets
);
1252 mModifiers
= aEvent
.mModifiers
;
1256 /******************************************************************************
1257 * mozilla::InternalUIEvent
1259 * XXX Why this inherits WidgetGUIEvent rather than WidgetEvent?
1260 ******************************************************************************/
1262 class InternalUIEvent
: public WidgetGUIEvent
{
1264 InternalUIEvent() : mDetail(0), mCausedByUntrustedEvent(false) {}
1266 InternalUIEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
1267 EventClassID aEventClassID
)
1268 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, aEventClassID
),
1270 mCausedByUntrustedEvent(false) {}
1272 InternalUIEvent(bool aIsTrusted
, EventMessage aMessage
,
1273 EventClassID aEventClassID
)
1274 : WidgetGUIEvent(aIsTrusted
, aMessage
, nullptr, aEventClassID
),
1276 mCausedByUntrustedEvent(false) {}
1279 virtual InternalUIEvent
* AsUIEvent() override
{ return this; }
1282 * If the UIEvent is caused by another event (e.g., click event),
1283 * aEventCausesThisEvent should be the event. If there is no such event,
1284 * this should be nullptr.
1286 InternalUIEvent(bool aIsTrusted
, EventMessage aMessage
,
1287 const WidgetEvent
* aEventCausesThisEvent
)
1288 : WidgetGUIEvent(aIsTrusted
, aMessage
, nullptr, eUIEventClass
),
1290 mCausedByUntrustedEvent(aEventCausesThisEvent
&&
1291 !aEventCausesThisEvent
->IsTrusted()) {}
1293 virtual WidgetEvent
* Duplicate() const override
{
1294 MOZ_ASSERT(mClass
== eUIEventClass
,
1295 "Duplicate() must be overridden by sub class");
1296 InternalUIEvent
* result
= new InternalUIEvent(false, mMessage
, nullptr);
1297 result
->AssignUIEventData(*this, true);
1298 result
->mFlags
= mFlags
;
1303 // mCausedByUntrustedEvent is true if the event is caused by untrusted event.
1304 bool mCausedByUntrustedEvent
;
1306 // If you check the event is a trusted event and NOT caused by an untrusted
1307 // event, IsTrustable() returns what you expected.
1308 bool IsTrustable() const { return IsTrusted() && !mCausedByUntrustedEvent
; }
1310 void AssignUIEventData(const InternalUIEvent
& aEvent
, bool aCopyTargets
) {
1311 AssignGUIEventData(aEvent
, aCopyTargets
);
1313 mDetail
= aEvent
.mDetail
;
1314 mCausedByUntrustedEvent
= aEvent
.mCausedByUntrustedEvent
;
1318 } // namespace mozilla
1320 #endif // mozilla_BasicEvents_h__