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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d11a911afb7baddbd00ec547cd0b5679be9873a7
4
- data.tar.gz: 0e28f797a62a8f8b640039b13f8ab54203e12602
2
+ SHA256:
3
+ metadata.gz: 5b2cff3db7ac17a89b029bc7782e8735b7f9959c4595804c39537af8d6232077
4
+ data.tar.gz: b7700dc452ea93b9ba17cbf381bb79acfd00747f6e653b309cf24174811598d3
5
5
  SHA512:
6
- metadata.gz: 31518c3f3adceb687937556bec2c598db034812662c48505616acd46462fed85a0ce1448b2aaea336ec3b3c5cf43605956079b3a1b6516a8035f6ce5265b837a
7
- data.tar.gz: d29797e2528c20b83ed3f54573a0cde76f665b6aa9773f6860481187461c2ec1f597c9505dae97f4ef35204f519464a5d27ee095439deb136910b9290315f2fa
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
- ## Usage
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
- TODO
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'] = "https://rubygems.org"
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jsrb
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/jsrb.rb CHANGED
@@ -10,3 +10,4 @@ require 'jsrb/not_fast_generator'
10
10
  require 'jsrb/js_statement_context'
11
11
  require 'jsrb/expr_chain'
12
12
  require 'jsrb/cond_chain'
13
+ require 'jsrb/railtie' if defined?(Rails::Railtie)
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.1.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-09 00:00:00.000000000 Z
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.5.1
158
+ rubygems_version: 2.7.6
137
159
  signing_key:
138
160
  specification_version: 4
139
161
  summary: generates JavaScript code with Ruby DSL