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_
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"
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::Local
<v8::FunctionTemplate
> CreateTemplate(v8::Isolate
* isolate
,
28 return CreateFunctionTemplate(isolate
, base::Bind(callback
));
30 static void SetAsFunctionHandler(v8::Isolate
* isolate
,
31 v8::Local
<v8::ObjectTemplate
> tmpl
,
33 CreateFunctionHandler(isolate
, tmpl
, base::Bind(callback
));
37 // Specialization for base::Callback.
39 struct CallbackTraits
<base::Callback
<T
> > {
40 static v8::Local
<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.
56 struct CallbackTraits
<T
, typename
base::enable_if
<
57 base::is_member_function_pointer
<T
>::value
>::type
> {
58 static v8::Local
<v8::FunctionTemplate
> CreateTemplate(v8::Isolate
* isolate
,
60 return CreateFunctionTemplate(isolate
, base::Bind(callback
),
61 HolderIsFirstArgument
);
63 static void SetAsFunctionHandler(v8::Isolate
* isolate
,
64 v8::Local
<v8::ObjectTemplate
> tmpl
,
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.
74 struct CallbackTraits
<v8::Local
<v8::FunctionTemplate
> > {
75 static v8::Local
<v8::FunctionTemplate
> CreateTemplate(
76 v8::Local
<v8::FunctionTemplate
> templ
) {
84 // ObjectTemplateBuilder provides a handy interface to creating
85 // v8::ObjectTemplate instances with various sorts of properties.
86 class GIN_EXPORT ObjectTemplateBuilder
{
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.
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.
104 ObjectTemplateBuilder
& SetMethod(const base::StringPiece
& name
,
106 return SetImpl(name
, CallbackTraits
<T
>::CreateTemplate(isolate_
, callback
));
109 ObjectTemplateBuilder
& SetProperty(const base::StringPiece
& name
,
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
));
123 ObjectTemplateBuilder
& SetCallAsFunctionHandler(const T
& callback
) {
124 CallbackTraits
<T
>::SetAsFunctionHandler(isolate_
, template_
, callback
);
127 ObjectTemplateBuilder
& AddNamedPropertyInterceptor();
128 ObjectTemplateBuilder
& AddIndexedPropertyInterceptor();
130 v8::Local
<v8::ObjectTemplate
> Build();
133 ObjectTemplateBuilder
& SetImpl(const base::StringPiece
& name
,
134 v8::Local
<v8::Data
> val
);
135 ObjectTemplateBuilder
& SetPropertyImpl(
136 const base::StringPiece
& name
, v8::Local
<v8::FunctionTemplate
> getter
,
137 v8::Local
<v8::FunctionTemplate
> setter
);
139 v8::Isolate
* isolate_
;
141 // ObjectTemplateBuilder should only be used on the stack.
142 v8::Local
<v8::ObjectTemplate
> template_
;
147 #endif // GIN_OBJECT_TEMPLATE_BUILDER_H_