OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/renderer/event_emitter.h" | 5 #include "extensions/renderer/event_emitter.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "gin/object_template_builder.h" | 9 #include "gin/object_template_builder.h" |
10 #include "gin/per_context_data.h" | 10 #include "gin/per_context_data.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 .SetMethod("hasListeners", &EventEmitter::HasListeners) | 27 .SetMethod("hasListeners", &EventEmitter::HasListeners) |
28 // The following methods aren't part of the public API, but are used | 28 // The following methods aren't part of the public API, but are used |
29 // by our custom bindings and exposed on the public event object. :( | 29 // by our custom bindings and exposed on the public event object. :( |
30 // TODO(devlin): Once we convert all custom bindings that use these, | 30 // TODO(devlin): Once we convert all custom bindings that use these, |
31 // they can be removed. | 31 // they can be removed. |
32 .SetMethod("dispatch", &EventEmitter::Dispatch); | 32 .SetMethod("dispatch", &EventEmitter::Dispatch); |
33 } | 33 } |
34 | 34 |
35 void EventEmitter::Fire(v8::Local<v8::Context> context, | 35 void EventEmitter::Fire(v8::Local<v8::Context> context, |
36 std::vector<v8::Local<v8::Value>>* args) { | 36 std::vector<v8::Local<v8::Value>>* args) { |
37 for (const auto& listener : listeners_) { | 37 // We create a local copy of listeners_ since the array can be modified during |
38 run_js_.Run(listener.Get(context->GetIsolate()), context, args->size(), | 38 // handling. |
39 args->data()); | 39 std::vector<v8::Local<v8::Function>> listeners; |
40 } | 40 listeners.reserve(listeners_.size()); |
| 41 for (const auto& listener : listeners_) |
| 42 listeners.push_back(listener.Get(context->GetIsolate())); |
| 43 |
| 44 for (const auto& listener : listeners) |
| 45 run_js_.Run(listener, context, args->size(), args->data()); |
41 } | 46 } |
42 | 47 |
43 void EventEmitter::AddListener(gin::Arguments* arguments) { | 48 void EventEmitter::AddListener(gin::Arguments* arguments) { |
44 v8::Local<v8::Function> listener; | 49 v8::Local<v8::Function> listener; |
45 if (!arguments->GetNext(&listener)) | 50 if (!arguments->GetNext(&listener)) |
46 return; | 51 return; |
47 | 52 |
48 v8::Local<v8::Object> holder; | 53 v8::Local<v8::Object> holder; |
49 CHECK(arguments->GetHolder(&holder)); | 54 CHECK(arguments->GetHolder(&holder)); |
50 CHECK(!holder.IsEmpty()); | 55 CHECK(!holder.IsEmpty()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 } | 94 } |
90 } | 95 } |
91 if (!valid) { | 96 if (!valid) { |
92 arguments->ThrowTypeError("Invalid invocation"); | 97 arguments->ThrowTypeError("Invalid invocation"); |
93 return; | 98 return; |
94 } | 99 } |
95 Fire(context, &v8_args); | 100 Fire(context, &v8_args); |
96 } | 101 } |
97 | 102 |
98 } // namespace extensions | 103 } // namespace extensions |
OLD | NEW |