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/. */
6
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 "nsIGlobalObject.h"
14 #include "nsThreadUtils.h"
15
16 namespace mozilla::dom {
17
18 /* static */
Constructor(const GlobalObject & aGlobal,ErrorResult & aRv)19 already_AddRefed<EventTarget> EventTarget::Constructor(
20 const GlobalObject& aGlobal, ErrorResult& aRv) {
21 nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
22 if (!global) {
23 aRv.Throw(NS_ERROR_UNEXPECTED);
24 return nullptr;
25 }
26 RefPtr<EventTarget> target = new ConstructibleEventTarget(global);
27 return target.forget();
28 }
29
ComputeWantsUntrusted(const Nullable<bool> & aWantsUntrusted,const AddEventListenerOptionsOrBoolean * aOptions,ErrorResult & aRv)30 bool EventTarget::ComputeWantsUntrusted(
31 const Nullable<bool>& aWantsUntrusted,
32 const AddEventListenerOptionsOrBoolean* aOptions, ErrorResult& aRv) {
33 if (aOptions && aOptions->IsAddEventListenerOptions()) {
34 const auto& options = aOptions->GetAsAddEventListenerOptions();
35 if (options.mWantUntrusted.WasPassed()) {
36 return options.mWantUntrusted.Value();
37 }
38 }
39
40 if (!aWantsUntrusted.IsNull()) {
41 return aWantsUntrusted.Value();
42 }
43
44 bool defaultWantsUntrusted = ComputeDefaultWantsUntrusted(aRv);
45 if (aRv.Failed()) {
46 return false;
47 }
48
49 return defaultWantsUntrusted;
50 }
51
AddEventListener(const nsAString & aType,EventListener * aCallback,const AddEventListenerOptionsOrBoolean & aOptions,const Nullable<bool> & aWantsUntrusted,ErrorResult & aRv)52 void EventTarget::AddEventListener(
53 const nsAString& aType, EventListener* aCallback,
54 const AddEventListenerOptionsOrBoolean& aOptions,
55 const Nullable<bool>& aWantsUntrusted, ErrorResult& aRv) {
56 bool wantsUntrusted = ComputeWantsUntrusted(aWantsUntrusted, &aOptions, aRv);
57 if (aRv.Failed()) {
58 return;
59 }
60
61 EventListenerManager* elm = GetOrCreateListenerManager();
62 if (!elm) {
63 aRv.Throw(NS_ERROR_UNEXPECTED);
64 return;
65 }
66
67 elm->AddEventListener(aType, aCallback, aOptions, wantsUntrusted);
68 }
69
AddEventListener(const nsAString & aType,nsIDOMEventListener * aListener,bool aUseCapture,const Nullable<bool> & aWantsUntrusted)70 nsresult EventTarget::AddEventListener(const nsAString& aType,
71 nsIDOMEventListener* aListener,
72 bool aUseCapture,
73 const Nullable<bool>& aWantsUntrusted) {
74 ErrorResult rv;
75 bool wantsUntrusted = ComputeWantsUntrusted(aWantsUntrusted, nullptr, rv);
76 if (rv.Failed()) {
77 return rv.StealNSResult();
78 }
79
80 EventListenerManager* elm = GetOrCreateListenerManager();
81 NS_ENSURE_STATE(elm);
82 elm->AddEventListener(aType, aListener, aUseCapture, wantsUntrusted);
83 return NS_OK;
84 }
85
RemoveEventListener(const nsAString & aType,EventListener * aListener,const EventListenerOptionsOrBoolean & aOptions,ErrorResult & aRv)86 void EventTarget::RemoveEventListener(
87 const nsAString& aType, EventListener* aListener,
88 const EventListenerOptionsOrBoolean& aOptions, ErrorResult& aRv) {
89 EventListenerManager* elm = GetExistingListenerManager();
90 if (elm) {
91 elm->RemoveEventListener(aType, aListener, aOptions);
92 }
93 }
94
RemoveEventListener(const nsAString & aType,nsIDOMEventListener * aListener,bool aUseCapture)95 void EventTarget::RemoveEventListener(const nsAString& aType,
96 nsIDOMEventListener* aListener,
97 bool aUseCapture) {
98 EventListenerManager* elm = GetExistingListenerManager();
99 if (elm) {
100 elm->RemoveEventListener(aType, aListener, aUseCapture);
101 }
102 }
103
AddSystemEventListener(const nsAString & aType,nsIDOMEventListener * aListener,bool aUseCapture,const Nullable<bool> & aWantsUntrusted)104 nsresult EventTarget::AddSystemEventListener(
105 const nsAString& aType, nsIDOMEventListener* aListener, bool aUseCapture,
106 const Nullable<bool>& aWantsUntrusted) {
107 ErrorResult rv;
108 bool wantsUntrusted = ComputeWantsUntrusted(aWantsUntrusted, nullptr, rv);
109 if (rv.Failed()) {
110 return rv.StealNSResult();
111 }
112
113 EventListenerManager* elm = GetOrCreateListenerManager();
114 NS_ENSURE_STATE(elm);
115
116 EventListenerFlags flags;
117 flags.mInSystemGroup = true;
118 flags.mCapture = aUseCapture;
119 flags.mAllowUntrustedEvents = wantsUntrusted;
120 elm->AddEventListenerByType(aListener, aType, flags);
121 return NS_OK;
122 }
123
RemoveSystemEventListener(const nsAString & aType,nsIDOMEventListener * aListener,bool aUseCapture)124 void EventTarget::RemoveSystemEventListener(const nsAString& aType,
125 nsIDOMEventListener* aListener,
126 bool aUseCapture) {
127 EventListenerManager* elm = GetExistingListenerManager();
128 if (elm) {
129 EventListenerFlags flags;
130 flags.mInSystemGroup = true;
131 flags.mCapture = aUseCapture;
132 elm->RemoveEventListenerByType(aListener, aType, flags);
133 }
134 }
135
GetEventHandler(nsAtom * aType)136 EventHandlerNonNull* EventTarget::GetEventHandler(nsAtom* aType) {
137 EventListenerManager* elm = GetExistingListenerManager();
138 return elm ? elm->GetEventHandler(aType) : nullptr;
139 }
140
SetEventHandler(const nsAString & aType,EventHandlerNonNull * aHandler,ErrorResult & aRv)141 void EventTarget::SetEventHandler(const nsAString& aType,
142 EventHandlerNonNull* aHandler,
143 ErrorResult& aRv) {
144 if (!StringBeginsWith(aType, u"on"_ns)) {
145 aRv.Throw(NS_ERROR_INVALID_ARG);
146 return;
147 }
148 RefPtr<nsAtom> type = NS_Atomize(aType);
149 SetEventHandler(type, aHandler);
150 }
151
SetEventHandler(nsAtom * aType,EventHandlerNonNull * aHandler)152 void EventTarget::SetEventHandler(nsAtom* aType,
153 EventHandlerNonNull* aHandler) {
154 GetOrCreateListenerManager()->SetEventHandler(aType, aHandler);
155 }
156
HasNonSystemGroupListenersForUntrustedKeyEvents() const157 bool EventTarget::HasNonSystemGroupListenersForUntrustedKeyEvents() const {
158 EventListenerManager* elm = GetExistingListenerManager();
159 return elm && elm->HasNonSystemGroupListenersForUntrustedKeyEvents();
160 }
161
HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents() const162 bool EventTarget::HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents()
163 const {
164 EventListenerManager* elm = GetExistingListenerManager();
165 return elm &&
166 elm->HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents();
167 }
168
IsApzAware() const169 bool EventTarget::IsApzAware() const {
170 EventListenerManager* elm = GetExistingListenerManager();
171 return elm && elm->HasApzAwareListeners();
172 }
173
DispatchEvent(Event & aEvent)174 void EventTarget::DispatchEvent(Event& aEvent) {
175 // The caller type doesn't really matter if we don't care about the
176 // return value, but let's be safe and pass NonSystem.
177 Unused << DispatchEvent(aEvent, CallerType::NonSystem, IgnoreErrors());
178 }
179
DispatchEvent(Event & aEvent,ErrorResult & aRv)180 void EventTarget::DispatchEvent(Event& aEvent, ErrorResult& aRv) {
181 // The caller type doesn't really matter if we don't care about the
182 // return value, but let's be safe and pass NonSystem.
183 Unused << DispatchEvent(aEvent, CallerType::NonSystem, IgnoreErrors());
184 }
185
GetOwnerGlobalForBindings()186 Nullable<WindowProxyHolder> EventTarget::GetOwnerGlobalForBindings() {
187 nsPIDOMWindowOuter* win = GetOwnerGlobalForBindingsInternal();
188 if (!win) {
189 return nullptr;
190 }
191
192 return WindowProxyHolder(win->GetBrowsingContext());
193 }
194
195 } // namespace mozilla::dom
196