Chromium Code Reviews| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 for (const auto& listener : listeners) { | 45 for (const auto& listener : listeners) { |
| 46 v8::TryCatch try_catch(context->GetIsolate()); | 46 v8::TryCatch try_catch(context->GetIsolate()); |
| 47 // SetVerbose() means the error will still get logged, which is what we | 47 // SetVerbose() means the error will still get logged, which is what we |
| 48 // want. We don't let it bubble up any further to prevent it from being | 48 // want. We don't let it bubble up any further to prevent it from being |
| 49 // surfaced in e.g. JS code that triggered the event. | 49 // surfaced in e.g. JS code that triggered the event. |
| 50 try_catch.SetVerbose(true); | 50 try_catch.SetVerbose(true); |
| 51 run_js_.Run(listener, context, args->size(), args->data()); | 51 run_js_.Run(listener, context, args->size(), args->data()); |
| 52 } | 52 } |
| 53 } | 53 } |
| 54 | 54 |
| 55 void EventEmitter::Invalidate() { | |
| 56 valid_ = false; | |
| 57 listeners_.clear(); | |
| 58 } | |
| 59 | |
| 55 void EventEmitter::AddListener(gin::Arguments* arguments) { | 60 void EventEmitter::AddListener(gin::Arguments* arguments) { |
| 61 if (!valid_) | |
|
jbroman
2017/03/01 17:49:47
This won't catch such objects which don't are crea
Devlin
2017/03/01 19:03:50
Yeah, I still don't have a complete grasp of all t
jbroman
2017/03/01 19:26:34
Well, that's slightly later than WillReleaseScript
Devlin
2017/03/02 17:26:32
Done. Added comments in InvalidateContext() and a
| |
| 62 return; | |
| 63 | |
| 56 v8::Local<v8::Function> listener; | 64 v8::Local<v8::Function> listener; |
| 57 // TODO(devlin): For some reason, we don't throw an error when someone calls | 65 // TODO(devlin): For some reason, we don't throw an error when someone calls |
| 58 // add/removeListener with no argument. We probably should. For now, keep | 66 // add/removeListener with no argument. We probably should. For now, keep |
| 59 // the status quo, but we should revisit this. | 67 // the status quo, but we should revisit this. |
| 60 if (!arguments->GetNext(&listener)) | 68 if (!arguments->GetNext(&listener)) |
| 61 return; | 69 return; |
| 62 | 70 |
| 63 v8::Local<v8::Object> holder; | 71 v8::Local<v8::Object> holder; |
| 64 CHECK(arguments->GetHolder(&holder)); | 72 CHECK(arguments->GetHolder(&holder)); |
| 65 CHECK(!holder.IsEmpty()); | 73 CHECK(!holder.IsEmpty()); |
| 66 v8::Local<v8::Context> context = holder->CreationContext(); | 74 v8::Local<v8::Context> context = holder->CreationContext(); |
| 67 if (!gin::PerContextData::From(context)) | 75 if (!gin::PerContextData::From(context)) |
| 68 return; | 76 return; |
| 69 | 77 |
| 70 if (!HasListener(listener)) { | 78 if (!HasListener(listener)) { |
| 71 listeners_.push_back( | 79 listeners_.push_back( |
| 72 v8::Global<v8::Function>(arguments->isolate(), listener)); | 80 v8::Global<v8::Function>(arguments->isolate(), listener)); |
| 73 if (listeners_.size() == 1) { | 81 if (listeners_.size() == 1) { |
| 74 listeners_changed_.Run(binding::EventListenersChanged::HAS_LISTENERS, | 82 listeners_changed_.Run(binding::EventListenersChanged::HAS_LISTENERS, |
| 75 context); | 83 context); |
| 76 } | 84 } |
| 77 } | 85 } |
| 78 } | 86 } |
| 79 | 87 |
| 80 void EventEmitter::RemoveListener(gin::Arguments* arguments) { | 88 void EventEmitter::RemoveListener(gin::Arguments* arguments) { |
| 89 if (!valid_) | |
|
jbroman
2017/03/01 17:49:47
Isn't |listeners_| empty in this case anyhow?
Devlin
2017/03/01 19:03:50
Yep, but this seemed more obvious to readers. If
| |
| 90 return; | |
| 91 | |
| 81 v8::Local<v8::Function> listener; | 92 v8::Local<v8::Function> listener; |
| 82 // See comment in AddListener(). | 93 // See comment in AddListener(). |
| 83 if (!arguments->GetNext(&listener)) | 94 if (!arguments->GetNext(&listener)) |
| 84 return; | 95 return; |
| 85 | 96 |
| 86 auto iter = std::find(listeners_.begin(), listeners_.end(), listener); | 97 auto iter = std::find(listeners_.begin(), listeners_.end(), listener); |
| 87 if (iter != listeners_.end()) { | 98 if (iter != listeners_.end()) { |
| 88 listeners_.erase(iter); | 99 listeners_.erase(iter); |
| 89 if (listeners_.empty()) { | 100 if (listeners_.empty()) { |
| 90 v8::Local<v8::Object> holder; | 101 v8::Local<v8::Object> holder; |
| 91 CHECK(arguments->GetHolder(&holder)); | 102 CHECK(arguments->GetHolder(&holder)); |
| 92 CHECK(!holder.IsEmpty()); | 103 CHECK(!holder.IsEmpty()); |
| 93 v8::Local<v8::Context> context = holder->CreationContext(); | 104 v8::Local<v8::Context> context = holder->CreationContext(); |
| 94 listeners_changed_.Run(binding::EventListenersChanged::NO_LISTENERS, | 105 listeners_changed_.Run(binding::EventListenersChanged::NO_LISTENERS, |
| 95 context); | 106 context); |
| 96 } | 107 } |
| 97 } | 108 } |
| 98 } | 109 } |
| 99 | 110 |
| 100 bool EventEmitter::HasListener(v8::Local<v8::Function> listener) { | 111 bool EventEmitter::HasListener(v8::Local<v8::Function> listener) { |
| 101 return std::find(listeners_.begin(), listeners_.end(), listener) != | 112 return std::find(listeners_.begin(), listeners_.end(), listener) != |
| 102 listeners_.end(); | 113 listeners_.end(); |
| 103 } | 114 } |
| 104 | 115 |
| 105 bool EventEmitter::HasListeners() { | 116 bool EventEmitter::HasListeners() { |
| 106 return !listeners_.empty(); | 117 return !listeners_.empty(); |
| 107 } | 118 } |
| 108 | 119 |
| 109 void EventEmitter::Dispatch(gin::Arguments* arguments) { | 120 void EventEmitter::Dispatch(gin::Arguments* arguments) { |
| 121 DCHECK(valid_); | |
|
jbroman
2017/03/01 19:26:34
Should this be a DCHECK or an early return? Script
Devlin
2017/03/02 17:26:32
Oh, right, we had to expose this. Forgot about th
| |
| 122 | |
| 110 if (listeners_.empty()) | 123 if (listeners_.empty()) |
| 111 return; | 124 return; |
| 112 v8::HandleScope handle_scope(arguments->isolate()); | 125 v8::HandleScope handle_scope(arguments->isolate()); |
| 113 v8::Local<v8::Context> context = | 126 v8::Local<v8::Context> context = |
| 114 arguments->isolate()->GetCurrentContext(); | 127 arguments->isolate()->GetCurrentContext(); |
| 115 std::vector<v8::Local<v8::Value>> v8_args; | 128 std::vector<v8::Local<v8::Value>> v8_args; |
| 116 if (arguments->Length() > 0) { | 129 if (arguments->Length() > 0) { |
| 117 // Converting to v8::Values should never fail. | 130 // Converting to v8::Values should never fail. |
| 118 CHECK(arguments->GetRemaining(&v8_args)); | 131 CHECK(arguments->GetRemaining(&v8_args)); |
| 119 } | 132 } |
| 120 Fire(context, &v8_args); | 133 Fire(context, &v8_args); |
| 121 } | 134 } |
| 122 | 135 |
| 123 } // namespace extensions | 136 } // namespace extensions |
| OLD | NEW |