1 // Copyright 2014 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.
5 #include "extensions/renderer/binding_generating_native_handler.h"
7 #include "extensions/renderer/script_context.h"
8 #include "extensions/renderer/v8_helpers.h"
10 namespace extensions
{
12 using namespace v8_helpers
;
14 BindingGeneratingNativeHandler::BindingGeneratingNativeHandler(
15 ScriptContext
* context
,
16 const std::string
& api_name
,
17 const std::string
& bind_to
)
18 : context_(context
), api_name_(api_name
), bind_to_(bind_to
) {}
20 v8::Local
<v8::Object
> BindingGeneratingNativeHandler::NewInstance() {
21 // This long sequence of commands effectively runs the JavaScript code,
22 // such that result[bind_to] is the compiled schema for |api_name|:
25 // result[bind_to] = require('binding').Binding.create(api_name).generate();
28 // Unfortunately using the v8 APIs makes that quite verbose.
29 // Each stage is marked with the code it executes.
30 v8::Isolate
* isolate
= context_
->isolate();
31 v8::EscapableHandleScope
scope(isolate
);
33 // Convert |api_name| and |bind_to| into their v8::Strings to pass
34 // through the v8 APIs.
35 v8::Local
<v8::String
> v8_api_name
;
36 v8::Local
<v8::String
> v8_bind_to
;
37 if (!ToV8String(isolate
, api_name_
, &v8_api_name
) ||
38 !ToV8String(isolate
, bind_to_
, &v8_bind_to
)) {
40 return v8::Local
<v8::Object
>();
43 v8::Local
<v8::Context
> v8_context
= context_
->v8_context();
45 // require('binding');
46 v8::Local
<v8::Object
> binding_module
;
47 if (!context_
->module_system()->Require("binding").ToLocal(&binding_module
)) {
49 return v8::Local
<v8::Object
>();
52 // require('binding').Binding;
53 v8::Local
<v8::Value
> binding_value
;
54 v8::Local
<v8::Object
> binding
;
55 if (!GetProperty(v8_context
, binding_module
, "Binding", &binding_value
) ||
56 !binding_value
->ToObject(v8_context
).ToLocal(&binding
)) {
58 return v8::Local
<v8::Object
>();
61 // require('binding').Binding.create;
62 v8::Local
<v8::Value
> create_binding_value
;
63 if (!GetProperty(v8_context
, binding
, "create", &create_binding_value
) ||
64 !create_binding_value
->IsFunction()) {
66 return v8::Local
<v8::Object
>();
68 v8::Local
<v8::Function
> create_binding
=
69 create_binding_value
.As
<v8::Function
>();
71 // require('Binding').Binding.create(api_name);
72 v8::Local
<v8::Value
> argv
[] = {v8_api_name
};
73 v8::Local
<v8::Value
> binding_instance_value
;
74 v8::Local
<v8::Object
> binding_instance
;
75 if (!CallFunction(v8_context
, create_binding
, binding
, arraysize(argv
), argv
,
76 &binding_instance_value
) ||
77 !binding_instance_value
->ToObject(v8_context
)
78 .ToLocal(&binding_instance
)) {
80 return v8::Local
<v8::Object
>();
83 // require('binding').Binding.create(api_name).generate;
84 v8::Local
<v8::Value
> generate_value
;
85 if (!GetProperty(v8_context
, binding_instance
, "generate", &generate_value
) ||
86 !generate_value
->IsFunction()) {
88 return v8::Local
<v8::Object
>();
90 v8::Local
<v8::Function
> generate
= generate_value
.As
<v8::Function
>();
92 // require('binding').Binding.create(api_name).generate();
93 v8::Local
<v8::Object
> object
= v8::Object::New(isolate
);
94 v8::Local
<v8::Value
> compiled_schema
;
95 if (!CallFunction(v8_context
, generate
, binding_instance
, 0, nullptr,
98 return v8::Local
<v8::Object
>();
102 // result[bind_to] = ...;
103 if (!SetProperty(v8_context
, object
, v8_bind_to
, compiled_schema
)) {
105 return v8::Local
<v8::Object
>();
108 return scope
.Escape(object
);
111 } // namespace extensions