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

Side by Side Diff: extensions/renderer/api_event_handler.cc

Issue 2469593002: [Extensions Bindings] Add Events support (Closed)
Patch Set: EventEmitter Created 4 years, 1 month 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "extensions/renderer/api_event_handler.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/values.h"
13 #include "content/public/child/v8_value_converter.h"
14 #include "gin/arguments.h"
15 #include "gin/per_context_data.h"
16
17 namespace extensions {
18
19 namespace {
20
21 const char kExtensionAPIEventPerContextKey[] = "extension_api_events";
22
23 } // namespace
24
25 APIEventHandler::APIEventPerContextData::APIEventPerContextData() = default;
26 APIEventHandler::APIEventPerContextData::~APIEventPerContextData() = default;
27
28 APIEventHandler::APIEventHandler(const binding::RunJSFunction& call_js)
29 : call_js_(call_js), weak_factory_(this) {}
30 APIEventHandler::~APIEventHandler() {}
31
32 v8::Local<v8::Object> APIEventHandler::CreateEventInstance(
33 const std::string& event_name,
34 v8::Local<v8::Context> context) {
35 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
36 DCHECK(per_context_data);
37 APIEventPerContextData* data = static_cast<APIEventPerContextData*>(
38 per_context_data->GetUserData(kExtensionAPIEventPerContextKey));
39 if (!data) {
40 auto api_data = base::MakeUnique<APIEventPerContextData>();
41 data = api_data.get();
42 per_context_data->SetUserData(kExtensionAPIEventPerContextKey,
43 api_data.release());
44 }
45
46 DCHECK(data->event_data.find(event_name) == data->event_data.end());
47
48 auto emitter = base::MakeUnique<EventEmitter>();
49 v8::Local<v8::Object> event_object =
50 emitter->GetWrapper(context->GetIsolate());
51 data->event_data.insert(std::make_pair(event_name, std::move(emitter)));
Devlin 2016/11/02 00:48:29 Most places instead seem to do: gin::CreateHandle
jbroman 2016/11/02 19:50:14 It's perhaps not obvious from the comment in gin/w
Devlin 2016/11/02 22:02:21 is there a way to run a gc in a unittest so we can
jbroman 2016/11/03 19:28:04 Yup, isolate->RequestGarbageCollectionForTesting(v
Devlin 2016/11/04 17:59:29 Nifty, thanks!
52
53 return event_object;
54 }
55
56 void APIEventHandler::FireEventInContext(const std::string& event_name,
57 v8::Local<v8::Context> context,
58 const base::ListValue& args) {
59 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
60 DCHECK(per_context_data);
61 APIEventPerContextData* data = static_cast<APIEventPerContextData*>(
62 per_context_data->GetUserData(kExtensionAPIEventPerContextKey));
63 if (!data)
64 return;
65
66 auto iter = data->event_data.find(event_name);
67 if (iter == data->event_data.end())
68 return;
69
70 EventEmitter::Listeners* listeners = iter->second->listeners();
71
72 std::vector<v8::Local<v8::Value>> v8_args;
jbroman 2016/11/02 19:50:14 Just confirming that this is the behaviour you wan
Devlin 2016/11/02 22:02:21 Good call! I've checked and this is what we're cu
jbroman 2016/11/03 19:28:04 Thanks!
73 v8_args.reserve(args.GetSize());
74 std::unique_ptr<content::V8ValueConverter> converter(
75 content::V8ValueConverter::create());
76 for (const auto& arg : args)
77 v8_args.push_back(converter->ToV8Value(arg.get(), context));
78
79 for (auto& listener : *listeners) {
jbroman 2016/11/02 19:50:14 nit: const auto&
Devlin 2016/11/02 22:02:21 Done.
80 call_js_.Run(listener.Get(context->GetIsolate()), context, v8_args.size(),
81 v8_args.data());
82 }
83 }
84
85 const EventEmitter::Listeners&
86 APIEventHandler::GetEventListenersForTesting(const std::string& event_name,
87 v8::Local<v8::Context> context) {
88 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
89 DCHECK(per_context_data);
90 APIEventPerContextData* data = static_cast<APIEventPerContextData*>(
91 per_context_data->GetUserData(kExtensionAPIEventPerContextKey));
92 DCHECK(data);
93
94 auto iter = data->event_data.find(event_name);
95 DCHECK(iter != data->event_data.end());
96 return *iter->second->listeners();
97 }
98
99 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698