ruby2js 4.0.2 → 4.1.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 +0 -1
- data/lib/ruby2js.rb +1 -1
- data/lib/ruby2js/converter.rb +1 -0
- data/lib/ruby2js/converter/class.rb +7 -5
- data/lib/ruby2js/converter/class2.rb +4 -4
- data/lib/ruby2js/converter/def.rb +7 -1
- data/lib/ruby2js/converter/dstr.rb +3 -1
- data/lib/ruby2js/converter/return.rb +1 -1
- data/lib/ruby2js/converter/send.rb +1 -0
- data/lib/ruby2js/converter/taglit.rb +13 -2
- data/lib/ruby2js/filter/cjs.rb +100 -2
- data/lib/ruby2js/filter/functions.rb +11 -6
- data/lib/ruby2js/filter/lit-element.rb +218 -0
- data/lib/ruby2js/filter/react.rb +276 -88
- data/lib/ruby2js/filter/tagged_templates.rb +4 -2
- data/lib/ruby2js/rails.rb +10 -0
- data/lib/ruby2js/version.rb +2 -2
- data/lib/tasks/README.md +4 -0
- data/lib/tasks/install/app/javascript/elements/index.js +2 -0
- data/lib/tasks/install/config/webpack/loaders/ruby2js.js +20 -0
- data/lib/tasks/install/litelement.rb +9 -0
- data/lib/tasks/install/preact.rb +3 -0
- data/lib/tasks/install/react.rb +2 -0
- data/lib/tasks/install/stimulus-sprockets.rb +32 -0
- data/lib/tasks/install/stimulus-webpacker.rb +5 -0
- data/lib/tasks/install/webpacker.rb +80 -0
- data/lib/tasks/nodetest.js +47 -0
- data/lib/tasks/ruby2js_tasks.rake +47 -0
- metadata +15 -2
data/lib/ruby2js/filter/react.rb
CHANGED
@@ -26,8 +26,13 @@ module Ruby2JS
|
|
26
26
|
extend SEXP
|
27
27
|
|
28
28
|
REACT_IMPORTS = {
|
29
|
-
React: s(:import, ['
|
30
|
-
ReactDOM: s(:import, ['
|
29
|
+
React: s(:import, ['react'], s(:attr, nil, :React)),
|
30
|
+
ReactDOM: s(:import, ['react-dom'], s(:attr, nil, :ReactDOM)),
|
31
|
+
Preact: s(:import,
|
32
|
+
[s(:pair, s(:sym, :as), s(:const, nil, :Preact)),
|
33
|
+
s(:pair, s(:sym, :from), s(:str, "preact"))],
|
34
|
+
s(:str, '*')),
|
35
|
+
PreactHook: s(:import, ["preact/hooks"], [s(:attr, nil, :useState)])
|
31
36
|
}
|
32
37
|
|
33
38
|
# the following command can be used to generate ReactAttrs:
|
@@ -71,17 +76,23 @@ module Ruby2JS
|
|
71
76
|
|
72
77
|
ReactLifecycle = %w(render componentDidMount shouldComponentUpdate
|
73
78
|
getShapshotBeforeUpdate componentDidUpdate componentWillUnmount
|
74
|
-
componentDidCatch)
|
79
|
+
componentDidCatch componentWillReceiveProps)
|
75
80
|
|
76
81
|
ReactAttrMap = Hash[ReactAttrs.map {|name| [name.downcase, name]}]
|
77
82
|
ReactAttrMap['for'] = 'htmlFor'
|
78
|
-
|
83
|
+
|
84
|
+
PreactAttrMap = {
|
85
|
+
htmlFor: 'for',
|
86
|
+
onDoubleClick: 'onDblClick',
|
87
|
+
tabIndex: 'tabindex'
|
88
|
+
}
|
79
89
|
|
80
90
|
def initialize(*args)
|
81
91
|
@react = nil
|
82
92
|
@reactApply = nil
|
83
93
|
@reactBlock = nil
|
84
94
|
@reactClass = nil
|
95
|
+
@reactMethod = nil
|
85
96
|
@react_props = []
|
86
97
|
@react_methods = []
|
87
98
|
@react_filter_functions = false
|
@@ -118,12 +129,23 @@ module Ruby2JS
|
|
118
129
|
def on_class(node)
|
119
130
|
cname, inheritance, *body = node.children
|
120
131
|
return super unless cname.children.first == nil
|
121
|
-
|
122
|
-
|
132
|
+
|
133
|
+
if inheritance == s(:const, nil, :React) or
|
123
134
|
inheritance == s(:const, s(:const, nil, :React), :Component) or
|
124
135
|
inheritance == s(:send, s(:const, nil, :React), :Component)
|
125
136
|
|
126
|
-
|
137
|
+
react = :React
|
138
|
+
prepend_list << REACT_IMPORTS[:React] if modules_enabled?
|
139
|
+
|
140
|
+
elsif inheritance == s(:const, nil, :Preact) or
|
141
|
+
inheritance == s(:const, s(:const, nil, :Preact), :Component) or
|
142
|
+
inheritance == s(:send, s(:const, nil, :Preact), :Component)
|
143
|
+
|
144
|
+
react = :Preact
|
145
|
+
prepend_list << REACT_IMPORTS[:Preact] if modules_enabled?
|
146
|
+
else
|
147
|
+
return super
|
148
|
+
end
|
127
149
|
|
128
150
|
# traverse down to actual list of class statements
|
129
151
|
if body.length == 1
|
@@ -141,12 +163,14 @@ module Ruby2JS
|
|
141
163
|
end
|
142
164
|
|
143
165
|
begin
|
144
|
-
react, @react = @react,
|
166
|
+
react, @react = @react, react
|
145
167
|
reactClass, @reactClass = @reactClass, true
|
146
168
|
|
147
169
|
pairs = []
|
148
170
|
|
149
|
-
|
171
|
+
createClass = (@react == :React and not es2015)
|
172
|
+
|
173
|
+
if createClass
|
150
174
|
# automatically capture the displayName for the class
|
151
175
|
pairs << s(:pair, s(:sym, :displayName),
|
152
176
|
s(:str, cname.children.last.to_s))
|
@@ -156,12 +180,11 @@ module Ruby2JS
|
|
156
180
|
statics = []
|
157
181
|
body.select {|child| child.type == :defs}.each do |child|
|
158
182
|
_parent, mname, args, *block = child.children
|
159
|
-
if
|
160
|
-
|
161
|
-
pairs << s(:defs, s(:self), mname, args, *block)
|
183
|
+
if not createClass
|
184
|
+
pairs << child
|
162
185
|
elsif child.is_method?
|
163
|
-
statics << s(:pair, s(:sym, mname),
|
164
|
-
[s(:send, nil, :proc), args, s(:autoreturn, *block)]))
|
186
|
+
statics << s(:pair, s(:sym, mname), child.updated(:block,
|
187
|
+
[s(:send, nil, :proc), args, s(:autoreturn, *block)]))
|
165
188
|
elsif \
|
166
189
|
block.length == 1 and
|
167
190
|
Converter::EXPRESSIONS.include? block.first.type
|
@@ -212,13 +235,53 @@ module Ruby2JS
|
|
212
235
|
scan_events[node.children]
|
213
236
|
end
|
214
237
|
end
|
215
|
-
scan_events[body]
|
238
|
+
scan_events[body] if createClass
|
216
239
|
|
217
240
|
# append statics (if any)
|
218
241
|
unless statics.empty?
|
219
242
|
pairs << s(:pair, s(:sym, :statics), s(:hash, *statics))
|
220
243
|
end
|
221
244
|
|
245
|
+
# determine if this class can be emitted as a hook
|
246
|
+
hook = (es2015 and inheritance.children.first == nil)
|
247
|
+
hookinit = nil
|
248
|
+
useState = []
|
249
|
+
body.each_with_index do |statement, index|
|
250
|
+
if statement.type == :def
|
251
|
+
method = statement.children.first
|
252
|
+
if method == :initialize
|
253
|
+
children = statement.children[2..-1]
|
254
|
+
children.pop unless children.last
|
255
|
+
while children.length == 1 and children.first.type == :begin
|
256
|
+
children = children.first.children
|
257
|
+
end
|
258
|
+
hookinit = index if children.any? {|child| child.type != :ivasgn}
|
259
|
+
elsif method == :render
|
260
|
+
nil
|
261
|
+
elsif ReactLifecycle.include? method.to_s
|
262
|
+
hook = false
|
263
|
+
elsif not statement.is_method?
|
264
|
+
hook = false
|
265
|
+
elsif method.to_s.end_with? '='
|
266
|
+
hook = false
|
267
|
+
end
|
268
|
+
elsif statement.type == :defs
|
269
|
+
hook = false
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
if hook
|
274
|
+
@reactClass = :hook
|
275
|
+
@react_props = []
|
276
|
+
@react_methods = []
|
277
|
+
|
278
|
+
if hookinit
|
279
|
+
body = body.dup
|
280
|
+
hookinit = body.delete_at(hookinit)
|
281
|
+
pairs.unshift process hookinit.children[2]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
222
285
|
# create a default getInitialState method if there is no such method
|
223
286
|
# and there are either references to instance variables or there are
|
224
287
|
# methods that need to be bound.
|
@@ -230,7 +293,13 @@ module Ruby2JS
|
|
230
293
|
then
|
231
294
|
@reactIvars = {pre: [], post: [], asgn: [], ref: [], cond: []}
|
232
295
|
react_walk(node)
|
233
|
-
|
296
|
+
|
297
|
+
if hook
|
298
|
+
react_walk(hookinit) if hookinit
|
299
|
+
useState = (@reactIvars[:asgn] + @reactIvars[:ref]).uniq
|
300
|
+
end
|
301
|
+
|
302
|
+
if createClass and not @reactIvars.values.flatten.empty?
|
234
303
|
body = [s(:def, :getInitialState, s(:args),
|
235
304
|
s(:return, s(:hash))), *body]
|
236
305
|
elsif not needs_binding.empty? or not @reactIvars.values.flatten.empty?
|
@@ -242,16 +311,21 @@ module Ruby2JS
|
|
242
311
|
body.select {|child| child.type == :def}.each do |child|
|
243
312
|
mname, args, *block = child.children
|
244
313
|
@reactMethod = mname
|
245
|
-
|
314
|
+
|
315
|
+
if @reactClass == :hook
|
316
|
+
@reactProps = s(:lvar, :"prop$")
|
317
|
+
else
|
318
|
+
@reactProps = child.updated(:attr, [s(:self), :props])
|
319
|
+
end
|
246
320
|
|
247
321
|
# analyze ivar usage
|
248
322
|
@reactIvars = {pre: [], post: [], asgn: [], ref: [], cond: []}
|
249
323
|
react_walk(child) unless mname == :initialize
|
250
|
-
@reactIvars[:capture] =
|
251
|
-
|
324
|
+
@reactIvars[:capture] = (@reactIvars[:pre] + @reactIvars[:post]).uniq
|
325
|
+
@reactIvars[:pre] = @reactIvars[:post] = [] if @reactClass == :hook
|
252
326
|
|
253
327
|
if mname == :initialize
|
254
|
-
mname =
|
328
|
+
mname = createClass ? :getInitialState : :initialize
|
255
329
|
|
256
330
|
# extract real list of statements
|
257
331
|
if block.length == 1
|
@@ -333,7 +407,7 @@ module Ruby2JS
|
|
333
407
|
else
|
334
408
|
# wrap multi-line blocks with a React Fragment
|
335
409
|
block = [s(:return,
|
336
|
-
s(:block, s(:send, nil,
|
410
|
+
s(:block, s(:send, nil, :"_#{@react}.Fragment"), s(:args), *block))]
|
337
411
|
end
|
338
412
|
end
|
339
413
|
|
@@ -359,14 +433,14 @@ module Ruby2JS
|
|
359
433
|
type = :begin if block.first.type == :return
|
360
434
|
end
|
361
435
|
|
362
|
-
if
|
436
|
+
if createClass
|
437
|
+
pairs << s(:pair, s(:sym, mname), child.updated(:block,
|
438
|
+
[s(:send, nil, :proc), args, process(s(type, *block))]))
|
439
|
+
else
|
363
440
|
pairs << child.updated(
|
364
441
|
ReactLifecycle.include?(mname.to_s) ? :defm : :def,
|
365
442
|
[mname, args, process(s(type, *block))]
|
366
443
|
)
|
367
|
-
else
|
368
|
-
pairs << s(:pair, s(:sym, mname), child.updated(:block,
|
369
|
-
[s(:send, nil, :proc), args, process(s(type, *block))]))
|
370
444
|
end
|
371
445
|
|
372
446
|
# retain comment
|
@@ -374,38 +448,70 @@ module Ruby2JS
|
|
374
448
|
@comments[pairs.last] = @comments[child]
|
375
449
|
end
|
376
450
|
end
|
451
|
+
|
452
|
+
if createClass
|
453
|
+
# emit a createClass statement
|
454
|
+
node.updated(:casgn, [nil, cname.children.last,
|
455
|
+
s(:send, s(:const, nil, :React), :createClass, s(:hash, *pairs))])
|
456
|
+
elsif hook
|
457
|
+
initialize = pairs.find_index {|node| node.type == :def and node.children.first == :initialize}
|
458
|
+
|
459
|
+
hash = {}
|
460
|
+
if initialize
|
461
|
+
hash = pairs.delete_at(initialize)
|
462
|
+
hash = hash.children.last while %i(def begin send).include? hash&.type
|
463
|
+
hash = s(:hash) unless hash&.type == :hash
|
464
|
+
hash = hash.children.map {|pair|
|
465
|
+
[pair.children.first.children.first, pair.children.last]
|
466
|
+
}.to_h
|
467
|
+
end
|
468
|
+
|
469
|
+
useState.each do |symbol|
|
470
|
+
hash[symbol.to_s[1..-1]] ||= s(:nil)
|
471
|
+
end
|
472
|
+
|
473
|
+
hash.sort.reverse.each do |var, value|
|
474
|
+
if @react == :Preact
|
475
|
+
hooker = nil
|
476
|
+
prepend_list << REACT_IMPORTS[:PreactHook] if modules_enabled?
|
477
|
+
else
|
478
|
+
hooker = s(:const, nil, :React)
|
479
|
+
end
|
480
|
+
|
481
|
+
setter = 'set' + var[0].upcase + var[1..-1]
|
482
|
+
pairs.unshift(s(:masgn, s(:mlhs, s(:lvasgn, var),
|
483
|
+
s(:lvasgn, setter)), s(:send, hooker, :useState, value)))
|
484
|
+
end
|
485
|
+
|
486
|
+
render = pairs.find_index {|node| node.type == :defm and node.children.first == :render}
|
487
|
+
if render
|
488
|
+
render = pairs.delete_at(render)
|
489
|
+
pairs.push s(:autoreturn, render.children.last)
|
490
|
+
end
|
491
|
+
|
492
|
+
has_cvar = lambda {|list|
|
493
|
+
list.any? {|node|
|
494
|
+
next unless Parser::AST::Node === node
|
495
|
+
return true if node.type == :cvar
|
496
|
+
has_cvar.call(node.children)
|
497
|
+
}
|
498
|
+
}
|
499
|
+
args = has_cvar[node.children] ? s(:args, s(:arg, 'prop$')) : s(:args)
|
500
|
+
|
501
|
+
node.updated(:def, [cname.children.last, args, s(:begin, *pairs)])
|
502
|
+
else
|
503
|
+
# emit a class that extends React.Component
|
504
|
+
node.updated(:class, [s(:const, nil, cname.children.last),
|
505
|
+
s(:attr, s(:const, nil, @react), :Component), *pairs])
|
506
|
+
end
|
377
507
|
ensure
|
378
508
|
@react = react
|
379
509
|
@reactClass = reactClass
|
380
510
|
@reactMethod = nil
|
381
511
|
end
|
382
|
-
|
383
|
-
if es2015
|
384
|
-
# emit a class that extends React.Component
|
385
|
-
node.updated(:class, [s(:const, nil, cname.children.last),
|
386
|
-
s(:attr, s(:const, nil, :React), :Component), *pairs])
|
387
|
-
else
|
388
|
-
# emit a createClass statement
|
389
|
-
node.updated(:casgn, [nil, cname.children.last,
|
390
|
-
s(:send, s(:const, nil, :React), :createClass, s(:hash, *pairs))])
|
391
|
-
end
|
392
512
|
end
|
393
513
|
|
394
514
|
def on_send(node)
|
395
|
-
# convert Vue.utile.defineReactive to class fields or assignments
|
396
|
-
if node.children.first == s(:send, s(:const, nil, :Vue), :util)
|
397
|
-
if node.children[1] == :defineReactive
|
398
|
-
if node.children[2].type == :cvar
|
399
|
-
return process s(:cvasgn, node.children[2].children.first,
|
400
|
-
node.children[3])
|
401
|
-
elsif node.children[2].type == :send
|
402
|
-
assign = node.children[2]
|
403
|
-
return assign.updated(nil, [assign.children[0],
|
404
|
-
assign.children[1].to_s + '=', node.children[3]])
|
405
|
-
end
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
515
|
# calls to methods (including getters) defined in this class
|
410
516
|
if node.children[0]==nil and Symbol === node.children[1]
|
411
517
|
if node.is_method?
|
@@ -423,16 +529,12 @@ module Ruby2JS
|
|
423
529
|
end
|
424
530
|
end
|
425
531
|
|
426
|
-
if node.children.first == s(:const, nil, :Vue)
|
427
|
-
node = node.updated(nil, [s(:const, nil, :React),
|
428
|
-
*node.children[1..-1]])
|
429
|
-
end
|
430
|
-
|
431
532
|
if not @react
|
432
533
|
# enable React filtering within React class method calls or
|
433
534
|
# React component calls
|
434
535
|
if \
|
435
536
|
node.children.first == s(:const, nil, :React) or
|
537
|
+
node.children.first == s(:const, nil, :Preact) or
|
436
538
|
node.children.first == s(:const, nil, :ReactDOM)
|
437
539
|
then
|
438
540
|
if modules_enabled?
|
@@ -440,7 +542,8 @@ module Ruby2JS
|
|
440
542
|
end
|
441
543
|
|
442
544
|
begin
|
443
|
-
react
|
545
|
+
react = @react
|
546
|
+
@react = (node.children.first.children.last == :Preact ? :Preact : :React)
|
444
547
|
return on_send(node)
|
445
548
|
ensure
|
446
549
|
@react = react
|
@@ -461,13 +564,26 @@ module Ruby2JS
|
|
461
564
|
end
|
462
565
|
|
463
566
|
elsif \
|
464
|
-
@reactApply and node.children[1] == :createElement and
|
465
|
-
node.children[0] == s(:const, nil, :React)
|
567
|
+
(@reactApply and node.children[1] == :createElement and
|
568
|
+
node.children[0] == s(:const, nil, :React)) or
|
569
|
+
(@reactApply and node.children[1] == :h and
|
570
|
+
node.children[0] == s(:const, nil, :Preact))
|
466
571
|
then
|
467
572
|
# push results of explicit calls to React.createElement
|
468
573
|
s(:send, s(:gvar, :$_), :push, s(:send, *node.children[0..1],
|
469
574
|
*process_all(node.children[2..-1])))
|
470
575
|
|
576
|
+
elsif \
|
577
|
+
@react == :Preact and node.children[1] == :h and node.children[0] == nil
|
578
|
+
then
|
579
|
+
if @reactApply
|
580
|
+
# push results of explicit calls to Preact.h
|
581
|
+
s(:send, s(:gvar, :$_), :push, s(:send, s(:const, nil, :Preact), :h,
|
582
|
+
*process_all(node.children[2..-1])))
|
583
|
+
else
|
584
|
+
node.updated(nil, [s(:const, nil, :Preact), :h, *process_all(node.children[2..-1])])
|
585
|
+
end
|
586
|
+
|
471
587
|
elsif !@jsx and node.children[0] == nil and node.children[1] =~ /^_\w/
|
472
588
|
# map method calls starting with an underscore to React calls
|
473
589
|
# to create an element.
|
@@ -549,7 +665,12 @@ module Ruby2JS
|
|
549
665
|
else
|
550
666
|
value = s(:str, values.join(' '))
|
551
667
|
end
|
552
|
-
|
668
|
+
|
669
|
+
if @react == :Preact
|
670
|
+
pairs.unshift s(:pair, s(:sym, :class), value)
|
671
|
+
else
|
672
|
+
pairs.unshift s(:pair, s(:sym, :className), value)
|
673
|
+
end
|
553
674
|
end
|
554
675
|
|
555
676
|
# support controlled form components
|
@@ -559,13 +680,28 @@ module Ruby2JS
|
|
559
680
|
['value', :value].include? pair.children.first.children.first
|
560
681
|
end
|
561
682
|
|
562
|
-
|
683
|
+
event = (@react == :Preact ? :onInput : :onChange)
|
684
|
+
|
685
|
+
|
686
|
+
# search for the presence of a onInput/onChange attribute
|
563
687
|
onChange = pairs.find_index do |pair|
|
564
|
-
|
688
|
+
pair.children.first.children[0].to_s == event.to_s
|
689
|
+
end
|
690
|
+
|
691
|
+
if event == :onInput and not onChange
|
692
|
+
# search for the presence of a 'onChange' attribute
|
693
|
+
onChange = pairs.find_index do |pair|
|
694
|
+
pair.children.first.children[0].to_s == 'onChange'
|
695
|
+
end
|
696
|
+
|
697
|
+
if onChange
|
698
|
+
pairs[onChange] = s(:pair, s(:sym, event),
|
699
|
+
pairs[onChange].children.last)
|
700
|
+
end
|
565
701
|
end
|
566
702
|
|
567
703
|
if value and pairs[value].children.last.type == :ivar and !onChange
|
568
|
-
pairs << s(:pair, s(:sym,
|
704
|
+
pairs << s(:pair, s(:sym, event),
|
569
705
|
s(:block, s(:send, nil, :proc), s(:args, s(:arg, :event)),
|
570
706
|
s(:ivasgn, pairs[value].children.last.children.first,
|
571
707
|
s(:attr, s(:attr, s(:lvar, :event), :target), :value))))
|
@@ -578,7 +714,7 @@ module Ruby2JS
|
|
578
714
|
end
|
579
715
|
|
580
716
|
if checked and pairs[checked].children.last.type == :ivar
|
581
|
-
pairs << s(:pair, s(:sym,
|
717
|
+
pairs << s(:pair, s(:sym, event),
|
582
718
|
s(:block, s(:send, nil, :proc), s(:args),
|
583
719
|
s(:ivasgn, pairs[checked].children.last.children.first,
|
584
720
|
s(:send, pairs[checked].children.last, :!))))
|
@@ -586,13 +722,25 @@ module Ruby2JS
|
|
586
722
|
end
|
587
723
|
end
|
588
724
|
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
[
|
725
|
+
if @react == :Preact
|
726
|
+
# replace selected Reactisms with native HTML
|
727
|
+
pairs.each_with_index do |pair, index|
|
728
|
+
next if pair.type == :kwsplat
|
729
|
+
name = pair.children.first.children.first.to_sym
|
730
|
+
if PreactAttrMap[name]
|
731
|
+
pairs[index] = pairs[index].updated(nil,
|
732
|
+
[s(:str, PreactAttrMap[name]), pairs[index].children.last])
|
733
|
+
end
|
734
|
+
end
|
735
|
+
else
|
736
|
+
# replace attribute names with case-sensitive javascript properties
|
737
|
+
pairs.each_with_index do |pair, index|
|
738
|
+
next if pair.type == :kwsplat
|
739
|
+
name = pair.children.first.children.first.downcase
|
740
|
+
if ReactAttrMap[name] and name.to_s != ReactAttrMap[name]
|
741
|
+
pairs[index] = pairs[index].updated(nil,
|
742
|
+
[s(:str, ReactAttrMap[name]), pairs[index].children.last])
|
743
|
+
end
|
596
744
|
end
|
597
745
|
end
|
598
746
|
|
@@ -654,8 +802,14 @@ module Ruby2JS
|
|
654
802
|
# explicit call to React.createElement
|
655
803
|
next true if arg.children[1] == :createElement and
|
656
804
|
arg.children[0] == s(:const, nil, :React)
|
657
|
-
|
658
|
-
|
805
|
+
|
806
|
+
# explicit call to Preact.h
|
807
|
+
next true if arg.children[1] == :h and
|
808
|
+
arg.children[0] == s(:const, nil, :Preact)
|
809
|
+
|
810
|
+
# explicit call to h
|
811
|
+
next true if arg.children[1] == :h and
|
812
|
+
arg.children[0] == nil
|
659
813
|
|
660
814
|
# JSX
|
661
815
|
next true if arg.type == :xstr
|
@@ -717,8 +871,13 @@ module Ruby2JS
|
|
717
871
|
params.pop if params.last == s(:nil)
|
718
872
|
|
719
873
|
# construct element using params
|
720
|
-
|
721
|
-
:
|
874
|
+
if @react == :Preact
|
875
|
+
element = node.updated(:send, [s(:const, nil, :Preact),
|
876
|
+
:h, *params])
|
877
|
+
else
|
878
|
+
element = node.updated(:send, [s(:const, nil, :React),
|
879
|
+
:createElement, *params])
|
880
|
+
end
|
722
881
|
|
723
882
|
if @reactApply
|
724
883
|
# if apply is set, emit code that pushes result
|
@@ -846,8 +1005,13 @@ module Ruby2JS
|
|
846
1005
|
while node != child
|
847
1006
|
if node.children[1] !~ /!$/
|
848
1007
|
# convert method name to hash {className: name} pair
|
849
|
-
|
850
|
-
s(:
|
1008
|
+
if @react == :Preact
|
1009
|
+
pair = s(:pair, s(:sym, :class),
|
1010
|
+
s(:str, node.children[1].to_s.gsub('_','-')))
|
1011
|
+
else
|
1012
|
+
pair = s(:pair, s(:sym, :className),
|
1013
|
+
s(:str, node.children[1].to_s.gsub('_','-')))
|
1014
|
+
end
|
851
1015
|
else
|
852
1016
|
# convert method name to hash {id: name} pair
|
853
1017
|
pair = s(:pair, s(:sym, :id),
|
@@ -917,8 +1081,11 @@ module Ruby2JS
|
|
917
1081
|
# Base Ruby2JS processing will convert the 'splat' to 'apply'
|
918
1082
|
child = node.children.first
|
919
1083
|
if \
|
920
|
-
child.children[1] == :createElement and
|
921
|
-
child.children[0] == s(:const, nil, :React)
|
1084
|
+
(child.children[1] == :createElement and
|
1085
|
+
child.children[0] == s(:const, nil, :React)) or
|
1086
|
+
(child.children[1] == :h and
|
1087
|
+
(child.children[0] == s(:const, nil, :Preact) or
|
1088
|
+
child.children[0] == nil))
|
922
1089
|
then
|
923
1090
|
begin
|
924
1091
|
reactApply, @reactApply = @reactApply, true
|
@@ -931,11 +1098,13 @@ module Ruby2JS
|
|
931
1098
|
@reactApply = reactApply
|
932
1099
|
end
|
933
1100
|
|
1101
|
+
target = child.children[0] || s(:const, nil, :Preact)
|
1102
|
+
|
934
1103
|
if reactApply
|
935
1104
|
return child.updated(:send, [s(:gvar, :$_), :push,
|
936
|
-
s(:send,
|
1105
|
+
s(:send, target, child.children[1], *params)])
|
937
1106
|
else
|
938
|
-
return child.updated(:send, [
|
1107
|
+
return child.updated(:send, [target, child.children[1], *params])
|
939
1108
|
end
|
940
1109
|
end
|
941
1110
|
|
@@ -952,7 +1121,7 @@ module Ruby2JS
|
|
952
1121
|
block = s(:block, s(:send, nil, :proc), s(:args),
|
953
1122
|
*node.children[2..-1])
|
954
1123
|
return on_send node.children.first.updated(:send,
|
955
|
-
[nil,
|
1124
|
+
[nil, :"_#{@react}.Fragment", block])
|
956
1125
|
|
957
1126
|
elsif !@jsx and child.children[0] == nil and child.children[1] =~ /^_\w/
|
958
1127
|
if node.children[1].children.empty?
|
@@ -998,13 +1167,17 @@ module Ruby2JS
|
|
998
1167
|
# convert global variables to refs
|
999
1168
|
def on_gvar(node)
|
1000
1169
|
return super unless @reactClass
|
1170
|
+
return super if @reactClass == :hook
|
1001
1171
|
s(:attr, s(:attr, s(:self), :refs), node.children.first.to_s[1..-1])
|
1002
1172
|
end
|
1003
1173
|
|
1004
1174
|
# convert instance variables to state
|
1005
1175
|
def on_ivar(node)
|
1006
1176
|
return super unless @reactClass
|
1007
|
-
|
1177
|
+
|
1178
|
+
if @reactClass == :hook
|
1179
|
+
node.updated(:lvar, [node.children.first.to_s[1..-1]])
|
1180
|
+
elsif @reactMethod and @reactIvars[:capture].include? node.children.first
|
1008
1181
|
node.updated(:lvar, ["$#{node.children.first[1..-1]}"])
|
1009
1182
|
else
|
1010
1183
|
node.updated(:attr, [s(:attr, s(:self), :state),
|
@@ -1016,11 +1189,17 @@ module Ruby2JS
|
|
1016
1189
|
def on_ivasgn(node)
|
1017
1190
|
return super unless @react
|
1018
1191
|
|
1192
|
+
if @reactClass == :hook
|
1193
|
+
var = node.children.first.to_s[1..-1]
|
1194
|
+
return node.updated(:send, [nil, 'set' + var[0].upcase + var[1..-1],
|
1195
|
+
process(node.children.last)])
|
1196
|
+
end
|
1197
|
+
|
1019
1198
|
if @reactMethod and @reactIvars[:capture].include? node.children.first
|
1020
1199
|
ivar = node.children.first.to_s
|
1021
1200
|
if @reactBlock
|
1022
1201
|
return s(:send, s(:self), :setState, s(:hash, s(:pair,
|
1023
|
-
s(:
|
1202
|
+
s(:str, ivar[1..-1]), process(s(:lvasgn, "$#{ivar[1..-1]}",
|
1024
1203
|
*node.children[1..-1])))))
|
1025
1204
|
else
|
1026
1205
|
return s(:lvasgn, "$#{ivar[1..-1]}",
|
@@ -1072,10 +1251,14 @@ module Ruby2JS
|
|
1072
1251
|
return super unless @react
|
1073
1252
|
return super unless node.children.first.type == :ivasgn
|
1074
1253
|
var = node.children.first.children.first
|
1075
|
-
if @
|
1254
|
+
if @reactClass == :hook
|
1255
|
+
var = node.children.first.children.first.to_s[1..-1]
|
1256
|
+
node.updated(:send, [nil, 'set' + var[0].upcase + var[1..-1],
|
1257
|
+
s(:send, s(:lvar, var), *node.children[1..-1])])
|
1258
|
+
elsif @reactMethod and @reactIvars[:capture].include? var
|
1076
1259
|
if @reactBlock
|
1077
1260
|
s(:send, s(:self), :setState, s(:hash, s(:pair,
|
1078
|
-
s(:
|
1261
|
+
s(:str, var[1..-1]), process(s(node.type,
|
1079
1262
|
s(:lvasgn, "$#{var[1..-1]}"), *node.children[1..-1])))))
|
1080
1263
|
else
|
1081
1264
|
process s(node.type, s(:lvasgn, "$#{var[1..-1]}"),
|
@@ -1118,9 +1301,13 @@ module Ruby2JS
|
|
1118
1301
|
return true if node.children[1] == :createElement and
|
1119
1302
|
node.children[0] == s(:const, nil, :React)
|
1120
1303
|
|
1121
|
-
# explicit call to
|
1122
|
-
return true if node.children[1] == :
|
1123
|
-
node.children[0] == s(:const, nil, :
|
1304
|
+
# explicit call to Preact.h
|
1305
|
+
return true if node.children[1] == :h and
|
1306
|
+
node.children[0] == s(:const, nil, :Preact)
|
1307
|
+
|
1308
|
+
# explicit call to h
|
1309
|
+
return true if node.children[1] == :h and
|
1310
|
+
node.children[0] == nil
|
1124
1311
|
end
|
1125
1312
|
|
1126
1313
|
# wunderbar style call
|
@@ -1256,6 +1443,7 @@ module Ruby2JS
|
|
1256
1443
|
@reactIvars = {pre: [], post: [], asgn: [], ref: [], cond: []}
|
1257
1444
|
react_walk(node.children.last)
|
1258
1445
|
@reactIvars[:capture] = (@reactIvars[:pre] + @reactIvars[:post]).uniq
|
1446
|
+
@reactIvars[:pre] = @reactIvars[:post] = [] if @reactClass == :hook
|
1259
1447
|
node = super
|
1260
1448
|
block = react_process_ivars([node.children.last.dup])
|
1261
1449
|
node.updated(nil, [*node.children[0..-2], s(:begin, *block)])
|
@@ -1280,7 +1468,7 @@ module Ruby2JS
|
|
1280
1468
|
# update ivars that are set and later referenced
|
1281
1469
|
unless @reactIvars[:post].empty?
|
1282
1470
|
updates = @reactIvars[:post].uniq.sort.reverse.map do |ivar|
|
1283
|
-
s(:pair, s(:
|
1471
|
+
s(:pair, s(:str, ivar.to_s[1..-1]),
|
1284
1472
|
s(:lvar, "$#{ivar.to_s[1..-1]}"))
|
1285
1473
|
end
|
1286
1474
|
update = s(:send, s(:self), :setState, s(:hash, *updates))
|