ruby2js 4.0.5 → 4.1.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
2
  SHA256:
3
- metadata.gz: 6728e4201e77b477a9203551b57de3f23b36077f6012061233d4b072d92886b9
4
- data.tar.gz: 7d5e6ef7aa5b9add1477b3cc642cc55714a657f7f962dbb6dd7af6688d45cfb0
3
+ metadata.gz: 46b6cba0b33ebf62cb966def9b680eda35f5e84ff0c3adaea058fc2aae242269
4
+ data.tar.gz: 6c5843992eccd24e8460b16f805eab16701d70d85e8ef4dcaffee948243666c0
5
5
  SHA512:
6
- metadata.gz: 321dc88308946ff626914ceb87fa93f93bec4f5cde0b660cab75d7df46b52f9ca63da830e7fab4f070b989586ef468b3cdf9d8f682f64b44ee06fef9df5230f7
7
- data.tar.gz: 22f5161f0bc03c294fbfd3f32be407030fea293985e1eff4c7d0fc464bd57aaa6a3cfc70e1bf9ed13e9bbb0dbbac9f394b860e76df52ae236b494accd86c840b
6
+ metadata.gz: 6910f39474f2c22c321b91ad742ab10f7fff08bc5408e53f9b4d0cdee4f4fead414519a1b31bf7e6f781dc31da71fbda55bc747132c0d78e8eeb62a8693ca419
7
+ data.tar.gz: 07b1ddbff32682c2ea3fa65570e40f97907eea4765d00ea4b7921bca5156f83f8f855178ab13ed3fc70b9edb8035fc801cdb4031c6f8176e044699099ac7dccd
@@ -36,7 +36,8 @@ module Ruby2JS
36
36
  end
37
37
 
38
38
  if inheritance
39
- init = s(:def, :initialize, s(:args), s(:super))
39
+ parent = @namespace.find(inheritance)&.[](:constructor)
40
+ init = s(:def, :initialize, parent || s(:args), s(:zsuper))
40
41
  else
41
42
  init = s(:def, :initialize, s(:args), nil)
42
43
  end
@@ -58,7 +59,7 @@ module Ruby2JS
58
59
  m = m.updated(:def, m.children[1..-1])
59
60
  end
60
61
 
61
- node = if m.type == :def
62
+ node = if m.type == :def or m.type == :defm
62
63
  if m.children.first == :initialize and !visible[:initialize]
63
64
  # constructor: remove from body and overwrite init function
64
65
  init = m
@@ -313,7 +314,7 @@ module Ruby2JS
313
314
  # prepend constructor
314
315
  if init
315
316
  constructor = init.updated(:constructor, [name, *init.children[1..-1]])
316
- @comments[constructor] = @comments[init] unless @comments[init].empty?
317
+ visible[:constructor] = init.children[1]
317
318
 
318
319
  if @ast.type == :class_extend or extend
319
320
  if es2015
@@ -329,6 +330,7 @@ module Ruby2JS
329
330
  end
330
331
  end
331
332
 
333
+ @comments[constructor] = @comments[init] unless @comments[init].empty?
332
334
  body.unshift constructor
333
335
  end
334
336
 
@@ -349,7 +351,7 @@ module Ruby2JS
349
351
  self.ivars = ivars
350
352
  @class_name = class_name
351
353
  @class_parent = class_parent
352
- @rbstack.pop
354
+ @namespace.defineProps @rbstack.pop
353
355
  @namespace.leave unless @ast.type == :class_module
354
356
  end
355
357
  end
@@ -99,7 +99,6 @@ module Ruby2JS
99
99
  end
100
100
  walk[@ast]
101
101
 
102
- # process leading initializers in constructor
103
102
  while constructor.length == 1 and constructor.first.type == :begin
104
103
  constructor = constructor.first.children.dup
105
104
  end
@@ -116,6 +115,7 @@ module Ruby2JS
116
115
  put 'static #$' + cvar.to_s[2..-1]
117
116
  end
118
117
 
118
+ # process leading initializers in constructor
119
119
  while constructor.length > 0 and constructor.first.type == :ivasgn
120
120
  put(index == 0 ? @nl : @sep)
121
121
  index += 1
@@ -227,14 +227,19 @@ module Ruby2JS
227
227
  if before.type == :regexp
228
228
  before = before.updated(:regexp, [*before.children[0...-1],
229
229
  s(:regopt, :g, *before.children.last)])
