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

Unified Diff: extensions/renderer/event_emitter.cc

Issue 2768093002: [Reland][Extensions Bindings] Add support for filtered events (Closed)
Patch Set: Fix Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « extensions/renderer/event_emitter.h ('k') | extensions/renderer/native_extension_bindings_system.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: extensions/renderer/event_emitter.cc
diff --git a/extensions/renderer/event_emitter.cc b/extensions/renderer/event_emitter.cc
index 82523e96aeef7458c56031d0531294bf8e8991e5..e6cd97721cff477f894d881cebcec3acaa6a6c11 100644
--- a/extensions/renderer/event_emitter.cc
+++ b/extensions/renderer/event_emitter.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "extensions/renderer/api_event_listeners.h"
#include "gin/object_template_builder.h"
#include "gin/per_context_data.h"
@@ -13,9 +14,12 @@ namespace extensions {
gin::WrapperInfo EventEmitter::kWrapperInfo = {gin::kEmbedderNativeGin};
-EventEmitter::EventEmitter(const binding::RunJSFunction& run_js,
- const ListenersChangedMethod& listeners_changed)
- : run_js_(run_js), listeners_changed_(listeners_changed) {}
+EventEmitter::EventEmitter(bool supports_filters,
+ std::unique_ptr<APIEventListeners> listeners,
+ const binding::RunJSFunction& run_js)
+ : supports_filters_(supports_filters),
+ listeners_(std::move(listeners)),
+ run_js_(run_js) {}
EventEmitter::~EventEmitter() {}
@@ -34,13 +38,11 @@ gin::ObjectTemplateBuilder EventEmitter::GetObjectTemplateBuilder(
}
void EventEmitter::Fire(v8::Local<v8::Context> context,
- std::vector<v8::Local<v8::Value>>* args) {
- // We create a local copy of listeners_ since the array can be modified during
- // handling.
- std::vector<v8::Local<v8::Function>> listeners;
- listeners.reserve(listeners_.size());
- for (const auto& listener : listeners_)
- listeners.push_back(listener.Get(context->GetIsolate()));
+ std::vector<v8::Local<v8::Value>>* args,
+ const EventFilteringInfo* filter) {
+ // Note that |listeners_| can be modified during handling.
+ std::vector<v8::Local<v8::Function>> listeners =
+ listeners_->GetListeners(filter, context);
for (const auto& listener : listeners) {
v8::TryCatch try_catch(context->GetIsolate());
@@ -52,9 +54,13 @@ void EventEmitter::Fire(v8::Local<v8::Context> context,
}
}
-void EventEmitter::Invalidate() {
+void EventEmitter::Invalidate(v8::Local<v8::Context> context) {
valid_ = false;
- listeners_.clear();
+ listeners_->Invalidate(context);
+}
+
+size_t EventEmitter::GetNumListeners() const {
+ return listeners_->GetNumListeners();
}
void EventEmitter::AddListener(gin::Arguments* arguments) {
@@ -72,6 +78,17 @@ void EventEmitter::AddListener(gin::Arguments* arguments) {
if (!arguments->GetNext(&listener))
return;
+ if (!arguments->PeekNext().IsEmpty() && !supports_filters_) {
+ arguments->ThrowTypeError("This event does not support filters");
+ return;
+ }
+
+ v8::Local<v8::Object> filter;
+ if (!arguments->PeekNext().IsEmpty() && !arguments->GetNext(&filter)) {
+ arguments->ThrowTypeError("Invalid invocation");
+ return;
+ }
+
v8::Local<v8::Object> holder;
CHECK(arguments->GetHolder(&holder));
CHECK(!holder.IsEmpty());
@@ -79,13 +96,10 @@ void EventEmitter::AddListener(gin::Arguments* arguments) {
if (!gin::PerContextData::From(context))
return;
- if (!HasListener(listener)) {
- listeners_.push_back(
- v8::Global<v8::Function>(arguments->isolate(), listener));
- if (listeners_.size() == 1) {
- listeners_changed_.Run(binding::EventListenersChanged::HAS_LISTENERS,
- context);
- }
+ std::string error;
+ if (!listeners_->AddListener(listener, filter, context, &error) &&
+ !error.empty()) {
+ arguments->ThrowTypeError(error);
}
}
@@ -99,34 +113,26 @@ void EventEmitter::RemoveListener(gin::Arguments* arguments) {
if (!arguments->GetNext(&listener))
return;
- auto iter = std::find(listeners_.begin(), listeners_.end(), listener);
- if (iter != listeners_.end()) {
- listeners_.erase(iter);
- if (listeners_.empty()) {
- v8::Local<v8::Object> holder;
- CHECK(arguments->GetHolder(&holder));
- CHECK(!holder.IsEmpty());
- v8::Local<v8::Context> context = holder->CreationContext();
- listeners_changed_.Run(binding::EventListenersChanged::NO_LISTENERS,
- context);
- }
- }
+ v8::Local<v8::Object> holder;
+ CHECK(arguments->GetHolder(&holder));
+ CHECK(!holder.IsEmpty());
+ v8::Local<v8::Context> context = holder->CreationContext();
+ listeners_->RemoveListener(listener, context);
}
bool EventEmitter::HasListener(v8::Local<v8::Function> listener) {
- return std::find(listeners_.begin(), listeners_.end(), listener) !=
- listeners_.end();
+ return listeners_->HasListener(listener);
}
bool EventEmitter::HasListeners() {
- return !listeners_.empty();
+ return listeners_->GetNumListeners() != 0;
}
void EventEmitter::Dispatch(gin::Arguments* arguments) {
if (!valid_)
return;
- if (listeners_.empty())
+ if (listeners_->GetNumListeners() == 0)
return;
v8::HandleScope handle_scope(arguments->isolate());
v8::Local<v8::Context> context =
@@ -136,7 +142,7 @@ void EventEmitter::Dispatch(gin::Arguments* arguments) {
// Converting to v8::Values should never fail.
CHECK(arguments->GetRemaining(&v8_args));
}
- Fire(context, &v8_args);
+ Fire(context, &v8_args, nullptr);
}
} // namespace extensions
« no previous file with comments | « extensions/renderer/event_emitter.h ('k') | extensions/renderer/native_extension_bindings_system.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698