| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/bindings/api_event_listeners.h" | 5 #include "extensions/renderer/bindings/api_event_listeners.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 } | 72 } |
| 73 | 73 |
| 74 *filter_dict = base::DictionaryValue::From(std::move(value)); | 74 *filter_dict = base::DictionaryValue::From(std::move(value)); |
| 75 return true; | 75 return true; |
| 76 } | 76 } |
| 77 | 77 |
| 78 } // namespace | 78 } // namespace |
| 79 | 79 |
| 80 UnfilteredEventListeners::UnfilteredEventListeners( | 80 UnfilteredEventListeners::UnfilteredEventListeners( |
| 81 const ListenersUpdated& listeners_updated, | 81 const ListenersUpdated& listeners_updated, |
| 82 int max_listeners) | 82 int max_listeners, |
| 83 : listeners_updated_(listeners_updated), max_listeners_(max_listeners) { | 83 bool supports_lazy_listeners) |
| 84 : listeners_updated_(listeners_updated), |
| 85 max_listeners_(max_listeners), |
| 86 supports_lazy_listeners_(supports_lazy_listeners) { |
| 84 DCHECK(max_listeners_ == binding::kNoListenerMax || max_listeners_ > 0); | 87 DCHECK(max_listeners_ == binding::kNoListenerMax || max_listeners_ > 0); |
| 85 } | 88 } |
| 86 UnfilteredEventListeners::~UnfilteredEventListeners() = default; | 89 UnfilteredEventListeners::~UnfilteredEventListeners() = default; |
| 87 | 90 |
| 88 bool UnfilteredEventListeners::AddListener(v8::Local<v8::Function> listener, | 91 bool UnfilteredEventListeners::AddListener(v8::Local<v8::Function> listener, |
| 89 v8::Local<v8::Object> filter, | 92 v8::Local<v8::Object> filter, |
| 90 v8::Local<v8::Context> context, | 93 v8::Local<v8::Context> context, |
| 91 std::string* error) { | 94 std::string* error) { |
| 92 // |filter| should be checked before getting here. | 95 // |filter| should be checked before getting here. |
| 93 DCHECK(filter.IsEmpty()) | 96 DCHECK(filter.IsEmpty()) |
| 94 << "Filtered events should use FilteredEventListeners"; | 97 << "Filtered events should use FilteredEventListeners"; |
| 95 | 98 |
| 96 if (HasListener(listener)) | 99 if (HasListener(listener)) |
| 97 return false; | 100 return false; |
| 98 | 101 |
| 99 if (max_listeners_ != binding::kNoListenerMax && | 102 if (max_listeners_ != binding::kNoListenerMax && |
| 100 listeners_.size() >= static_cast<size_t>(max_listeners_)) { | 103 listeners_.size() >= static_cast<size_t>(max_listeners_)) { |
| 101 *error = kErrorTooManyListeners; | 104 *error = kErrorTooManyListeners; |
| 102 return false; | 105 return false; |
| 103 } | 106 } |
| 104 | 107 |
| 105 listeners_.push_back( | 108 listeners_.push_back( |
| 106 v8::Global<v8::Function>(context->GetIsolate(), listener)); | 109 v8::Global<v8::Function>(context->GetIsolate(), listener)); |
| 107 if (listeners_.size() == 1) { | 110 if (listeners_.size() == 1) { |
| 108 listeners_updated_.Run(binding::EventListenersChanged::HAS_LISTENERS, | 111 listeners_updated_.Run(binding::EventListenersChanged::HAS_LISTENERS, |
| 109 nullptr, true, context); | 112 nullptr, supports_lazy_listeners_, context); |
| 110 } | 113 } |
| 111 | 114 |
| 112 return true; | 115 return true; |
| 113 } | 116 } |
| 114 | 117 |
| 115 void UnfilteredEventListeners::RemoveListener(v8::Local<v8::Function> listener, | 118 void UnfilteredEventListeners::RemoveListener(v8::Local<v8::Function> listener, |
| 116 v8::Local<v8::Context> context) { | 119 v8::Local<v8::Context> context) { |
| 117 auto iter = std::find(listeners_.begin(), listeners_.end(), listener); | 120 auto iter = std::find(listeners_.begin(), listeners_.end(), listener); |
| 118 if (iter == listeners_.end()) | 121 if (iter == listeners_.end()) |
| 119 return; | 122 return; |
| 120 | 123 |
| 121 listeners_.erase(iter); | 124 listeners_.erase(iter); |
| 122 if (listeners_.empty()) { | 125 if (listeners_.empty()) { |
| 123 listeners_updated_.Run(binding::EventListenersChanged::NO_LISTENERS, | 126 listeners_updated_.Run(binding::EventListenersChanged::NO_LISTENERS, |
| 124 nullptr, true, context); | 127 nullptr, supports_lazy_listeners_, context); |
| 125 } | 128 } |
| 126 } | 129 } |
| 127 | 130 |
| 128 bool UnfilteredEventListeners::HasListener(v8::Local<v8::Function> listener) { | 131 bool UnfilteredEventListeners::HasListener(v8::Local<v8::Function> listener) { |
| 129 return std::find(listeners_.begin(), listeners_.end(), listener) != | 132 return std::find(listeners_.begin(), listeners_.end(), listener) != |
| 130 listeners_.end(); | 133 listeners_.end(); |
| 131 } | 134 } |
| 132 | 135 |
| 133 size_t UnfilteredEventListeners::GetNumListeners() { | 136 size_t UnfilteredEventListeners::GetNumListeners() { |
| 134 return listeners_.size(); | 137 return listeners_.size(); |
| 135 } | 138 } |
| 136 | 139 |
| 137 std::vector<v8::Local<v8::Function>> UnfilteredEventListeners::GetListeners( | 140 std::vector<v8::Local<v8::Function>> UnfilteredEventListeners::GetListeners( |
| 138 const EventFilteringInfo* filter, | 141 const EventFilteringInfo* filter, |
| 139 v8::Local<v8::Context> context) { | 142 v8::Local<v8::Context> context) { |
| 140 std::vector<v8::Local<v8::Function>> listeners; | 143 std::vector<v8::Local<v8::Function>> listeners; |
| 141 listeners.reserve(listeners_.size()); | 144 listeners.reserve(listeners_.size()); |
| 142 for (const auto& listener : listeners_) | 145 for (const auto& listener : listeners_) |
| 143 listeners.push_back(listener.Get(context->GetIsolate())); | 146 listeners.push_back(listener.Get(context->GetIsolate())); |
| 144 return listeners; | 147 return listeners; |
| 145 } | 148 } |
| 146 | 149 |
| 147 void UnfilteredEventListeners::Invalidate(v8::Local<v8::Context> context) { | 150 void UnfilteredEventListeners::Invalidate(v8::Local<v8::Context> context) { |
| 148 if (!listeners_.empty()) { | 151 if (!listeners_.empty()) { |
| 149 listeners_.clear(); | 152 listeners_.clear(); |
| 153 // We don't want to update stored lazy listeners in this case, since the |
| 154 // extension didn't unregister interest in the event. |
| 155 bool update_lazy_listeners = false; |
| 150 listeners_updated_.Run(binding::EventListenersChanged::NO_LISTENERS, | 156 listeners_updated_.Run(binding::EventListenersChanged::NO_LISTENERS, |
| 151 nullptr, false, context); | 157 nullptr, update_lazy_listeners, context); |
| 152 } | 158 } |
| 153 } | 159 } |
| 154 | 160 |
| 155 struct FilteredEventListeners::ListenerData { | 161 struct FilteredEventListeners::ListenerData { |
| 156 bool operator==(v8::Local<v8::Function> other_function) const { | 162 bool operator==(v8::Local<v8::Function> other_function) const { |
| 157 // Note that we only consider the listener function here, and not the | 163 // Note that we only consider the listener function here, and not the |
| 158 // filter. This implies that it's invalid to try and add the same | 164 // filter. This implies that it's invalid to try and add the same |
| 159 // function for multiple filters. | 165 // function for multiple filters. |
| 160 // TODO(devlin): It's always been this way, but should it be? | 166 // TODO(devlin): It's always been this way, but should it be? |
| 161 return function == other_function; | 167 return function == other_function; |
| 162 } | 168 } |
| 163 | 169 |
| 164 v8::Global<v8::Function> function; | 170 v8::Global<v8::Function> function; |
| 165 int filter_id; | 171 int filter_id; |
| 166 }; | 172 }; |
| 167 | 173 |
| 168 FilteredEventListeners::FilteredEventListeners( | 174 FilteredEventListeners::FilteredEventListeners( |
| 169 const ListenersUpdated& listeners_updated, | 175 const ListenersUpdated& listeners_updated, |
| 170 const std::string& event_name, | 176 const std::string& event_name, |
| 171 int max_listeners, | 177 int max_listeners, |
| 178 bool supports_lazy_listeners, |
| 172 EventFilter* event_filter) | 179 EventFilter* event_filter) |
| 173 : listeners_updated_(listeners_updated), | 180 : listeners_updated_(listeners_updated), |
| 174 event_name_(event_name), | 181 event_name_(event_name), |
| 175 max_listeners_(max_listeners), | 182 max_listeners_(max_listeners), |
| 183 supports_lazy_listeners_(supports_lazy_listeners), |
| 176 event_filter_(event_filter) {} | 184 event_filter_(event_filter) {} |
| 177 FilteredEventListeners::~FilteredEventListeners() = default; | 185 FilteredEventListeners::~FilteredEventListeners() = default; |
| 178 | 186 |
| 179 bool FilteredEventListeners::AddListener(v8::Local<v8::Function> listener, | 187 bool FilteredEventListeners::AddListener(v8::Local<v8::Function> listener, |
| 180 v8::Local<v8::Object> filter, | 188 v8::Local<v8::Object> filter, |
| 181 v8::Local<v8::Context> context, | 189 v8::Local<v8::Context> context, |
| 182 std::string* error) { | 190 std::string* error) { |
| 183 if (HasListener(listener)) | 191 if (HasListener(listener)) |
| 184 return false; | 192 return false; |
| 185 | 193 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 201 *error = "Could not add listener"; | 209 *error = "Could not add listener"; |
| 202 return false; | 210 return false; |
| 203 } | 211 } |
| 204 | 212 |
| 205 const EventMatcher* matcher = event_filter_->GetEventMatcher(filter_id); | 213 const EventMatcher* matcher = event_filter_->GetEventMatcher(filter_id); |
| 206 DCHECK(matcher); | 214 DCHECK(matcher); |
| 207 listeners_.push_back( | 215 listeners_.push_back( |
| 208 {v8::Global<v8::Function>(context->GetIsolate(), listener), filter_id}); | 216 {v8::Global<v8::Function>(context->GetIsolate(), listener), filter_id}); |
| 209 if (value_counter_.Add(*matcher->value())) { | 217 if (value_counter_.Add(*matcher->value())) { |
| 210 listeners_updated_.Run(binding::EventListenersChanged::HAS_LISTENERS, | 218 listeners_updated_.Run(binding::EventListenersChanged::HAS_LISTENERS, |
| 211 matcher->value(), true, context); | 219 matcher->value(), supports_lazy_listeners_, context); |
| 212 } | 220 } |
| 213 | 221 |
| 214 return true; | 222 return true; |
| 215 } | 223 } |
| 216 | 224 |
| 217 void FilteredEventListeners::RemoveListener(v8::Local<v8::Function> listener, | 225 void FilteredEventListeners::RemoveListener(v8::Local<v8::Function> listener, |
| 218 v8::Local<v8::Context> context) { | 226 v8::Local<v8::Context> context) { |
| 219 auto iter = std::find(listeners_.begin(), listeners_.end(), listener); | 227 auto iter = std::find(listeners_.begin(), listeners_.end(), listener); |
| 220 if (iter == listeners_.end()) | 228 if (iter == listeners_.end()) |
| 221 return; | 229 return; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 } | 265 } |
| 258 | 266 |
| 259 void FilteredEventListeners::InvalidateListener( | 267 void FilteredEventListeners::InvalidateListener( |
| 260 const ListenerData& listener, | 268 const ListenerData& listener, |
| 261 bool was_manual, | 269 bool was_manual, |
| 262 v8::Local<v8::Context> context) { | 270 v8::Local<v8::Context> context) { |
| 263 EventMatcher* matcher = event_filter_->GetEventMatcher(listener.filter_id); | 271 EventMatcher* matcher = event_filter_->GetEventMatcher(listener.filter_id); |
| 264 DCHECK(matcher); | 272 DCHECK(matcher); |
| 265 if (value_counter_.Remove(*matcher->value())) { | 273 if (value_counter_.Remove(*matcher->value())) { |
| 266 listeners_updated_.Run(binding::EventListenersChanged::NO_LISTENERS, | 274 listeners_updated_.Run(binding::EventListenersChanged::NO_LISTENERS, |
| 267 matcher->value(), was_manual, context); | 275 matcher->value(), |
| 276 was_manual && supports_lazy_listeners_, context); |
| 268 } | 277 } |
| 269 | 278 |
| 270 event_filter_->RemoveEventMatcher(listener.filter_id); | 279 event_filter_->RemoveEventMatcher(listener.filter_id); |
| 271 } | 280 } |
| 272 | 281 |
| 273 } // namespace extensions | 282 } // namespace extensions |
| OLD | NEW |