Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / events / Event.h
blobcec4150bad3d529ced4fb705f36e624f85092fdb
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_
10 #include <cstdint>
11 #include "Units.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"
20 #include "nsCOMPtr.h"
21 #include "nsCycleCollectionParticipant.h"
22 #include "nsID.h"
23 #include "nsISupports.h"
24 #include "nsStringFwd.h"
25 #include "nsWrapperCache.h"
27 class PickleIterator;
28 class nsCycleCollectionTraversalCallback;
29 class nsIContent;
30 class nsIGlobalObject;
31 class nsIPrincipal;
32 class nsPIDOMWindowInner;
33 class nsPresContext;
35 namespace IPC {
36 class Message;
37 class MessageReader;
38 class MessageWriter;
39 } // namespace IPC
41 namespace mozilla::dom {
43 class BeforeUnloadEvent;
44 class CustomEvent;
45 class Document;
46 class DragEvent;
47 class EventTarget;
48 class EventMessageAutoOverride;
49 // ExtendableEvent is a ServiceWorker event that is not
50 // autogenerated since it has some extra methods.
51 class ExtendableEvent;
52 class KeyboardEvent;
53 class MouseEvent;
54 class MessageEvent;
55 class TimeEvent;
56 class UIEvent;
57 class WantsPopupControlCheck;
58 class XULCommandEvent;
59 struct EventInit;
61 #define GENERATED_EVENT(EventClass_) class EventClass_;
62 #include "mozilla/dom/GeneratedEventList.h"
63 #undef GENERATED_EVENT
65 // IID for Event
66 #define NS_EVENT_IID \
67 { \
68 0x71139716, 0x4d91, 0x4dee, { \
69 0xba, 0xf9, 0xe3, 0x3b, 0x80, 0xc1, 0x61, 0x61 \
70 } \
73 class Event : public nsISupports, public nsWrapperCache {
74 public:
75 NS_DECLARE_STATIC_IID_ACCESSOR(NS_EVENT_IID)
77 Event(EventTarget* aOwner, nsPresContext* aPresContext, WidgetEvent* aEvent);
78 explicit Event(nsPIDOMWindowInner* aWindow);
80 protected:
81 virtual ~Event();
83 private:
84 void ConstructorInit(EventTarget* aOwner, nsPresContext* aPresContext,
85 WidgetEvent* aEvent);
87 void UpdateDefaultPreventedOnContentForDragEvent();
89 public:
90 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
91 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Event)
93 nsIGlobalObject* GetParentObject() const { return mOwner; }
95 JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
97 virtual JSObject* WrapObjectInternal(JSContext* aCx,
98 JS::Handle<JSObject*> aGivenProto);
100 #define GENERATED_EVENT(EventClass_) \
101 virtual EventClass_* As##EventClass_() { return nullptr; }
102 #include "mozilla/dom/GeneratedEventList.h"
103 #undef GENERATED_EVENT
105 // ExtendableEvent is a ServiceWorker event that is not
106 // autogenerated since it has some extra methods.
107 virtual ExtendableEvent* AsExtendableEvent() { return nullptr; }
109 virtual TimeEvent* AsTimeEvent() { return nullptr; }
111 // BeforeUnloadEvent is not autogenerated because it has a setter.
112 virtual BeforeUnloadEvent* AsBeforeUnloadEvent() { return nullptr; }
114 // KeyboardEvent has all sorts of non-autogeneratable bits so far.
115 virtual KeyboardEvent* AsKeyboardEvent() { return nullptr; }
117 // DragEvent has a non-autogeneratable initDragEvent.
118 virtual DragEvent* AsDragEvent() { return nullptr; }
120 // XULCommandEvent has a non-autogeneratable initCommandEvent.
121 virtual XULCommandEvent* AsXULCommandEvent() { return nullptr; }
123 // MouseEvent has a non-autogeneratable initMouseEvent and other
124 // non-autogeneratable methods.
125 virtual MouseEvent* AsMouseEvent() { return nullptr; }
127 // UIEvent has a non-autogeneratable initUIEvent.
128 virtual UIEvent* AsUIEvent() { return nullptr; }
130 // CustomEvent has a non-autogeneratable initCustomEvent.
131 virtual CustomEvent* AsCustomEvent() { return nullptr; }
133 // MessageEvent has a non-autogeneratable initMessageEvent and more.
134 virtual MessageEvent* AsMessageEvent() { return nullptr; }
136 void InitEvent(const nsAString& aEventTypeArg, bool aCanBubble,
137 bool aCancelable) {
138 InitEvent(aEventTypeArg, aCanBubble ? CanBubble::eYes : CanBubble::eNo,
139 aCancelable ? Cancelable::eYes : Cancelable::eNo);
142 void InitEvent(const nsAString& aEventTypeArg, mozilla::CanBubble,
143 mozilla::Cancelable,
144 mozilla::Composed = mozilla::Composed::eDefault);
146 void SetTarget(EventTarget* aTarget);
147 virtual void DuplicatePrivateData();
148 bool IsDispatchStopped();
149 WidgetEvent* WidgetEventPtr();
150 const WidgetEvent* WidgetEventPtr() const {
151 return const_cast<Event*>(this)->WidgetEventPtr();
153 virtual void Serialize(IPC::MessageWriter* aWriter,
154 bool aSerializeInterfaceType);
155 virtual bool Deserialize(IPC::MessageReader* aReader);
156 void SetOwner(EventTarget* aOwner);
157 void StopCrossProcessForwarding();
158 void SetTrusted(bool aTrusted);
160 // When listening to chrome EventTargets, in the parent process, nsWindowRoot
161 // might receive events we've already handled via
162 // InProcessBrowserChildMessageManager, and handlers should call this to avoid
163 // handling the same event twice.
164 bool ShouldIgnoreChromeEventTargetListener() const;
166 void InitPresContextData(nsPresContext* aPresContext);
168 // Returns true if the event should be trusted.
169 bool Init(EventTarget* aGlobal);
171 static const char16_t* GetEventName(EventMessage aEventType);
172 static CSSIntPoint GetClientCoords(nsPresContext* aPresContext,
173 WidgetEvent* aEvent,
174 LayoutDeviceIntPoint aPoint,
175 CSSIntPoint aDefaultPoint);
176 static CSSIntPoint GetPageCoords(nsPresContext* aPresContext,
177 WidgetEvent* aEvent,
178 LayoutDeviceIntPoint aPoint,
179 CSSIntPoint aDefaultPoint);
180 static Maybe<CSSIntPoint> GetScreenCoords(nsPresContext* aPresContext,
181 WidgetEvent* aEvent,
182 LayoutDeviceIntPoint aPoint);
183 MOZ_CAN_RUN_SCRIPT_BOUNDARY
184 static CSSIntPoint GetOffsetCoords(nsPresContext* aPresContext,
185 WidgetEvent* aEvent,
186 LayoutDeviceIntPoint aPoint,
187 CSSIntPoint aDefaultPoint);
189 static already_AddRefed<Event> Constructor(EventTarget* aEventTarget,
190 const nsAString& aType,
191 const EventInit& aParam);
193 static already_AddRefed<Event> Constructor(const GlobalObject& aGlobal,
194 const nsAString& aType,
195 const EventInit& aParam);
197 void GetType(nsAString& aType) const;
199 EventTarget* GetTarget() const;
200 EventTarget* GetCurrentTarget() const;
202 // This method returns the document which is associated with the event target.
203 already_AddRefed<Document> GetDocument() const;
205 void ComposedPath(nsTArray<RefPtr<EventTarget>>& aPath);
207 uint16_t EventPhase() const;
209 void StopPropagation();
211 void StopImmediatePropagation();
213 bool Bubbles() const { return mEvent->mFlags.mBubbles; }
215 bool Cancelable() const { return mEvent->mFlags.mCancelable; }
217 bool Composed() const { return mEvent->mFlags.mComposed; }
219 bool CancelBubble() const { return mEvent->PropagationStopped(); }
220 void SetCancelBubble(bool aCancelBubble) {
221 if (aCancelBubble) {
222 mEvent->StopPropagation();
226 // For C++ consumers only!
227 void PreventDefault();
229 // You MUST NOT call PreventDefault(JSContext*, CallerType) from C++ code. A
230 // call of this method always sets Event.defaultPrevented true for web
231 // contents. If default action handler calls this, web applications see wrong
232 // defaultPrevented value.
233 virtual void PreventDefault(JSContext* aCx, CallerType aCallerType);
235 // You MUST NOT call DefaultPrevented(CallerType) from C++ code. This may
236 // return false even if PreventDefault() has been called.
237 // See comments in its implementation for the details.
238 bool DefaultPrevented(CallerType aCallerType) const;
240 bool DefaultPrevented() const { return mEvent->DefaultPrevented(); }
242 bool DefaultPreventedByChrome() const {
243 return mEvent->mFlags.mDefaultPreventedByChrome;
246 bool DefaultPreventedByContent() const {
247 return mEvent->mFlags.mDefaultPreventedByContent;
250 void PreventMultipleActions() {
251 mEvent->mFlags.mMultipleActionsPrevented = true;
254 bool MultipleActionsPrevented() const {
255 return mEvent->mFlags.mMultipleActionsPrevented;
258 bool ReturnValue(CallerType aCallerType) const;
260 void SetReturnValue(bool aReturnValue, CallerType aCallerType);
262 bool IsTrusted() const { return mEvent->IsTrusted(); }
264 bool IsSynthesized() const { return mEvent->mFlags.mIsSynthesizedForTests; }
266 bool IsSafeToBeDispatchedAsynchronously() const {
267 // If mEvent is not created by dom::Event nor its subclasses, its lifetime
268 // is not guaranteed. So, only when mEventIsInternal is true, it's safe
269 // to be dispatched asynchronously.
270 return mEventIsInternal;
273 double TimeStamp();
275 EventTarget* GetOriginalTarget() const;
276 EventTarget* GetExplicitOriginalTarget() const;
277 EventTarget* GetComposedTarget() const;
280 * @param aCalledByDefaultHandler Should be true when this is called by
281 * C++ or Chrome. Otherwise, e.g., called
282 * by a call of Event.preventDefault() in
283 * content script, false.
285 void PreventDefaultInternal(bool aCalledByDefaultHandler,
286 nsIPrincipal* aPrincipal = nullptr);
288 bool IsMainThreadEvent() { return mIsMainThreadEvent; }
290 void MarkUninitialized() {
291 mEvent->mMessage = eVoidEvent;
292 mEvent->mSpecifiedEventTypeString.Truncate();
293 mEvent->mSpecifiedEventType = nullptr;
297 * For WidgetEvent, return it's type in string.
299 * @param aEvent is a WidgetEvent to get its type.
300 * @param aType is a string where to return the type.
302 static void GetWidgetEventType(WidgetEvent* aEvent, nsAString& aType);
304 void RequestReplyFromRemoteContent() {
305 mEvent->MarkAsWaitingReplyFromRemoteProcess();
308 bool IsWaitingReplyFromRemoteContent() const {
309 return mEvent->IsWaitingReplyFromRemoteProcess();
312 bool IsReplyEventFromRemoteContent() const {
313 return mEvent->IsHandledInRemoteProcess();
316 static bool IsDragExitEnabled(JSContext* aCx, JSObject* aGlobal);
318 protected:
319 // Internal helper functions
320 void SetEventType(const nsAString& aEventTypeArg);
321 already_AddRefed<nsIContent> GetTargetFromFrame();
323 friend class EventMessageAutoOverride;
324 friend class PopupBlocker;
325 friend class WantsPopupControlCheck;
326 void SetWantsPopupControlCheck(bool aCheck) {
327 mWantsPopupControlCheck = aCheck;
330 bool GetWantsPopupControlCheck() {
331 return IsTrusted() && mWantsPopupControlCheck;
334 void SetComposed(bool aComposed) { mEvent->SetComposed(aComposed); }
336 already_AddRefed<EventTarget> EnsureWebAccessibleRelatedTarget(
337 EventTarget* aRelatedTarget);
339 mozilla::WidgetEvent* mEvent;
340 RefPtr<nsPresContext> mPresContext;
341 nsCOMPtr<EventTarget> mExplicitOriginalTarget;
342 nsCOMPtr<nsIGlobalObject> mOwner;
343 bool mEventIsInternal;
344 bool mPrivateDataDuplicated;
345 bool mIsMainThreadEvent;
346 // True when popup control check should rely on event.type, not
347 // WidgetEvent.mMessage.
348 bool mWantsPopupControlCheck;
352 * RAII helper-class to override an event's message (i.e. its DOM-exposed
353 * type), for as long as the object is alive. Restores the original
354 * EventMessage when destructed.
356 * Notable requirements:
357 * - The original & overriding messages must be known (not eUnidentifiedEvent).
358 * - The original & overriding messages must be different.
359 * - The passed-in Event must outlive this RAII helper.
361 class MOZ_RAII EventMessageAutoOverride {
362 public:
363 explicit EventMessageAutoOverride(Event* aEvent,
364 EventMessage aOverridingMessage)
365 : mEvent(aEvent), mOrigMessage(mEvent->mEvent->mMessage) {
366 MOZ_ASSERT(aOverridingMessage != mOrigMessage,
367 "Don't use this class if you're not actually overriding");
368 MOZ_ASSERT(aOverridingMessage != eUnidentifiedEvent,
369 "Only use this class with a valid overriding EventMessage");
370 MOZ_ASSERT(mOrigMessage != eUnidentifiedEvent &&
371 mEvent->mEvent->mSpecifiedEventTypeString.IsEmpty(),
372 "Only use this class on events whose overridden type is "
373 "known (so we can restore it properly)");
375 mEvent->mEvent->mMessage = aOverridingMessage;
378 ~EventMessageAutoOverride() { mEvent->mEvent->mMessage = mOrigMessage; }
380 protected:
381 // Non-owning ref, which should be safe since we're a stack-allocated object
382 // with limited lifetime. Whoever creates us should keep mEvent alive.
383 Event* const MOZ_NON_OWNING_REF mEvent;
384 const EventMessage mOrigMessage;
387 class MOZ_STACK_CLASS WantsPopupControlCheck {
388 public:
389 explicit WantsPopupControlCheck(Event* aEvent) : mEvent(aEvent) {
390 mOriginalWantsPopupControlCheck = mEvent->GetWantsPopupControlCheck();
391 mEvent->SetWantsPopupControlCheck(mEvent->IsTrusted());
394 ~WantsPopupControlCheck() {
395 mEvent->SetWantsPopupControlCheck(mOriginalWantsPopupControlCheck);
398 private:
399 Event* mEvent;
400 bool mOriginalWantsPopupControlCheck;
403 NS_DEFINE_STATIC_IID_ACCESSOR(Event, NS_EVENT_IID)
405 } // namespace mozilla::dom
407 already_AddRefed<mozilla::dom::Event> NS_NewDOMEvent(
408 mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext,
409 mozilla::WidgetEvent* aEvent);
411 #endif // mozilla_dom_Event_h_