/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
enumclass CrossProcessForwarding { // eStop prevents the event to be sent to remote process.
eStop, // eAllow keeps current state of the event whether it's sent to remote // process. In other words, eAllow does NOT mean that making the event // sent to remote process when IsCrossProcessForwardingStopped() returns // true.
eAllow,
};
/****************************************************************************** * mozilla::BaseEventFlags * * BaseEventFlags must be a POD struct for safe to use memcpy (including * in ParamTraits<BaseEventFlags>). So don't make virtual methods, constructor, * destructor and operators. * This is necessary for VC which is NOT C++0x compiler.
******************************************************************************/
struct BaseEventFlags { public: // If mIsTrusted is true, the event is a trusted event. Otherwise, it's // an untrusted event. bool mIsTrusted : 1; // If mInBubblingPhase is true, the event is in bubbling phase or target // phase. bool mInBubblingPhase : 1; // If mInCapturePhase is true, the event is in capture phase or target phase. bool mInCapturePhase : 1; // If mInTargetPhase is true, the event is in target phase. bool mInTargetPhase : 1; // If mInSystemGroup is true, the event is being dispatched in system group. bool mInSystemGroup : 1; // If mCancelable is true, the event can be consumed. I.e., calling // dom::Event::PreventDefault() can prevent the default action. bool mCancelable : 1; // If mBubbles is true, the event can bubble. Otherwise, cannot be handled // in bubbling phase. bool mBubbles : 1; // If mPropagationStopped is true, dom::Event::StopPropagation() or // dom::Event::StopImmediatePropagation() has been called. bool mPropagationStopped : 1; // If mImmediatePropagationStopped is true, // dom::Event::StopImmediatePropagation() has been called. // Note that mPropagationStopped must be true when this is true. bool mImmediatePropagationStopped : 1; // If mDefaultPrevented is true, the event has been consumed. // E.g., dom::Event::PreventDefault() has been called or // the default action has been performed. bool mDefaultPrevented : 1; // If mDefaultPreventedByContent is true, the event has been // consumed by content. // Note that mDefaultPrevented must be true when this is true. bool mDefaultPreventedByContent : 1; // If mDefaultPreventedByChrome is true, the event has been // consumed by chrome. // Note that mDefaultPrevented must be true when this is true. bool mDefaultPreventedByChrome : 1; // mMultipleActionsPrevented may be used when default handling don't want to // be prevented, but only one of the event targets should handle the event. // For example, when a <label> element is in another <label> element and // the first <label> element is clicked, that one may set this true. // Then, the second <label> element won't handle the event. bool mMultipleActionsPrevented : 1; // If mIsBeingDispatched is true, the DOM event created from the event is // dispatching into the DOM tree and not completed. bool mIsBeingDispatched : 1; // If mDispatchedAtLeastOnce is true, the event has been dispatched // as a DOM event and the dispatch has been completed in the process. // So, this is false even if the event has already been dispatched // in another process. bool mDispatchedAtLeastOnce : 1; // If mIsSynthesizedForTests is true, the event has been synthesized for // automated tests or something hacky approach of an add-on. bool mIsSynthesizedForTests : 1; // If mExceptionWasRaised is true, one of the event handlers has raised an // exception. bool mExceptionWasRaised : 1; // If mRetargetToNonNativeAnonymous is true and the target is in a non-native // native anonymous subtree, the event target is set to mOriginalTarget. bool mRetargetToNonNativeAnonymous : 1; // If mNoContentDispatch is true, the event is never dispatched to the // event handlers which are added to the contents, onfoo attributes and // properties. Note that this flag is ignored when // EventChainPreVisitor::mForceContentDispatch is set true. For exapmle, // window and document object sets it true. Therefore, web applications // can handle the event if they add event listeners to the window or the // document. // XXX This is an ancient and broken feature, don't use this for new bug // as far as possible. bool mNoContentDispatch : 1; // If mOnlyChromeDispatch is true, the event is dispatched to only chrome. bool mOnlyChromeDispatch : 1; // Indicates if the key combination is reserved by chrome. This is set by // MarkAsReservedByChrome(). bool mIsReservedByChrome : 1; // If mOnlySystemGroupDispatchInContent is true, event listeners added to // the default group for non-chrome EventTarget won't be called. // Be aware, if this is true, EventDispatcher needs to check if each event // listener is added to chrome node, so, don't set this to true for the // events which are fired a lot of times like eMouseMove. bool mOnlySystemGroupDispatchInContent : 1; // If mOnlySystemGroupDispatch is true, the event will be dispatched only to // event listeners added in the system group. bool mOnlySystemGroupDispatch : 1; // The event's action will be handled by APZ. The main thread should not // perform its associated action. bool mHandledByAPZ : 1; // True if the event is currently being handled by an event listener that // was registered as a passive listener. bool mInPassiveListener : 1; // If mComposed is true, the event fired by nodes in shadow DOM can cross the // boundary of shadow DOM and light DOM. bool mComposed : 1; // Similar to mComposed. Set it to true to allow events cross the boundary // between native non-anonymous content and native anonymouse content bool mComposedInNativeAnonymousContent : 1; // Set to true for events which are suppressed or delayed so that later a // DelayedEvent of it is dispatched. This is used when parent side process // the key event after content side, and may drop the event if the event // was suppressed or delayed in contents side. // It is also set to true for the events (in a DelayedInputEvent), which will // be dispatched afterwards. bool mIsSuppressedOrDelayed : 1; // Certain mouse events can be marked as positionless to return 0 from // coordinate related getters. bool mIsPositionless : 1;
// Flags managing state of propagation between processes. // Note the the following flags shouldn't be referred directly. Use utility // methods instead.
// If mNoRemoteProcessDispatch is true, the event is not allowed to be sent // to remote process. bool mNoRemoteProcessDispatch : 1; // If mWantReplyFromContentProcess is true, the event will be redispatched // in the parent process after the content process has handled it. Useful // for when the parent process need the know first how the event was used // by content before handling it itself. bool mWantReplyFromContentProcess : 1; // If mPostedToRemoteProcess is true, the event has been posted to the // remote process (but it's not handled yet if it's not a duplicated event // instance). bool mPostedToRemoteProcess : 1; // If mCameFromAnotherProcess is true, the event came from another process. bool mCameFromAnotherProcess : 1;
/** * Helper methods for methods of DOM Event.
*/ inlinevoid StopPropagation() { mPropagationStopped = true; } inlinevoid StopImmediatePropagation() {
StopPropagation();
mImmediatePropagationStopped = true;
} inlinevoid PreventDefault(bool aCalledByDefaultHandler = true) { if (!mCancelable) { return;
}
mDefaultPrevented = true; // Note that even if preventDefault() has already been called by chrome, // a call of preventDefault() by content needs to overwrite // mDefaultPreventedByContent to true because in such case, defaultPrevented // must be true when web apps check it after they call preventDefault(). if (aCalledByDefaultHandler) {
StopCrossProcessForwarding();
mDefaultPreventedByChrome = true;
} else {
mDefaultPreventedByContent = true;
}
} // This should be used only before dispatching events into the DOM tree. inlinevoid PreventDefaultBeforeDispatch(
CrossProcessForwarding aCrossProcessForwarding) { if (!mCancelable) { return;
}
mDefaultPrevented = true; if (aCrossProcessForwarding == CrossProcessForwarding::eStop) {
StopCrossProcessForwarding();
}
} inlinebool DefaultPrevented() const { return mDefaultPrevented; } inlinebool DefaultPreventedByContent() const {
MOZ_ASSERT(!mDefaultPreventedByContent || DefaultPrevented()); return mDefaultPreventedByContent;
} inlinebool IsTrusted() const { return mIsTrusted; } inlinebool PropagationStopped() const { return mPropagationStopped; }
// Helper methods to access flags managing state of propagation between // processes.
/** * Prevent to be dispatched to remote process.
*/ inlinevoid StopCrossProcessForwarding() {
MOZ_ASSERT(!mPostedToRemoteProcess);
mNoRemoteProcessDispatch = true;
mWantReplyFromContentProcess = false;
} /** * Return true if the event shouldn't be dispatched to remote process.
*/ inlinebool IsCrossProcessForwardingStopped() const { return mNoRemoteProcessDispatch;
} /** * Mark the event as waiting reply from remote process. * If the caller needs to win other keyboard event handlers in chrome, * the caller should call StopPropagation() too. * Otherwise, if the caller just needs to know if the event is consumed by * either content or chrome, it should just call this because the event * may be reserved by chrome and it needs to be dispatched into the DOM * tree in chrome for checking if it's reserved before being sent to any * remote processes.
*/ inlinevoid MarkAsWaitingReplyFromRemoteProcess() {
MOZ_ASSERT(!mPostedToRemoteProcess);
mNoRemoteProcessDispatch = false;
mWantReplyFromContentProcess = true;
} /** * Reset "waiting reply from remote process" state. This is useful when * you dispatch a copy of an event coming from different process.
*/ inlinevoid ResetWaitingReplyFromRemoteProcessState() { if (IsWaitingReplyFromRemoteProcess()) { // FYI: mWantReplyFromContentProcess is also used for indicating // "handled in remote process" state. Therefore, only when // IsWaitingReplyFromRemoteProcess() returns true, this should // reset the flag.
mWantReplyFromContentProcess = false;
}
} /** * Return true if the event handler should wait reply event. I.e., if this * returns true, any event handler should do nothing with the event.
*/ inlinebool IsWaitingReplyFromRemoteProcess() const { return !mNoRemoteProcessDispatch && mWantReplyFromContentProcess;
} /** * Mark the event as already handled in the remote process. This should be * called when initializing reply events.
*/ inlinevoid MarkAsHandledInRemoteProcess() {
mNoRemoteProcessDispatch = true;
mWantReplyFromContentProcess = true;
mPostedToRemoteProcess = false;
} /** * Return true if the event has already been handled in the remote process.
*/ inlinebool IsHandledInRemoteProcess() const { return mNoRemoteProcessDispatch && mWantReplyFromContentProcess;
} /** * Return true if the event should be sent back to its parent process.
*/ inlinebool WantReplyFromContentProcess() const {
MOZ_ASSERT(!XRE_IsParentProcess()); return IsWaitingReplyFromRemoteProcess();
} /** * Mark the event has already posted to a remote process.
*/ inlinevoid MarkAsPostedToRemoteProcess() {
MOZ_ASSERT(!IsCrossProcessForwardingStopped());
mPostedToRemoteProcess = true;
} /** * Reset the cross process dispatching state. This should be used when a * process receives the event because the state is in the sender.
*/ inlinevoid ResetCrossProcessDispatchingState() {
MOZ_ASSERT(!IsCrossProcessForwardingStopped());
mPostedToRemoteProcess = false; // Ignore propagation state in the remote process if it's marked as // "waiting reply from remote process" because the process needs to // stop propagation in the process until receiving a reply event. // Note that the propagation stopped flag is important for the reply event // handler in the main process because it's used for making whether it's // ignored by the remote process or not. if (!XRE_IsParentProcess() && IsWaitingReplyFromRemoteProcess()) {
mPropagationStopped = mImmediatePropagationStopped = false;
} // mDispatchedAtLeastOnce indicates the state in current process.
mDispatchedAtLeastOnce = false;
} /** * Return true if the event has been posted to a remote process. * Note that MarkAsPostedToRemoteProcess() is called by * ParamTraits<mozilla::WidgetEvent>. Therefore, it *might* be possible * that posting the event failed even if this returns true. But that must * really rare. If that'd be problem for you, you should unmark this in * BrowserParent or somewhere.
*/ inlinebool HasBeenPostedToRemoteProcess() const { return mPostedToRemoteProcess;
} /** * Return true if the event came from another process.
*/ inlinebool CameFromAnotherProcess() const { return mCameFromAnotherProcess; } /** * Mark the event as coming from another process.
*/ inlinevoid MarkAsComingFromAnotherProcess() {
mCameFromAnotherProcess = true;
} /** * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to * content because it shouldn't be cancelable.
*/ inlinevoid MarkAsReservedByChrome() {
MOZ_ASSERT(!mPostedToRemoteProcess);
mIsReservedByChrome = true; // For reserved commands (such as Open New Tab), we don't need to wait for // the content to answer, neither to give a chance for content to override // its behavior.
StopCrossProcessForwarding(); // If the event is reserved by chrome, we shouldn't expose the event to // web contents because such events shouldn't be cancelable. So, it's not // good behavior to fire such events but to ignore the defaultPrevented // attribute value in chrome.
mOnlySystemGroupDispatchInContent = true;
} /** * Return true if the event is reserved by chrome.
*/ inlinebool IsReservedByChrome() const {
MOZ_ASSERT(!mIsReservedByChrome || (IsCrossProcessForwardingStopped() &&
mOnlySystemGroupDispatchInContent)); return mIsReservedByChrome;
}
inlinevoid Clear() { SetRawFlags(0); } // Get if either the instance's bit or the aOther's bit is true, the // instance's bit becomes true. In other words, this works like: // eventFlags |= aOther; inlinevoidUnion(const BaseEventFlags& aOther) {
RawFlags rawFlags = GetRawFlags() | aOther.GetRawFlags();
SetRawFlags(rawFlags);
}
private: typedef uint64_t RawFlags;
inlinevoid SetRawFlags(RawFlags aRawFlags) {
static_assert(sizeof(BaseEventFlags) <= sizeof(RawFlags), "mozilla::EventFlags must not be bigger than the RawFlags");
memcpy(this, &aRawFlags, sizeof(BaseEventFlags));
} inline RawFlags GetRawFlags() const {
RawFlags result = 0;
memcpy(&result, this, sizeof(BaseEventFlags)); return result;
}
};
virtual WidgetEvent* Duplicate() const {
MOZ_ASSERT(mClass == eBasicEventClass, "Duplicate() must be overridden by sub class");
WidgetEvent* result = new WidgetEvent(false, mMessage, this);
result->AssignEventData(*this, true);
result->mFlags = mFlags; return result;
}
EventClassID mClass;
EventMessage mMessage; // Relative to the widget of the event, or if there is no widget then it is // in screen coordinates. Not modified by layout code. // This is in visual coordinates, i.e. the correct RelativeTo value that // expresses what this is relative to is `{viewportFrame, Visual}`, where // `viewportFrame` is the viewport frame of the widget's root document.
LayoutDeviceIntPoint mRefPoint; // The previous mRefPoint, if known, used to calculate mouse movement deltas.
LayoutDeviceIntPoint mLastRefPoint; // The sequence number of the last potentially focus changing event handled // by APZ. This is used to track when that event has been processed by // content, and focus can be reconfirmed for async keyboard scrolling.
uint64_t mFocusSequenceNumber; // See BaseEventFlags definition for the detail.
BaseEventFlags mFlags;
// If JS creates an event with unknown event type or known event type but // for different event interface, the event type is stored to this. // NOTE: This is always used if the instance is a WidgetCommandEvent instance // or "input" event is dispatched with dom::Event class.
RefPtr<nsAtom> mSpecifiedEventType;
// nsAtom isn't available on non-main thread due to unsafe. Therefore, // mSpecifiedEventTypeString is used instead of mSpecifiedEventType if // the event is created in non-main thread.
nsString mSpecifiedEventTypeString;
// Event targets, needed by DOM Events // Note that when you need event target for DOM event, you should use // Get*DOMEventTarget() instead of accessing these members directly.
nsCOMPtr<dom::EventTarget> mTarget;
nsCOMPtr<dom::EventTarget> mCurrentTarget;
nsCOMPtr<dom::EventTarget> mOriginalTarget;
/// The possible related target
nsCOMPtr<dom::EventTarget> mRelatedTarget;
nsCOMPtr<dom::EventTarget> mOriginalRelatedTarget;
nsTArray<EventTargetChainItem>* mPath;
// The LayersId of the content process that this event should be // dispatched to. This field is only used in the chrome process // and doesn't get remoted to child processes.
layers::LayersId mLayersId;
void AssignEventData(const WidgetEvent& aEvent, bool aCopyTargets) { // mClass should be initialized with the constructor. // mMessage should be initialized with the constructor.
mRefPoint = aEvent.mRefPoint; // mLastRefPoint doesn't need to be copied.
mFocusSequenceNumber = aEvent.mFocusSequenceNumber; // mLayersId intentionally not copied, since it's not used within content
AssignEventTime(aEvent); // mFlags should be copied manually if it's necessary.
mSpecifiedEventType = aEvent.mSpecifiedEventType; // mSpecifiedEventTypeString should be copied manually if it's necessary.
mTarget = aCopyTargets ? aEvent.mTarget : nullptr;
mCurrentTarget = aCopyTargets ? aEvent.mCurrentTarget : nullptr;
mOriginalTarget = aCopyTargets ? aEvent.mOriginalTarget : nullptr;
mRelatedTarget = aCopyTargets ? aEvent.mRelatedTarget : nullptr;
mOriginalRelatedTarget =
aCopyTargets ? aEvent.mOriginalRelatedTarget : nullptr;
}
/** * Helper methods for methods of DOM Event.
*/ void StopPropagation() { mFlags.StopPropagation(); } void StopImmediatePropagation() { mFlags.StopImmediatePropagation(); } void PreventDefault(bool aCalledByDefaultHandler = true,
nsIPrincipal* aPrincipal = nullptr);
/** * Prevent to be dispatched to remote process.
*/ inlinevoid StopCrossProcessForwarding() {
mFlags.StopCrossProcessForwarding();
} /** * Return true if the event shouldn't be dispatched to remote process.
*/ inlinebool IsCrossProcessForwardingStopped() const { return mFlags.IsCrossProcessForwardingStopped();
} /** * Mark the event as waiting reply from remote process. * Note that this also stops immediate propagation in current process.
*/ inlinevoid MarkAsWaitingReplyFromRemoteProcess() {
mFlags.MarkAsWaitingReplyFromRemoteProcess();
} /** * Reset "waiting reply from remote process" state. This is useful when * you dispatch a copy of an event coming from different process.
*/ inlinevoid ResetWaitingReplyFromRemoteProcessState() {
mFlags.ResetWaitingReplyFromRemoteProcessState();
} /** * Return true if the event handler should wait reply event. I.e., if this * returns true, any event handler should do nothing with the event.
*/ inlinebool IsWaitingReplyFromRemoteProcess() const { return mFlags.IsWaitingReplyFromRemoteProcess();
} /** * Mark the event as already handled in the remote process. This should be * called when initializing reply events.
*/ inlinevoid MarkAsHandledInRemoteProcess() {
mFlags.MarkAsHandledInRemoteProcess();
} /** * Return true if the event has already been handled in the remote process. * I.e., if this returns true, the event is a reply event.
*/ inlinebool IsHandledInRemoteProcess() const { return mFlags.IsHandledInRemoteProcess();
} /** * Return true if the event should be sent back to its parent process. * So, usual event handlers shouldn't call this.
*/ inlinebool WantReplyFromContentProcess() const { return mFlags.WantReplyFromContentProcess();
} /** * Mark the event has already posted to a remote process.
*/ inlinevoid MarkAsPostedToRemoteProcess() {
mFlags.MarkAsPostedToRemoteProcess();
} /** * Reset the cross process dispatching state. This should be used when a * process receives the event because the state is in the sender.
*/ inlinevoid ResetCrossProcessDispatchingState() {
mFlags.ResetCrossProcessDispatchingState();
} /** * Return true if the event has been posted to a remote process.
*/ inlinebool HasBeenPostedToRemoteProcess() const { return mFlags.HasBeenPostedToRemoteProcess();
} /** * Return true if the event came from another process.
*/ inlinebool CameFromAnotherProcess() const { return mFlags.CameFromAnotherProcess();
} /** * Mark the event as coming from another process.
*/ inlinevoid MarkAsComingFromAnotherProcess() {
mFlags.MarkAsComingFromAnotherProcess();
} /** * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to * content because it shouldn't be cancelable.
*/ inlinevoid MarkAsReservedByChrome() { mFlags.MarkAsReservedByChrome(); } /** * Return true if the event is reserved by chrome.
*/ inlinebool IsReservedByChrome() const { return mFlags.IsReservedByChrome(); }
/** * Return true if the corresponding DOM event supports screen(X|Y), etc.
*/
[[nodiscard]] inlinebool DOMEventSupportsCoords() const { switch (mClass) { case eMouseEventClass: case eMouseScrollEventClass: case eWheelEventClass: case eTouchEventClass: case eDragEventClass: case ePointerEventClass: case eSimpleGestureEventClass: returntrue; default: returnfalse;
}
}
/** * Utils for checking event types
*/
/** * As*Event() returns the pointer of the instance only when the instance is * the class or one of its derived class.
*/ #define NS_ROOT_EVENT_CLASS(aPrefix, aName) #define NS_EVENT_CLASS(aPrefix, aName) \ virtual aPrefix##aName* As##aName(); \ const aPrefix##aName* As##aName() const;
#include"mozilla/EventClassList.h"
#undef NS_EVENT_CLASS #undef NS_ROOT_EVENT_CLASS
/** * Returns true if the event is a query content event.
*/ bool IsQueryContentEvent() const; /** * Returns true if the event is a selection event.
*/ bool IsSelectionEvent() const; /** * Returns true if the event is a content command event.
*/ bool IsContentCommandEvent() const;
/** * Returns true if the event mMessage is one of mouse events.
*/ bool HasMouseEventMessage() const;
/** * Returns true if the event class is eMouseEventClass or the event message * is ePointerClick.
*/
[[nodiscard]] bool IsMouseEventClassOrHasClickRelatedPointerEvent() const;
/** * Returns true if the event mMessage is one of drag events.
*/ bool HasDragEventMessage() const; /** * Returns true if aMessage or mMessage is one of key events.
*/ staticbool IsKeyEventMessage(EventMessage aMessage); bool HasKeyEventMessage() const { return IsKeyEventMessage(mMessage); } /** * Returns true if the event mMessage is one of composition events or text * event.
*/ bool HasIMEEventMessage() const;
/** * Returns true if the event can be sent to remote process.
*/ bool CanBeSentToRemoteProcess() const; /** * Returns true if the original target is a remote process and the event * will be posted to the remote process later.
*/ bool WillBeSentToRemoteProcess() const; /** * Returns true if the event is related to IME handling. It includes * IME events, query content events and selection events. * Be careful when you use this.
*/ bool IsIMERelatedEvent() const;
/** * Whether the event should be handled by the frame of the mouse cursor * position or not. When it should be handled there (e.g., the mouse events), * this returns true.
*/ bool IsUsingCoordinates() const; /** * Whether the event should be handled by the focused DOM window in the * same top level window's or not. E.g., key events, IME related events * (including the query content events, they are used in IME transaction) * should be handled by the (last) focused window rather than the dispatched * window. * * NOTE: Even if this returns true, the event isn't going to be handled by the * application level active DOM window which is on another top level window. * So, when the event is fired on a deactive window, the event is going to be * handled by the last focused DOM window in the last focused window.
*/ bool IsTargetedAtFocusedWindow() const; /** * Whether the event should be handled by the focused content or not. E.g., * key events, IME related events and other input events which are not handled * by the frame of the mouse cursor position. * * NOTE: Even if this returns true, the event isn't going to be handled by the * application level active DOM window which is on another top level window. * So, when the event is fired on a deactive window, the event is going to be * handled by the last focused DOM element of the last focused DOM window in * the last focused window.
*/ bool IsTargetedAtFocusedContent() const; /** * Whether the event should cause a DOM event.
*/ bool IsAllowedToDispatchDOMEvent() const; /** * Whether the event should be dispatched in system group.
*/ bool IsAllowedToDispatchInSystemGroup() const; /** * Whether the event should be blocked for fingerprinting resistance.
*/ bool IsBlockedForFingerprintingResistance() const; /** * Whether the event handler can flush pending notifications or not.
*/ bool AllowFlushingPendingNotifications() const; /** * Initialize mComposed
*/ void SetDefaultComposed() { switch (mClass) { case eClipboardEventClass:
mFlags.mComposed = true; break; case eCompositionEventClass:
mFlags.mComposed =
mMessage == eCompositionStart || mMessage == eCompositionUpdate ||
mMessage == eCompositionChange || mMessage == eCompositionEnd; break; case eDragEventClass: // All drag & drop events are composed
mFlags.mComposed = mMessage == eDrag || mMessage == eDragEnd ||
mMessage == eDragEnter || mMessage == eDragExit ||
mMessage == eDragLeave || mMessage == eDragOver ||
mMessage == eDragStart || mMessage == eDrop; break; case eEditorInputEventClass:
mFlags.mComposed =
mMessage == eEditorInput || mMessage == eEditorBeforeInput; break; case eFocusEventClass:
mFlags.mComposed = mMessage == eBlur || mMessage == eFocus ||
mMessage == eFocusOut || mMessage == eFocusIn; break; case eKeyboardEventClass:
mFlags.mComposed =
mMessage == eKeyDown || mMessage == eKeyUp || mMessage == eKeyPress; break; case eMouseEventClass:
mFlags.mComposed =
mMessage == eMouseDoubleClick || mMessage == eMouseDown ||
mMessage == eMouseUp || mMessage == eMouseOver ||
mMessage == eMouseOut || mMessage == eMouseMove ||
mMessage == eXULPopupShowing || mMessage == eXULPopupHiding ||
mMessage == eXULPopupShown || mMessage == eXULPopupHidden || // `click` event, `auxclick` event and `contextmenu` event should be // created as a PointerEvent, but they were MouseEvent before. // Additionally, we support dispatching untrusted these events to // some elements may cause a default action of it even if they are // created with MouseEvent. Therefore, we need to allow these event // messages here.
mMessage == ePointerClick || mMessage == ePointerAuxClick ||
mMessage == eContextMenu; break; case ePointerEventClass: // All pointer events are composed
mFlags.mComposed =
mMessage == ePointerClick || mMessage == ePointerAuxClick ||
mMessage == eContextMenu || mMessage == ePointerDown ||
mMessage == ePointerMove || mMessage == ePointerUp ||
mMessage == ePointerCancel || mMessage == ePointerOver ||
mMessage == ePointerOut || mMessage == ePointerGotCapture ||
mMessage == ePointerLostCapture; break; case eTouchEventClass: // All touch events are composed
mFlags.mComposed = mMessage == eTouchStart || mMessage == eTouchEnd ||
mMessage == eTouchMove || mMessage == eTouchCancel; break; case eUIEventClass:
mFlags.mComposed = mMessage == eLegacyDOMFocusIn ||
mMessage == eLegacyDOMFocusOut ||
mMessage == eLegacyDOMActivate; break; case eWheelEventClass: // All wheel events are composed
mFlags.mComposed = mMessage == eWheel; break; case eMouseScrollEventClass: // Legacy mouse scroll events are composed too, for consistency with // wheel.
mFlags.mComposed = mMessage == eLegacyMouseLineOrPageScroll ||
mMessage == eLegacyMousePixelScroll; break; default:
mFlags.mComposed = false; break;
}
}
void SetDefaultComposedInNativeAnonymousContent() { // For compatibility concerns, we set mComposedInNativeAnonymousContent to // false for those events we want to stop propagation. // // nsVideoFrame may create anonymous image element which fires eLoad, // eLoadStart, eLoadEnd, eLoadError. We don't want these events cross // the boundary of NAC
mFlags.mComposedInNativeAnonymousContent =
mMessage != eLoad && mMessage != eLoadStart && mMessage != eLoadEnd &&
mMessage != eLoadError;
}
bool IsUserAction() const;
/** * Return true if the event should be handled without (pointer) capturing * element.
*/
[[nodiscard]] bool ShouldIgnoreCapturingContent() const;
};
virtual WidgetEvent* Duplicate() const override {
MOZ_ASSERT(mClass == eGUIEventClass, "Duplicate() must be overridden by sub class"); // Not copying widget, it is a weak reference.
WidgetGUIEvent* result = new WidgetGUIEvent(false, mMessage, nullptr, this);
result->AssignGUIEventData(*this, true);
result->mFlags = mFlags; return result;
}
// Originator of the event
nsCOMPtr<nsIWidget> mWidget;
void AssignGUIEventData(const WidgetGUIEvent& aEvent, bool aCopyTargets) {
AssignEventData(aEvent, aCopyTargets); // widget should be initialized with the constructor.
}
};
/****************************************************************************** * mozilla::Modifier * * All modifier keys should be defined here. This is used for managing * modifier states for DOM Level 3 or later.
******************************************************************************/
virtual WidgetEvent* Duplicate() const override {
MOZ_ASSERT(mClass == eInputEventClass, "Duplicate() must be overridden by sub class"); // Not copying widget, it is a weak reference.
WidgetInputEvent* result = new WidgetInputEvent(false, mMessage, nullptr, this);
result->AssignInputEventData(*this, true);
result->mFlags = mFlags; return result;
}
/** * Returns a modifier of "Accel" virtual modifier which is used for shortcut * key.
*/ static Modifier AccelModifier();
/** * GetModifier() returns a modifier flag which is activated by aDOMKeyName.
*/ static Modifier GetModifier(const nsAString& aDOMKeyName);
// true indicates the accel key on the environment is down bool IsAccel() const { return ((mModifiers & AccelModifier()) != 0); }
// true indicates the shift key is down bool IsShift() const { return ((mModifiers & MODIFIER_SHIFT) != 0); } // true indicates the control key is down bool IsControl() const { return ((mModifiers & MODIFIER_CONTROL) != 0); } // true indicates the alt key is down bool IsAlt() const { return ((mModifiers & MODIFIER_ALT) != 0); } // true indicates the meta key is down (Command key on macOS, Windows logo key // on Windows, Super/Hyper key on Linux, Meta key on Android). bool IsMeta() const { return ((mModifiers & MODIFIER_META) != 0); } // true indicates the alt graph key is down // NOTE: on Mac, the option key press causes both IsAlt() and IsAltGrpah() // return true. bool IsAltGraph() const { return ((mModifiers & MODIFIER_ALTGRAPH) != 0); } // true indicates the CapLock LED is turn on. bool IsCapsLocked() const { return ((mModifiers & MODIFIER_CAPSLOCK) != 0); } // true indicates the NumLock LED is turn on. bool IsNumLocked() const { return ((mModifiers & MODIFIER_NUMLOCK) != 0); } // true indicates the ScrollLock LED is turn on. bool IsScrollLocked() const { return ((mModifiers & MODIFIER_SCROLLLOCK) != 0);
}
// true indicates the Fn key is down, but this is not supported by native // key event on any platform. bool IsFn() const { return ((mModifiers & MODIFIER_FN) != 0); } // true indicates the FnLock LED is turn on, but we don't know such // keyboards nor platforms. bool IsFnLocked() const { return ((mModifiers & MODIFIER_FNLOCK) != 0); } // true indicates the Symbol is down, but this is not supported by native // key event on any platforms. bool IsSymbol() const { return ((mModifiers & MODIFIER_SYMBOL) != 0); } // true indicates the SymbolLock LED is turn on, but we don't know such // keyboards nor platforms. bool IsSymbolLocked() const { return ((mModifiers & MODIFIER_SYMBOLLOCK) != 0);
}
/****************************************************************************** * mozilla::InternalUIEvent * * XXX Why this inherits WidgetGUIEvent rather than WidgetEvent?
******************************************************************************/
class InternalUIEvent : public WidgetGUIEvent { protected:
InternalUIEvent() : mDetail(0), mCausedByUntrustedEvent(false) {}
/** * If the UIEvent is caused by another event (e.g., click event), * aEventCausesThisEvent should be the event. If there is no such event, * this should be nullptr.
*/
InternalUIEvent(bool aIsTrusted, EventMessage aMessage, const WidgetEvent* aEventCausesThisEvent, const WidgetEventTime* aTime = nullptr)
: WidgetGUIEvent(aIsTrusted, aMessage, nullptr, eUIEventClass, aTime),
mDetail(0),
mCausedByUntrustedEvent(aEventCausesThisEvent &&
!aEventCausesThisEvent->IsTrusted()) {}
virtual WidgetEvent* Duplicate() const override {
MOZ_ASSERT(mClass == eUIEventClass, "Duplicate() must be overridden by sub class");
InternalUIEvent* result = new InternalUIEvent(false, mMessage, nullptr, this);
result->AssignUIEventData(*this, true);
result->mFlags = mFlags; return result;
}
int32_t mDetail; // mCausedByUntrustedEvent is true if the event is caused by untrusted event. bool mCausedByUntrustedEvent;
// If you check the event is a trusted event and NOT caused by an untrusted // event, IsTrustable() returns what you expected. bool IsTrustable() const { return IsTrusted() && !mCausedByUntrustedEvent; }
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.58Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.