jsrb 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -5
- data/.yardopts +3 -0
- data/README.md +108 -95
- data/jsrb.gemspec +0 -2
- data/lib/jsrb/base.rb +157 -26
- data/lib/jsrb/cond_chain.rb +17 -12
- data/lib/jsrb/expr_chain.rb +90 -295
- data/lib/jsrb/js_statement_context.rb +8 -8
- data/lib/jsrb/railtie.rb +1 -1
- data/lib/jsrb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 648a40f61a953168044bacbdc32e18b5e634b10f7978e6856a0eb5704b7e5659
|
4
|
+
data.tar.gz: 6a65ed913dbfccc2dd6518d826e9ae430d66bf96774dc418a874180cb9252f0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 077a2481fc02d3b1a50ef6d36a92402b8f170e30764c5db614a58dce4b073615d1bfb7cdd560c4868e3425319388e29cc6fd4517f8f3179b5b38463459713d8a
|
7
|
+
data.tar.gz: 02547dbba6d6554cfd37174de4cbba978bef8d0cbafeb43a2d24b698f5dcf7d0598d8050dbf86e71e0f59344f569428686d1f077988c8192f8d71ee2b79a0274
|
data/.rubocop.yml
CHANGED
@@ -8,7 +8,7 @@ Metrics/LineLength:
|
|
8
8
|
Max: 130
|
9
9
|
|
10
10
|
Metrics/MethodLength:
|
11
|
-
Max:
|
11
|
+
Max: 50
|
12
12
|
|
13
13
|
Metrics/AbcSize:
|
14
14
|
Max: 25
|
@@ -16,6 +16,11 @@ Metrics/AbcSize:
|
|
16
16
|
Metrics/ClassLength:
|
17
17
|
Max: 200
|
18
18
|
|
19
|
+
Metrics/BlockLength:
|
20
|
+
Max: 50
|
21
|
+
Exclude:
|
22
|
+
- 'spec/**/*'
|
23
|
+
|
19
24
|
Style/MissingRespondToMissing:
|
20
25
|
Enabled: false
|
21
26
|
|
@@ -34,7 +39,3 @@ Style/LambdaCall:
|
|
34
39
|
|
35
40
|
Style/MethodMissingSuper:
|
36
41
|
Enabled: false
|
37
|
-
|
38
|
-
Metrics/BlockLength:
|
39
|
-
Exclude:
|
40
|
-
- 'spec/**/*'
|
data/.yardopts
CHANGED
data/README.md
CHANGED
@@ -6,28 +6,28 @@ Jsrb is a template engine to generate JavaScript code in simple Ruby DSL.
|
|
6
6
|
|
7
7
|
# Getting Started
|
8
8
|
|
9
|
-
Jsrb handler works in `.jsrb` view files. All ruby syntax is available and `
|
9
|
+
Jsrb handler works in `.jsrb` view files. All ruby syntax is available and `js` is provided in it. You can construct JavaScript code via `js`.
|
10
10
|
|
11
|
-
```
|
12
|
-
name =
|
13
|
-
ary =
|
14
|
-
obj =
|
15
|
-
result =
|
11
|
+
```ruby
|
12
|
+
name = js.var!(:name) { 'foo' }
|
13
|
+
ary = js.var! :ary
|
14
|
+
obj = js.var! :obj
|
15
|
+
result = js.var!
|
16
16
|
# var name = 'foo';
|
17
17
|
# var ary;
|
18
18
|
# var obj;
|
19
|
-
# var _v1;
|
19
|
+
# var _v1; // auto generated
|
20
20
|
|
21
|
-
|
21
|
+
js.set! ary, [1, 2, 3]
|
22
22
|
# ary = [1, 2, 3];
|
23
23
|
|
24
|
-
|
24
|
+
js.set! obj, {
|
25
25
|
name: name,
|
26
26
|
profile: {
|
27
27
|
age: 20,
|
28
28
|
sex: 'm'
|
29
29
|
}
|
30
|
-
|
30
|
+
}
|
31
31
|
# obj = {
|
32
32
|
# name: name,
|
33
33
|
# profile: {
|
@@ -36,22 +36,23 @@ obj.set!(
|
|
36
36
|
# }
|
37
37
|
# };
|
38
38
|
|
39
|
-
|
39
|
+
js.set! result, (obj.name + "(" + obj.profile.age + ")")
|
40
40
|
# _v1 = obj.name + "(" + obj.profile.age + ")";
|
41
41
|
|
42
|
-
|
42
|
+
js.set! ary, ary.map { |x| x * 2 }
|
43
43
|
# ary = ary.map(function(x) {
|
44
44
|
# return x * 2;
|
45
45
|
# });
|
46
46
|
|
47
|
-
|
48
|
-
|
47
|
+
js.if!(ary[1] === 4) {
|
48
|
+
js.set! result, 'four'
|
49
49
|
}.elsif(ary[1] === 2) {
|
50
|
-
|
50
|
+
js.set! result, 'two'
|
51
51
|
}.else {
|
52
|
-
|
52
|
+
js.set! result, 'other'
|
53
53
|
}
|
54
|
-
# //
|
54
|
+
# // The actual output will have certain immediate functions
|
55
|
+
# // that preserve variable scope for each case.
|
55
56
|
# if (ary[1] === 4) {
|
56
57
|
# _v1 = 'four'
|
57
58
|
# } else if (ary[1] === 2) {
|
@@ -60,51 +61,58 @@ jsrb.if!(ary[1] === 4) {
|
|
60
61
|
# _v1 = 'other'
|
61
62
|
# }
|
62
63
|
|
63
|
-
|
64
|
+
js.set! result, js.expr.Date.new
|
64
65
|
# _v1 = new Date;
|
65
66
|
|
66
|
-
|
67
|
+
js.set! js.expr.console.log('hello')
|
67
68
|
# console.log('hello');
|
68
69
|
```
|
69
70
|
|
70
71
|
# Usage
|
71
72
|
|
73
|
+
In contrast to Ruby, statements and expressions are
|
74
|
+
specifically distinguished as different elements in JavaScript.
|
75
|
+
And the program is composed of a list of statements.
|
76
|
+
This means that the jsrb file will have a series of statement pushing expression in it.
|
77
|
+
|
78
|
+
To make clear whether a method is pushing statement or not, jsrb adopted the rule that the name of method pushing statement should be `#..!`.
|
79
|
+
|
72
80
|
## Statements
|
73
81
|
|
74
82
|
### Variable declaration
|
75
83
|
|
76
|
-
`
|
84
|
+
`js.var!` pushes a **VariableDeclaration** into current context.
|
77
85
|
|
78
|
-
```
|
86
|
+
```ruby
|
79
87
|
# with variable name and initializer
|
80
|
-
|
88
|
+
js.var!('varname') { 100 }
|
81
89
|
# var varname = 100;
|
82
90
|
|
83
91
|
# without initializer
|
84
|
-
|
92
|
+
js.var!('varname')
|
85
93
|
# var varname;
|
86
94
|
|
87
95
|
# variable name is auto-generated if not specified
|
88
|
-
|
96
|
+
js.var!
|
89
97
|
# var _v1;
|
90
98
|
|
91
99
|
# var! returns Jsrb::ExprChain instance, so that you can
|
92
100
|
# assign value with `.set!` method.
|
93
|
-
a =
|
94
|
-
|
101
|
+
a = js.var!
|
102
|
+
js.set! a, 100
|
95
103
|
# var _v1;
|
96
104
|
# v1 = 100;
|
97
105
|
```
|
98
106
|
|
99
107
|
### If statement, and conditional expression
|
100
108
|
|
101
|
-
`
|
109
|
+
`js.if!` pushes an **IfStatement** into current context, `js.if` to build **a conditional expression**.
|
102
110
|
|
103
|
-
```
|
111
|
+
```ruby
|
104
112
|
# start with `#if!`
|
105
113
|
# and chain `#elsif` to add next case.
|
106
114
|
# Note that this is a statement, not expression.
|
107
|
-
|
115
|
+
js.if!(v === 1) {
|
108
116
|
# ..
|
109
117
|
}.elsif(v === 2) {
|
110
118
|
# ..
|
@@ -113,105 +121,110 @@ jsrb.if!(v === 1) {
|
|
113
121
|
}
|
114
122
|
|
115
123
|
# if you don't need else clause, close with `#end`
|
116
|
-
|
124
|
+
js.if!(v === 1) {
|
117
125
|
# ..
|
118
126
|
}.end
|
119
127
|
|
120
128
|
# if you want to regard this as an expression, use `#if` without exclamation.
|
121
|
-
|
129
|
+
js.set! v, js.if(v === 1) {
|
122
130
|
# ..
|
123
131
|
}.else {
|
124
132
|
# ..
|
125
133
|
}
|
126
134
|
```
|
127
135
|
|
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
136
|
### Expression statement
|
140
137
|
|
141
|
-
`
|
138
|
+
`js.do!` pushes an **ExpressionStatement** of a given expression.
|
142
139
|
|
143
|
-
```
|
144
|
-
get_elements =
|
145
|
-
get_elements.('.foo').forEach { |n| n.delete.() }
|
140
|
+
```ruby
|
141
|
+
get_elements = js.expr[:getElements]
|
142
|
+
js.do! get_elements.('.foo').forEach { |n| n.delete.() }
|
146
143
|
# getElements('.foo').forEach(function(n) { return n.delete(); });
|
147
144
|
```
|
148
145
|
|
149
|
-
##
|
146
|
+
## Expressions
|
150
147
|
|
151
148
|
Expression chain (`ExprChain` class) is an utility class to construct JavaScript expressions.
|
152
149
|
|
153
|
-
### Initialize with wrapping
|
150
|
+
### Initialize with wrapping ruby values
|
154
151
|
|
155
|
-
`
|
156
|
-
Some methods in
|
152
|
+
`js.expr` create a new `ExprChain` instance, taking an initial value optionally.
|
153
|
+
Some methods in `js` automatically convert ruby value to ExprChain.
|
157
154
|
|
158
|
-
```
|
159
|
-
x =
|
155
|
+
```ruby
|
156
|
+
x = js.var! :x
|
160
157
|
|
161
|
-
|
158
|
+
js.set! x, js.expr(100)
|
162
159
|
# x = 100;
|
163
|
-
# set! automatically
|
164
|
-
|
160
|
+
# set! automatically wraps argument with ExprChain.
|
161
|
+
js.set! x, 100
|
165
162
|
# x = 100;
|
166
|
-
#
|
167
|
-
# you
|
168
|
-
|
169
|
-
|
163
|
+
#
|
164
|
+
# Note that if you need to compare a ruby value by operator with another one,
|
165
|
+
# you have to wrap it.
|
166
|
+
js.set! x, (js.expr(100) < js.expr.y) # (100 < js.expr.y) will fail.
|
170
167
|
```
|
171
168
|
|
169
|
+
See the conversion section to check mappings from ruby value to JavaScript one.
|
170
|
+
|
172
171
|
### Chains
|
173
172
|
|
174
173
|
#### Member expression
|
175
174
|
|
176
|
-
`ExprChain#[],
|
175
|
+
`ExprChain#[], #..` constructs **MemberExpression**.
|
177
176
|
`#[]` and `#member!` is safe. `#..` can be used only if the name has no conflict.
|
178
177
|
|
179
|
-
```
|
180
|
-
x =
|
178
|
+
```ruby
|
179
|
+
x = js.var! :x
|
181
180
|
|
182
|
-
obj =
|
183
|
-
#
|
181
|
+
obj = js.expr[:someObj]
|
182
|
+
# js.expr with no argument constructs empty chain,
|
184
183
|
# in which every member chain will be an identifier.
|
185
|
-
|
186
|
-
# x = someObj['field'];
|
187
|
-
x.set! obj['field']
|
184
|
+
js.set! x, obj.field
|
188
185
|
# x = someObj['field'];
|
189
|
-
|
186
|
+
js.set! x, obj[:field]
|
190
187
|
# x = someObj['field'];
|
191
188
|
|
192
|
-
|
189
|
+
js.set! x, obj.send # NOTE that this is interpreted as a ruby Object's method, and causes an error.
|
190
|
+
```
|
191
|
+
|
192
|
+
#### Assignment
|
193
|
+
|
194
|
+
`ExprChain#set` constructs an **AssignmentExpression**.
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
a = js.var! :a
|
198
|
+
# var a;
|
199
|
+
|
200
|
+
js.do! a.set 100
|
201
|
+
# a = 100;
|
202
|
+
|
203
|
+
# js.set!(a, b) is short hand of js.do!(a.set(b))
|
204
|
+
js.set! a, 100
|
205
|
+
# a = 100;
|
193
206
|
```
|
194
207
|
|
195
208
|
#### Function Call
|
196
209
|
|
197
210
|
`ExprChain#call, so #.(), #.. with argument or block` constructs **CallExpression**.
|
198
211
|
|
199
|
-
```
|
200
|
-
|
201
|
-
console = jsrb.expr['console']
|
212
|
+
```ruby
|
213
|
+
console = js.expr[:console]
|
202
214
|
|
203
215
|
# using call method
|
204
|
-
console.log.('foo')
|
216
|
+
js.do! console.log.('foo')
|
205
217
|
# console.log('foo')
|
206
|
-
console.log.call('foo')
|
218
|
+
js.do! console.log.call('foo')
|
207
219
|
# console.log('foo')
|
208
220
|
|
209
221
|
# using dynamic method
|
210
222
|
# if #..() has at least one argument or block, it will be a call expression.
|
211
|
-
console.log('foo')
|
223
|
+
js.do! console.log('foo')
|
212
224
|
# console.log('foo')
|
213
|
-
|
214
|
-
|
225
|
+
|
226
|
+
js.do! js.expr(:ary).forEach { |item| item.execute.() }
|
227
|
+
# ary.forEach(function(item) { return item.execute(); });
|
215
228
|
```
|
216
229
|
|
217
230
|
#### Operators
|
@@ -219,44 +232,44 @@ x.map { |item| item.field }.as_statement!
|
|
219
232
|
Any ruby-overridable and JS-existing operators are overridden for chaining.
|
220
233
|
Supported operators are: `** + - * / % >> << & ^ | <= < > >= == === != ! && ||`.
|
221
234
|
|
222
|
-
```
|
223
|
-
x =
|
224
|
-
a =
|
235
|
+
```ruby
|
236
|
+
x = js.var! :x
|
237
|
+
a = js.expr[:a]
|
225
238
|
|
226
|
-
|
239
|
+
js.set! x, (a === 1)
|
227
240
|
# x = a === 1;
|
228
241
|
|
229
|
-
|
242
|
+
js.set! x, (a * a)
|
230
243
|
# x = a * a;
|
231
244
|
|
232
|
-
|
245
|
+
js.set! x, (3 * a) # raises an error because the method :* of Fixnum does not accept ExprChain as RHS.
|
233
246
|
```
|
234
247
|
|
235
248
|
#### New
|
236
249
|
|
237
|
-
`ExprChain#new
|
250
|
+
`ExprChain#new` constructs **NewExpression**.
|
238
251
|
|
239
|
-
```
|
240
|
-
x =
|
252
|
+
```ruby
|
253
|
+
x = js.var! :x
|
241
254
|
|
242
|
-
|
255
|
+
js.set! x, js.expr[:Date].new
|
243
256
|
# x = new Date;
|
244
257
|
```
|
245
258
|
|
246
259
|
#### Function expression
|
247
260
|
|
248
|
-
`ExprChain#
|
261
|
+
`ExprChain#forall` constructs **FunctionExpression**. You can also construct it directly from Proc or passing a block.
|
249
262
|
|
250
|
-
```
|
251
|
-
ary =
|
263
|
+
```ruby
|
264
|
+
ary = js.var! :ary, [1, 2, 3]
|
252
265
|
|
253
|
-
ary.map((
|
266
|
+
js.do! ary.map((js.expr[:x] * 2).forall('x'))
|
254
267
|
# ary.map(function(x) { return x * 2; });
|
255
268
|
|
256
|
-
ary.map { |x| x * 2 }
|
269
|
+
js.do! ary.map { |x| x * 2 }
|
257
270
|
# ary.map(function(x) { return x * 2; });
|
258
271
|
|
259
|
-
ary.map(->(x) { x * 2 })
|
272
|
+
js.do! ary.map(->(x) { x * 2 })
|
260
273
|
# ary.map(function(x) { return x * 2; });
|
261
274
|
```
|
262
275
|
|
@@ -283,10 +296,10 @@ Every Ruby's generic value will be converted to Javascript value by following ru
|
|
283
296
|
|
284
297
|
You can add custom chain methods in `ExprChain` via `Jsrb::ExprChain.#add_custom_chain`.
|
285
298
|
|
286
|
-
```
|
299
|
+
```ruby
|
287
300
|
Jsrb::ExprChain.add_custom_chain('log_here', '__tap_log__')
|
288
301
|
|
289
|
-
|
302
|
+
js.do! js.expr[:foo][:bar].log_here
|
290
303
|
# __tap_log__(foo['bar']);
|
291
304
|
```
|
292
305
|
|
data/jsrb.gemspec
CHANGED
@@ -4,7 +4,6 @@ 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
|
8
7
|
Gem::Specification.new do |spec|
|
9
8
|
spec.name = 'jsrb'
|
10
9
|
spec.version = Jsrb::VERSION
|
@@ -42,4 +41,3 @@ Gem::Specification.new do |spec|
|
|
42
41
|
spec.add_development_dependency 'rake', '~> 10.0'
|
43
42
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
44
43
|
end
|
45
|
-
# rubocop:enable Metrics/BlockLength
|
data/lib/jsrb/base.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Jsrb
|
4
|
-
# Base is a centralized class for Jsrb template.
|
5
|
-
# `
|
4
|
+
# `Jsrb::Base` is a centralized class for Jsrb template.
|
5
|
+
# `js`, accessed from views (i.e. `*.jsrb` files), is an instance of Jsrb::Base.
|
6
6
|
#
|
7
|
-
# Jsrb::Base provides
|
8
|
-
#
|
9
|
-
# with
|
7
|
+
# `Jsrb::Base` provides the interface for pushing statements,
|
8
|
+
# constructing expressions and generating JavaScript outputs
|
9
|
+
# with handling an internal statement context properly.
|
10
10
|
class Base
|
11
|
+
# @private
|
11
12
|
def initialize
|
12
13
|
@context = JSStatementContext.new
|
13
14
|
end
|
@@ -24,29 +25,136 @@ module Jsrb
|
|
24
25
|
end
|
25
26
|
|
26
27
|
#
|
27
|
-
# Pushes
|
28
|
-
# and returns an access to created identifier.
|
28
|
+
# **Pushes** an ExpressionStatement to the current context
|
29
29
|
#
|
30
|
-
# @
|
30
|
+
# @example
|
31
|
+
# js.do!(js.expr[:x].set(100))
|
32
|
+
# # =>
|
33
|
+
# # x = 100;
|
34
|
+
# @param [Jsrb::ExprChain] expr target expression.
|
35
|
+
# @return [nil]
|
36
|
+
def do!(expr)
|
37
|
+
ast = expr.object
|
38
|
+
raise ArgumentError, 'Expression is empty' unless ast
|
39
|
+
|
40
|
+
@context.push(
|
41
|
+
type: 'ExpressionStatement',
|
42
|
+
expression: ast
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# **Pushes** an assignment statement `lhs = rhs;`.
|
48
|
+
# This is a short hand of `js.do! lhs_expr.set(rhs_expr)`
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# a = js.var! :a
|
52
|
+
# js.set!(a, 'dog')
|
53
|
+
# # =>
|
54
|
+
# # var a;
|
55
|
+
# # a = 'dog';
|
56
|
+
#
|
57
|
+
# # directly pass a symbol of identifier name
|
58
|
+
# js.set!(:x, 100)
|
59
|
+
# # =>
|
60
|
+
# # x = 100;
|
61
|
+
# @param [Jsrb::ExprChain, String, Symbol] expr target expression.
|
62
|
+
# @return [nil]
|
63
|
+
def set!(lhs, rhs)
|
64
|
+
lhs_expr = lhs.is_a?(ExprChain) ? lhs : expr(lhs)
|
65
|
+
do! lhs_expr.set(rhs)
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# **Pushes** a VariableDeclaration to the current context
|
70
|
+
# and returns an access to the created identifier.
|
71
|
+
# @example
|
72
|
+
# name = js.var!(:name) { 'foo' }
|
73
|
+
# # var name = 'foo';
|
74
|
+
#
|
75
|
+
# ary = js.var! :ary
|
76
|
+
# # var ary;
|
77
|
+
#
|
78
|
+
# obj = js.var! :obj
|
79
|
+
# # var obj;
|
80
|
+
#
|
81
|
+
# result = js.var!
|
82
|
+
# # var _v1; //<- auto generate variable name
|
83
|
+
# @param [Symbol] name a name of identifier, autogenerated if not given
|
31
84
|
# @yield optional block for initializer
|
32
|
-
# @yieldreturn an initializer expression
|
33
|
-
# @return [Jsrb::ExprChain] the expression
|
85
|
+
# @yieldreturn an initializer expression
|
86
|
+
# @return [Jsrb::ExprChain] the expression which represents a newly created identifier
|
34
87
|
def var!(id = nil)
|
35
88
|
id ||= @context.gen_var_name!
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
89
|
+
val_ast =
|
90
|
+
if block_given?
|
91
|
+
raw_expr = yield
|
92
|
+
raw_expr.is_a?(ExprChain) ? raw_expr.unwrap : @context.ruby_to_js_ast(raw_expr)
|
93
|
+
end
|
94
|
+
if val_ast
|
95
|
+
@context.push(
|
96
|
+
type: 'VariableDeclaration',
|
97
|
+
declarations: [{
|
98
|
+
type: 'VariableDeclarator',
|
99
|
+
id: {
|
100
|
+
type: 'Identifier',
|
101
|
+
name: id.to_s
|
102
|
+
},
|
103
|
+
init: val_ast
|
104
|
+
}],
|
105
|
+
kind: 'var'
|
106
|
+
)
|
40
107
|
else
|
41
|
-
|
108
|
+
@context.push(
|
109
|
+
type: 'VariableDeclaration',
|
110
|
+
declarations: [{
|
111
|
+
type: 'VariableDeclarator',
|
112
|
+
id: {
|
113
|
+
type: 'Identifier',
|
114
|
+
name: id.to_s
|
115
|
+
}
|
116
|
+
}],
|
117
|
+
kind: 'var'
|
118
|
+
)
|
42
119
|
end
|
43
|
-
expr
|
120
|
+
expr[id]
|
44
121
|
end
|
45
122
|
|
46
123
|
#
|
47
|
-
#
|
48
|
-
#
|
124
|
+
# **Starts** a new conditional chain that pushes an IfStatement
|
125
|
+
# to the current context at end.
|
126
|
+
#
|
127
|
+
# @example
|
128
|
+
# js.if!(expr1) {
|
129
|
+
# # ..
|
130
|
+
# }.elsif(expr2) {
|
131
|
+
# # ..
|
132
|
+
# }.else {
|
133
|
+
# # ..
|
134
|
+
# }
|
135
|
+
# # =>
|
136
|
+
# # // The actual output will have certain immediate functions
|
137
|
+
# # // that preserve variable scope for each case.
|
138
|
+
# # if (..expr1..) {
|
139
|
+
# # // ..
|
140
|
+
# # } else if (..expr2..) {
|
141
|
+
# # // ..
|
142
|
+
# # } else {
|
143
|
+
# # // ..
|
144
|
+
# # }
|
49
145
|
#
|
146
|
+
# # If you don't have else clause, close with `#end`.
|
147
|
+
# js.if!(expr1) {
|
148
|
+
# # ..
|
149
|
+
# }.elsif(expr2) {
|
150
|
+
# # ..
|
151
|
+
# }.end
|
152
|
+
# # =>
|
153
|
+
# # if (..expr1..) {
|
154
|
+
# # // ..
|
155
|
+
# # } else if (..expr2..) {
|
156
|
+
# # // ..
|
157
|
+
# # }
|
50
158
|
# @param [Jsrb::ExprChain, convertible ruby values] cond_expr an expression for the test
|
51
159
|
# @yield new context block for the consequent case
|
52
160
|
# @return [Jsrb::CondChain] condition chainable instance
|
@@ -55,8 +163,31 @@ module Jsrb
|
|
55
163
|
end
|
56
164
|
|
57
165
|
#
|
58
|
-
# Constructs a new conditional chain that
|
166
|
+
# **Constructs** a new conditional chain that
|
167
|
+
# represents a conditional expression at end.
|
59
168
|
#
|
169
|
+
# @example
|
170
|
+
# result = var!
|
171
|
+
# js.do! result, js.if(expr1) {
|
172
|
+
# result_expr1
|
173
|
+
# }.elsif(expr2) {
|
174
|
+
# result_expr2
|
175
|
+
# }.else {
|
176
|
+
# result_expr3
|
177
|
+
# }
|
178
|
+
# # =>
|
179
|
+
# # // The actual output will have certain immediate functions
|
180
|
+
# # // that preserve variable scope for each case.
|
181
|
+
# # var _v1;
|
182
|
+
# # _v1 = (function() {
|
183
|
+
# # if (..expr1..) {
|
184
|
+
# # return ..result_expr1..;
|
185
|
+
# # } else if (..expr2..) {
|
186
|
+
# # return ..result_expr2..;
|
187
|
+
# # } else {
|
188
|
+
# # return ..result_expr3..;
|
189
|
+
# # }
|
190
|
+
# # })()
|
60
191
|
# @param [Jsrb::ExprChain, convertible ruby values] cond_expr an expression for the test
|
61
192
|
# @yield new context block for the consequent case
|
62
193
|
# @return [Jsrb::CondChain] condition chainable instance
|
@@ -65,9 +196,9 @@ module Jsrb
|
|
65
196
|
end
|
66
197
|
|
67
198
|
#
|
68
|
-
# Constructs a new expression chain with a given JavaScript AST node.
|
199
|
+
# **Constructs** a new expression chain with a given JavaScript AST node.
|
69
200
|
#
|
70
|
-
# @param
|
201
|
+
# @param [convertible ruby values] object represents JavaScript expression AST node
|
71
202
|
# @return [Jsrb::ExprChain] chainable instance
|
72
203
|
def expr(object = nil)
|
73
204
|
@context.new_expression(object)
|
@@ -75,22 +206,22 @@ module Jsrb
|
|
75
206
|
|
76
207
|
class << self
|
77
208
|
#
|
78
|
-
# Shows JavaScript generator class name, 'Jsrb::NotFastGenerator' by default.
|
209
|
+
# Shows JavaScript generator class name, `'Jsrb::NotFastGenerator'` by default.
|
79
210
|
#
|
80
211
|
# ### **Help wanted!**
|
81
212
|
#
|
82
213
|
# *Jsrb::NotFastGenerator uses ExecJS and escodegen to generate JavaScript.
|
83
|
-
# It could be more efficient and get better error messages if
|
84
|
-
#
|
214
|
+
# It could be more efficient and get better error messages if we
|
215
|
+
# implement it in Ruby*.
|
85
216
|
#
|
217
|
+
# @return [String] class name of a code generator
|
86
218
|
def code_generator
|
87
219
|
@code_generator || 'Jsrb::NotFastGenerator'
|
88
220
|
end
|
89
221
|
|
90
222
|
attr_writer :code_generator
|
91
223
|
|
92
|
-
private
|
93
|
-
|
224
|
+
# @private
|
94
225
|
def code_generator_class
|
95
226
|
@code_generator_class ||= Object.const_get(code_generator)
|
96
227
|
end
|