Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: extensions/renderer/bindings/api_event_listeners.cc

Issue 2973903002: [Extensions Bindings] Introduce a supportsLazyListeners property (Closed)
Patch Set: onMessage event fix Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « extensions/renderer/bindings/api_event_listeners.h ('k') | extensions/renderer/bindings/api_event_listeners_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698