blob: 2d67bb8e65e1201e06f7b7fd33cee06018b39d27 [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
vmpstr98a2fad2015-11-30 20:15:178#include <type_traits>
9
[email protected]b520e132013-11-29 03:21:4810#include "base/bind.h"
[email protected]bf3dd3c2013-12-06 06:55:2511#include "base/callback.h"
[email protected]b520e132013-11-29 03:21:4812#include "base/strings/string_piece.h"
13#include "gin/converter.h"
14#include "gin/function_template.h"
[email protected]48c21632013-12-12 21:32:3415#include "gin/gin_export.h"
[email protected]b520e132013-11-29 03:21:4816#include "v8/include/v8.h"
17
18namespace gin {
19
Devlin Cronine9db9842018-04-09 17:51:0520namespace internal {
21
vmpstr98a2fad2015-11-30 20:15:1722template <typename T>
tzikc21a0dc2017-11-14 08:23:4423v8::Local<v8::FunctionTemplate> CreateFunctionTemplate(v8::Isolate* isolate,
Devlin Cronine9db9842018-04-09 17:51:0524 T callback,
25 const char* type_name) {
tzikc21a0dc2017-11-14 08:23:4426 // We need to handle member function pointers case specially because the first
27 // parameter for callbacks to MFP should typically come from the the
28 // JavaScript "this" object the function was called on, not from the first
29 // normal parameter.
Devlin Cronine9db9842018-04-09 17:51:0530 InvokerOptions options;
31 if (std::is_member_function_pointer<T>::value) {
32 options.holder_is_first_argument = true;
33 options.holder_type = type_name;
34 }
35 return ::gin::CreateFunctionTemplate(
36 isolate, base::BindRepeating(std::move(callback)), std::move(options));
tzikc21a0dc2017-11-14 08:23:4437}
[email protected]bf3dd3c2013-12-06 06:55:2538
Devlin Cronine9db9842018-04-09 17:51:0539} // namespace internal
40
tzikc21a0dc2017-11-14 08:23:4441template <typename T>
42void SetAsFunctionHandler(v8::Isolate* isolate,
43 v8::Local<v8::ObjectTemplate> tmpl,
44 T callback) {
45 // We need to handle member function pointers case specially because the first
46 // parameter for callbacks to MFP should typically come from the the
47 // JavaScript "this" object the function was called on, not from the first
48 // normal parameter.
Devlin Cronine9db9842018-04-09 17:51:0549 InvokerOptions options = {std::is_member_function_pointer<T>::value, nullptr};
[email protected]bf3dd3c2013-12-06 06:55:2550
tzikc21a0dc2017-11-14 08:23:4451 CreateFunctionHandler(isolate, tmpl, base::BindRepeating(std::move(callback)),
Devlin Cronine9db9842018-04-09 17:51:0552 std::move(options));
tzikc21a0dc2017-11-14 08:23:4453}
[email protected]bf3dd3c2013-12-06 06:55:2554
[email protected]b520e132013-11-29 03:21:4855// ObjectTemplateBuilder provides a handy interface to creating
56// v8::ObjectTemplate instances with various sorts of properties.
[email protected]48c21632013-12-12 21:32:3457class GIN_EXPORT ObjectTemplateBuilder {
[email protected]b520e132013-11-29 03:21:4858 public:
59 explicit ObjectTemplateBuilder(v8::Isolate* isolate);
Devlin Cronine9db9842018-04-09 17:51:0560 ObjectTemplateBuilder(v8::Isolate* isolate, const char* type_name);
vmpstr8ed6f862016-02-25 20:25:1461 ObjectTemplateBuilder(const ObjectTemplateBuilder& other);
[email protected]b520e132013-11-29 03:21:4862 ~ObjectTemplateBuilder();
63
64 // It's against Google C++ style to return a non-const ref, but we take some
65 // poetic license here in order that all calls to Set() can be via the '.'
66 // operator and line up nicely.
67 template<typename T>
68 ObjectTemplateBuilder& SetValue(const base::StringPiece& name, T val) {
69 return SetImpl(name, ConvertToV8(isolate_, val));
70 }
71
[email protected]bf3dd3c2013-12-06 06:55:2572 // In the following methods, T and U can be function pointer, member function
73 // pointer, base::Callback, or v8::FunctionTemplate. Most clients will want to
74 // use one of the first two options. Also see gin::CreateFunctionTemplate()
75 // for creating raw function templates.
[email protected]b520e132013-11-29 03:21:4876 template<typename T>
77 ObjectTemplateBuilder& SetMethod(const base::StringPiece& name,
[email protected]bf3dd3c2013-12-06 06:55:2578 const T& callback) {
Devlin Cronine9db9842018-04-09 17:51:0579 return SetImpl(
80 name, internal::CreateFunctionTemplate(isolate_, callback, type_name_));
[email protected]bf3dd3c2013-12-06 06:55:2581 }
82 template<typename T>
83 ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
84 const T& getter) {
Devlin Cronine9db9842018-04-09 17:51:0585 return SetPropertyImpl(
86 name, internal::CreateFunctionTemplate(isolate_, getter, type_name_),
87 v8::Local<v8::FunctionTemplate>());
[email protected]bf3dd3c2013-12-06 06:55:2588 }
89 template<typename T, typename U>
90 ObjectTemplateBuilder& SetProperty(const base::StringPiece& name,
91 const T& getter, const U& setter) {
Devlin Cronine9db9842018-04-09 17:51:0592 return SetPropertyImpl(
93 name, internal::CreateFunctionTemplate(isolate_, getter, type_name_),
94 internal::CreateFunctionTemplate(isolate_, setter, type_name_));
[email protected]b520e132013-11-29 03:21:4895 }
[email protected]5c969b82014-03-12 04:59:0596 ObjectTemplateBuilder& AddNamedPropertyInterceptor();
97 ObjectTemplateBuilder& AddIndexedPropertyInterceptor();
[email protected]b520e132013-11-29 03:21:4898
99 v8::Local<v8::ObjectTemplate> Build();
100
101 private:
102 ObjectTemplateBuilder& SetImpl(const base::StringPiece& name,
deepak.sfaaa1b62015-04-30 07:30:48103 v8::Local<v8::Data> val);
[email protected]bf3dd3c2013-12-06 06:55:25104 ObjectTemplateBuilder& SetPropertyImpl(
deepak.sfaaa1b62015-04-30 07:30:48105 const base::StringPiece& name, v8::Local<v8::FunctionTemplate> getter,
106 v8::Local<v8::FunctionTemplate> setter);
[email protected]b520e132013-11-29 03:21:48107
108 v8::Isolate* isolate_;
109
Devlin Cronine9db9842018-04-09 17:51:05110 // If provided, |type_name_| will be used to give a user-friendly error
111 // message if a member function is invoked on the wrong type of object.
112 const char* type_name_ = nullptr;
113
[email protected]b520e132013-11-29 03:21:48114 // ObjectTemplateBuilder should only be used on the stack.
115 v8::Local<v8::ObjectTemplate> template_;
116};
117
118} // namespace gin
119
120#endif // GIN_OBJECT_TEMPLATE_BUILDER_H_