Chromium Code Reviews| Index: extensions/renderer/api_binding_bridge.cc |
| diff --git a/extensions/renderer/api_binding_bridge.cc b/extensions/renderer/api_binding_bridge.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..264805684134ede7f976a4a805a4f57a8c63c442 |
| --- /dev/null |
| +++ b/extensions/renderer/api_binding_bridge.cc |
| @@ -0,0 +1,103 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "extensions/renderer/api_binding_bridge.h" |
| + |
| +#include "gin/converter.h" |
| +#include "gin/object_template_builder.h" |
| + |
| +namespace extensions { |
| + |
| +namespace { |
| + |
| +const char kApiObjectKey[] = "extensions::bridge::api_object"; |
| +const char kHookObjectKey[] = "extensions::bridge::hook_object"; |
| + |
| +v8::Local<v8::Private> GetPrivatePropertyName(v8::Isolate* isolate, |
| + const char* key) { |
| + return v8::Private::ForApi(isolate, gin::StringToSymbol(isolate, key)); |
| +} |
| + |
| +} // namespace |
| + |
| +gin::WrapperInfo APIBindingBridge::kWrapperInfo = {gin::kEmbedderNativeGin}; |
| + |
| +APIBindingBridge::APIBindingBridge(v8::Local<v8::Context> context, |
| + v8::Local<v8::Value> api_object, |
| + v8::Local<v8::Value> js_hook_interface, |
| + const std::string& extension_id, |
| + const std::string& context_type, |
| + const binding::RunJSFunction& run_js) |
| + : extension_id_(extension_id), |
| + context_type_(context_type), |
| + run_js_(run_js) { |
| + v8::Isolate* isolate = context->GetIsolate(); |
| + v8::Local<v8::Object> wrapper = GetWrapper(isolate); |
| + v8::Maybe<bool> result = wrapper->SetPrivate( |
| + context, GetPrivatePropertyName(isolate, kApiObjectKey), api_object); |
| + if (!result.IsJust() || !result.FromJust()) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + result = wrapper->SetPrivate(context, |
| + GetPrivatePropertyName(isolate, kHookObjectKey), |
| + js_hook_interface); |
| + DCHECK(result.IsJust() && result.FromJust()); |
| +} |
| + |
| +APIBindingBridge::~APIBindingBridge() {} |
| + |
| +gin::ObjectTemplateBuilder APIBindingBridge::GetObjectTemplateBuilder( |
| + v8::Isolate* isolate) { |
| + return Wrappable<APIBindingBridge>::GetObjectTemplateBuilder(isolate) |
| + .SetMethod("registerCustomHook", &APIBindingBridge::RegisterCustomHook); |
| +} |
| + |
| +void APIBindingBridge::RegisterCustomHook(v8::Isolate* isolate, |
| + v8::Local<v8::Function> function) { |
| + // The object and arguments here are meant to match those passed to the hook |
| + // functions in binding.js. |
| + v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| + v8::Local<v8::Object> hook_object = v8::Object::New(isolate); |
| + v8::Local<v8::Object> wrapper = GetWrapper(isolate); |
| + v8::Local<v8::Value> hook_interface; |
|
jbroman
2016/12/20 20:51:34
The naming is a little funny here, with kHookObjec
Devlin
2016/12/20 22:20:19
s/kHookObjectKey/kHookInterfaceKey
|
| + if (!wrapper |
| + ->GetPrivate(context, |
| + GetPrivatePropertyName(isolate, kHookObjectKey)) |
| + .ToLocal(&hook_interface)) { |
| + return; |
|
jbroman
2016/12/20 20:51:34
nit: It'd be pretty surprising for these private p
Devlin
2016/12/20 22:20:19
ToLocalChecked()'ing.
|
| + } |
| + v8::Maybe<bool> result = hook_object->CreateDataProperty( |
| + context, gin::StringToSymbol(isolate, "apiFunctions"), hook_interface); |
| + if (!result.IsJust() || !result.FromJust()) |
| + return; |
| + |
| + v8::Local<v8::Value> api_object; |
| + if (!wrapper |
| + ->GetPrivate(context, GetPrivatePropertyName(isolate, kApiObjectKey)) |
| + .ToLocal(&api_object)) { |
| + return; |
| + } |
| + result = hook_object->CreateDataProperty( |
| + context, gin::StringToSymbol(isolate, "compiledApi"), api_object); |
| + if (!result.IsJust() || !result.FromJust()) |
| + return; |
| + |
| + // TODO(devlin): The binding.js version of these hooks also has a 'schema' |
| + // property. I wonder if we can factor that out? If not, we'll need to add it |
| + // here. |
| + |
| + result = hook_object->SetPrototype(context, v8::Null(isolate)); |
| + if (!result.IsJust() || !result.FromJust()) |
| + return; |
| + |
| + v8::Local<v8::String> extension_id = |
| + gin::StringToSymbol(isolate, extension_id_); |
| + v8::Local<v8::String> context_type = |
| + gin::StringToSymbol(isolate, context_type_); |
| + v8::Local<v8::Value> args[] = {hook_object, extension_id, context_type}; |
| + run_js_.Run(function, context, arraysize(args), args); |
| +} |
| + |
| +} // namespace extensions |