/
react.go
127 lines (111 loc) · 2.42 KB
/
react.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package react
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
)
type React struct {
pool *Pool
opt *Option
}
// Create a new react object.
func NewReact() (*React, error) {
return NewReactWithOption(DefaultReactOption())
}
// Create a new react object using option.
// opt: Option for react object.
func NewReactWithOption(opt *Option) (*React, error) {
if opt == nil {
return nil, errors.New("react: nil opt *Option")
}
err := opt.Validate()
if err != nil {
return nil, err
}
pool, err := NewPool(opt)
if err != nil {
return nil, err
}
return &React{pool: pool, opt: opt}, nil
}
// Returns a default option for react.
func DefaultReactOption() *Option {
src, err := Asset("assets/react.js")
if err != nil {
panic(err)
}
return &Option{
Source: src,
PoolSize: 10,
GlobalObjectName: "self",
}
}
// Render react component.
// name: component name
// params: component properties
func (rc *React) RenderComponent(name string, params interface{}) (string, error) {
vm := rc.pool.Get()
defer rc.pool.Put(vm)
objName := rc.opt.GlobalObjectName
var js string
if params == nil {
js = fmt.Sprintf(`
%v.React.renderToString(
%v.React.createFactory(%v.%v)()
)`, objName, objName, objName, name)
} else {
j, err := json.Marshal(params)
if err != nil {
return "", err
}
js = fmt.Sprintf(`
%v.React.renderToString(
%v.React.createFactory(%v.%v)(%v)
)`, objName, objName, objName, name, string(j))
}
if vm.PevalString(js) == 1 {
return "", errors.New(vm.SafeToString(-1))
}
v := vm.SafeToString(-1)
vm.Pop()
return v, nil
}
// Run javascript code and returns its result value.
// src: javascript source
func (rc *React) RunScript(src string) (string, error) {
vm := rc.pool.Get()
defer rc.pool.Put(vm)
js := `
(function() {
return %v
})();
`
if vm.PevalString(fmt.Sprintf(js, src)) == 1 {
return "", errors.New(vm.SafeToString(-1))
}
ret := vm.SafeToString(-1)
vm.Pop()
return ret, nil
}
// Load javascript code.
// src: javascript source
func (rc *React) Load(src []byte) error {
for i := 0; i < rc.pool.size; i++ {
vm := rc.pool.Get()
defer rc.pool.Put(vm)
if vm.PevalString(string(src)) == 1 {
panic(vm.SafeToString(-1))
}
}
return nil
}
// Load javascript file.
// path: path for javascript source file
func (rc *React) LoadFile(path string) error {
src, err := ioutil.ReadFile(path)
if err != nil {
return err
}
return rc.Load(src)
}