jsrb 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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