ruby2js 3.5.0 → 3.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -657
- data/lib/ruby2js.rb +30 -2
- data/lib/ruby2js/converter.rb +7 -5
- data/lib/ruby2js/converter/class2.rb +63 -20
- data/lib/ruby2js/converter/def.rb +1 -1
- data/lib/ruby2js/converter/import.rb +17 -1
- data/lib/ruby2js/converter/ivar.rb +10 -2
- data/lib/ruby2js/converter/literal.rb +14 -2
- data/lib/ruby2js/converter/module.rb +5 -0
- data/lib/ruby2js/converter/send.rb +4 -3
- data/lib/ruby2js/converter/xstr.rb +1 -1
- data/lib/ruby2js/filter/active_functions.rb +43 -0
- data/lib/ruby2js/filter/camelCase.rb +4 -3
- data/lib/ruby2js/filter/esm.rb +96 -4
- data/lib/ruby2js/filter/functions.rb +23 -3
- data/lib/ruby2js/filter/node.rb +95 -74
- data/lib/ruby2js/filter/nokogiri.rb +15 -41
- data/lib/ruby2js/filter/return.rb +2 -0
- data/lib/ruby2js/filter/securerandom.rb +33 -0
- data/lib/ruby2js/filter/vue.rb +9 -0
- data/lib/ruby2js/rails.rb +15 -9
- data/lib/ruby2js/serializer.rb +3 -1
- data/lib/ruby2js/version.rb +2 -2
- data/ruby2js.gemspec +1 -1
- metadata +9 -7
- data/lib/ruby2js/filter/esm_migration.rb +0 -72
@@ -7,33 +7,7 @@ module Ruby2JS
|
|
7
7
|
include SEXP
|
8
8
|
extend SEXP
|
9
9
|
|
10
|
-
|
11
|
-
jsdom: s(:casgn, nil, :JSDOM,
|
12
|
-
s(:attr, s(:send, nil, :require, s(:str, "jsdom")), :JSDOM))
|
13
|
-
}
|
14
|
-
|
15
|
-
ESM_SETUP = {
|
16
|
-
jsdom: s(:import, ["jsdom"], [s(:attr, nil, :JSDOM)])
|
17
|
-
}
|
18
|
-
|
19
|
-
def initialize(*args)
|
20
|
-
@nokogiri_setup = nil
|
21
|
-
super
|
22
|
-
end
|
23
|
-
|
24
|
-
def process(node)
|
25
|
-
return super if @nokogiri_setup
|
26
|
-
@nokogiri_setup = Set.new
|
27
|
-
result = super
|
28
|
-
|
29
|
-
if @nokogiri_setup.empty?
|
30
|
-
result
|
31
|
-
else
|
32
|
-
setup = @esm ? ESM_SETUP : CJS_SETUP;
|
33
|
-
s(:begin,
|
34
|
-
*@nokogiri_setup.to_a.map {|token| setup[token]}, result)
|
35
|
-
end
|
36
|
-
end
|
10
|
+
IMPORT_JSDOM = s(:import, ["jsdom"], [s(:attr, nil, :JSDOM)])
|
37
11
|
|
38
12
|
def on_send(node)
|
39
13
|
target, method, *args = node.children
|
@@ -55,7 +29,7 @@ module Ruby2JS
|
|
55
29
|
[:HTML, :HTML5].include? method and
|
56
30
|
target == s(:const, nil, :Nokogiri)
|
57
31
|
then
|
58
|
-
|
32
|
+
prepend_list << IMPORT_JSDOM
|
59
33
|
S(:attr, s(:attr, s(:send, s(:const, nil, :JSDOM), :new,
|
60
34
|
*process_all(args)), :window), :document)
|
61
35
|
|
@@ -65,7 +39,7 @@ module Ruby2JS
|
|
65
39
|
target.children.first == s(:const, nil, :Nokogiri) and
|
66
40
|
[:HTML, :HTML5].include? target.children.last
|
67
41
|
then
|
68
|
-
|
42
|
+
prepend_list << IMPORT_JSDOM
|
69
43
|
S(:attr, s(:attr, s(:send, s(:const, nil, :JSDOM), :new,
|
70
44
|
*process_all(args)), :window), :document)
|
71
45
|
|
@@ -73,40 +47,40 @@ module Ruby2JS
|
|
73
47
|
method == :at and
|
74
48
|
args.length == 1 and args.first.type == :str
|
75
49
|
then
|
76
|
-
S(:send, target, :querySelector, process(args.first))
|
50
|
+
S(:send, process(target), :querySelector, process(args.first))
|
77
51
|
|
78
52
|
elsif \
|
79
53
|
method == :search and
|
80
54
|
args.length == 1 and args.first.type == :str
|
81
55
|
then
|
82
|
-
S(:send, target, :querySelectorAll, process(args.first))
|
56
|
+
S(:send, process(target), :querySelectorAll, process(args.first))
|
83
57
|
|
84
58
|
elsif method === :parent and args.length == 0
|
85
|
-
S(:attr, target, :parentNode)
|
59
|
+
S(:attr, process(target), :parentNode)
|
86
60
|
|
87
61
|
elsif method === :name and args.length == 0
|
88
|
-
S(:attr, target, :nodeName)
|
62
|
+
S(:attr, process(target), :nodeName)
|
89
63
|
|
90
64
|
elsif [:text, :content].include? method and args.length == 0
|
91
|
-
S(:attr, target, :textContent)
|
65
|
+
S(:attr, process(target), :textContent)
|
92
66
|
|
93
67
|
elsif method == :content= and args.length == 1
|
94
|
-
S(:send, target, :textContent=, *process_all(args))
|
68
|
+
S(:send, process(target), :textContent=, *process_all(args))
|
95
69
|
|
96
70
|
elsif method === :inner_html and args.length == 0
|
97
|
-
S(:attr, target, :innerHTML)
|
71
|
+
S(:attr, process(target), :innerHTML)
|
98
72
|
|
99
73
|
elsif method == :inner_html= and args.length == 1
|
100
|
-
S(:send, target, :innerHTML=, *process_all(args))
|
74
|
+
S(:send, process(target), :innerHTML=, *process_all(args))
|
101
75
|
|
102
76
|
elsif method === :to_html and args.length == 0
|
103
|
-
S(:attr, target, :outerHTML)
|
77
|
+
S(:attr, process(target), :outerHTML)
|
104
78
|
|
105
79
|
elsif \
|
106
80
|
[:attr, :get_attribute].include? method and
|
107
81
|
args.length == 1 and args.first.type == :str
|
108
82
|
then
|
109
|
-
S(:send, target, :getAttribute, process(args.first))
|
83
|
+
S(:send, process(target), :getAttribute, process(args.first))
|
110
84
|
|
111
85
|
elsif \
|
112
86
|
[:key?, :has_attribute].include? method and
|
@@ -180,14 +154,14 @@ module Ruby2JS
|
|
180
154
|
[:add_next_sibling, :next=, :after].include? method and
|
181
155
|
args.length == 1
|
182
156
|
then
|
183
|
-
S(:send, s(:attr, target, :parentNode), :insertBefore,
|
157
|
+
S(:send, s(:attr, process(target), :parentNode), :insertBefore,
|
184
158
|
process(args.first), s(:attr, target, :nextSibling))
|
185
159
|
|
186
160
|
elsif \
|
187
161
|
[:add_previous_sibling, :previous=, :before].include? method and
|
188
162
|
args.length == 1
|
189
163
|
then
|
190
|
-
S(:send, s(:attr, target, :parentNode), :insertBefore,
|
164
|
+
S(:send, s(:attr, process(target), :parentNode), :insertBefore,
|
191
165
|
process(args.first), target)
|
192
166
|
|
193
167
|
elsif method == :prepend_child and args.length == 1
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'ruby2js'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
# Experimental secure random support
|
5
|
+
|
6
|
+
module Ruby2JS
|
7
|
+
module Filter
|
8
|
+
module SecureRandom
|
9
|
+
include SEXP
|
10
|
+
extend SEXP
|
11
|
+
|
12
|
+
IMPORT_BASE62_RANDOM = s(:import, ['base62-random'],
|
13
|
+
s(:attr, nil, :base62_random))
|
14
|
+
|
15
|
+
def on_send(node)
|
16
|
+
target, method, *args = node.children
|
17
|
+
|
18
|
+
if target == s(:const, nil, :SecureRandom)
|
19
|
+
if method == :alphanumeric and args.length == 1
|
20
|
+
prepend_list << IMPORT_BASE62_RANDOM
|
21
|
+
node.updated(nil, [nil, :base62_random, *args])
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
else
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
DEFAULTS.push SecureRandom
|
32
|
+
end
|
33
|
+
end
|
data/lib/ruby2js/filter/vue.rb
CHANGED
@@ -106,6 +106,7 @@ module Ruby2JS
|
|
106
106
|
computed = []
|
107
107
|
setters = []
|
108
108
|
options = []
|
109
|
+
watch = nil
|
109
110
|
el = nil
|
110
111
|
mixins = []
|
111
112
|
|
@@ -205,6 +206,9 @@ module Ruby2JS
|
|
205
206
|
end
|
206
207
|
|
207
208
|
@vue_h = args.children.first.children.last
|
209
|
+
elsif method == :watch and args.children.length == 0 and block.type == :hash
|
210
|
+
watch = process(block)
|
211
|
+
next
|
208
212
|
elsif method == :initialize
|
209
213
|
method = :data
|
210
214
|
|
@@ -332,6 +336,11 @@ module Ruby2JS
|
|
332
336
|
hash << s(:pair, s(:sym, :computed), s(:hash, *computed))
|
333
337
|
end
|
334
338
|
|
339
|
+
# append watch to hash
|
340
|
+
if watch
|
341
|
+
hash << s(:pair, s(:sym, :watch), watch)
|
342
|
+
end
|
343
|
+
|
335
344
|
# convert class name to camel case
|
336
345
|
cname = cname.children.last
|
337
346
|
camel = cname.to_s.gsub(/[^\w]/, '-').
|
data/lib/ruby2js/rails.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Example usage:
|
2
2
|
#
|
3
|
-
# $ echo gem 'ruby2js', require: 'ruby2js/rails'
|
3
|
+
# $ echo "gem 'ruby2js', require: 'ruby2js/rails'" >> Gemfile
|
4
4
|
# $ bundle update
|
5
5
|
# $ rails generate controller Say hello
|
6
6
|
# $ echo 'alert "Hello world!"' > app/views/say/hello.js.rb
|
@@ -13,8 +13,8 @@
|
|
13
13
|
#
|
14
14
|
# Asset Pipeline:
|
15
15
|
#
|
16
|
-
# Ruby2JS registers ".
|
17
|
-
# You can add "ruby_thing.js.
|
16
|
+
# Ruby2JS registers ".rb.js" extension.
|
17
|
+
# You can add "ruby_thing.js.rb" to your app/javascript folder
|
18
18
|
# and '= require ruby_thing' from other js sources.
|
19
19
|
#
|
20
20
|
# (options are not yet supported, but by requiring the appropriate files
|
@@ -26,15 +26,17 @@ module Ruby2JS
|
|
26
26
|
class Template
|
27
27
|
cattr_accessor :default_format
|
28
28
|
self.default_format = Mime[:js]
|
29
|
-
def self.call(template)
|
30
|
-
"Ruby2JS.convert(#{template.source.inspect}).to_s"
|
29
|
+
def self.call(template, source)
|
30
|
+
"Ruby2JS.convert(#{template.source.inspect}, file: source).to_s"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
ActiveSupport.on_load(:action_view) do
|
35
|
+
ActionView::Template.register_template_handler :rb, Template
|
36
|
+
end
|
35
37
|
|
36
38
|
class SprocketProcessor
|
37
|
-
def initialize(
|
39
|
+
def initialize(file = nil)
|
38
40
|
@file = file
|
39
41
|
end
|
40
42
|
def render(context , _)
|
@@ -46,10 +48,14 @@ module Ruby2JS
|
|
46
48
|
class Engine < ::Rails::Engine
|
47
49
|
engine_name "ruby2js"
|
48
50
|
|
51
|
+
config.app_generators.javascripts true
|
52
|
+
config.app_generators.javascript_engine :rb
|
53
|
+
|
49
54
|
config.assets.configure do |env|
|
50
|
-
env.
|
55
|
+
env.register_mime_type 'text/ruby', extensions: ['.js.rb', '.rb']
|
56
|
+
env.register_transformer 'text/ruby', 'text/javascript', SprocketProcessor
|
57
|
+
env.register_preprocessor 'text/javascript', SprocketProcessor
|
51
58
|
end
|
52
|
-
|
53
59
|
end
|
54
60
|
|
55
61
|
end
|
data/lib/ruby2js/serializer.rb
CHANGED
@@ -42,6 +42,7 @@ module Ruby2JS
|
|
42
42
|
|
43
43
|
class Serializer
|
44
44
|
attr_reader :timestamps
|
45
|
+
attr_accessor :file_name
|
45
46
|
|
46
47
|
def initialize
|
47
48
|
@sep = '; '
|
@@ -56,6 +57,7 @@ module Ruby2JS
|
|
56
57
|
@timestamps = {}
|
57
58
|
|
58
59
|
@ast = nil
|
60
|
+
@file_name = ''
|
59
61
|
end
|
60
62
|
|
61
63
|
def timestamp(file)
|
@@ -363,7 +365,7 @@ module Ruby2JS
|
|
363
365
|
|
364
366
|
@sourcemap = {
|
365
367
|
version: 3,
|
366
|
-
file: @
|
368
|
+
file: @file_name,
|
367
369
|
sources: sources.map(&:name),
|
368
370
|
mappings: @mappings
|
369
371
|
}
|
data/lib/ruby2js/version.rb
CHANGED
data/ruby2js.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
11
11
|
s.require_paths = ["lib".freeze]
|
12
|
-
s.authors = ["Sam Ruby".freeze]
|
12
|
+
s.authors = ["Sam Ruby".freeze, "Jared White".freeze]
|
13
13
|
s.description = " The base package maps Ruby syntax to JavaScript semantics.\n Filters may be provided to add Ruby-specific or framework specific\n behavior.\n".freeze
|
14
14
|
s.email = "rubys@intertwingly.net".freeze
|
15
15
|
s.files = %w(ruby2js.gemspec README.md) + Dir.glob("{lib}/**/*")
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby2js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Ruby
|
8
|
-
|
8
|
+
- Jared White
|
9
|
+
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-01-01 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: parser
|
@@ -121,10 +122,10 @@ files:
|
|
121
122
|
- lib/ruby2js/es2021/strict.rb
|
122
123
|
- lib/ruby2js/execjs.rb
|
123
124
|
- lib/ruby2js/filter.rb
|
125
|
+
- lib/ruby2js/filter/active_functions.rb
|
124
126
|
- lib/ruby2js/filter/camelCase.rb
|
125
127
|
- lib/ruby2js/filter/cjs.rb
|
126
128
|
- lib/ruby2js/filter/esm.rb
|
127
|
-
- lib/ruby2js/filter/esm_migration.rb
|
128
129
|
- lib/ruby2js/filter/functions.rb
|
129
130
|
- lib/ruby2js/filter/jquery.rb
|
130
131
|
- lib/ruby2js/filter/matchAll.rb
|
@@ -134,6 +135,7 @@ files:
|
|
134
135
|
- lib/ruby2js/filter/react.rb
|
135
136
|
- lib/ruby2js/filter/require.rb
|
136
137
|
- lib/ruby2js/filter/return.rb
|
138
|
+
- lib/ruby2js/filter/securerandom.rb
|
137
139
|
- lib/ruby2js/filter/tagged_templates.rb
|
138
140
|
- lib/ruby2js/filter/underscore.rb
|
139
141
|
- lib/ruby2js/filter/vue.rb
|
@@ -149,7 +151,7 @@ homepage: http://github.com/rubys/ruby2js
|
|
149
151
|
licenses:
|
150
152
|
- MIT
|
151
153
|
metadata: {}
|
152
|
-
post_install_message:
|
154
|
+
post_install_message:
|
153
155
|
rdoc_options: []
|
154
156
|
require_paths:
|
155
157
|
- lib
|
@@ -164,8 +166,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
166
|
- !ruby/object:Gem::Version
|
165
167
|
version: '0'
|
166
168
|
requirements: []
|
167
|
-
rubygems_version: 3.
|
168
|
-
signing_key:
|
169
|
+
rubygems_version: 3.1.4
|
170
|
+
signing_key:
|
169
171
|
specification_version: 4
|
170
172
|
summary: Minimal yet extensible Ruby to JavaScript conversion.
|
171
173
|
test_files: []
|
@@ -1,72 +0,0 @@
|
|
1
|
-
require 'ruby2js'
|
2
|
-
|
3
|
-
module Ruby2JS
|
4
|
-
module Filter
|
5
|
-
module ESMMigration
|
6
|
-
include SEXP
|
7
|
-
|
8
|
-
def initialize(*args)
|
9
|
-
@esm_include = nil
|
10
|
-
super
|
11
|
-
end
|
12
|
-
|
13
|
-
def process(node)
|
14
|
-
return super if @esm_include
|
15
|
-
@esm_include = Set.new
|
16
|
-
@esm_exclude = Set.new
|
17
|
-
@esm_export = nil
|
18
|
-
result = super
|
19
|
-
|
20
|
-
esm_walk(result)
|
21
|
-
|
22
|
-
inventory = (@esm_include - @esm_exclude).to_a.sort
|
23
|
-
|
24
|
-
if inventory.empty? and not @esm_export
|
25
|
-
result
|
26
|
-
else
|
27
|
-
list = inventory.map do |name|
|
28
|
-
if name == "React" and defined? Ruby2JS::Filter::React
|
29
|
-
s(:import, "#{name.downcase}", s(:const, nil, name))
|
30
|
-
elsif not %w(JSON Object).include? name
|
31
|
-
s(:import, "./#{name.downcase}.js", s(:const, nil, name))
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
list.push result
|
36
|
-
|
37
|
-
if @esm_export
|
38
|
-
list.push s(:export, :default, s(:const, nil, @esm_export))
|
39
|
-
end
|
40
|
-
|
41
|
-
s(:begin, *list.compact)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# gather constants
|
46
|
-
def esm_walk(node)
|
47
|
-
# extract ivars and cvars
|
48
|
-
if node.type == :const and node.children.first == nil
|
49
|
-
@esm_include << node.children.last.to_s
|
50
|
-
elsif node.type == :xnode
|
51
|
-
name = node.children.first
|
52
|
-
@esm_include << name unless name.empty? or name =~ /^[a-z]/
|
53
|
-
elsif node.type == :casgn and node.children.first == nil
|
54
|
-
@esm_exclude << node.children[1].to_s
|
55
|
-
elsif node.type == :class and node.children.first.type == :const
|
56
|
-
if node.children.first.children.first == nil
|
57
|
-
name = node.children.first.children.last.to_s
|
58
|
-
@esm_exclude << name
|
59
|
-
@esm_export ||= name
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# recurse
|
64
|
-
node.children.each do |child|
|
65
|
-
esm_walk(child) if Parser::AST::Node === child
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
DEFAULTS.push ESMMigration
|
71
|
-
end
|
72
|
-
end
|