ruby2js 3.6.0 → 3.6.1
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 +4 -4
- data/README.md +5 -750
- data/lib/ruby2js/converter/module.rb +5 -0
- data/lib/ruby2js/filter/active_functions.rb +1 -1
- data/lib/ruby2js/filter/functions.rb +9 -3
- data/lib/ruby2js/filter/nokogiri.rb +12 -12
- data/lib/ruby2js/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: 11ab4e0003f0ff4f5821c00d5e282dead1201f97d4a2cc9ffb5c1188687f6079
|
4
|
+
data.tar.gz: fe572bef6b5ee55d46d72bb71dfcca5793fff8dd29a44243da637a7b91264bf7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f865febd41bda90440a03b5ccdb7ac921eb794701c61d120b28a850d03001ee95ae0403bd50123d96c0f85b5e3a0e672066fcde7da68216c28f6f5895b2f9398
|
7
|
+
data.tar.gz: cf4811376c6daf78e951f688b6b2ee78e1b627135ed365e7197a6a318601b8b6313d2c4123031fd395cf5342707914e56bc29d946e15dc8f1dc7d53d35b053c6
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
Ruby2JS
|
2
2
|
=======
|
3
3
|
|
4
4
|
Minimal yet extensible Ruby to JavaScript conversion.
|
@@ -7,59 +7,14 @@ Minimal yet extensible Ruby to JavaScript conversion.
|
|
7
7
|
[](https://badge.fury.io/rb/ruby2js)
|
8
8
|
[](https://gitter.im/ruby2js/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
9
9
|
|
10
|
-
Description
|
11
|
-
---
|
12
|
-
|
13
|
-
The base package maps Ruby syntax to JavaScript semantics.
|
14
|
-
For example:
|
15
|
-
|
16
|
-
* a Ruby Hash literal becomes a JavaScript Object literal
|
17
|
-
* Ruby symbols become JavaScript strings.
|
18
|
-
* Ruby method calls become JavaScript function calls IF
|
19
|
-
there are either one or more arguments passed OR
|
20
|
-
parenthesis are used
|
21
|
-
* otherwise Ruby method calls become JavaScript property accesses.
|
22
|
-
* by default, methods and procs return `undefined`
|
23
|
-
* splats mapped to spread syntax when ES2015 or later is selected, and
|
24
|
-
to equivalents using `apply`, `concat`, `slice`, and `arguments` otherwise.
|
25
|
-
* ruby string interpolation is expanded into string + operations
|
26
|
-
* `and` and `or` become `&&` and `||`
|
27
|
-
* `a ** b` becomes `Math.pow(a,b)`
|
28
|
-
* `<< a` becomes `.push(a)`
|
29
|
-
* `unless` becomes `if !`
|
30
|
-
* `until` becomes `while !`
|
31
|
-
* `case` and `when` becomes `switch` and `case`
|
32
|
-
* ruby for loops become js for loops
|
33
|
-
* `(1...4).step(2){` becomes `for (var i = 1; i < 4; i += 2) {`
|
34
|
-
* `x.forEach { next }` becomes `x.forEach(function() {return})`
|
35
|
-
* `lambda {}` and `proc {}` becomes `function() {}`
|
36
|
-
* `class Person; end` becomes `function Person() {}`
|
37
|
-
* instance methods become prototype methods
|
38
|
-
* instance variables become underscored, `@name` becomes `this._name`
|
39
|
-
* self is assigned to this is if used
|
40
|
-
* Any block becomes and explicit argument `new Promise do; y(); end` becomes `new Promise(function() {y()})`
|
41
|
-
* regular expressions are mapped to js
|
42
|
-
* `raise` becomes `throw`
|
43
10
|
|
44
|
-
|
45
|
-
|
46
|
-
mapped to
|
47
|
-
[Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FObject%2FdefineProperty),
|
48
|
-
so avoid these if you wish to target users running IE8 or lower.
|
11
|
+
Documentation
|
12
|
+
---
|
49
13
|
|
50
|
-
|
51
|
-
defining and extending an existing class, whereas JavaScript does not. This
|
52
|
-
means that Ruby2JS needs to be told when a class is being extended, which is
|
53
|
-
done by prepending the `class` keyword with two plus signs, thus:
|
54
|
-
`++class C; ...; end`.
|
14
|
+
* Visit **[ruby2js.com](https://www.ruby2js.com)** for detailed setup instructions and API reference.
|
55
15
|
|
56
|
-
|
57
|
-
behavior. Filters are essentially macro facilities that operate on
|
58
|
-
an AST representation of the code.
|
16
|
+
* [Try Ruby2JS online](https://whimsy.apache.org/ruby2js)
|
59
17
|
|
60
|
-
See
|
61
|
-
[notimplemented_spec](https://github.com/rubys/ruby2js/blob/master/spec/notimplemented_spec.rb)
|
62
|
-
for a list of Ruby features _known_ to be not implemented.
|
63
18
|
|
64
19
|
Synopsis
|
65
20
|
---
|
@@ -96,706 +51,6 @@ Enable ES2015 support:
|
|
96
51
|
puts Ruby2JS.convert('"#{a}"', eslevel: 2015)
|
97
52
|
```
|
98
53
|
|
99
|
-
Enable strict support:
|
100
|
-
|
101
|
-
```ruby
|
102
|
-
puts Ruby2JS.convert('a=1', strict: true)
|
103
|
-
```
|
104
|
-
|
105
|
-
Emit strict equality comparisons:
|
106
|
-
|
107
|
-
```ruby
|
108
|
-
puts Ruby2JS.convert('a==1', comparison: :identity)
|
109
|
-
```
|
110
|
-
|
111
|
-
Emit nullish coalescing operators:
|
112
|
-
|
113
|
-
```ruby
|
114
|
-
puts Ruby2JS.convert('a || 1', or: :nullish)
|
115
|
-
```
|
116
|
-
|
117
|
-
Emit underscored private fields (allowing subclass access):
|
118
|
-
|
119
|
-
```ruby
|
120
|
-
puts Ruby2JS.convert('class C; def initialize; @f=1; end; end',
|
121
|
-
eslevel: 2020, underscored_private: true)
|
122
|
-
```
|
123
|
-
|
124
|
-
With [ExecJS](https://github.com/sstephenson/execjs):
|
125
|
-
```ruby
|
126
|
-
require 'ruby2js/execjs'
|
127
|
-
require 'date'
|
128
|
-
|
129
|
-
context = Ruby2JS.compile(Date.today.strftime('d = new Date(%Y, %-m-1, %-d)'))
|
130
|
-
puts context.eval('d.getYear()')+1900
|
131
|
-
```
|
132
|
-
|
133
|
-
Conversions can be explored interactively using the
|
134
|
-
[demo](https://github.com/rubys/ruby2js/blob/master/demo/ruby2js.rb) provided.
|
135
|
-
|
136
|
-
Introduction
|
137
|
-
---
|
138
|
-
|
139
|
-
JavaScript is a language where `0` is considered `false`, strings are
|
140
|
-
immutable, and the behaviors for operators like `==` are, at best,
|
141
|
-
[convoluted](https://zero.milosz.ca/).
|
142
|
-
|
143
|
-
Any attempt to bridge the semantics of Ruby and JavaScript will involve
|
144
|
-
trade-offs. Consider the following expression:
|
145
|
-
|
146
|
-
```ruby
|
147
|
-
a[-1]
|
148
|
-
```
|
149
|
-
|
150
|
-
Programmers who are familiar with Ruby will recognize that this returns the
|
151
|
-
last element (or character) of an array (or string). However, the meaning is
|
152
|
-
quite different if `a` is a Hash.
|
153
|
-
|
154
|
-
One way to resolve this is to change the way indexing operators are evaluated,
|
155
|
-
and to provide a runtime library that adds properties to global JavaScript
|
156
|
-
objects to handle this. This is the approach that [Opal](https://opalrb.com/)
|
157
|
-
takes. It is a fine approach, with a number of benefits. It also has some
|
158
|
-
notable drawbacks. For example,
|
159
|
-
[readability](https://opalrb.com/try/#code:a%20%3D%20%22abc%22%3B%20puts%20a[-1])
|
160
|
-
and
|
161
|
-
[compatibility with other frameworks](https://github.com/opal/opal/issues/400).
|
162
|
-
|
163
|
-
Another approach is to simply accept JavaScript semantics for what they are.
|
164
|
-
This would mean that negative indexes would return `undefined` for arrays
|
165
|
-
and strings. This is the base approach provided by ruby2js.
|
166
|
-
|
167
|
-
A third approach would be to do static transformations on the source in order
|
168
|
-
to address common usage patterns or idioms. These transformations can even be
|
169
|
-
occasionally unsafe, as long as the transformations themselves are opt-in.
|
170
|
-
ruby2js provides a number of such filters, including one that handles negative
|
171
|
-
indexes when passed as a literal. As indicated above, this is unsafe in that
|
172
|
-
it will do the wrong thing when it encounters a hash index which is expressed
|
173
|
-
as a literal constant negative one. My experience is that such is rare enough
|
174
|
-
to be safely ignored, but YMMV. More troublesome, this also won’t work when
|
175
|
-
the index is not a literal (e.g., `a[n]`) and the index happens to be
|
176
|
-
negative at runtime.
|
177
|
-
|
178
|
-
This quickly gets into gray areas. `each` in Ruby is a common method that
|
179
|
-
facilitates iteration over arrays. `forEach` is the JavaScript equivalent.
|
180
|
-
Mapping this is fine until you start using a framework like jQuery which
|
181
|
-
provides a function named [each](https://api.jquery.com/jQuery.each/).
|
182
|
-
|
183
|
-
Fortunately, Ruby provides `?` and `!` as legal suffixes for method names,
|
184
|
-
Ruby2js filters do an exact match, so if you select a filter that maps `each`
|
185
|
-
to `forEach`, `each!` will pass through the filter. The final code that emits
|
186
|
-
JavaScript function calls and parameter accesses will strip off these
|
187
|
-
suffixes.
|
188
|
-
|
189
|
-
This approach works well if it is an occasional change, but if the usage is
|
190
|
-
pervasive, most filters support options to `exclude` a list of mappings,
|
191
|
-
for example:
|
192
|
-
|
193
|
-
```ruby
|
194
|
-
puts Ruby2JS.convert('jQuery("li").each {|index| ...}', exclude: :each)
|
195
|
-
```
|
196
|
-
|
197
|
-
Alternatively, you can change the default:
|
198
|
-
|
199
|
-
```ruby
|
200
|
-
Ruby2JS::Filter.exclude :each
|
201
|
-
```
|
202
|
-
|
203
|
-
Static transformations and runtime libraries aren't aren’t mutually exclusive.
|
204
|
-
With enough of each, one could reproduce any functionality desired.
|
205
|
-
|
206
|
-
Integrations
|
207
|
-
---
|
208
|
-
|
209
|
-
While this is a low level library suitable for DIY integration, one of the
|
210
|
-
obvious uses of a tool that produces JavaScript is by web servers. Ruby2JS
|
211
|
-
includes several integrations:
|
212
|
-
|
213
|
-
* [CGI](https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/cgi.rb)
|
214
|
-
* [Sinatra](https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/sinatra.rb)
|
215
|
-
* [Rails](https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/rails.rb)
|
216
|
-
* [Haml](https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/haml.rb)
|
217
|
-
|
218
|
-
As you might expect, CGI is a bit sluggish. By contrast, Sinatra and Rails
|
219
|
-
are quite speedy as the bulk of the time is spent on the initial load of the
|
220
|
-
required libraries.
|
221
|
-
|
222
|
-
For easy integration with Webpack (and Webpacker in Rails 5+), you can use the
|
223
|
-
[rb2js-loader](https://github.com/whitefusionhq/rb2js-loader) plugin.
|
224
|
-
|
225
|
-
Filters
|
226
|
-
---
|
227
|
-
|
228
|
-
In general, making use of a filter is as simple as requiring it. If multiple
|
229
|
-
filters are selected, they will all be applied in parallel in one pass through
|
230
|
-
the script.
|
231
|
-
|
232
|
-
* <a id="return" href="https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/filter/return.rb">return</a>
|
233
|
-
adds `return` to the last expression in functions.
|
234
|
-
|
235
|
-
* <a id="require" href="https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/filter/require.rb">require</a>
|
236
|
-
supports `require` and `require_relative` statements. Contents of files
|
237
|
-
that are required are converted to JavaScript and expanded inline.
|
238
|
-
`require` function calls in expressions are left alone.
|
239
|
-
|
240
|
-
* <a id="camelCase" href="https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/filter/camelCase.rb">camelCase</a>
|
241
|
-
converts `underscore_case` to `camelCase`. See
|
242
|
-
[camelcase_spec](https://github.com/rubys/ruby2js/blob/master/spec/camelcase_spec.rb)
|
243
|
-
for examples.
|
244
|
-
|
245
|
-
* <a id="functions" href="https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/filter/functions.rb">functions</a>
|
246
|
-
|
247
|
-
* `.abs` becomes `Math.abs()`
|
248
|
-
* `.all?` becomes `.every`
|
249
|
-
* `.any?` becomes `.some`
|
250
|
-
* `.ceil` becomes `Math.ceil()`
|
251
|
-
* `.chr` becomes `fromCharCode`
|
252
|
-
* `.clear` becomes `.length = 0`
|
253
|
-
* `.delete` becomes `delete target[arg]`
|
254
|
-
* `.downcase` becomes `.toLowerCase`
|
255
|
-
* `.each` becomes `.forEach`
|
256
|
-
* `.each_key` becomes `for (i in ...) {}`
|
257
|
-
* `.each_pair` becomes `for (var key in item) {var value = item[key]; ...}`
|
258
|
-
* `.each_value` becomes `.forEach`
|
259
|
-
* `.each_with_index` becomes `.forEach`
|
260
|
-
* `.end_with?` becomes `.slice(-arg.length) == arg`
|
261
|
-
* `.empty?` becomes `.length == 0`
|
262
|
-
* `.find_index` becomes `findIndex`
|
263
|
-
* `.first` becomes `[0]`
|
264
|
-
* `.first(n)` becomes `.slice(0, n)`
|
265
|
-
* `.floor` becomes `Math.floor()`
|
266
|
-
* `.gsub` becomes `replace(//g)`
|
267
|
-
* `.include?` becomes `.indexOf() != -1`
|
268
|
-
* `.inspect` becomes `JSON.stringify()`
|
269
|
-
* `.keys()` becomes `Object.keys()`
|
270
|
-
* `.last` becomes `[*.length-1]`
|
271
|
-
* `.last(n)` becomes `.slice(*.length-1, *.length)`
|
272
|
-
* `.lstrip` becomes `.replace(/^\s+/, "")`
|
273
|
-
* `.max` becomes `Math.max.apply(Math)`
|
274
|
-
* `.merge` becomes `Object.assign({}, ...)`
|
275
|
-
* `.merge!` becomes `Object.assign()`
|
276
|
-
* `.min` becomes `Math.min.apply(Math)`
|
277
|
-
* `.nil?` becomes `== null`
|
278
|
-
* `.ord` becomes `charCodeAt(0)`
|
279
|
-
* `puts` becomes `console.log`
|
280
|
-
* `.replace` becomes `.length = 0; ...push.apply(*)`
|
281
|
-
* `.respond_to?` becomes `right in left`
|
282
|
-
* `.rstrip` becomes `.replace(/s+$/, "")`
|
283
|
-
* `.scan` becomes `.match(//g)`
|
284
|
-
* `.sum` becomes `.reduce(function(a, b) {a + b}, 0)`
|
285
|
-
* `.start_with?` becomes `.substring(0, arg.length) == arg`
|
286
|
-
* `.upto(lim)` becomes `for (var i=num; i<=lim; i+=1)`
|
287
|
-
* `.downto(lim)` becomes `for (var i=num; i>=lim; i-=1)`
|
288
|
-
* `.step(lim, n).each` becomes `for (var i=num; i<=lim; i+=n)`
|
289
|
-
* `.step(lim, -n).each` becomes `for (var i=num; i>=lim; i-=n)`
|
290
|
-
* `(0..a).to_a` becomes `Array.apply(null, {length: a}).map(Function.call, Number)`
|
291
|
-
* `(b..a).to_a` becomes `Array.apply(null, {length: (a-b+1)}).map(Function.call, Number).map(function (idx) { return idx+b })`
|
292
|
-
* `(b...a).to_a` becomes `Array.apply(null, {length: (a-b)}).map(Function.call, Number).map(function (idx) { return idx+b })`
|
293
|
-
* `.strip` becomes `.trim`
|
294
|
-
* `.sub` becomes `.replace`
|
295
|
-
* `.tap {|n| n}` becomes `(function(n) {n; return n})(...)`
|
296
|
-
* `.to_f` becomes `parseFloat`
|
297
|
-
* `.to_i` becomes `parseInt`
|
298
|
-
* `.to_s` becomes `.to_String`
|
299
|
-
* `.upcase` becomes `.toUpperCase`
|
300
|
-
* `.yield_self {|n| n}` becomes `(function(n) {return n})(...)`
|
301
|
-
* `[-n]` becomes `[*.length-n]` for literal values of `n`
|
302
|
-
* `[n...m]` becomes `.slice(n,m)`
|
303
|
-
* `[n..m]` becomes `.slice(n,m+1)`
|
304
|
-
* `[/r/, n]` becomes `.match(/r/)[n]`
|
305
|
-
* `[/r/, n]=` becomes `.replace(/r/, ...)`
|
306
|
-
* `(1..2).each {|i| ...}` becomes `for (var i=1 i<=2; i+=1)`
|
307
|
-
* `"string" * length` becomes `new Array(length + 1).join("string")`
|
308
|
-
* `.sub!` and `.gsub!` become equivalent `x = x.replace` statements
|
309
|
-
* `.map!`, `.reverse!`, and `.select` become equivalent
|
310
|
-
`.splice(0, .length, *.method())` statements
|
311
|
-
* `@foo.call(args)` becomes `this._foo(args)`
|
312
|
-
* `@@foo.call(args)` becomes `this.constructor._foo(args)`
|
313
|
-
* `Array(x)` becomes `Array.prototype.slice.call(x)`
|
314
|
-
* `delete x` becomes `delete x` (note lack of parenthesis)
|
315
|
-
* `setInterval` and `setTimeout` allow block to be treated as the
|
316
|
-
first parameter on the call
|
317
|
-
* for the following methods, if the block consists entirely of a simple
|
318
|
-
expression (or ends with one), a `return` is added prior to the
|
319
|
-
expression: `sub`, `gsub`, `any?`, `all?`, `map`, `find`, `find_index`.
|
320
|
-
* New classes subclassed off of `Exception` will become subclassed off
|
321
|
-
of `Error` instead; and default constructors will be provided
|
322
|
-
* `loop do...end` will be replaced with `while (true) {...}`
|
323
|
-
* `raise Exception.new(...)` will be replaced with `throw new Error(...)`
|
324
|
-
* `block_given?` will check for the presence of optional argument `_implicitBlockYield` which is a function made accessible through the use of `yield` in a method body.
|
325
|
-
|
326
|
-
Additionally, there is one mapping that will only be done if explicitly
|
327
|
-
included (pass `include: :class` as a `convert` option to enable):
|
328
|
-
|
329
|
-
* `.class` becomes `.constructor`
|
330
|
-
|
331
|
-
* <a id="active_functions" href="https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/filter/active_functions.rb">active_functions</a>
|
332
|
-
|
333
|
-
Provides functionality inspired by Rails' ActiveSupport. Works in conjunction
|
334
|
-
with the tiny NPM dependency `@ruby2js/active-functions` which must be added to
|
335
|
-
your application.
|
336
|
-
|
337
|
-
* `value.blank?` becomes `blank$(value)`
|
338
|
-
* `value.present?` becomes `present$(value)`
|
339
|
-
* `value.presence` becomes `presence$(value)`
|
340
|
-
|
341
|
-
Note: these conversions are only done if eslevel >= 2015. Import statements
|
342
|
-
will be added to the top of the code output automatically. By default they
|
343
|
-
will be `@ruby2js/active-functions`, but you can pass an `import_from_skypack: true` option to `convert` to use the Skypack CDN instead.
|
344
|
-
|
345
|
-
* <a id="tagged_templates" href="https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/filter/tagged_templates.rb">tagged_templates</a>
|
346
|
-
|
347
|
-
Allows you to turn certain method calls with a string argument into tagged
|
348
|
-
template literals. By default it supports html and css, so you can write
|
349
|
-
`html "<div>#{1+2}</div>"` which converts to `` html`<div>${1+2}</div>` ``.
|
350
|
-
Works nicely with squiggly heredocs for multi-line templates as well. If you
|
351
|
-
need to configure the tag names yourself, pass a `template_literal_tags`
|
352
|
-
option to `convert` with an array of tag name symbols.
|
353
|
-
|
354
|
-
Note: these conversions are only done if eslevel >= 2015
|
355
|
-
|
356
|
-
* <a href="https://github.com/rubys/ruby2js/blob/master/lib/ruby2js/filter/esm.rb">esm</a>
|
357
|
-
|
358
|
-
Provides conversion of import and export statements for use with modern ES builders like Webpack.
|
359
|
-
|
360
|
-
Examples:
|
361
|
-
|
362
|
-
**import**
|
363
|
-
|
364
|
-
```ruby
|
365
|
-
import "./index.scss"
|
366
|
-
# => import "./index.scss"
|
367
|
-
|
368
|
-
import Something from "./lib/something"
|
369
|
-
# => import Something from "./lib/something"
|
370
|
-
|
371
|
-
import Something, "./lib/something"
|
372
|
-
# => import Something from "./lib/something"
|
373
|
-
|
374
|
-
import [ LitElement, html, css ], from: "lit-element"
|
375
|
-
# => import { LitElement, html, css } from "lit-element"
|
376
|
-
|
377
|
-
import React, from: "react"
|
378
|
-
# => import React from "react"
|
379
|
-
|
380
|
-
import React, as: "*", from: "react"
|
381
|
-
# => import React as * from "react"
|
382
|
-
```
|
383
|
-
|
384
|
-
**export**
|
385
|
-
|
386
|
-
```ruby
|
387
|
-
export hash = { ab: 123 }
|
388
|
-
# => export const hash = {ab: 123};
|
389
|
-
|
390
|
-
export func = ->(x) { x * 10 }
|
391
|
-
# => export const func = x => x * 10;
|
392
|
-
|
393
|
-
export def multiply(x, y)
|
394
|
-
return x * y
|
395
|
-
end
|
396
|
-
# => export function multiply(x, y) {
|
397
|
-
# return x * y
|
398
|
-
# }
|
399
|
-
|
400
|
-
export default class MyClass
|
401
|
-
end
|
402
|
-
# => export default class MyClass {
|
403
|
-
# };
|
404
|
-
|
405
|
-
# or final export statement:
|
406
|
-
export [ one, two, default: three ]
|
407
|
-
# => export { one, two, three as default }
|
408
|
-
```
|
409
|
-
|
410
|
-
If the "autoexports" option is `true`, all top level modules, classes,
|
411
|
-
methods and constants will automatically be exported.
|
412
|
-
|
413
|
-
The esm filter also provides a way to specify "autoimports" when you run the
|
414
|
-
conversion. It will add the relevant import statements automatically whenever
|
415
|
-
a particular class or function name is referenced. These can be either default
|
416
|
-
or named exports. Simply provide an `autoimports` hash with one or more keys
|
417
|
-
to the `Ruby2JS.convert` method. Examples:
|
418
|
-
|
419
|
-
```ruby
|
420
|
-
require "ruby2js/filter/esm"
|
421
|
-
puts Ruby2JS.convert('class MyElement < LitElement; end',
|
422
|
-
eslevel: 2020, autoimports: {[:LitElement] => "lit-element"})
|
423
|
-
```
|
424
|
-
|
425
|
-
```js
|
426
|
-
// JavaScript output:
|
427
|
-
import { LitElement } from "lit-element"
|
428
|
-
class MyElement extends LitElement {}
|
429
|
-
```
|
430
|
-
|
431
|
-
```ruby
|
432
|
-
require "ruby2js/filter/esm"
|
433
|
-
puts Ruby2JS.convert('AWN.new({position: "top-right"}).success("Hello World")',
|
434
|
-
eslevel: 2020, autoimports: {:AWN => "awesome-notifications"})
|
435
|
-
```
|
436
|
-
|
437
|
-
```js
|
438
|
-
// JavaScript output:
|
439
|
-
import AWN from "awesome-notifications"
|
440
|
-
new AWN({position: "top-right"}).success("Hello World")
|
441
|
-
```
|
442
|
-
|
443
|
-
The esm filter is able to recognize if you are defining a class or function
|
444
|
-
within the code itself and it won't add that import statement accordingly.
|
445
|
-
If for some reason you wish to disable autoimports entirely on a file-by-file
|
446
|
-
basis (for instance when using the Webpack loader), you can add a magic comment
|
447
|
-
to the top of the code:
|
448
|
-
|
449
|
-
```ruby
|
450
|
-
require "ruby2js/filter/esm"
|
451
|
-
puts Ruby2JS.convert(
|
452
|
-
"# autoimports: false\n" +
|
453
|
-
'AWN.new({position: "top-right"}).success("Hello World")',
|
454
|
-
eslevel: 2020, autoimports: {:AWN => "awesome-notifications"}
|
455
|
-
)
|
456
|
-
```
|
457
|
-
|
458
|
-
```js
|
459
|
-
// autoimports: false
|
460
|
-
new AWN({position: "top-right"}).success("Hello World")
|
461
|
-
```
|
462
|
-
|
463
|
-
* <a id="node" href="https://github.com/rubys/ruby2js/blob/master/spec/node_spec.rb">node</a>
|
464
|
-
|
465
|
-
* `` `command` `` becomes `child_process.execSync("command", {encoding: "utf8"})`
|
466
|
-
* `ARGV` becomes `process.argv.slice(2)`
|
467
|
-
* `__dir__` becomes `__dirname`
|
468
|
-
* `Dir.chdir` becomes `process.chdir`
|
469
|
-
* `Dir.entries` becomes `fs.readdirSync`
|
470
|
-
* `Dir.home` becomes `os.homedir()`
|
471
|
-
* `Dir.mkdir` becomes `fs.mkdirSync`
|
472
|
-
* `Dir.mktmpdir` becomes `fs.mkdtempSync`
|
473
|
-
* `Dir.pwd` becomes `process.cwd`
|
474
|
-
* `Dir.rmdir` becomes `fs.rmdirSync`
|
475
|
-
* `Dir.tmpdir` becomes `os.tmpdir()`
|
476
|
-
* `ENV` becomes `process.env`
|
477
|
-
* `__FILE__` becomes `__filename`
|
478
|
-
* `File.absolute_path` becomes `path.resolve`
|
479
|
-
* `File.absolute_path?` becomes `path.isAbsolute`
|
480
|
-
* `File.basename` becomes `path.basename`
|
481
|
-
* `File.chmod` becomes `fs.chmodSync`
|
482
|
-
* `File.chown` becomes `fs.chownSync`
|
483
|
-
* `File.cp` becomes `fs.copyFileSync`
|
484
|
-
* `File.dirname` becomes `path.dirname`
|
485
|
-
* `File.exist?` becomes `fs.existsSync`
|
486
|
-
* `File.extname` becomes `path.extname`
|
487
|
-
* `File.join` becomes `path.join`
|
488
|
-
* `File.lchmod` becomes `fs.lchmodSync`
|
489
|
-
* `File.link` becomes `fs.linkSync`
|
490
|
-
* `File.ln` becomes `fs.linkSync`
|
491
|
-
* `File.lstat` becomes `fs.lstatSync`
|
492
|
-
* `File::PATH_SEPARATOR` becomes `path.delimiter`
|
493
|
-
* `File.read` becomes `fs.readFileSync`
|
494
|
-
* `File.readlink` becomes `fs.readlinkSync`
|
495
|
-
* `File.realpath` becomes `fs.realpathSync`
|
496
|
-
* `File.rename` becomes `fs.renameSync`
|
497
|
-
* `File::SEPARATOR` becomes `path.sep`
|
498
|
-
* `File.stat` becomes `fs.statSync`
|
499
|
-
* `File.symlink` becomes `fs.symlinkSync`
|
500
|
-
* `File.truncate` becomes `fs.truncateSync`
|
501
|
-
* `File.unlink` becomes `fs.unlinkSync`
|
502
|
-
* `FileUtils.cd` becomes `process.chdir`
|
503
|
-
* `FileUtils.cp` becomes `fs.copyFileSync`
|
504
|
-
* `FileUtils.ln` becomes `fs.linkSync`
|
505
|
-
* `FileUtils.ln_s` becomes `fs.symlinkSync`
|
506
|
-
* `FileUtils.mkdir` becomes `fs.mkdirSync`
|
507
|
-
* `FileUtils.mv` becomes `fs.renameSync`
|
508
|
-
* `FileUtils.pwd` becomes `process.cwd`
|
509
|
-
* `FileUtils.rm` becomes `fs.unlinkSync`
|
510
|
-
* `IO.read` becomes `fs.readFileSync`
|
511
|
-
* `IO.write` becomes `fs.writeFileSync`
|
512
|
-
* `system` becomes `child_process.execSync(..., {stdio: "inherit"})`
|
513
|
-
|
514
|
-
* <a id="nokogiri" href="https://github.com/rubys/ruby2js/blob/master/spec/nokogiri.rb">nokogiri</a>
|
515
|
-
* `add_child` becomes `appendChild`
|
516
|
-
* `add_next_sibling` becomes `node.parentNode.insertBefore(sibling, node.nextSibling)`
|
517
|
-
* `add_previous_sibling` becomes `node.parentNode.insertBefore(sibling, node)`
|
518
|
-
* `after` becomes `node.parentNode.insertBefore(sibling, node.nextSibling)`
|
519
|
-
* `at` becomes `querySelector`
|
520
|
-
* `attr` becomes `getAttribute`
|
521
|
-
* `attribute` becomes `getAttributeNode`
|
522
|
-
* `before` becomes `node.parentNode.insertBefore(sibling, node)`
|
523
|
-
* `cdata?` becomes `node.nodeType === Node.CDATA_SECTION_NODE`
|
524
|
-
* `children` becomes `childNodes`
|
525
|
-
* `comment?` becomes `node.nodeType === Node.COMMENT_NODE`
|
526
|
-
* `content` becomes `textContent`
|
527
|
-
* `create_element` becomes `createElement`
|
528
|
-
* `document` becomes `ownerDocument`
|
529
|
-
* `element?` becomes `node.nodeType === Node.ELEMENT_NODE`
|
530
|
-
* `fragment?` becomes `node.nodeType === Node.FRAGMENT_NODE`
|
531
|
-
* `get_attribute` becomes `getAttribute`
|
532
|
-
* `has_attribute` becomes `hasAttribute`
|
533
|
-
* `inner_html` becomes `innerHTML`
|
534
|
-
* `key?` becomes `hasAttribute`
|
535
|
-
* `name` becomes `nextSibling`
|
536
|
-
* `next` becomes `nodeName`
|
537
|
-
* `next=` becomes `node.parentNode.insertBefore(sibling,node.nextSibling)`
|
538
|
-
* `next_element` becomes `nextElement`
|
539
|
-
* `next_sibling` becomes `nextSibling`
|
540
|
-
* `Nokogiri::HTML5` becomes `new JSDOM().window.document`
|
541
|
-
* `Nokogiri::HTML5.parse` becomes `new JSDOM().window.document`
|
542
|
-
* `Nokogiri::HTML` becomes `new JSDOM().window.document`
|
543
|
-
* `Nokogiri::HTML.parse` becomes `new JSDOM().window.document`
|
544
|
-
* `Nokogiri::XML::Node.new` becomes `document.createElement()`
|
545
|
-
* `parent` becomes `parentNode`
|
546
|
-
* `previous=` becomes `node.parentNode.insertBefore(sibling, node)`
|
547
|
-
* `previous_element` becomes `previousElement`
|
548
|
-
* `previous_sibling` becomes `previousSibling`
|
549
|
-
* `processing_instruction?` becomes `node.nodeType === Node.PROCESSING_INSTRUCTION_NODE`
|
550
|
-
* `remove_attribute` becomes `removeAttribute`
|
551
|
-
* `root` becomes `documentElement`
|
552
|
-
* `search` becomes `querySelectorAll`
|
553
|
-
* `set_attribute` becomes `setAttribute`
|
554
|
-
* `text?` becomes `node.nodeType === Node.TEXT_NODE`
|
555
|
-
* `text` becomes `textContent`
|
556
|
-
* `to_html` becomes `outerHTML`
|
557
|
-
|
558
|
-
* <a id="underscore" href="https://github.com/rubys/ruby2js/blob/master/spec/underscore.rb">underscore</a>
|
559
|
-
|
560
|
-
* `.clone()` becomes `_.clone()`
|
561
|
-
* `.compact()` becomes `_.compact()`
|
562
|
-
* `.count_by {}` becomes `_.countBy {}`
|
563
|
-
* `.find {}` becomes `_.find {}`
|
564
|
-
* `.find_by()` becomes `_.findWhere()`
|
565
|
-
* `.flatten()` becomes `_.flatten()`
|
566
|
-
* `.group_by {}` becomes `_.groupBy {}`
|
567
|
-
* `.has_key?()` becomes `_.has()`
|
568
|
-
* `.index_by {}` becomes `_.indexBy {}`
|
569
|
-
* `.invert()` becomes `_.invert()`
|
570
|
-
* `.invoke(&:n)` becomes `_.invoke(, :n)`
|
571
|
-
* `.map(&:n)` becomes `_.pluck(, :n)`
|
572
|
-
* `.merge!()` becomes `_.extend()`
|
573
|
-
* `.merge()` becomes `_.extend({}, )`
|
574
|
-
* `.reduce {}` becomes `_.reduce {}`
|
575
|
-
* `.reduce()` becomes `_.reduce()`
|
576
|
-
* `.reject {}` becomes `_.reject {}`
|
577
|
-
* `.sample()` becomes `_.sample()`
|
578
|
-
* `.select {}` becomes `_.select {}`
|
579
|
-
* `.shuffle()` becomes `_.shuffle()`
|
580
|
-
* `.size()` becomes `_.size()`
|
581
|
-
* `.sort()` becomes `_.sort_by(, _.identity)`
|
582
|
-
* `.sort_by {}` becomes `_.sortBy {}`
|
583
|
-
* `.times {}` becomes `_.times {}`
|
584
|
-
* `.values()` becomes `_.values()`
|
585
|
-
* `.where()` becomes `_.where()`
|
586
|
-
* `.zip()` becomes `_.zip()`
|
587
|
-
* `(n...m)` becomes `_.range(n, m)`
|
588
|
-
* `(n..m)` becomes `_.range(n, m+1)`
|
589
|
-
* `.compact!`, `.flatten!`, `shuffle!`, `reject!`, `sort_by!`, and
|
590
|
-
`.uniq` become equivalent `.splice(0, .length, *.method())` statements
|
591
|
-
* for the following methods, if the block consists entirely of a simple
|
592
|
-
expression (or ends with one), a `return` is added prior to the
|
593
|
-
expression: `reduce`, `sort_by`, `group_by`, `index_by`, `count_by`,
|
594
|
-
`find`, `select`, `reject`.
|
595
|
-
* `is_a?` and `kind_of?` map to `Object.prototype.toString.call() ===
|
596
|
-
"[object #{type}]" for the following types: `Arguments`, `Boolean`,
|
597
|
-
`Date`, `Error`, `Function`, `Number`, `Object`, `RegExp`, `String`; and
|
598
|
-
maps Ruby names to JavaScript equivalents for `Exception`, `Float`,
|
599
|
-
`Hash`, `Proc`, and `Regexp`. Additionally, `is_a?` and `kind_of?` map
|
600
|
-
to `Array.isArray()` for `Array`.
|
601
|
-
|
602
|
-
* <a id="jquery" href="https://github.com/rubys/ruby2js/blob/master/spec/jquery.rb">jquery</a>
|
603
|
-
|
604
|
-
* maps Ruby unary operator `~` to jQuery `$` function
|
605
|
-
* maps Ruby attribute syntax to jquery attribute syntax
|
606
|
-
* `.to_a` becomes `toArray`
|
607
|
-
* maps `$$` to jQuery `$` function
|
608
|
-
* defaults the fourth parameter of $$.post to `"json"`, allowing Ruby block
|
609
|
-
syntax to be used for the success function.
|
610
|
-
|
611
|
-
* <a id="minitest-jasmine" href="https://github.com/rubys/ruby2js/blob/master/spec/minitest-jasmine.rb">minitest-jasmine</a>
|
612
|
-
* maps subclasses of `Minitest::Test` to `describe` calls
|
613
|
-
* maps `test_` methods inside subclasses of `Minitest::Test` to `it` calls
|
614
|
-
* maps `setup`, `teardown`, `before`, and `after` calls to `beforeEach`
|
615
|
-
and `afterEach` calls
|
616
|
-
* maps `assert` and `refute` calls to `expect`...`toBeTruthy()` and
|
617
|
-
`toBeFalsy` calls
|
618
|
-
* maps `assert_equal`, `refute_equal`, `.must_equal` and `.cant_equal`
|
619
|
-
calls to `expect`...`toBe()` calls
|
620
|
-
* maps `assert_in_delta`, `refute_in_delta`, `.must_be_within_delta`,
|
621
|
-
`.must_be_close_to`, `.cant_be_within_delta`, and `.cant_be_close_to`
|
622
|
-
calls to `expect`...`toBeCloseTo()` calls
|
623
|
-
* maps `assert_includes`, `refute_includes`, `.must_include`, and
|
624
|
-
`.cant_include` calls to `expect`...`toContain()` calls
|
625
|
-
* maps `assert_match`, `refute_match`, `.must_match`, and `.cant_match`
|
626
|
-
calls to `expect`...`toMatch()` calls
|
627
|
-
* maps `assert_nil`, `refute_nil`, `.must_be_nil`, and `.cant_be_nill` calls
|
628
|
-
to `expect`...`toBeNull()` calls
|
629
|
-
* maps `assert_operator`, `refute_operator`, `.must_be`, and `.cant_be`
|
630
|
-
calls to `expect`...`toBeGreaterThan()` or `toBeLessThan` calls
|
631
|
-
|
632
|
-
* <a id="cjs" href="https://github.com/rubys/ruby2js/blob/master/spec/cjs">cjs</a>
|
633
|
-
* maps `export def f` to `exports.f =`
|
634
|
-
* maps `export async def f` to `exports.f = async`
|
635
|
-
* maps `export v =` to `exports.v =`
|
636
|
-
* maps `export default proc` to `module.exports =`
|
637
|
-
* maps `export default async proc` to `module.exports = async`
|
638
|
-
* maps `export default` to `module.exports =`
|
639
|
-
|
640
|
-
* <a id="matchAll" href="https://github.com/rubys/ruby2js/blob/master/spec/matchAll">matchAll</a>
|
641
|
-
|
642
|
-
For ES level < 2020:
|
643
|
-
|
644
|
-
* maps `str.matchAll(pattern).forEach {}` to
|
645
|
-
`while (match = pattern.exec(str)) {}`
|
646
|
-
|
647
|
-
Note `pattern` must be a simple variable with a value of a regular
|
648
|
-
expression with the `g` flag set at runtime.
|
649
|
-
|
650
|
-
[Wunderbar](https://github.com/rubys/wunderbar) includes additional demos:
|
651
|
-
|
652
|
-
* [chat](https://github.com/rubys/wunderbar/blob/master/demo/chat.rb),
|
653
|
-
[diskusage](https://github.com/rubys/wunderbar/blob/master/demo/diskusage.rb),
|
654
|
-
and [wiki](https://github.com/rubys/wunderbar/blob/master/demo/wiki.rb) make
|
655
|
-
use of the jquery filter.
|
656
|
-
|
657
|
-
ES2015 support
|
658
|
-
---
|
659
|
-
|
660
|
-
When option `eslevel: 2015` is provided, the following additional
|
661
|
-
conversions are made:
|
662
|
-
|
663
|
-
* `"#{a}"` becomes <code>\`${a}\`</code>
|
664
|
-
* `a = 1` becomes `let a = 1`
|
665
|
-
* `A = 1` becomes `const A = 1`
|
666
|
-
* `a, b = b, a` becomes `[a, b] = [b, a]`
|
667
|
-
* `a, (foo, *bar) = x` becomes `let [a, [foo, ...bar]] = x`
|
668
|
-
* `def f(a, (foo, *bar))` becomes `function f(a, [foo, ...bar])`
|
669
|
-
* `def a(b=1)` becomes `function a(b=1)`
|
670
|
-
* `def a(*b)` becomes `function a(...b)`
|
671
|
-
* `.each_value` becomes `for (i of ...) {}`
|
672
|
-
* `a(*b)` becomes `a(...b)`
|
673
|
-
* `"#{a}"` becomes <code>\`${a}\`</code>
|
674
|
-
* `lambda {|x| x}` becomes `(x) => {return x}`
|
675
|
-
* `proc {|x| x}` becomes `(x) => {x}`
|
676
|
-
* `a {|x|}` becomes `a((x) => {})`
|
677
|
-
* `class Person; end` becomes `class Person {}`
|
678
|
-
* `(0...a).to_a` becomes `[...Array(a).keys()]`
|
679
|
-
* `(0..a).to_a` becomes `[...Array(a+1).keys()]`
|
680
|
-
* `(b..a).to_a` becomes `Array.from({length: (a-b+1)}, (_, idx) => idx+b)`
|
681
|
-
|
682
|
-
ES2015 class support includes constructors, super, methods, class methods,
|
683
|
-
instance methods, instance variables, class variables, getters, setters,
|
684
|
-
attr_accessor, attr_reader, attr_writer, etc.
|
685
|
-
|
686
|
-
Additionally, the `functions` filter will provide the following conversion:
|
687
|
-
|
688
|
-
* `Array(x)` becomes `Array.from(x)`
|
689
|
-
* `.inject(n) {}` becomes `.reduce(() => {}, n)`
|
690
|
-
|
691
|
-
Keyword arguments and optional keyword arguments will be mapped to
|
692
|
-
parameter destructuring.
|
693
|
-
|
694
|
-
Classes defined with a `method_missing` method will emit a `Proxy` object
|
695
|
-
for each instance that will forward calls. Note that in order to forward
|
696
|
-
arguments, this proxy will return a function that will need to be called,
|
697
|
-
making it impossible to proxy attributes/getters. As a special accommodation,
|
698
|
-
if the `method_missing` method is defined to only accept a single parameter
|
699
|
-
it will be called with only the method name, and it is free to return
|
700
|
-
either values or functions.
|
701
|
-
|
702
|
-
ES2016 support
|
703
|
-
---
|
704
|
-
|
705
|
-
When option `eslevel: 2016` is provided, the following additional
|
706
|
-
conversion is made:
|
707
|
-
|
708
|
-
* `a ** b` becomes `a ** b`
|
709
|
-
|
710
|
-
Additionally the following conversions is added to the `functions` filter:
|
711
|
-
|
712
|
-
* `.include?` becomes `.includes`
|
713
|
-
|
714
|
-
ES2017 support
|
715
|
-
---
|
716
|
-
|
717
|
-
When option `eslevel: 2017` is provided, the following additional
|
718
|
-
conversions are made by the `functions` filter:
|
719
|
-
|
720
|
-
* `.values()` becomes `Object.values()`
|
721
|
-
* `.entries()` becomes `Object.entries()`
|
722
|
-
* `.each_pair {}` becomes `for (let [key, value] of Object.entries()) {}`
|
723
|
-
|
724
|
-
async support:
|
725
|
-
|
726
|
-
* `async def` becomes `async function`
|
727
|
-
* `async lambda` becomes `async =>`
|
728
|
-
* `async proc` becomes `async =>`
|
729
|
-
* `async ->` becomes `async =>`
|
730
|
-
* `foo bar, async do...end` becomes `foo(bar, async () => {})`
|
731
|
-
|
732
|
-
ES2018 support
|
733
|
-
---
|
734
|
-
|
735
|
-
When option `eslevel: 2018` is provided, the following additional
|
736
|
-
conversion is made by the `functions` filter:
|
737
|
-
|
738
|
-
* `.merge` becomes `{...a, ...b}`
|
739
|
-
|
740
|
-
Additionally, rest arguments can now be used with keyword arguments and
|
741
|
-
optional keyword arguments.
|
742
|
-
|
743
|
-
ES2019 support
|
744
|
-
---
|
745
|
-
|
746
|
-
When option `eslevel: 2019` is provided, the following additional
|
747
|
-
conversion is made by the `functions` filter:
|
748
|
-
|
749
|
-
* `.flatten` becomes `.flat(Infinity)`
|
750
|
-
* `.lstrip` becomes `.trimEnd`
|
751
|
-
* `.rstrip` becomes `.trimStart`
|
752
|
-
* `a.to_h` becomes `Object.fromEntries(a)`
|
753
|
-
* `Hash[a]` becomes `Object.fromEntries(a)`
|
754
|
-
|
755
|
-
Additionally, `rescue` without a variable will map to `catch` without a
|
756
|
-
variable.
|
757
|
-
|
758
|
-
ES2020 support
|
759
|
-
---
|
760
|
-
|
761
|
-
When option `eslevel: 2020` is provided, the following additional
|
762
|
-
conversions are made:
|
763
|
-
|
764
|
-
* `@x` becomes `this.#x`
|
765
|
-
* `@@x` becomes `ClassName.#x`
|
766
|
-
* `a&.b` becomes `a?.b`
|
767
|
-
* `.scan` becomes `Array.from(str.matchAll(/.../g), s => s.slice(1))`
|
768
|
-
|
769
|
-
ES2021 support
|
770
|
-
---
|
771
|
-
|
772
|
-
When option `eslevel: 2021` is provided, the following additional
|
773
|
-
conversions are made:
|
774
|
-
|
775
|
-
* `x ||= 1` becomes `x ||= 1`
|
776
|
-
* `x &&= 1` becomes `x &&= 1`
|
777
|
-
* `1000000.000001` becomes `1_000_000.000_001`
|
778
|
-
|
779
|
-
Picking a Ruby to JS mapping tool
|
780
|
-
---
|
781
|
-
|
782
|
-
> dsl — A domain specific language, where code is written in one language and
|
783
|
-
> errors are given in another.
|
784
|
-
> -- [Devil’s Dictionary of Programming](https://programmingisterrible.com/post/65781074112/devils-dictionary-of-programming)
|
785
|
-
|
786
|
-
If you simply want to get a job done, and would like a mature and tested
|
787
|
-
framework, and only use one of the many integrations that
|
788
|
-
[Opal](https://opalrb.com/) provides, then Opal is the way to go right now.
|
789
|
-
|
790
|
-
ruby2js is for those that want to produce JavaScript that looks like it
|
791
|
-
wasn’t machine generated, and want the absolute bare minimum in terms of
|
792
|
-
limitations as to what JavaScript can be produced.
|
793
|
-
|
794
|
-
[Try](https://intertwingly.net/projects/ruby2js) for yourself.
|
795
|
-
[Compare](https://opalrb.com/try/#code:).
|
796
|
-
|
797
|
-
And, of course, the right solution might be to use
|
798
|
-
[CoffeeScript](https://coffeescript.org/) instead.
|
799
54
|
|
800
55
|
License
|
801
56
|
---
|
@@ -28,7 +28,7 @@ module Ruby2JS
|
|
28
28
|
af_import = @options[:import_from_skypack] ? "https://cdn.skypack.dev/@ruby2js/active-functions" : "@ruby2js/active-functions"
|
29
29
|
|
30
30
|
if found_node = prepend_list.find {|ast| ast.type == :import && ast.children.first == af_import}
|
31
|
-
unless found_node.children.find {|
|
31
|
+
unless found_node.children.last.find {|const| const.children.last == token}
|
32
32
|
prepend_list.delete found_node
|
33
33
|
prepend_list << s(:import, found_node.children.first, found_node.children.last.push(s(:const, nil, token)))
|
34
34
|
end
|
@@ -26,9 +26,15 @@ module Ruby2JS
|
|
26
26
|
return super if excluded?(method)
|
27
27
|
|
28
28
|
if [:max, :min].include? method and args.length == 0
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
if target.type == :array
|
30
|
+
process S(:send, s(:const, nil, :Math), node.children[1],
|
31
|
+
*target.children)
|
32
|
+
elsif node.is_method?
|
33
|
+
process S(:send, s(:const, nil, :Math), node.children[1],
|
34
|
+
s(:splat, target))
|
35
|
+
else
|
36
|
+
return super
|
37
|
+
end
|
32
38
|
|
33
39
|
elsif method == :call and target and target.type == :ivar
|
34
40
|
process S(:send, s(:self), "_#{target.children.first.to_s[1..-1]}",
|
@@ -47,40 +47,40 @@ module Ruby2JS
|
|
47
47
|
method == :at and
|
48
48
|
args.length == 1 and args.first.type == :str
|
49
49
|
then
|
50
|
-
S(:send, target, :querySelector, process(args.first))
|
50
|
+
S(:send, process(target), :querySelector, process(args.first))
|
51
51
|
|
52
52
|
elsif \
|
53
53
|
method == :search and
|
54
54
|
args.length == 1 and args.first.type == :str
|
55
55
|
then
|
56
|
-
S(:send, target, :querySelectorAll, process(args.first))
|
56
|
+
S(:send, process(target), :querySelectorAll, process(args.first))
|
57
57
|
|
58
58
|
elsif method === :parent and args.length == 0
|
59
|
-
S(:attr, target, :parentNode)
|
59
|
+
S(:attr, process(target), :parentNode)
|
60
60
|
|
61
61
|
elsif method === :name and args.length == 0
|
62
|
-
S(:attr, target, :nodeName)
|
62
|
+
S(:attr, process(target), :nodeName)
|
63
63
|
|
64
64
|
elsif [:text, :content].include? method and args.length == 0
|
65
|
-
S(:attr, target, :textContent)
|
65
|
+
S(:attr, process(target), :textContent)
|
66
66
|
|
67
67
|
elsif method == :content= and args.length == 1
|
68
|
-
S(:send, target, :textContent=, *process_all(args))
|
68
|
+
S(:send, process(target), :textContent=, *process_all(args))
|
69
69
|
|
70
70
|
elsif method === :inner_html and args.length == 0
|
71
|
-
S(:attr, target, :innerHTML)
|
71
|
+
S(:attr, process(target), :innerHTML)
|
72
72
|
|
73
73
|
elsif method == :inner_html= and args.length == 1
|
74
|
-
S(:send, target, :innerHTML=, *process_all(args))
|
74
|
+
S(:send, process(target), :innerHTML=, *process_all(args))
|
75
75
|
|
76
76
|
elsif method === :to_html and args.length == 0
|
77
|
-
S(:attr, target, :outerHTML)
|
77
|
+
S(:attr, process(target), :outerHTML)
|
78
78
|
|
79
79
|
elsif \
|
80
80
|
[:attr, :get_attribute].include? method and
|
81
81
|
args.length == 1 and args.first.type == :str
|
82
82
|
then
|
83
|
-
S(:send, target, :getAttribute, process(args.first))
|
83
|
+
S(:send, process(target), :getAttribute, process(args.first))
|
84
84
|
|
85
85
|
elsif \
|
86
86
|
[:key?, :has_attribute].include? method and
|
@@ -154,14 +154,14 @@ module Ruby2JS
|
|
154
154
|
[:add_next_sibling, :next=, :after].include? method and
|
155
155
|
args.length == 1
|
156
156
|
then
|
157
|
-
S(:send, s(:attr, target, :parentNode), :insertBefore,
|
157
|
+
S(:send, s(:attr, process(target), :parentNode), :insertBefore,
|
158
158
|
process(args.first), s(:attr, target, :nextSibling))
|
159
159
|
|
160
160
|
elsif \
|
161
161
|
[:add_previous_sibling, :previous=, :before].include? method and
|
162
162
|
args.length == 1
|
163
163
|
then
|
164
|
-
S(:send, s(:attr, target, :parentNode), :insertBefore,
|
164
|
+
S(:send, s(:attr, process(target), :parentNode), :insertBefore,
|
165
165
|
process(args.first), target)
|
166
166
|
|
167
167
|
elsif method == :prepend_child and args.length == 1
|
data/lib/ruby2js/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby2js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.6.
|
4
|
+
version: 3.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Ruby
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-01-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parser
|