1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_Event_h_
8 #define mozilla_dom_Event_h_
12 #include "js/TypeDecls.h"
13 #include "mozilla/AlreadyAddRefed.h"
14 #include "mozilla/Assertions.h"
15 #include "mozilla/Attributes.h"
16 #include "mozilla/BasicEvents.h"
17 #include "mozilla/RefPtr.h"
18 #include "mozilla/Maybe.h"
19 #include "mozilla/dom/BindingDeclarations.h"
21 #include "nsCycleCollectionParticipant.h"
23 #include "nsISupports.h"
24 #include "nsStringFwd.h"
25 #include "nsWrapperCache.h"
28 class nsCycleCollectionTraversalCallback
;
30 class nsIGlobalObject
;
32 class nsPIDOMWindowInner
;
41 namespace mozilla::dom
{
43 class BeforeUnloadEvent
;
48 class EventMessageAutoOverride
;
49 // ExtendableEvent is a ServiceWorker event that is not
50 // autogenerated since it has some extra methods.
51 class ExtendableEvent
;
57 class WantsPopupControlCheck
;
58 class XULCommandEvent
;
61 #define GENERATED_EVENT(EventClass_) class EventClass_;
62 #include "mozilla/dom/GeneratedEventList.h"
63 #undef GENERATED_EVENT
66 #define NS_EVENT_IID \
68 0x71139716, 0x4d91, 0x4dee, { \
69 0xba, 0xf9, 0xe3, 0x3b, 0x80, 0xc1, 0x61, 0x61 \
73 class Event
: public nsISupports
, public nsWrapperCache
{
75 NS_DECLARE_STATIC_IID_ACCESSOR(NS_EVENT_IID
)
77 Event(EventTarget
* aOwner
, nsPresContext
* aPresContext
, WidgetEvent
* aEvent
);
78 explicit Event(nsPIDOMWindowInner
* aWindow
);
84 void ConstructorInit(EventTarget
* aOwner
, nsPresContext
* aPresContext
,
88 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
89 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Event
)
91 nsIGlobalObject
* GetParentObject() { return mOwner
; }
93 JSObject
* WrapObject(JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) final
;
95 virtual JSObject
* WrapObjectInternal(JSContext
* aCx
,
96 JS::Handle
<JSObject
*> aGivenProto
);
98 #define GENERATED_EVENT(EventClass_) \
99 virtual EventClass_* As##EventClass_() { return nullptr; }
100 #include "mozilla/dom/GeneratedEventList.h"
101 #undef GENERATED_EVENT
103 // ExtendableEvent is a ServiceWorker event that is not
104 // autogenerated since it has some extra methods.
105 virtual ExtendableEvent
* AsExtendableEvent() { return nullptr; }
107 virtual TimeEvent
* AsTimeEvent() { return nullptr; }
109 // BeforeUnloadEvent is not autogenerated because it has a setter.
110 virtual BeforeUnloadEvent
* AsBeforeUnloadEvent() { return nullptr; }
112 // KeyboardEvent has all sorts of non-autogeneratable bits so far.
113 virtual KeyboardEvent
* AsKeyboardEvent() { return nullptr; }
115 // DragEvent has a non-autogeneratable initDragEvent.
116 virtual DragEvent
* AsDragEvent() { return nullptr; }
118 // XULCommandEvent has a non-autogeneratable initCommandEvent.
119 virtual XULCommandEvent
* AsXULCommandEvent() { return nullptr; }
121 // MouseEvent has a non-autogeneratable initMouseEvent and other
122 // non-autogeneratable methods.
123 virtual MouseEvent
* AsMouseEvent() { return nullptr; }
125 // UIEvent has a non-autogeneratable initUIEvent.
126 virtual UIEvent
* AsUIEvent() { return nullptr; }
128 // CustomEvent has a non-autogeneratable initCustomEvent.
129 virtual CustomEvent
* AsCustomEvent() { return nullptr; }
131 // MessageEvent has a non-autogeneratable initMessageEvent and more.
132 virtual MessageEvent
* AsMessageEvent() { return nullptr; }
134 void InitEvent(const nsAString
& aEventTypeArg
, bool aCanBubble
,
136 InitEvent(aEventTypeArg
, aCanBubble
? CanBubble::eYes
: CanBubble::eNo
,
137 aCancelable
? Cancelable::eYes
: Cancelable::eNo
);
140 void InitEvent(const nsAString
& aEventTypeArg
, mozilla::CanBubble
,
142 mozilla::Composed
= mozilla::Composed::eDefault
);
144 void SetTarget(EventTarget
* aTarget
);
145 virtual void DuplicatePrivateData();
146 bool IsDispatchStopped();
147 WidgetEvent
* WidgetEventPtr();
148 const WidgetEvent
* WidgetEventPtr() const {
149 return const_cast<Event
*>(this)->WidgetEventPtr();
151 virtual void Serialize(IPC::MessageWriter
* aWriter
,
152 bool aSerializeInterfaceType
);
153 virtual bool Deserialize(IPC::MessageReader
* aReader
);
154 void SetOwner(EventTarget
* aOwner
);
155 void StopCrossProcessForwarding();
156 void SetTrusted(bool aTrusted
);
158 // When listening to chrome EventTargets, in the parent process, nsWindowRoot
159 // might receive events we've already handled via
160 // InProcessBrowserChildMessageManager, and handlers should call this to avoid
161 // handling the same event twice.
162 bool ShouldIgnoreChromeEventTargetListener() const;
164 void InitPresContextData(nsPresContext
* aPresContext
);
166 // Returns true if the event should be trusted.
167 bool Init(EventTarget
* aGlobal
);
169 static const char16_t
* GetEventName(EventMessage aEventType
);
170 static CSSIntPoint
GetClientCoords(nsPresContext
* aPresContext
,
172 LayoutDeviceIntPoint aPoint
,
173 CSSIntPoint aDefaultPoint
);
174 static CSSIntPoint
GetPageCoords(nsPresContext
* aPresContext
,
176 LayoutDeviceIntPoint aPoint
,
177 CSSIntPoint aDefaultPoint
);
178 static Maybe
<CSSIntPoint
> GetScreenCoords(nsPresContext
* aPresContext
,
180 LayoutDeviceIntPoint aPoint
);
181 MOZ_CAN_RUN_SCRIPT_BOUNDARY
182 static CSSIntPoint
GetOffsetCoords(nsPresContext
* aPresContext
,
184 LayoutDeviceIntPoint aPoint
,
185 CSSIntPoint aDefaultPoint
);
187 static already_AddRefed
<Event
> Constructor(EventTarget
* aEventTarget
,
188 const nsAString
& aType
,
189 const EventInit
& aParam
);
191 static already_AddRefed
<Event
> Constructor(const GlobalObject
& aGlobal
,
192 const nsAString
& aType
,
193 const EventInit
& aParam
);
195 void GetType(nsAString
& aType
) const;
197 EventTarget
* GetTarget() const;
198 EventTarget
* GetCurrentTarget() const;
200 // This method returns the document which is associated with the event target.
201 already_AddRefed
<Document
> GetDocument() const;
203 void ComposedPath(nsTArray
<RefPtr
<EventTarget
>>& aPath
);
205 uint16_t EventPhase() const;
207 void StopPropagation();
209 void StopImmediatePropagation();
211 bool Bubbles() const { return mEvent
->mFlags
.mBubbles
; }
213 bool Cancelable() const { return mEvent
->mFlags
.mCancelable
; }
215 bool Composed() const { return mEvent
->mFlags
.mComposed
; }
217 bool CancelBubble() const { return mEvent
->PropagationStopped(); }
218 void SetCancelBubble(bool aCancelBubble
) {
220 mEvent
->StopPropagation();
224 // For C++ consumers only!
225 void PreventDefault();
227 // You MUST NOT call PreventDefault(JSContext*, CallerType) from C++ code. A
228 // call of this method always sets Event.defaultPrevented true for web
229 // contents. If default action handler calls this, web applications see wrong
230 // defaultPrevented value.
231 virtual void PreventDefault(JSContext
* aCx
, CallerType aCallerType
);
233 // You MUST NOT call DefaultPrevented(CallerType) from C++ code. This may
234 // return false even if PreventDefault() has been called.
235 // See comments in its implementation for the details.
236 bool DefaultPrevented(CallerType aCallerType
) const;
238 bool DefaultPrevented() const { return mEvent
->DefaultPrevented(); }
240 bool DefaultPreventedByChrome() const {
241 return mEvent
->mFlags
.mDefaultPreventedByChrome
;
244 bool DefaultPreventedByContent() const {
245 return mEvent
->mFlags
.mDefaultPreventedByContent
;
248 void PreventMultipleActions() {
249 mEvent
->mFlags
.mMultipleActionsPrevented
= true;
252 bool MultipleActionsPrevented() const {
253 return mEvent
->mFlags
.mMultipleActionsPrevented
;
256 bool ReturnValue(CallerType aCallerType
) const;
258 void SetReturnValue(bool aReturnValue
, CallerType aCallerType
);
260 bool IsTrusted() const { return mEvent
->IsTrusted(); }
262 bool IsSynthesized() const { return mEvent
->mFlags
.mIsSynthesizedForTests
; }
264 bool IsSafeToBeDispatchedAsynchronously() const {
265 // If mEvent is not created by dom::Event nor its subclasses, its lifetime
266 // is not guaranteed. So, only when mEventIsInternal is true, it's safe
267 // to be dispatched asynchronously.
268 return mEventIsInternal
;
273 EventTarget
* GetOriginalTarget() const;
274 EventTarget
* GetExplicitOriginalTarget() const;
275 EventTarget
* GetComposedTarget() const;
278 * @param aCalledByDefaultHandler Should be true when this is called by
279 * C++ or Chrome. Otherwise, e.g., called
280 * by a call of Event.preventDefault() in
281 * content script, false.
283 void PreventDefaultInternal(bool aCalledByDefaultHandler
,
284 nsIPrincipal
* aPrincipal
= nullptr);
286 bool IsMainThreadEvent() { return mIsMainThreadEvent
; }
288 void MarkUninitialized() {
289 mEvent
->mMessage
= eVoidEvent
;
290 mEvent
->mSpecifiedEventTypeString
.Truncate();
291 mEvent
->mSpecifiedEventType
= nullptr;
295 * For WidgetEvent, return it's type in string.
297 * @param aEvent is a WidgetEvent to get its type.
298 * @param aType is a string where to return the type.
300 static void GetWidgetEventType(WidgetEvent
* aEvent
, nsAString
& aType
);
302 void RequestReplyFromRemoteContent() {
303 mEvent
->MarkAsWaitingReplyFromRemoteProcess();
306 bool IsWaitingReplyFromRemoteContent() const {
307 return mEvent
->IsWaitingReplyFromRemoteProcess();
310 bool IsReplyEventFromRemoteContent() const {
311 return mEvent
->IsHandledInRemoteProcess();
314 static bool IsDragExitEnabled(JSContext
* aCx
, JSObject
* aGlobal
);
317 // Internal helper functions
318 void SetEventType(const nsAString
& aEventTypeArg
);
319 already_AddRefed
<nsIContent
> GetTargetFromFrame();
321 friend class EventMessageAutoOverride
;
322 friend class PopupBlocker
;
323 friend class WantsPopupControlCheck
;
324 void SetWantsPopupControlCheck(bool aCheck
) {
325 mWantsPopupControlCheck
= aCheck
;
328 bool GetWantsPopupControlCheck() {
329 return IsTrusted() && mWantsPopupControlCheck
;
332 void SetComposed(bool aComposed
) { mEvent
->SetComposed(aComposed
); }
334 already_AddRefed
<EventTarget
> EnsureWebAccessibleRelatedTarget(
335 EventTarget
* aRelatedTarget
);
337 mozilla::WidgetEvent
* mEvent
;
338 RefPtr
<nsPresContext
> mPresContext
;
339 nsCOMPtr
<EventTarget
> mExplicitOriginalTarget
;
340 nsCOMPtr
<nsIGlobalObject
> mOwner
;
341 bool mEventIsInternal
;
342 bool mPrivateDataDuplicated
;
343 bool mIsMainThreadEvent
;
344 // True when popup control check should rely on event.type, not
345 // WidgetEvent.mMessage.
346 bool mWantsPopupControlCheck
;
350 * RAII helper-class to override an event's message (i.e. its DOM-exposed
351 * type), for as long as the object is alive. Restores the original
352 * EventMessage when destructed.
354 * Notable requirements:
355 * - The original & overriding messages must be known (not eUnidentifiedEvent).
356 * - The original & overriding messages must be different.
357 * - The passed-in Event must outlive this RAII helper.
359 class MOZ_RAII EventMessageAutoOverride
{
361 explicit EventMessageAutoOverride(Event
* aEvent
,
362 EventMessage aOverridingMessage
)
363 : mEvent(aEvent
), mOrigMessage(mEvent
->mEvent
->mMessage
) {
364 MOZ_ASSERT(aOverridingMessage
!= mOrigMessage
,
365 "Don't use this class if you're not actually overriding");
366 MOZ_ASSERT(aOverridingMessage
!= eUnidentifiedEvent
,
367 "Only use this class with a valid overriding EventMessage");
368 MOZ_ASSERT(mOrigMessage
!= eUnidentifiedEvent
&&
369 mEvent
->mEvent
->mSpecifiedEventTypeString
.IsEmpty(),
370 "Only use this class on events whose overridden type is "
371 "known (so we can restore it properly)");
373 mEvent
->mEvent
->mMessage
= aOverridingMessage
;
376 ~EventMessageAutoOverride() { mEvent
->mEvent
->mMessage
= mOrigMessage
; }
379 // Non-owning ref, which should be safe since we're a stack-allocated object
380 // with limited lifetime. Whoever creates us should keep mEvent alive.
381 Event
* const MOZ_NON_OWNING_REF mEvent
;
382 const EventMessage mOrigMessage
;
385 class MOZ_STACK_CLASS WantsPopupControlCheck
{
387 explicit WantsPopupControlCheck(Event
* aEvent
) : mEvent(aEvent
) {
388 mOriginalWantsPopupControlCheck
= mEvent
->GetWantsPopupControlCheck();
389 mEvent
->SetWantsPopupControlCheck(mEvent
->IsTrusted());
392 ~WantsPopupControlCheck() {
393 mEvent
->SetWantsPopupControlCheck(mOriginalWantsPopupControlCheck
);
398 bool mOriginalWantsPopupControlCheck
;
401 NS_DEFINE_STATIC_IID_ACCESSOR(Event
, NS_EVENT_IID
)
403 } // namespace mozilla::dom
405 already_AddRefed
<mozilla::dom::Event
> NS_NewDOMEvent(
406 mozilla::dom::EventTarget
* aOwner
, nsPresContext
* aPresContext
,
407 mozilla::WidgetEvent
* aEvent
);
409 #endif // mozilla_dom_Event_h_