Index: extensions/renderer/api_event_handler.cc |
diff --git a/extensions/renderer/api_event_handler.cc b/extensions/renderer/api_event_handler.cc |
index 33de4ff74f545f85bec5089552c056d84582e8f0..f3b4c8476780c9771575af046ae861f3e41e1097 100644 |
--- a/extensions/renderer/api_event_handler.cc |
+++ b/extensions/renderer/api_event_handler.cc |
@@ -15,6 +15,7 @@ |
#include "base/supports_user_data.h" |
#include "base/values.h" |
#include "content/public/child/v8_value_converter.h" |
+#include "extensions/renderer/api_event_listeners.h" |
#include "extensions/renderer/event_emitter.h" |
#include "gin/handle.h" |
#include "gin/per_context_data.h" |
@@ -24,6 +25,7 @@ namespace extensions { |
namespace { |
void DoNothingOnListenersChanged(binding::EventListenersChanged change, |
+ const base::DictionaryValue* filter, |
v8::Local<v8::Context> context) {} |
const char kExtensionAPIEventPerContextKey[] = "extension_api_events"; |
@@ -98,7 +100,7 @@ void DispatchEvent(const v8::FunctionCallbackInfo<v8::Value>& info) { |
gin::Converter<EventEmitter*>::FromV8(isolate, v8_emitter.Get(isolate), |
&emitter); |
CHECK(emitter); |
- emitter->Fire(context, &args); |
+ emitter->Fire(context, &args, nullptr); |
} |
} // namespace |
@@ -111,6 +113,7 @@ APIEventHandler::~APIEventHandler() {} |
v8::Local<v8::Object> APIEventHandler::CreateEventInstance( |
const std::string& event_name, |
+ bool supports_filters, |
v8::Local<v8::Context> context) { |
// We need a context scope since gin::CreateHandle only takes the isolate |
// and infers the context from that. |
@@ -121,9 +124,19 @@ v8::Local<v8::Object> APIEventHandler::CreateEventInstance( |
APIEventPerContextData* data = GetContextData(context, true); |
DCHECK(data->emitters.find(event_name) == data->emitters.end()); |
+ APIEventListeners::ListenersUpdated updated = |
+ base::Bind(listeners_changed_, event_name); |
+ std::unique_ptr<APIEventListeners> listeners; |
+ if (supports_filters) { |
+ listeners = base::MakeUnique<FilteredEventListeners>(updated, event_name, |
+ &event_filter_); |
+ } else { |
+ listeners = base::MakeUnique<UnfilteredEventListeners>(updated); |
+ } |
+ |
gin::Handle<EventEmitter> emitter_handle = gin::CreateHandle( |
context->GetIsolate(), |
- new EventEmitter(call_js_, base::Bind(listeners_changed_, event_name))); |
+ new EventEmitter(supports_filters, std::move(listeners), call_js_)); |
CHECK(!emitter_handle.IsEmpty()); |
v8::Local<v8::Value> emitter_value = emitter_handle.ToV8(); |
CHECK(emitter_value->IsObject()); |
@@ -139,9 +152,13 @@ v8::Local<v8::Object> APIEventHandler::CreateAnonymousEventInstance( |
v8::Local<v8::Context> context) { |
v8::Context::Scope context_scope(context); |
APIEventPerContextData* data = GetContextData(context, true); |
+ bool supports_filters = false; |
+ std::unique_ptr<APIEventListeners> listeners = |
+ base::MakeUnique<UnfilteredEventListeners>( |
+ base::Bind(&DoNothingOnListenersChanged)); |
gin::Handle<EventEmitter> emitter_handle = gin::CreateHandle( |
context->GetIsolate(), |
- new EventEmitter(call_js_, base::Bind(&DoNothingOnListenersChanged))); |
+ new EventEmitter(supports_filters, std::move(listeners), call_js_)); |
CHECK(!emitter_handle.IsEmpty()); |
v8::Local<v8::Object> emitter_object = emitter_handle.ToV8().As<v8::Object>(); |
data->anonymous_emitters.push_back( |
@@ -159,7 +176,7 @@ void APIEventHandler::InvalidateCustomEvent(v8::Local<v8::Context> context, |
return; |
} |
- emitter->Invalidate(); |
+ emitter->Invalidate(context); |
auto emitter_entry = std::find(data->anonymous_emitters.begin(), |
data->anonymous_emitters.end(), event); |
if (emitter_entry == data->anonymous_emitters.end()) { |
@@ -172,7 +189,8 @@ void APIEventHandler::InvalidateCustomEvent(v8::Local<v8::Context> context, |
void APIEventHandler::FireEventInContext(const std::string& event_name, |
v8::Local<v8::Context> context, |
- const base::ListValue& args) { |
+ const base::ListValue& args, |
+ const EventFilteringInfo& filter) { |
APIEventPerContextData* data = GetContextData(context, false); |
if (!data) |
return; |
@@ -187,7 +205,7 @@ void APIEventHandler::FireEventInContext(const std::string& event_name, |
&emitter); |
CHECK(emitter); |
- if (emitter->listeners()->empty()) |
+ if (emitter->GetNumListeners() == 0u) |
return; |
// Note: since we only convert the arguments once, if a listener modifies an |
@@ -202,7 +220,7 @@ void APIEventHandler::FireEventInContext(const std::string& event_name, |
v8_args.reserve(args.GetSize()); |
for (const auto& arg : args) |
v8_args.push_back(converter->ToV8Value(arg.get(), context)); |
- emitter->Fire(context, &v8_args); |
+ emitter->Fire(context, &v8_args, &filter); |
} else { |
v8::Isolate* isolate = context->GetIsolate(); |
v8::HandleScope handle_scope(isolate); |
@@ -253,17 +271,14 @@ void APIEventHandler::InvalidateContext(v8::Local<v8::Context> context) { |
gin::Converter<EventEmitter*>::FromV8(isolate, pair.second.Get(isolate), |
&emitter); |
CHECK(emitter); |
- emitter->Invalidate(); |
- // When the context is shut down, all listeners are removed. |
- listeners_changed_.Run( |
- pair.first, binding::EventListenersChanged::NO_LISTENERS, context); |
+ emitter->Invalidate(context); |
} |
for (const auto& global : data->anonymous_emitters) { |
EventEmitter* emitter = nullptr; |
gin::Converter<EventEmitter*>::FromV8(isolate, global.Get(isolate), |
&emitter); |
CHECK(emitter); |
- emitter->Invalidate(); |
+ emitter->Invalidate(context); |
} |
data->emitters.clear(); |
@@ -288,7 +303,7 @@ size_t APIEventHandler::GetNumEventListenersForTesting( |
gin::Converter<EventEmitter*>::FromV8( |
context->GetIsolate(), iter->second.Get(context->GetIsolate()), &emitter); |
CHECK(emitter); |
- return emitter->listeners()->size(); |
+ return emitter->GetNumListeners(); |
} |
} // namespace extensions |