230
- elsif before.type == :str
230
+ elsif before.type == :str and not es2021
231
231
  before = before.updated(:regexp,
232
232
  [s(:str, Regexp.escape(before.children.first)), s(:regopt, :g)])
233
233
  end
234
234
  if after.type == :str
235
235
  after = s(:str, after.children.first.gsub(/\\(\d)/, "$\\1"))
236
236
  end
237
- process node.updated nil, [target, :replace, before, after]
237
+
238
+ if es2021
239
+ process node.updated nil, [target, :replaceAll, before, after]
240
+ else
241
+ process node.updated nil, [target, :replace, before, after]
242
+ end
238
243
 
239
244
  elsif method == :ord and args.length == 0
240
245
  if target.type == :str
@@ -767,10 +772,10 @@ module Ruby2JS
767
772
  body.any? {|statement| statement.type == :def and
768
773
  statement.children.first == :initialize}
769
774
  then
770
- body.unshift S(:def, :initialize, s(:args, s(:arg, :message)),
771
- s(:begin, S(:send, s(:self), :message=, s(:lvar, :message)),
772
- S(:send, s(:self), :name=, s(:sym, name.children[1])),
773
- S(:send, s(:self), :stack=, s(:send, s(:send, nil, :Error,
775
+ body.unshift s(:def, :initialize, s(:args, s(:arg, :message)),
776
+ s(:begin, s(:send, s(:self), :message=, s(:lvar, :message)),
777
+ s(:send, s(:self), :name=, s(:sym, name.children[1])),
778
+ s(:send, s(:self), :stack=, s(:attr, s(:send, nil, :Error,
774
779
  s(:lvar, :message)), :stack))))
775
780
  end
776
781
 
@@ -27,7 +27,11 @@ module Ruby2JS
27
27
 
28
28
  REACT_IMPORTS = {
29
29
  React: s(:import, ['react'], s(:attr, nil, :React)),
30
- ReactDOM: s(:import, ['react-dom'], s(:attr, nil, :ReactDOM))
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, '*'))
31
35
  }
32
36
 
33
37
  # the following command can be used to generate ReactAttrs:
@@ -75,7 +79,12 @@ module Ruby2JS
75
79
 
76
80
  ReactAttrMap = Hash[ReactAttrs.map {|name| [name.downcase, name]}]
77
81
  ReactAttrMap['for'] = 'htmlFor'
78
- ReactFragment = :'_React.Fragment'
82
+
83
+ PreactAttrMap = {
84
+ htmlFor: 'for',
85
+ onDoubleClick: 'onDblClick',
86
+ tabIndex: 'tabindex'
87
+ }
79
88
 
80
89
  def initialize(*args)
81
90
  @react = nil
@@ -118,12 +127,23 @@ module Ruby2JS
118
127
  def on_class(node)
119
128
  cname, inheritance, *body = node.children
120
129
  return super unless cname.children.first == nil
121
- return super unless inheritance == s(:const, nil, :React) or
122
- inheritance == s(:const, nil, :Vue) or
130
+
131
+ if inheritance == s(:const, nil, :React) or
123
132
  inheritance == s(:const, s(:const, nil, :React), :Component) or
124
133
  inheritance == s(:send, s(:const, nil, :React), :Component)
125
134
 
126
- prepend_list << REACT_IMPORTS[:React] if modules_enabled?
135
+ react = :React
136
+ prepend_list << REACT_IMPORTS[:React] if modules_enabled?
137
+
138
+ elsif inheritance == s(:const, nil, :Preact) or
139
+ inheritance == s(:const, s(:const, nil, :Preact), :Component) or
140
+ inheritance == s(:send, s(:const, nil, :Preact), :Component)
141
+
142
+ react = :Preact
143
+ prepend_list << REACT_IMPORTS[:Preact] if modules_enabled?
144
+ else
145
+ return super
146
+ end
127
147
 
128
148
  # traverse down to actual list of class statements
129
149
  if body.length == 1
@@ -141,12 +161,14 @@ module Ruby2JS
141
161
  end
142
162
 
143
163
  begin
144
- react, @react = @react, true
164
+ react, @react = @react, react
145
165
  reactClass, @reactClass = @reactClass, true
146
166
 
147
167
  pairs = []
148
168
 
149
- unless es2015
169
+ createClass = (@react == :React and not es2015)
170
+
171
+ if createClass
150
172
  # automatically capture the displayName for the class
151
173
  pairs << s(:pair, s(:sym, :displayName),
152
174
  s(:str, cname.children.last.to_s))
@@ -156,9 +178,8 @@ module Ruby2JS
156
178
  statics = []
157
179
  body.select {|child| child.type == :defs}.each do |child|
158
180
  _parent, mname, args, *block = child.children
159
- if es2015
160
- block = [s(:autoreturn, *block)] unless child.is_method?
161
- pairs << s(:defs, s(:self), mname, args, *block)
181
+ if not createClass
182
+ pairs << child
162
183
  elsif child.is_method?
163
184
  statics << s(:pair, s(:sym, mname), process(child.updated(:block,
164
185
  [s(:send, nil, :proc), args, s(:autoreturn, *block)])))
@@ -212,7 +233,7 @@ module Ruby2JS
212
233
  scan_events[node.children]
213
234
  end
214
235
  end
215
- scan_events[body] unless es2015
236
+ scan_events[body] if createClass
216
237
 
217
238
  # append statics (if any)
218
239
  unless statics.empty?
@@ -230,7 +251,7 @@ module Ruby2JS
230
251
  then
231
252
  @reactIvars = {pre: [], post: [], asgn: [], ref: [], cond: []}
232
253
  react_walk(node)
233
- if not es2015 and not @reactIvars.values.flatten.empty?
254
+ if createClass and not @reactIvars.values.flatten.empty?
234
255
  body = [s(:def, :getInitialState, s(:args),
235
256
  s(:return, s(:hash))), *body]
236
257
  elsif not needs_binding.empty? or not @reactIvars.values.flatten.empty?
@@ -251,7 +272,7 @@ module Ruby2JS
251
272
  (@reactIvars[:pre] + @reactIvars[:post]).uniq
252
273
 
253
274
  if mname == :initialize
254
- mname = es2015 ? :initialize : :getInitialState
275
+ mname = createClass ? :getInitialState : :initialize
255
276
 
256
277
  # extract real list of statements
257
278
  if block.length == 1
@@ -333,7 +354,7 @@ module Ruby2JS
333
354
  else
334
355
  # wrap multi-line blocks with a React Fragment
335
356
  block = [s(:return,
336
- s(:block, s(:send, nil, ReactFragment), s(:args), *block))]
357
+ s(:block, s(:send, nil, :"_#{@react}.Fragment"), s(:args), *block))]
337
358
  end
338
359
  end
339
360
 
@@ -359,14 +380,14 @@ module Ruby2JS
359
380
  type = :begin if block.first.type == :return
360
381
  end
361
382
 
362
- if es2015
383
+ if createClass
384
+ pairs << s(:pair, s(:sym, mname), child.updated(:block,
385
+ [s(:send, nil, :proc), args, process(s(type, *block))]))
386
+ else
363
387
  pairs << child.updated(
364
388
  ReactLifecycle.include?(mname.to_s) ? :defm : :def,
365
389
  [mname, args, process(s(type, *block))]
366
390
  )
367
- else
368
- pairs << s(:pair, s(:sym, mname), child.updated(:block,
369
- [s(:send, nil, :proc), args, process(s(type, *block))]))
370
391
  end
371
392
 
372
393
  # retain comment
@@ -374,38 +395,24 @@ module Ruby2JS
374
395
  @comments[pairs.last] = @comments[child]
375
396
  end
376
397
  end
398
+
399
+ if createClass
400
+ # emit a createClass statement
401
+ node.updated(:casgn, [nil, cname.children.last,
402
+ s(:send, s(:const, nil, :React), :createClass, s(:hash, *pairs))])
403
+ else
404
+ # emit a class that extends React.Component
405
+ node.updated(:class, [s(:const, nil, cname.children.last),
406
+ s(:attr, s(:const, nil, @react), :Component), *pairs])
407
+ end
377
408
  ensure
378
409
  @react = react
379
410
  @reactClass = reactClass
380
411
  @reactMethod = nil
381
412
  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
413
  end
393
414
 
394
415
  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
416
  # calls to methods (including getters) defined in this class
410
417
  if node.children[0]==nil and Symbol === node.children[1]
411
418
  if node.is_method?
@@ -423,16 +430,12 @@ module Ruby2JS
423
430
  end
424
431
  end
425
432
 
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
433
  if not @react
432
434
  # enable React filtering within React class method calls or
433
435
  # React component calls
434
436
  if \
435
437
  node.children.first == s(:const, nil, :React) or
438
+ node.children.first == s(:const, nil, :Preact) or
436
439
  node.children.first == s(:const, nil, :ReactDOM)
437
440
  then
438
441
  if modules_enabled?
@@ -440,7 +443,8 @@ module Ruby2JS
440
443
  end
441
444
 
442
445
  begin
443
- react, @react = @react, true
446
+ react = @react
447
+ @react = (node.children.first.children.last == :Preact ? :Preact : :React)
444
448
  return on_send(node)
445
449
  ensure
446
450
  @react = react
@@ -461,13 +465,26 @@ module Ruby2JS
461
465
  end
462
466
 
463
467
  elsif \
464
- @reactApply and node.children[1] == :createElement and
465
- node.children[0] == s(:const, nil, :React)
468
+ (@reactApply and node.children[1] == :createElement and
469
+ node.children[0] == s(:const, nil, :React)) or
470
+ (@reactApply and node.children[1] == :h and
471
+ node.children[0] == s(:const, nil, :Preact))
466
472
  then
467
473
  # push results of explicit calls to React.createElement
468
474
  s(:send, s(:gvar, :$_), :push, s(:send, *node.children[0..1],
469
475
  *process_all(node.children[2..-1])))
470
476
 
477
+ elsif \
478
+ @react == :Preact and node.children[1] == :h and node.children[0] == nil
479
+ then
480
+ if @reactApply
481
+ # push results of explicit calls to Preact.h
482
+ s(:send, s(:gvar, :$_), :push, s(:send, s(:const, nil, :Preact), :h,
483
+ *process_all(node.children[2..-1])))
484
+ else
485
+ node.updated(nil, [s(:const, nil, :Preact), :h, *process_all(node.children[2..-1])])
486
+ end
487
+
471
488
  elsif !@jsx and node.children[0] == nil and node.children[1] =~ /^_\w/
472
489
  # map method calls starting with an underscore to React calls
473
490
  # to create an element.
@@ -549,7 +566,12 @@ module Ruby2JS
549
566
  else
550
567
  value = s(:str, values.join(' '))
551
568
  end
552
- pairs.unshift s(:pair, s(:sym, :className), value)
569
+
570
+ if @react == :Preact
571
+ pairs.unshift s(:pair, s(:sym, :class), value)
572
+ else
573
+ pairs.unshift s(:pair, s(:sym, :className), value)
574
+ end
553
575
  end
554
576
 
555
577
  # support controlled form components
@@ -559,13 +581,28 @@ module Ruby2JS
559
581
  ['value', :value].include? pair.children.first.children.first
560
582
  end
561
583
 
562
- # search for the presence of a 'onChange' attribute
584
+ event = (@react == :Preact ? :onInput : :onChange)
585
+
586
+
587
+ # search for the presence of a onInput/onChange attribute
563
588
  onChange = pairs.find_index do |pair|
564
- ['onChange', :onChange].include? pair.children.first.children[0]
589
+ pair.children.first.children[0].to_s == event.to_s
590
+ end
591
+
592
+ if event == :onInput and not onChange
593
+ # search for the presence of a 'onChange' attribute
594
+ onChange = pairs.find_index do |pair|
595
+ pair.children.first.children[0].to_s == 'onChange'
596
+ end
597
+
598
+ if onChange
599
+ pairs[onChange] = s(:pair, s(:sym, event),
600
+ pairs[onChange].children.last)
601
+ end
565
602
  end
566
603
 
567
604
  if value and pairs[value].children.last.type == :ivar and !onChange
568
- pairs << s(:pair, s(:sym, :onChange),
605
+ pairs << s(:pair, s(:sym, event),
569
606
  s(:block, s(:send, nil, :proc), s(:args, s(:arg, :event)),
570
607
  s(:ivasgn, pairs[value].children.last.children.first,
571
608
  s(:attr, s(:attr, s(:lvar, :event), :target), :value))))
@@ -578,7 +615,7 @@ module Ruby2JS
578
615
  end
579
616
 
580
617
  if checked and pairs[checked].children.last.type == :ivar
581
- pairs << s(:pair, s(:sym, :onChange),
618
+ pairs << s(:pair, s(:sym, event),
582
619
  s(:block, s(:send, nil, :proc), s(:args),
583
620
  s(:ivasgn, pairs[checked].children.last.children.first,
584
621
  s(:send, pairs[checked].children.last, :!))))
@@ -586,13 +623,25 @@ module Ruby2JS
586
623
  end
587
624
  end
588
625
 
589
- # replace attribute names with case-sensitive javascript properties
590
- pairs.each_with_index do |pair, index|
591
- next if pair.type == :kwsplat
592
- name = pair.children.first.children.first.downcase
593
- if ReactAttrMap[name] and name.to_s != ReactAttrMap[name]
594
- pairs[index] = pairs[index].updated(nil,
595
- [s(:str, ReactAttrMap[name]), pairs[index].children.last])
626
+ if @react == :Preact
627
+ # replace selected Reactisms with native HTML
628
+ pairs.each_with_index do |pair, index|
629
+ next if pair.type == :kwsplat
630
+ name = pair.children.first.children.first.to_sym
631
+ if PreactAttrMap[name]
632
+ pairs[index] = pairs[index].updated(nil,
633
+ [s(:str, PreactAttrMap[name]), pairs[index].children.last])
634
+ end
635
+ end
636
+ else
637
+ # replace attribute names with case-sensitive javascript properties
638
+ pairs.each_with_index do |pair, index|
639
+ next if pair.type == :kwsplat
640
+ name = pair.children.first.children.first.downcase
641
+ if ReactAttrMap[name] and name.to_s != ReactAttrMap[name]
642
+ pairs[index] = pairs[index].updated(nil,
643
+ [s(:str, ReactAttrMap[name]), pairs[index].children.last])
644
+ end
596
645
  end
597
646
  end
598
647
 
@@ -654,8 +703,14 @@ module Ruby2JS
654
703
  # explicit call to React.createElement
655
704
  next true if arg.children[1] == :createElement and
656
705
  arg.children[0] == s(:const, nil, :React)
657
- next true if arg.children[1] == :createElement and
658
- arg.children[0] == s(:const, nil, :Vue)
706
+
707
+ # explicit call to Preact.h
708
+ next true if arg.children[1] == :h and
709
+ arg.children[0] == s(:const, nil, :Preact)
710
+
711
+ # explicit call to h
712
+ next true if arg.children[1] == :h and
713
+ arg.children[0] == nil
659
714
 
660
715
  # JSX
661
716
  next true if arg.type == :xstr
@@ -717,8 +772,13 @@ module Ruby2JS
717
772
  params.pop if params.last == s(:nil)
718
773
 
719
774
  # construct element using params
720
- element = node.updated(:send, [s(:const, nil, :React),
721
- :createElement, *params])
775
+ if @react == :Preact
776
+ element = node.updated(:send, [s(:const, nil, :Preact),
777
+ :h, *params])
778
+ else
779
+ element = node.updated(:send, [s(:const, nil, :React),
780
+ :createElement, *params])
781
+ end
722
782
 
723
783
  if @reactApply
724
784
  # if apply is set, emit code that pushes result
@@ -846,8 +906,13 @@ module Ruby2JS
846
906
  while node != child
847
907
  if node.children[1] !~ /!$/
848
908
  # convert method name to hash {className: name} pair
849
- pair = s(:pair, s(:sym, :className),
850
- s(:str, node.children[1].to_s.gsub('_','-')))
909
+ if @react == :Preact
910
+ pair = s(:pair, s(:sym, :class),
911
+ s(:str, node.children[1].to_s.gsub('_','-')))
912
+ else
913
+ pair = s(:pair, s(:sym, :className),
914
+ s(:str, node.children[1].to_s.gsub('_','-')))
915
+ end
851
916
  else
852
917
  # convert method name to hash {id: name} pair
853
918
  pair = s(:pair, s(:sym, :id),
@@ -917,8 +982,11 @@ module Ruby2JS
917
982
  # Base Ruby2JS processing will convert the 'splat' to 'apply'
918
983
  child = node.children.first
919
984
  if \
920
- child.children[1] == :createElement and
921
- child.children[0] == s(:const, nil, :React)
985
+ (child.children[1] == :createElement and
986
+ child.children[0] == s(:const, nil, :React)) or
987
+ (child.children[1] == :h and
988
+ (child.children[0] == s(:const, nil, :Preact) or
989
+ child.children[0] == nil))
922
990
  then
923
991
  begin
924
992
  reactApply, @reactApply = @reactApply, true
@@ -931,11 +999,13 @@ module Ruby2JS
931
999
  @reactApply = reactApply
932
1000
  end
933
1001
 
1002
+ target = child.children[0] || s(:const, nil, :Preact)
1003
+
934
1004
  if reactApply
935
1005
  return child.updated(:send, [s(:gvar, :$_), :push,
936
- s(:send, *child.children[0..1], *params)])
1006
+ s(:send, target, child.children[1], *params)])
937
1007
  else
938
- return child.updated(:send, [*child.children[0..1], *params])
1008
+ return child.updated(:send, [target, child.children[1], *params])
939
1009
  end
940
1010
  end
941
1011
 
@@ -952,7 +1022,7 @@ module Ruby2JS
952
1022
  block = s(:block, s(:send, nil, :proc), s(:args),
953
1023
  *node.children[2..-1])
954
1024
  return on_send node.children.first.updated(:send,
955
- [nil, ReactFragment, block])
1025
+ [nil, :"_#{@react}.Fragment", block])
956
1026
 
957
1027
  elsif !@jsx and child.children[0] == nil and child.children[1] =~ /^_\w/
958
1028
  if node.children[1].children.empty?
@@ -1020,7 +1090,7 @@ module Ruby2JS
1020
1090
  ivar = node.children.first.to_s
1021
1091
  if @reactBlock
1022
1092
  return s(:send, s(:self), :setState, s(:hash, s(:pair,
1023
- s(:lvar, ivar[1..-1]), process(s(:lvasgn, "$#{ivar[1..-1]}",
1093
+ s(:str, ivar[1..-1]), process(s(:lvasgn, "$#{ivar[1..-1]}",
1024
1094
  *node.children[1..-1])))))
1025
1095
  else
1026
1096
  return s(:lvasgn, "$#{ivar[1..-1]}",
@@ -1075,7 +1145,7 @@ module Ruby2JS
1075
1145
  if @reactMethod and @reactIvars[:capture].include? var
1076
1146
  if @reactBlock
1077
1147
  s(:send, s(:self), :setState, s(:hash, s(:pair,
1078
- s(:lvar, var[1..-1]), process(s(node.type,
1148
+ s(:str, var[1..-1]), process(s(node.type,
1079
1149
  s(:lvasgn, "$#{var[1..-1]}"), *node.children[1..-1])))))
1080
1150
  else
1081
1151
  process s(node.type, s(:lvasgn, "$#{var[1..-1]}"),
@@ -1118,9 +1188,13 @@ module Ruby2JS
1118
1188
  return true if node.children[1] == :createElement and
1119
1189
  node.children[0] == s(:const, nil, :React)
1120
1190
 
1121
- # explicit call to Vue.createElement
1122
- return true if node.children[1] == :createElement and
1123
- node.children[0] == s(:const, nil, :Vue)
1191
+ # explicit call to Preact.h
1192
+ return true if node.children[1] == :h and
1193
+ node.children[0] == s(:const, nil, :Preact)
1194
+
1195
+ # explicit call to h
1196
+ return true if node.children[1] == :h and
1197
+ node.children[0] == nil
1124
1198
  end
1125
1199
 
1126
1200
  # wunderbar style call
@@ -1280,7 +1354,7 @@ module Ruby2JS
1280
1354
  # update ivars that are set and later referenced
1281
1355
  unless @reactIvars[:post].empty?
1282
1356
  updates = @reactIvars[:post].uniq.sort.reverse.map do |ivar|
1283
- s(:pair, s(:lvar, ivar.to_s[1..-1]),
1357
+ s(:pair, s(:str, ivar.to_s[1..-1]),
1284
1358
  s(:lvar, "$#{ivar.to_s[1..-1]}"))
1285
1359
  end
1286
1360
  update = s(:send, s(:self), :setState, s(:hash, *updates))
@@ -1,8 +1,8 @@
1
1
  module Ruby2JS
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 4
4
- MINOR = 0
5
- TINY = 5
4
+ MINOR = 1
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -0,0 +1,20 @@
1
+ const { environment } = require('@rails/webpacker')
2
+
3
+ module.exports = {
4
+ test: /\.js\.rb$/,
5
+ use: [
6
+ {
7
+ loader: "babel-loader",
8
+ options: environment.loaders.get('babel').use[0].options
9
+ },
10
+
11
+ {
12
+ loader: "@ruby2js/webpack-loader",
13
+ options: {
14
+ autoexports: "default",
15
+ eslevel: 2021,
16
+ filters: ["esm", "functions"]
17
+ }
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,3 @@
1
+ @ruby2js_options = {filters: ['react']}
2
+ @yarn_add='preact'
3
+ eval IO.read "#{__dir__}/webpacker.rb"
@@ -27,40 +27,25 @@ insert_into_file Rails.root.join("config/webpacker.yml").to_s,
27
27
  # install webpack loader
28
28
  run "yarn add @ruby2js/webpack-loader #{@yarn_add}"
29
29
 
30
+ target = Rails.root.join("config/webpack/loaders/ruby2js.js").to_s
31
+
30
32
  # default config
31
- config = <<~CONFIG
32
- // Insert rb2js loader at the end of list
33
- environment.loaders.append('rb2js', {
34
- test: /\.js\.rb$/,
35
- use: [
36
- {
37
- loader: "babel-loader",
38
- options: environment.loaders.get('babel').use[0].options
39
- },
33
+ if not File.exist? target
34
+ # may be called via eval, or directly. Resolve source either way.
35
+ source_paths.unshift __dir__
36
+ source_paths.unshift File.dirname(caller.first)
37
+ directory "config/webpack/loaders", File.dirname(target)
38
+ end
40
39
 
41
- {
42
- loader: "@ruby2js/webpack-loader",
43
- options: {
44
- autoexports: "default",
45
- eslevel: 2021,
46
- filters: ["esm", "functions"]
47
- }
48
- },
49
- ]
50
- })
51
- CONFIG
40
+ # load config
41
+ insert_into_file Rails.root.join("config/webpack/environment.js").to_s,
42
+ "environment.loaders.prepend('ruby2js', require('./loaders/ruby2js'))\n"
52
43
 
53
44
  # read current configuration
54
- target = Rails.root.join("config/webpack/environment.js").to_s
55
45
  before = IO.read(target)
56
46
 
57
- # extract indentation and options either from the current configuration or the
58
- # default configuration.
59
- if before.include? '@ruby2js/webpack-loader'
60
- match = /^(\s*)options: (\{.*?\n\1\})/m.match(before)
61
- else
62
- match = /^(\s*)options: (\{.*?\n\1\})/m.match(config)
63
- end
47
+ # extract indentation and options
48
+ match = /^(\s*)options: (\{.*?\n\1\})/m.match(before)
64
49
 
65
50
  # evaluate base options. Here it is handy that Ruby's syntax for hashes is
66
51
  # fairly close to JavaScript's object literals. May run into problems in the
@@ -90,8 +75,6 @@ replacement = Ruby2JS.convert(merged.inspect + "\n").to_s.
90
75
  gsub(/^/, match[1]).strip
91
76
 
92
77
  # Update configuration
93
- if before.include? '@ruby2js/webpack-loader'
78
+ unless before.include? replacement
94
79
  gsub_file target, match[2].to_s, replacement
95
- else
96
- append_to_file target, "\n" + config.sub(match[2], replacement)
97
80
  end
@@ -12,6 +12,11 @@ namespace :ruby2js do
12
12
  template 'install/litelement.rb'
13
13
  end
14
14
 
15
+ desc "Install Ruby2JS with Preact support"
16
+ task :preact do
17
+ template 'install/preact.rb'
18
+ end
19
+
15
20
  desc "Install Ruby2JS with React support"
16
21
  task :react do
17
22
  template 'install/react.rb'
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: 4.0.5
4
+ version: 4.1.0
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: 2021-03-11 00:00:00.000000000 Z
12
+ date: 2021-03-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parser
@@ -159,7 +159,9 @@ files:
159
159
  - lib/ruby2js/version.rb
160
160
  - lib/tasks/README.md
161
161
  - lib/tasks/install/app/javascript/elements/index.js
162
+ - lib/tasks/install/config/webpack/loaders/ruby2js.js
162
163
  - lib/tasks/install/litelement.rb
164
+ - lib/tasks/install/preact.rb
163
165
  - lib/tasks/install/react.rb
164
166
  - lib/tasks/install/stimulus-sprockets.rb
165
167
  - lib/tasks/install/stimulus-webpacker.rb