extensions: Register 'app' and 'webstore' bindings only if they are available.
[chromium-blink-merge.git] / gin / object_template_builder.h
blob3d025a9deb145337840c0737734d744ef302a67f
1 // Copyright 2013 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 #ifndef GIN_OBJECT_TEMPLATE_BUILDER_H_
6 #define GIN_OBJECT_TEMPLATE_BUILDER_H_
8 #include "base/bind.h"
9 #include "base/callback.h"
10 #include "base/strings/string_piece.h"
11 #include "base/template_util.h"
12 #include "gin/converter.h"
13 #include "gin/function_template.h"
14 #include "gin/gin_export.h"
15 #include "v8/include/v8.h"
17 namespace gin {
19 namespace {
21 // Base template - used only for non-member function pointers. Other types
22 // either go to one of the below specializations, or go here and fail to compile
23 // because of base::Bind().
24 template<typename T, typename Enable = void>
25 struct CallbackTraits {
26 static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
27 T callback) {
28 return CreateFunctionTemplate(isolate, base::Bind(callback));
30 static void SetAsFunctionHandler(v8::Isolate* isolate,
31 v8::Local<v8::ObjectTemplate> tmpl,
32 T callback) {
33 CreateFunctionHandler(isolate, tmpl, base::Bind(callback));
37 // Specialization for base::Callback.
38 template<typename T>
39 struct CallbackTraits<base::Callback<T> > {
40 static v8::Handle<v8::FunctionTemplate> CreateTemplate(
41 v8::Isolate* isolate, const base::Callback<T>& callback) {
42 return CreateFunctionTemplate(isolate, callback);
44 static void SetAsFunctionHandler(v8::Isolate* isolate,
45 v8::Local<v8::ObjectTemplate> tmpl,
46 const base::Callback<T>& callback) {
47 CreateFunctionHandler(isolate, tmpl, callback);
51 // Specialization for member function pointers. We need to handle this case
52 // specially because the first parameter for callbacks to MFP should typically
53 // come from the the JavaScript "this" object the function was called on, not
54 // from the first normal parameter.
55 template<typename T>
56 struct CallbackTraits<T, typename base::enable_if<
57 base::is_member_function_pointer<T>::value>::type> {
58 static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
59 T callback) {
60 return CreateFunctionTemplate(isolate, base::Bind(callback),
61 HolderIsFirstArgument);
63 static void SetAsFunctionHandler(v8::Isolate* isolate,
64 v8::Local<v8::ObjectTemplate> tmpl,
65 T callback) {
66 CreateFunctionHandler(
67 isolate, tmpl, base::Bind(callback), HolderIsFirstArgument);
71 // This specialization allows people to construct function templates directly if
72 // they need to do fancier stuff.
73 template<>
74 struct GIN_EXPORT CallbackTraits<v8::Handle<v8::FunctionTemplate> > {
75 static v8::Handle<v8::FunctionTemplate> CreateTemplate(
76 v8::Handle<v8::FunctionTemplate> templ) {
77 return templ;
81 } // namespace
84 // ObjectTemplateBuilder provides a handy interface to creating
85 // v8::ObjectTemplate instances with various sorts of properties.
86 class GIN_EXPORT ObjectTemplateBuilder {
87 public:
88 explicit ObjectTemplateBuilder(v8::Isolate* isolate);
89 ~ObjectTemplateBuilder();
91 // It's against Google C++ style to return a non-const ref, but we take some
92 // poetic license here in order that all calls to Set() can be via the '.'
93 // operator and line up nicely.
94 template<typename T>
95 ObjectTemplateBuilder& SetValue(const base::StringPiece& name, T val) {
96 return SetImpl(name, ConvertToV8(isolate_, val));
99 // In the following methods, T and U can be function pointer, member function
100 // pointer, base::Callback, or v8::FunctionTemplate. Most clients will want to
101 // use one of the first two options. Also see gin::CreateFunctionTemplate()
102 // for creating raw function templates.
103 template<typename T>
104 ObjectTemplateBuilder& SetMethod(const base::StringPiece& name,
105 const T& callback) {
106 return SetImpl(name, CallbackTraits<T>::CreateTemplate(isolate_, callback));
108 template<typename T>
109 ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
110 const T& getter) {
111 return SetPropertyImpl(name,
112 CallbackTraits<T>::CreateTemplate(isolate_, getter),
113 v8::Local<v8::FunctionTemplate>());
115 template<typename T, typename U>
116 ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
117 const T& getter, const U& setter) {
118 return SetPropertyImpl(name,
119 CallbackTraits<T>::CreateTemplate(isolate_, getter),
120 CallbackTraits<U>::CreateTemplate(isolate_, setter));
122 template<typename T>
123 ObjectTemplateBuilder& SetCallAsFunctionHandler(const T& callback) {
124 CallbackTraits<T>::SetAsFunctionHandler(isolate_, template_, callback);
125 return *this;
127 ObjectTemplateBuilder& AddNamedPropertyInterceptor();
128 ObjectTemplateBuilder& AddIndexedPropertyInterceptor();
130 v8::Local<v8::ObjectTemplate> Build();
132 private:
133 ObjectTemplateBuilder& SetImpl(const base::StringPiece& name,
134 v8::Handle<v8::Data> val);
135 ObjectTemplateBuilder& SetPropertyImpl(
136 const base::StringPiece& name, v8::Handle<v8::FunctionTemplate> getter,
137 v8::Handle<v8::FunctionTemplate> setter);
139 v8::Isolate* isolate_;
141 // ObjectTemplateBuilder should only be used on the stack.
142 v8::Local<v8::ObjectTemplate> template_;
145 } // namespace gin
147 #endif // GIN_OBJECT_TEMPLATE_BUILDER_H_