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 #include "mozilla/EventListenerManager.h"
8 #include "mozilla/dom/EventTarget.h"
9 #include "mozilla/dom/EventTargetBinding.h"
10 #include "mozilla/dom/ConstructibleEventTarget.h"
11 #include "mozilla/dom/Nullable.h"
12 #include "mozilla/dom/WindowProxyHolder.h"
13 #include "nsGlobalWindowInner.h"
14 #include "nsGlobalWindowOuter.h"
15 #include "nsIGlobalObject.h"
16 #include "nsPIDOMWindow.h"
17 #include "nsThreadUtils.h"
19 namespace mozilla::dom
{
22 already_AddRefed
<EventTarget
> EventTarget::Constructor(
23 const GlobalObject
& aGlobal
, ErrorResult
& aRv
) {
24 nsCOMPtr
<nsIGlobalObject
> global
= do_QueryInterface(aGlobal
.GetAsSupports());
26 aRv
.Throw(NS_ERROR_UNEXPECTED
);
29 RefPtr
<EventTarget
> target
= new ConstructibleEventTarget(global
);
30 return target
.forget();
33 bool EventTarget::ComputeWantsUntrusted(
34 const Nullable
<bool>& aWantsUntrusted
,
35 const AddEventListenerOptionsOrBoolean
* aOptions
, ErrorResult
& aRv
) {
36 if (aOptions
&& aOptions
->IsAddEventListenerOptions()) {
37 const auto& options
= aOptions
->GetAsAddEventListenerOptions();
38 if (options
.mWantUntrusted
.WasPassed()) {
39 return options
.mWantUntrusted
.Value();
43 if (!aWantsUntrusted
.IsNull()) {
44 return aWantsUntrusted
.Value();
47 bool defaultWantsUntrusted
= ComputeDefaultWantsUntrusted(aRv
);
52 return defaultWantsUntrusted
;
55 void EventTarget::AddEventListener(
56 const nsAString
& aType
, EventListener
* aCallback
,
57 const AddEventListenerOptionsOrBoolean
& aOptions
,
58 const Nullable
<bool>& aWantsUntrusted
, ErrorResult
& aRv
) {
59 bool wantsUntrusted
= ComputeWantsUntrusted(aWantsUntrusted
, &aOptions
, aRv
);
64 EventListenerManager
* elm
= GetOrCreateListenerManager();
66 aRv
.Throw(NS_ERROR_UNEXPECTED
);
70 elm
->AddEventListener(aType
, aCallback
, aOptions
, wantsUntrusted
);
73 nsresult
EventTarget::AddEventListener(const nsAString
& aType
,
74 nsIDOMEventListener
* aListener
,
76 const Nullable
<bool>& aWantsUntrusted
) {
78 bool wantsUntrusted
= ComputeWantsUntrusted(aWantsUntrusted
, nullptr, rv
);
80 return rv
.StealNSResult();
83 EventListenerManager
* elm
= GetOrCreateListenerManager();
85 elm
->AddEventListener(aType
, aListener
, aUseCapture
, wantsUntrusted
);
89 void EventTarget::RemoveEventListener(
90 const nsAString
& aType
, EventListener
* aListener
,
91 const EventListenerOptionsOrBoolean
& aOptions
, ErrorResult
& aRv
) {
92 EventListenerManager
* elm
= GetExistingListenerManager();
94 elm
->RemoveEventListener(aType
, aListener
, aOptions
);
98 void EventTarget::RemoveEventListener(const nsAString
& aType
,
99 nsIDOMEventListener
* aListener
,
101 EventListenerManager
* elm
= GetExistingListenerManager();
103 elm
->RemoveEventListener(aType
, aListener
, aUseCapture
);
107 nsresult
EventTarget::AddSystemEventListener(
108 const nsAString
& aType
, nsIDOMEventListener
* aListener
, bool aUseCapture
,
109 const Nullable
<bool>& aWantsUntrusted
) {
111 bool wantsUntrusted
= ComputeWantsUntrusted(aWantsUntrusted
, nullptr, rv
);
113 return rv
.StealNSResult();
116 EventListenerManager
* elm
= GetOrCreateListenerManager();
117 NS_ENSURE_STATE(elm
);
119 EventListenerFlags flags
;
120 flags
.mInSystemGroup
= true;
121 flags
.mCapture
= aUseCapture
;
122 flags
.mAllowUntrustedEvents
= wantsUntrusted
;
123 elm
->AddEventListenerByType(aListener
, aType
, flags
);
127 void EventTarget::RemoveSystemEventListener(const nsAString
& aType
,
128 nsIDOMEventListener
* aListener
,
130 EventListenerManager
* elm
= GetExistingListenerManager();
132 EventListenerFlags flags
;
133 flags
.mInSystemGroup
= true;
134 flags
.mCapture
= aUseCapture
;
135 elm
->RemoveEventListenerByType(aListener
, aType
, flags
);
139 EventHandlerNonNull
* EventTarget::GetEventHandler(nsAtom
* aType
) {
140 EventListenerManager
* elm
= GetExistingListenerManager();
141 return elm
? elm
->GetEventHandler(aType
) : nullptr;
144 void EventTarget::SetEventHandler(const nsAString
& aType
,
145 EventHandlerNonNull
* aHandler
,
147 if (!StringBeginsWith(aType
, u
"on"_ns
)) {
148 aRv
.Throw(NS_ERROR_INVALID_ARG
);
151 RefPtr
<nsAtom
> type
= NS_Atomize(aType
);
152 SetEventHandler(type
, aHandler
);
155 void EventTarget::SetEventHandler(nsAtom
* aType
,
156 EventHandlerNonNull
* aHandler
) {
157 GetOrCreateListenerManager()->SetEventHandler(aType
, aHandler
);
160 bool EventTarget::HasNonSystemGroupListenersForUntrustedKeyEvents() const {
161 EventListenerManager
* elm
= GetExistingListenerManager();
162 return elm
&& elm
->HasNonSystemGroupListenersForUntrustedKeyEvents();
165 bool EventTarget::HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents()
167 EventListenerManager
* elm
= GetExistingListenerManager();
169 elm
->HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents();
172 bool EventTarget::IsApzAware() const {
173 EventListenerManager
* elm
= GetExistingListenerManager();
174 return elm
&& elm
->HasApzAwareListeners();
177 void EventTarget::DispatchEvent(Event
& aEvent
) {
178 // The caller type doesn't really matter if we don't care about the
179 // return value, but let's be safe and pass NonSystem.
180 Unused
<< DispatchEvent(aEvent
, CallerType::NonSystem
, IgnoreErrors());
183 void EventTarget::DispatchEvent(Event
& aEvent
, ErrorResult
& aRv
) {
184 // The caller type doesn't really matter if we don't care about the
185 // return value, but let's be safe and pass NonSystem.
186 Unused
<< DispatchEvent(aEvent
, CallerType::NonSystem
, IgnoreErrors());
189 Nullable
<WindowProxyHolder
> EventTarget::GetOwnerGlobalForBindings() {
190 nsPIDOMWindowOuter
* win
= GetOwnerGlobalForBindingsInternal();
195 return WindowProxyHolder(win
->GetBrowsingContext());
198 nsPIDOMWindowInner
* EventTarget::GetAsWindowInner() {
199 return IsInnerWindow() ? static_cast<nsGlobalWindowInner
*>(this) : nullptr;
202 const nsPIDOMWindowInner
* EventTarget::GetAsWindowInner() const {
203 return IsInnerWindow() ? static_cast<const nsGlobalWindowInner
*>(this)
207 nsPIDOMWindowOuter
* EventTarget::GetAsWindowOuter() {
208 return IsOuterWindow() ? static_cast<nsGlobalWindowOuter
*>(this) : nullptr;
211 const nsPIDOMWindowOuter
* EventTarget::GetAsWindowOuter() const {
212 return IsOuterWindow() ? static_cast<const nsGlobalWindowOuter
*>(this)
216 nsPIDOMWindowInner
* EventTarget::AsWindowInner() {
217 MOZ_DIAGNOSTIC_ASSERT(IsInnerWindow());
218 return static_cast<nsGlobalWindowInner
*>(this);
221 const nsPIDOMWindowInner
* EventTarget::AsWindowInner() const {
222 MOZ_DIAGNOSTIC_ASSERT(IsInnerWindow());
223 return static_cast<const nsGlobalWindowInner
*>(this);
226 nsPIDOMWindowOuter
* EventTarget::AsWindowOuter() {
227 MOZ_DIAGNOSTIC_ASSERT(IsOuterWindow());
228 return static_cast<nsGlobalWindowOuter
*>(this);
231 const nsPIDOMWindowOuter
* EventTarget::AsWindowOuter() const {
232 MOZ_DIAGNOSTIC_ASSERT(IsOuterWindow());
233 return static_cast<const nsGlobalWindowOuter
*>(this);
236 } // namespace mozilla::dom