Refactor Windows MessageBox fallback code.
[chromium-blink-merge.git] / gin / object_template_builder.h
blob6367b71245c81dbb70b12c926811d3a63e6d0ed8
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));
32 // Specialization for base::Callback.
33 template<typename T>
34 struct CallbackTraits<base::Callback<T> > {
35 static v8::Handle<v8::FunctionTemplate> CreateTemplate(
36 v8::Isolate* isolate, const base::Callback<T>& callback) {
37 return CreateFunctionTemplate(isolate, callback);
41 // Specialization for member function pointers. We need to handle this case
42 // specially because the first parameter for callbacks to MFP should typically
43 // come from the the JavaScript "this" object the function was called on, not
44 // from the first normal parameter.
45 template<typename T>
46 struct CallbackTraits<T, typename base::enable_if<
47 base::is_member_function_pointer<T>::value>::type> {
48 static v8::Handle<v8::FunctionTemplate> CreateTemplate(v8::Isolate* isolate,
49 T callback) {
50 return CreateFunctionTemplate(isolate, base::Bind(callback),
51 HolderIsFirstArgument);
55 // This specialization allows people to construct function templates directly if
56 // they need to do fancier stuff.
57 template<>
58 struct GIN_EXPORT CallbackTraits<v8::Handle<v8::FunctionTemplate> > {
59 static v8::Handle<v8::FunctionTemplate> CreateTemplate(
60 v8::Handle<v8::FunctionTemplate> templ) {
61 return templ;
65 } // namespace
68 // ObjectTemplateBuilder provides a handy interface to creating
69 // v8::ObjectTemplate instances with various sorts of properties.
70 class GIN_EXPORT ObjectTemplateBuilder {
71 public:
72 explicit ObjectTemplateBuilder(v8::Isolate* isolate);
73 ~ObjectTemplateBuilder();
75 // It's against Google C++ style to return a non-const ref, but we take some
76 // poetic license here in order that all calls to Set() can be via the '.'
77 // operator and line up nicely.
78 template<typename T>
79 ObjectTemplateBuilder& SetValue(const base::StringPiece& name, T val) {
80 return SetImpl(name, ConvertToV8(isolate_, val));
83 // In the following methods, T and U can be function pointer, member function
84 // pointer, base::Callback, or v8::FunctionTemplate. Most clients will want to
85 // use one of the first two options. Also see gin::CreateFunctionTemplate()
86 // for creating raw function templates.
87 template<typename T>
88 ObjectTemplateBuilder& SetMethod(const base::StringPiece& name,
89 const T& callback) {
90 return SetImpl(name, CallbackTraits<T>::CreateTemplate(isolate_, callback));
92 template<typename T>
93 ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
94 const T& getter) {
95 return SetPropertyImpl(name,
96 CallbackTraits<T>::CreateTemplate(isolate_, getter),
97 v8::Local<v8::FunctionTemplate>());
99 template<typename T, typename U>
100 ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
101 const T& getter, const U& setter) {
102 return SetPropertyImpl(name,
103 CallbackTraits<T>::CreateTemplate(isolate_, getter),
104 CallbackTraits<U>::CreateTemplate(isolate_, setter));
107 v8::Local<v8::ObjectTemplate> Build();
109 private:
110 ObjectTemplateBuilder& SetImpl(const base::StringPiece& name,
111 v8::Handle<v8::Data> val);
112 ObjectTemplateBuilder& SetPropertyImpl(
113 const base::StringPiece& name, v8::Handle<v8::FunctionTemplate> getter,
114 v8::Handle<v8::FunctionTemplate> setter);
116 v8::Isolate* isolate_;
118 // ObjectTemplateBuilder should only be used on the stack.
119 v8::Local<v8::ObjectTemplate> template_;
122 } // namespace gin
124 #endif // GIN_OBJECT_TEMPLATE_BUILDER_H_