28 EventTarget::~EventTarget() {}
33 for (
auto& listener : listeners_) {
34 tracer->
Trace(&listener.callback_);
36 for (
auto& pair : on_listeners_) {
37 tracer->
Trace(pair.second);
42 if (FindListener(callback, type) != listeners_.end())
44 listeners_.emplace_back(callback, type);
48 std::function<
void()> callback) {
49 cpp_listeners_.emplace(
to_string(type), callback);
54 auto it = FindListener(callback, type);
55 if (it != listeners_.end()) {
56 if (is_dispatching_) {
57 it->should_remove_ =
true;
70 if (is_dispatching_) {
72 "Already dispatching events.");
75 if (did_listeners_throw)
76 *did_listeners_throw =
false;
77 is_dispatching_ =
true;
85 InvokeListeners(event, did_listeners_throw);
89 for (
auto it = listeners_.begin(); it != listeners_.end();) {
90 if (it->should_remove_)
91 it = listeners_.erase(it);
96 is_dispatching_ =
false;
98 event->current_target =
nullptr;
99 return !
event->default_prevented;
102 EventTarget::ListenerInfo::ListenerInfo(
Listener listener,
103 const std::string& type)
104 : callback_(listener), type_(type), should_remove_(
false) {}
106 EventTarget::ListenerInfo::~ListenerInfo() {}
109 bool* did_listeners_throw) {
110 if (event->is_stopped())
113 event->current_target =
this;
117 if (cpp_listeners_.count(event->type) > 0)
118 cpp_listeners_.at(event->type)();
123 auto on_iter = on_listeners_.find(event->type);
124 if (on_iter != on_listeners_.end()) {
127 if (on_iter->second->has_value()) {
129 on_iter->second->value().CallWithThis(
this, event);
130 if (holds_alternative<JsError>(except)) {
133 if (did_listeners_throw)
134 *did_listeners_throw =
true;
136 if (event->is_immediate_stopped()) {
142 if (listeners_.empty())
148 auto end = --listeners_.end();
154 auto it = listeners_.begin();
156 if (it->should_remove_)
159 if (it->type_ == event->type && it->callback_.has_value()) {
161 if (holds_alternative<JsError>(except)) {
164 if (did_listeners_throw)
165 *did_listeners_throw =
true;
169 if (event->is_immediate_stopped())
171 }
while ((it++) != end);
174 std::list<EventTarget::ListenerInfo>::iterator EventTarget::FindListener(
175 const Listener& callback,
const std::string& type) {
176 auto it = listeners_.begin();
177 for (; it != listeners_.end(); it++) {
178 if (it->type_ == type && callback == it->callback_) {
ExceptionOr< bool > DispatchEventInternal(RefPtr< Event > event, bool *did_listeners_throw)
void Trace(memory::HeapTracer *tracer) const override
void Trace(const Traceable *ptr)
void RemoveEventListener(const std::string &type, Listener callback)
void UnsetCppEventListener(EventType type)
void Trace(memory::HeapTracer *tracer) const override
ExceptionOr< bool > DispatchEvent(RefPtr< Event > event)
void AddEventListener(const std::string &type, Listener callback)
static JsError DOMException(ExceptionCode code)
void OnUncaughtException(JSValueRef exception, bool in_promise)
void SetCppEventListener(EventType type, std::function< void()> callback)