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 +4 -4
- data/lib/ruby2js/converter/class.rb +6 -4
- data/lib/ruby2js/converter/class2.rb +1 -1
- data/lib/ruby2js/filter/functions.rb +11 -6
- data/lib/ruby2js/filter/react.rb +153 -79
- data/lib/ruby2js/version.rb +2 -2
- data/lib/tasks/install/config/webpack/loaders/ruby2js.js +20 -0
- data/lib/tasks/install/preact.rb +3 -0
- data/lib/tasks/install/webpacker.rb +14 -31
- data/lib/tasks/ruby2js_tasks.rake +5 -0
- metadata +4 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 46b6cba0b33ebf62cb966def9b680eda35f5e84ff0c3adaea058fc2aae242269
         | 
| 4 | 
            +
              data.tar.gz: 6c5843992eccd24e8460b16f805eab16701d70d85e8ef4dcaffee948243666c0
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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 | 
            -
                       | 
| 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 | 
            -
                     | 
| 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 | 
            -
             | 
| 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  | 
| 771 | 
            -
                          s(:begin,  | 
| 772 | 
            -
                           | 
| 773 | 
            -
                           | 
| 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 |  | 
    
        data/lib/ruby2js/filter/react.rb
    CHANGED
    
    | @@ -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 | 
            -
             | 
| 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 | 
            -
             | 
| 122 | 
            -
             | 
| 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 | 
            -
             | 
| 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,  | 
| 164 | 
            +
                      react, @react = @react, react
         | 
| 145 165 | 
             
                      reactClass, @reactClass = @reactClass, true
         | 
| 146 166 |  | 
| 147 167 | 
             
                      pairs = []
         | 
| 148 168 |  | 
| 149 | 
            -
                       | 
| 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  | 
| 160 | 
            -
                           | 
| 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]  | 
| 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  | 
| 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 =  | 
| 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,  | 
| 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  | 
| 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 | 
| 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 | 
            -
             | 
| 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 | 
            -
                         | 
| 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 | 
            -
                           | 
| 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,  | 
| 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,  | 
| 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 | 
            -
                       | 
| 590 | 
            -
             | 
| 591 | 
            -
                         | 
| 592 | 
            -
             | 
| 593 | 
            -
             | 
| 594 | 
            -
                           | 
| 595 | 
            -
                            [ | 
| 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 | 
            -
             | 
| 658 | 
            -
             | 
| 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 | 
            -
                       | 
| 721 | 
            -
                        : | 
| 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 | 
            -
                             | 
| 850 | 
            -
                              s(: | 
| 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,  | 
| 1006 | 
            +
                          s(:send, target, child.children[1], *params)])
         | 
| 937 1007 | 
             
                      else
         | 
| 938 | 
            -
                        return child.updated(:send, [ | 
| 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,  | 
| 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(: | 
| 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(: | 
| 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  | 
| 1122 | 
            -
                      return true if node.children[1] == : | 
| 1123 | 
            -
                        node.children[0] == s(:const, nil, : | 
| 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(: | 
| 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))
         | 
    
        data/lib/ruby2js/version.rb
    CHANGED
    
    
| @@ -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 | 
            +
            }
         | 
| @@ -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 | 
            -
             | 
| 32 | 
            -
               | 
| 33 | 
            -
               | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 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 | 
            -
             | 
| 43 | 
            -
             | 
| 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 | 
| 58 | 
            -
             | 
| 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 | 
            -
             | 
| 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 | 
| 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- | 
| 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
         |