jsrb 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.ruby-version +1 -0
- data/README.md +285 -5
- data/jsrb.gemspec +4 -1
- data/lib/jsrb/railtie.rb +26 -0
- data/lib/jsrb/version.rb +1 -1
- data/lib/jsrb.rb +1 -0
- metadata +25 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5b2cff3db7ac17a89b029bc7782e8735b7f9959c4595804c39537af8d6232077
|
4
|
+
data.tar.gz: b7700dc452ea93b9ba17cbf381bb79acfd00747f6e653b309cf24174811598d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 934089fa92db021a2d90e738286de40dbc094286a5f0f4ed281626bd6d666b66d25d643ac4f117289b616c3c4b8d173fac5dcb86d29a645df7cf415c8c4e4939
|
7
|
+
data.tar.gz: 9a1de7b3fd7a00e7facb9c633352e06a142ccb01680d819bba30d3f56c7be226682a00693098068ad85fee4a76ef83a3246377e2c85e5399553b6794adf6defb
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.1
|
data/README.md
CHANGED
@@ -1,14 +1,294 @@
|
|
1
|
-
[![CircleCI](https://circleci.com/gh/effective-spa/jsrb.svg?style=svg)](https://circleci.com/gh/effective-spa/jsrb) [![codecov](https://codecov.io/gh/effective-spa/jsrb/branch/master/graph/badge.svg)](https://codecov.io/gh/effective-spa/jsrb) [![Maintainability](https://api.codeclimate.com/v1/badges/8bf4666ed7b983f01519/maintainability)](https://codeclimate.com/github/effective-spa/jsrb/maintainability)
|
2
|
-
|
3
|
-
**This library is still development version. It's currently not recommended to be used in production environment.**
|
1
|
+
[![CircleCI](https://circleci.com/gh/effective-spa/jsrb.svg?style=svg)](https://circleci.com/gh/effective-spa/jsrb) [![codecov](https://codecov.io/gh/effective-spa/jsrb/branch/master/graph/badge.svg)](https://codecov.io/gh/effective-spa/jsrb) [![Maintainability](https://api.codeclimate.com/v1/badges/8bf4666ed7b983f01519/maintainability)](https://codeclimate.com/github/effective-spa/jsrb/maintainability) [![Gem Version](https://badge.fury.io/rb/jsrb.svg)](https://badge.fury.io/rb/jsrb)
|
4
2
|
|
5
3
|
# Jsrb
|
6
4
|
|
7
5
|
Jsrb is a template engine to generate JavaScript code in simple Ruby DSL.
|
8
6
|
|
9
|
-
|
7
|
+
# Getting Started
|
8
|
+
|
9
|
+
Jsrb handler works in jsrb files, which contain `.js.jsrb` extension. All ruby syntax is available and `jsrb` is provided in it. You can construct JavaScript code via `jsrb`.
|
10
|
+
|
11
|
+
```rb
|
12
|
+
name = jsrb.var!(:name) { 'foo' }
|
13
|
+
ary = jsrb.var! :ary
|
14
|
+
obj = jsrb.var! :obj
|
15
|
+
result = jsrb.var!
|
16
|
+
# var name = 'foo';
|
17
|
+
# var ary;
|
18
|
+
# var obj;
|
19
|
+
# var _v1; <- auto generate variable name
|
20
|
+
|
21
|
+
ary.set!([1, 2, 3])
|
22
|
+
# ary = [1, 2, 3];
|
23
|
+
|
24
|
+
obj.set!(
|
25
|
+
name: name,
|
26
|
+
profile: {
|
27
|
+
age: 20,
|
28
|
+
sex: 'm'
|
29
|
+
}
|
30
|
+
)
|
31
|
+
# obj = {
|
32
|
+
# name: name,
|
33
|
+
# profile: {
|
34
|
+
# age: 20,
|
35
|
+
# sex: 'm'
|
36
|
+
# }
|
37
|
+
# };
|
38
|
+
|
39
|
+
result.set! (obj.name + "(" + obj.profile.age + ")")
|
40
|
+
# _v1 = obj.name + "(" + obj.profile.age + ")";
|
41
|
+
|
42
|
+
ary.set! ary.map { |x| x * 2 }
|
43
|
+
# ary = ary.map(function(x) {
|
44
|
+
# return x * 2;
|
45
|
+
# });
|
46
|
+
|
47
|
+
jsrb.if!(ary[1] === 4) {
|
48
|
+
result.set! 'four'
|
49
|
+
}.elsif(ary[1] === 2) {
|
50
|
+
result.set! 'two'
|
51
|
+
}.else {
|
52
|
+
result.set! 'other'
|
53
|
+
}
|
54
|
+
# // the actual output doesn't looks like this, but will be better code in regard to variable scope.
|
55
|
+
# if (ary[1] === 4) {
|
56
|
+
# _v1 = 'four'
|
57
|
+
# } else if (ary[1] === 2) {
|
58
|
+
# _v1 = 'two'
|
59
|
+
# } else {
|
60
|
+
# _v1 = 'other'
|
61
|
+
# }
|
62
|
+
|
63
|
+
result.set! jsrb.expr.Date.new!
|
64
|
+
# _v1 = new Date;
|
65
|
+
|
66
|
+
jsrb.expr.console.log('hello').as_statement!
|
67
|
+
# console.log('hello');
|
68
|
+
```
|
69
|
+
|
70
|
+
# Usage
|
71
|
+
|
72
|
+
## Statements
|
73
|
+
|
74
|
+
### Variable declaration
|
75
|
+
|
76
|
+
`jsrb.var!` pushes a **VariableDeclaration** into current context.
|
77
|
+
|
78
|
+
```rb
|
79
|
+
# with variable name and initializer
|
80
|
+
jsrb.var!('varname') { 100 }
|
81
|
+
# var varname = 100;
|
82
|
+
|
83
|
+
# without initializer
|
84
|
+
jsrb.var!('varname')
|
85
|
+
# var varname;
|
86
|
+
|
87
|
+
# variable name is auto-generated if not specified
|
88
|
+
jsrb.var!
|
89
|
+
# var _v1;
|
90
|
+
|
91
|
+
# var! returns Jsrb::ExprChain instance, so that you can
|
92
|
+
# assign value with `.set!` method.
|
93
|
+
a = jsrb.var!
|
94
|
+
a.set! 100
|
95
|
+
# var _v1;
|
96
|
+
# v1 = 100;
|
97
|
+
```
|
98
|
+
|
99
|
+
### If statement, and conditional expression
|
100
|
+
|
101
|
+
`jsrb.if!` pushes an **IfStatement** into current context, `jsrb.if` to build **a conditional expression**.
|
102
|
+
|
103
|
+
```rb
|
104
|
+
# start with `#if!`
|
105
|
+
# and chain `#elsif` to add next case.
|
106
|
+
# Note that this is a statement, not expression.
|
107
|
+
jsrb.if!(v === 1) {
|
108
|
+
# ..
|
109
|
+
}.elsif(v === 2) {
|
110
|
+
# ..
|
111
|
+
}.else {
|
112
|
+
# ..
|
113
|
+
}
|
114
|
+
|
115
|
+
# if you don't need else clause, close with `#end`
|
116
|
+
jsrb.if!(v === 1) {
|
117
|
+
# ..
|
118
|
+
}.end
|
119
|
+
|
120
|
+
# if you want to regard this as an expression, use `#if` without exclamation.
|
121
|
+
v.set! jsrb.if(v === 1) {
|
122
|
+
# ..
|
123
|
+
}.else {
|
124
|
+
# ..
|
125
|
+
}
|
126
|
+
```
|
127
|
+
|
128
|
+
### Assignment statement
|
129
|
+
|
130
|
+
`ExprChain#set!` pushes an **assignment statement** (ExpressionStatement of AssignmentExpression).
|
131
|
+
|
132
|
+
```rb
|
133
|
+
a = jsrb.var! :a
|
134
|
+
a.set! 100
|
135
|
+
# var a;
|
136
|
+
# a = 100;
|
137
|
+
```
|
138
|
+
|
139
|
+
### Expression statement
|
140
|
+
|
141
|
+
`ExprChain#as_statement!` pushes an **ExpressionStatement** of the left hand side of chain.
|
142
|
+
|
143
|
+
```rb
|
144
|
+
get_elements = jsrb.expr['getElements']
|
145
|
+
get_elements.('.foo').forEach { |n| n.delete.() }.as_statement!
|
146
|
+
# getElements('.foo').forEach(function(n) { return n.delete(); });
|
147
|
+
```
|
148
|
+
|
149
|
+
## Expression chain
|
150
|
+
|
151
|
+
Expression chain (`ExprChain` class) is an utility class to construct JavaScript expressions.
|
152
|
+
|
153
|
+
### Initialize with wrapping a ruby value
|
154
|
+
|
155
|
+
`jsrb.expr` create a new `ExprChain` instance, taking an initial value optionally.
|
156
|
+
Some methods in jsrb automatically convert ruby expression to ExprChain.
|
157
|
+
|
158
|
+
```rb
|
159
|
+
x = jsrb.var! :x
|
160
|
+
|
161
|
+
x.set! jsrb.expr(100)
|
162
|
+
# x = 100;
|
163
|
+
# set! automatically wrap with ExprChain.
|
164
|
+
x.set! 100
|
165
|
+
# x = 100;
|
166
|
+
# If you need to compare by operator with another ExprChain,
|
167
|
+
# you have to wrap first.
|
168
|
+
x.set!(jsrb.expr(100) < jsrb.expr.y)
|
169
|
+
# x.set!(100 < jsrb.expr.y) will fail.
|
170
|
+
```
|
171
|
+
|
172
|
+
### Chains
|
173
|
+
|
174
|
+
#### Member expression
|
175
|
+
|
176
|
+
`ExprChain#[], #member!, #..` constructs **MemberExpression**.
|
177
|
+
`#[]` and `#member!` is safe. `#..` can be used only if the name has no conflict.
|
178
|
+
|
179
|
+
```rb
|
180
|
+
x = jsrb.var! :x
|
181
|
+
|
182
|
+
obj = jsrb.expr['someObj']
|
183
|
+
# jsrb.expr with no argument constructs empty chain,
|
184
|
+
# in which every member chain will be an identifier.
|
185
|
+
x.set! obj.field
|
186
|
+
# x = someObj['field'];
|
187
|
+
x.set! obj['field']
|
188
|
+
# x = someObj['field'];
|
189
|
+
x.set! obj.member! 'field'
|
190
|
+
# x = someObj['field'];
|
191
|
+
|
192
|
+
x.set! obj.send # NOTE that this is interpreted as a ruby Object's method, and causes an error.
|
193
|
+
```
|
194
|
+
|
195
|
+
#### Function Call
|
196
|
+
|
197
|
+
`ExprChain#call, so #.(), #.. with argument or block` constructs **CallExpression**.
|
198
|
+
|
199
|
+
```rb
|
200
|
+
x = jsrb.var! :x
|
201
|
+
console = jsrb.expr['console']
|
202
|
+
|
203
|
+
# using call method
|
204
|
+
console.log.('foo').as_statement!
|
205
|
+
# console.log('foo')
|
206
|
+
console.log.call('foo').as_statement!
|
207
|
+
# console.log('foo')
|
208
|
+
|
209
|
+
# using dynamic method
|
210
|
+
# if #..() has at least one argument or block, it will be a call expression.
|
211
|
+
console.log('foo').as_statement!
|
212
|
+
# console.log('foo')
|
213
|
+
x.map { |item| item.field }.as_statement!
|
214
|
+
# x.map(function(item) { return item.field; });
|
215
|
+
```
|
216
|
+
|
217
|
+
#### Operators
|
218
|
+
|
219
|
+
Any ruby-overridable and JS-existing operators are overridden for chaining.
|
220
|
+
Supported operators are: `** + - * / % >> << & ^ | <= < > >= == === != ! && ||`.
|
221
|
+
|
222
|
+
```rb
|
223
|
+
x = jsrb.var! :x
|
224
|
+
a = jsrb.expr['a']
|
225
|
+
|
226
|
+
x.set!(a === 1)
|
227
|
+
# x = a === 1;
|
228
|
+
|
229
|
+
x.set!(a * a)
|
230
|
+
# x = a * a;
|
231
|
+
|
232
|
+
x.set!(3 * a) # raises an error because Fixnum does not accept ExprChain as RHS.
|
233
|
+
```
|
234
|
+
|
235
|
+
#### New
|
236
|
+
|
237
|
+
`ExprChain#new!` constructs **NewExpression**.
|
238
|
+
|
239
|
+
```rb
|
240
|
+
x = jsrb.var! :x
|
241
|
+
|
242
|
+
x.set! jsrb.expr['Date'].new!
|
243
|
+
# x = new Date;
|
244
|
+
```
|
245
|
+
|
246
|
+
#### Function expression
|
247
|
+
|
248
|
+
`ExprChain#for_all!` constructs **FunctionExpression**. You can also construct it from Proc directly or passing a block.
|
249
|
+
|
250
|
+
```rb
|
251
|
+
ary = jsrb.var! :ary, [1, 2, 3]
|
252
|
+
|
253
|
+
ary.map((jsrb.expr['x'] * 2).for_all!('x')).as_statement!
|
254
|
+
# ary.map(function(x) { return x * 2; });
|
255
|
+
|
256
|
+
ary.map { |x| x * 2 }.as_statement!
|
257
|
+
# ary.map(function(x) { return x * 2; });
|
258
|
+
|
259
|
+
ary.map(->(x) { x * 2 }).as_statement!
|
260
|
+
# ary.map(function(x) { return x * 2; });
|
261
|
+
```
|
262
|
+
|
263
|
+
# Conversion
|
264
|
+
|
265
|
+
Every Ruby's generic value will be converted to Javascript value by following rule:
|
266
|
+
|
267
|
+
|Ruby value|JavaScript|
|
268
|
+
|---|---|
|
269
|
+
| finite `100` | `100` |
|
270
|
+
| NaN `Float::NAN` | `NaN` |
|
271
|
+
| +Infinity `Float::INFINITY` | `Number.POSITIVE_INFINITY` |
|
272
|
+
| -Infinity `Float::INFINITY` | `Number.NEGATIVE_INFINITY` |
|
273
|
+
| `true` | `true` |
|
274
|
+
| `false` | `false` |
|
275
|
+
| `:foo` | `"foo"` |
|
276
|
+
| `"foo"` | `"foo"` |
|
277
|
+
| `nil` | `null` |
|
278
|
+
| `[1, 2, 3]` | `[1, 2, 3]` |
|
279
|
+
| `{ foo: 'bar' }` | `{ "foo": "bar" }` |
|
280
|
+
| `->(x, y, z) { x + y + z }` | `function (x, y, z) { return x + y + z; }` |
|
281
|
+
|
282
|
+
# Customize Chain
|
283
|
+
|
284
|
+
You can add custom chain methods in `ExprChain` via `Jsrb::ExprChain.#add_custom_chain`.
|
285
|
+
|
286
|
+
```rb
|
287
|
+
Jsrb::ExprChain.add_custom_chain('log_here', '__tap_log__')
|
10
288
|
|
11
|
-
|
289
|
+
jsrb.expr['foo']['bar'].log_here.as_statement!
|
290
|
+
# __tap_log__(foo['bar']);
|
291
|
+
```
|
12
292
|
|
13
293
|
## Contributing
|
14
294
|
|
data/jsrb.gemspec
CHANGED
@@ -4,6 +4,7 @@ lib = File.expand_path('lib', __dir__)
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require 'jsrb/version'
|
6
6
|
|
7
|
+
# rubocop:disable Metrics/BlockLength
|
7
8
|
Gem::Specification.new do |spec|
|
8
9
|
spec.name = 'jsrb'
|
9
10
|
spec.version = Jsrb::VERSION
|
@@ -18,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
18
19
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
19
20
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
20
21
|
if spec.respond_to?(:metadata)
|
21
|
-
spec.metadata['allowed_push_host'] =
|
22
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
22
23
|
else
|
23
24
|
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
24
25
|
'public gem pushes.'
|
@@ -35,6 +36,8 @@ Gem::Specification.new do |spec|
|
|
35
36
|
spec.add_runtime_dependency 'stitch-rb', '~> 0.0.8'
|
36
37
|
|
37
38
|
spec.add_development_dependency 'bundler', '~> 1.13'
|
39
|
+
spec.add_development_dependency 'rails', '~> 5.0', '>= 5.0.0'
|
38
40
|
spec.add_development_dependency 'rake', '~> 10.0'
|
39
41
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
40
42
|
end
|
43
|
+
# rubocop:enable Metrics/BlockLength
|
data/lib/jsrb/railtie.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsrb
|
4
|
+
class Handler
|
5
|
+
cattr_accessor :default_format
|
6
|
+
self.default_format = Mime[:js]
|
7
|
+
|
8
|
+
def self.call(template)
|
9
|
+
%(jsrb = Jsrb::Base.new; #{template.source}; jsrb.generate_code)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Railtie < ::Rails::Railtie
|
14
|
+
initializer :server_component do
|
15
|
+
ActiveSupport.on_load :action_view do
|
16
|
+
ActionView::Template.register_template_handler :jsrb, Jsrb::Handler
|
17
|
+
end
|
18
|
+
|
19
|
+
ActiveSupport.on_load :action_controller do
|
20
|
+
ActionController::Renderers.add :jsrb do |obj, _options|
|
21
|
+
send_data obj.to_s, type: Mime[:js]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/jsrb/version.rb
CHANGED
data/lib/jsrb.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shun MIZUKAMI
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: execjs
|
@@ -58,6 +58,26 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '1.13'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rails
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '5.0'
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 5.0.0
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - "~>"
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '5.0'
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 5.0.0
|
61
81
|
- !ruby/object:Gem::Dependency
|
62
82
|
name: rake
|
63
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,6 +118,7 @@ files:
|
|
98
118
|
- ".gitignore"
|
99
119
|
- ".rspec"
|
100
120
|
- ".rubocop.yml"
|
121
|
+
- ".ruby-version"
|
101
122
|
- ".travis.yml"
|
102
123
|
- Gemfile
|
103
124
|
- LICENSE.txt
|
@@ -110,6 +131,7 @@ files:
|
|
110
131
|
- lib/jsrb/expr_chain.rb
|
111
132
|
- lib/jsrb/js_statement_context.rb
|
112
133
|
- lib/jsrb/not_fast_generator.rb
|
134
|
+
- lib/jsrb/railtie.rb
|
113
135
|
- lib/jsrb/vendor/escodegen.browser.js
|
114
136
|
- lib/jsrb/version.rb
|
115
137
|
homepage: https://github.com/effective-spa/jsrb
|
@@ -133,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
155
|
version: '0'
|
134
156
|
requirements: []
|
135
157
|
rubyforge_project:
|
136
|
-
rubygems_version: 2.
|
158
|
+
rubygems_version: 2.7.6
|
137
159
|
signing_key:
|
138
160
|
specification_version: 4
|
139
161
|
summary: generates JavaScript code with Ruby DSL
|