blob: 3d025a9deb145337840c0737734d744ef302a67f [file] [log] [blame]
[email protected]b520e132013-11-29 03:21:481// 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.
4
5#ifndef GIN_OBJECT_TEMPLATE_BUILDER_H_
6#define GIN_OBJECT_TEMPLATE_BUILDER_H_
7
8#include "base/bind.h"
[email protected]bf3dd3c2013-12-06 06:55:259#include "base/callback.h"
[email protected]b520e132013-11-29 03:21:4810#include "base/strings/string_piece.h"
[email protected]bf3dd3c2013-12-06 06:55:2511#include "base/template_util.h"
[email protected]b520e132013-11-29 03:21:4812#include "gin/converter.h"
13#include "gin/function_template.h"
[email protected]48c21632013-12-12 21:32:3414#include "gin/gin_export.h"
[email protected]b520e132013-11-29 03:21:4815#include "v8/include/v8.h"
16
17namespace gin {
18
[email protected]bf3dd3c2013-12-06 06:55:2519namespace {
20
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().
24template<typename T, typename Enable = void>
25struct CallbackTraits {
26 static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
27 T callback) {
28 return CreateFunctionTemplate(isolate, base::Bind(callback));
29 }
[email protected]777183d02014-03-10 12:55:1930 static void SetAsFunctionHandler(v8::Isolate* isolate,
31 v8::Local<v8::ObjectTemplate> tmpl,
32 T callback) {
33 CreateFunctionHandler(isolate, tmpl, base::Bind(callback));
34 }
[email protected]bf3dd3c2013-12-06 06:55:2535};
36
37// Specialization for base::Callback.
38template<typename T>
39struct 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);
43 }
[email protected]777183d02014-03-10 12:55:1944 static void SetAsFunctionHandler(v8::Isolate* isolate,
45 v8::Local<v8::ObjectTemplate> tmpl,
46 const base::Callback<T>& callback) {
47 CreateFunctionHandler(isolate, tmpl, callback);
48 }
[email protected]bf3dd3c2013-12-06 06:55:2549};
50
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.
55template<typename T>
56struct CallbackTraits<T, typename base::enable_if<
[email protected]6fe56102013-12-08 07:10:5857 base::is_member_function_pointer<T>::value>::type> {
[email protected]bf3dd3c2013-12-06 06:55:2558 static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
59 T callback) {
60 return CreateFunctionTemplate(isolate, base::Bind(callback),
61 HolderIsFirstArgument);
62 }
[email protected]777183d02014-03-10 12:55:1963 static void SetAsFunctionHandler(v8::Isolate* isolate,
64 v8::Local<v8::ObjectTemplate> tmpl,
65 T callback) {
66 CreateFunctionHandler(
67 isolate, tmpl, base::Bind(callback), HolderIsFirstArgument);
68 }
[email protected]bf3dd3c2013-12-06 06:55:2569};
70
71// This specialization allows people to construct function templates directly if
72// they need to do fancier stuff.
73template<>
[email protected]48c21632013-12-12 21:32:3474struct GIN_EXPORT CallbackTraits<v8::Handle<v8::FunctionTemplate> > {
[email protected]bf3dd3c2013-12-06 06:55:2575 static v8::Handle<v8::FunctionTemplate> CreateTemplate(
76 v8::Handle<v8::FunctionTemplate> templ) {
77 return templ;
78 }
79};
80
81} // namespace
82
83
[email protected]b520e132013-11-29 03:21:4884// ObjectTemplateBuilder provides a handy interface to creating
85// v8::ObjectTemplate instances with various sorts of properties.
[email protected]48c21632013-12-12 21:32:3486class GIN_EXPORT ObjectTemplateBuilder {
[email protected]b520e132013-11-29 03:21:4887 public:
88 explicit ObjectTemplateBuilder(v8::Isolate* isolate);
89 ~ObjectTemplateBuilder();
90
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));
97 }
98
[email protected]bf3dd3c2013-12-06 06:55:2599 // 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.
[email protected]b520e132013-11-29 03:21:48103 template<typename T>
104 ObjectTemplateBuilder& SetMethod(const base::StringPiece& name,
[email protected]bf3dd3c2013-12-06 06:55:25105 const T& callback) {
106 return SetImpl(name, CallbackTraits<T>::CreateTemplate(isolate_, callback));
107 }
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>());
114 }
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));
[email protected]b520e132013-11-29 03:21:48121 }
[email protected]777183d02014-03-10 12:55:19122 template<typename T>
123 ObjectTemplateBuilder& SetCallAsFunctionHandler(const T& callback) {
124 CallbackTraits<T>::SetAsFunctionHandler(isolate_, template_, callback);
125 return *this;
126 }
[email protected]5c969b82014-03-12 04:59:05127 ObjectTemplateBuilder& AddNamedPropertyInterceptor();
128 ObjectTemplateBuilder& AddIndexedPropertyInterceptor();
[email protected]b520e132013-11-29 03:21:48129
130 v8::Local<v8::ObjectTemplate> Build();
131
132 private:
133 ObjectTemplateBuilder& SetImpl(const base::StringPiece& name,
134 v8::Handle<v8::Data> val);
[email protected]bf3dd3c2013-12-06 06:55:25135 ObjectTemplateBuilder& SetPropertyImpl(
136 const base::StringPiece& name, v8::Handle<v8::FunctionTemplate> getter,
137 v8::Handle<v8::FunctionTemplate> setter);
[email protected]b520e132013-11-29 03:21:48138
139 v8::Isolate* isolate_;
140
141 // ObjectTemplateBuilder should only be used on the stack.
142 v8::Local<v8::ObjectTemplate> template_;
143};
144
145} // namespace gin
146
147#endif // GIN_OBJECT_TEMPLATE_BUILDER_H_