js 0.0.1 → 2.5.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 +7 -0
- data/ext/js/bindgen/.clang-format +2 -0
- data/ext/js/bindgen/rb-js-abi-host.c +342 -0
- data/ext/js/bindgen/rb-js-abi-host.h +82 -0
- data/ext/js/bindgen/rb-js-abi-host.wit +47 -0
- data/ext/js/depend +10 -0
- data/ext/js/extconf.rb +3 -0
- data/ext/js/js-core.c +577 -0
- data/ext/witapi/bindgen/.clang-format +2 -0
- data/ext/witapi/bindgen/rb-abi-guest.c +222 -0
- data/ext/witapi/bindgen/rb-abi-guest.h +77 -0
- data/ext/witapi/bindgen/rb-abi-guest.wit +25 -0
- data/ext/witapi/depend +11 -0
- data/ext/witapi/extconf.rb +3 -0
- data/ext/witapi/witapi-core.c +325 -0
- data/js.gemspec +26 -16
- data/lib/js/array.rb +9 -0
- data/lib/js/hash.rb +8 -0
- data/lib/js/nil_class.rb +6 -0
- data/lib/js/require_remote/evaluator.rb +15 -0
- data/lib/js/require_remote/url_resolver.rb +45 -0
- data/lib/js/require_remote.rb +85 -0
- data/lib/js/version.rb +2 -2
- data/lib/js.rb +238 -3
- metadata +39 -22
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -22
- data/README.md +0 -35
- data/Rakefile +0 -1
data/js.gemspec
CHANGED
@@ -1,19 +1,29 @@
|
|
1
|
-
#
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'js/version'
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
7
|
-
gem.name = "js"
|
8
|
-
gem.version = Js::VERSION
|
9
|
-
gem.authors = ["Charles Lowell"]
|
10
|
-
gem.email = ["cowboyd@thefrontside.net"]
|
11
|
-
gem.description = %q{embed a JavaScript interpreter}
|
12
|
-
gem.summary = %q{use JavaScript objects from Ruby and embed Ruby objects into JavaScript}
|
13
|
-
gem.homepage = ""
|
3
|
+
require_relative "lib/js/version"
|
14
4
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "js"
|
7
|
+
spec.version = JS::VERSION
|
8
|
+
spec.authors = ["Yuta Saito"]
|
9
|
+
spec.email = ["kateinoigakukun@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{JavaScript bindings for ruby.wasm}
|
12
|
+
spec.description = %q{JavaScript bindings for ruby.wasm. This gem provides a way to use JavaScript functionalities from Ruby through WebAssembly.}
|
13
|
+
spec.homepage = "https://github.com/ruby/ruby.wasm"
|
14
|
+
|
15
|
+
spec.metadata = {
|
16
|
+
"source_code_uri" => "https://github.com/ruby/ruby.wasm/tree/main/packages/gems/js",
|
17
|
+
}
|
18
|
+
|
19
|
+
spec.license = "MIT"
|
20
|
+
|
21
|
+
spec.files = Dir.chdir(__dir__) do
|
22
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
23
|
+
(File.expand_path(f) == __FILE__) ||
|
24
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
spec.extensions = ["ext/js/extconf.rb", "ext/witapi/extconf.rb"]
|
19
29
|
end
|
data/lib/js/array.rb
ADDED
data/lib/js/hash.rb
ADDED
data/lib/js/nil_class.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module JS
|
2
|
+
class RequireRemote
|
3
|
+
# Execute the body of the response and record the URL.
|
4
|
+
class Evaluator
|
5
|
+
def evaluate(code, filename, final_url)
|
6
|
+
Kernel.eval(code, ::Object::TOPLEVEL_BINDING, filename)
|
7
|
+
$LOADED_FEATURES << final_url
|
8
|
+
end
|
9
|
+
|
10
|
+
def evaluated?(url)
|
11
|
+
$LOADED_FEATURES.include?(url)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module JS
|
2
|
+
class RequireRemote
|
3
|
+
ScriptLocation = Data.define(:url, :filename)
|
4
|
+
|
5
|
+
# When require_relative is called within a running Ruby script,
|
6
|
+
# the URL is resolved from a relative file path based on the URL of the running Ruby script.
|
7
|
+
# It uses a stack to store URLs of running Ruby Script.
|
8
|
+
# Push the URL onto the stack before executing the new script.
|
9
|
+
# Then pop it when the script has finished executing.
|
10
|
+
class URLResolver
|
11
|
+
def initialize(base_url)
|
12
|
+
@url_stack = [base_url]
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_location(relative_feature)
|
16
|
+
filename = filename_from(relative_feature)
|
17
|
+
url = resolve(filename)
|
18
|
+
ScriptLocation.new(url, filename)
|
19
|
+
end
|
20
|
+
|
21
|
+
def push(url)
|
22
|
+
@url_stack.push url
|
23
|
+
end
|
24
|
+
|
25
|
+
def pop()
|
26
|
+
@url_stack.pop
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def filename_from(relative_feature)
|
32
|
+
if relative_feature.end_with?(".rb")
|
33
|
+
relative_feature
|
34
|
+
else
|
35
|
+
"#{relative_feature}.rb"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return a URL object of JavaScript.
|
40
|
+
def resolve(relative_filepath)
|
41
|
+
JS.global[:URL].new relative_filepath, @url_stack.last
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "singleton"
|
2
|
+
require "js"
|
3
|
+
require_relative "./require_remote/url_resolver"
|
4
|
+
require_relative "./require_remote/evaluator"
|
5
|
+
|
6
|
+
module JS
|
7
|
+
# This class is used to load remote Ruby scripts.
|
8
|
+
#
|
9
|
+
# == Example
|
10
|
+
#
|
11
|
+
# require 'js/require_remote'
|
12
|
+
# JS::RequireRemote.instance.load("foo")
|
13
|
+
#
|
14
|
+
# This class is intended to be used to replace Kernel#require_relative.
|
15
|
+
#
|
16
|
+
# == Example
|
17
|
+
#
|
18
|
+
# require 'js/require_remote'
|
19
|
+
# module Kernel
|
20
|
+
# def require_relative(path) = JS::RequireRemote.instance.load(path)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# If you want to load the bundled gem
|
24
|
+
#
|
25
|
+
# == Example
|
26
|
+
#
|
27
|
+
# require 'js/require_remote'
|
28
|
+
# module Kernel
|
29
|
+
# alias original_require_relative require_relative
|
30
|
+
#
|
31
|
+
# def require_relative(path)
|
32
|
+
# caller_path = caller_locations(1, 1).first.absolute_path || ''
|
33
|
+
# dir = File.dirname(caller_path)
|
34
|
+
# file = File.absolute_path(path, dir)
|
35
|
+
#
|
36
|
+
# original_require_relative(file)
|
37
|
+
# rescue LoadError
|
38
|
+
# JS::RequireRemote.instance.load(path)
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
class RequireRemote
|
43
|
+
include Singleton
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
base_url = JS.global[:URL].new(JS.global[:location][:href])
|
47
|
+
@resolver = URLResolver.new(base_url)
|
48
|
+
@evaluator = Evaluator.new
|
49
|
+
end
|
50
|
+
|
51
|
+
# Load the given feature from remote.
|
52
|
+
def load(relative_feature)
|
53
|
+
location = @resolver.get_location(relative_feature)
|
54
|
+
|
55
|
+
# Do not load the same URL twice.
|
56
|
+
return false if @evaluator.evaluated?(location.url[:href].to_s)
|
57
|
+
|
58
|
+
response = JS.global.fetch(location.url).await
|
59
|
+
unless response[:status].to_i == 200
|
60
|
+
raise LoadError.new "cannot load such url -- #{response[:status]} #{location.url}"
|
61
|
+
end
|
62
|
+
|
63
|
+
# The fetch API may have responded to a redirect response
|
64
|
+
# and fetched the script from a different URL than the original URL.
|
65
|
+
# Retrieve the final URL again from the response object.
|
66
|
+
final_url = response[:url].to_s
|
67
|
+
|
68
|
+
# Do not evaluate the same URL twice.
|
69
|
+
return false if @evaluator.evaluated?(final_url)
|
70
|
+
|
71
|
+
code = response.text().await.to_s
|
72
|
+
|
73
|
+
evaluate(code, location.filename, final_url)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def evaluate(code, filename, final_url)
|
79
|
+
@resolver.push(final_url)
|
80
|
+
@evaluator.evaluate(code, filename, final_url)
|
81
|
+
@resolver.pop
|
82
|
+
true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/js/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module
|
2
|
-
VERSION = "
|
1
|
+
module JS
|
2
|
+
VERSION = "2.5.0"
|
3
3
|
end
|
data/lib/js.rb
CHANGED
@@ -1,5 +1,240 @@
|
|
1
|
-
require "js
|
1
|
+
require "js.so"
|
2
|
+
require_relative "js/hash.rb"
|
3
|
+
require_relative "js/array.rb"
|
4
|
+
require_relative "js/nil_class.rb"
|
2
5
|
|
3
|
-
module
|
4
|
-
|
6
|
+
# The JS module provides a way to interact with JavaScript from Ruby.
|
7
|
+
#
|
8
|
+
# == Example
|
9
|
+
#
|
10
|
+
# require 'js'
|
11
|
+
# JS.eval("return 1 + 2") # => 3
|
12
|
+
# JS.global[:document].write("Hello, world!")
|
13
|
+
# div = JS.global[:document].createElement("div")
|
14
|
+
# div[:innerText] = "click me"
|
15
|
+
# body = JS.global[:document][:body]
|
16
|
+
# if body[:classList].contains?("main")
|
17
|
+
# body.appendChild(div)
|
18
|
+
# end
|
19
|
+
# div.addEventListener("click") do |event|
|
20
|
+
# puts event # => # [object MouseEvent]
|
21
|
+
# puts event[:detail] # => 1
|
22
|
+
# div[:innerText] = "clicked!"
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# If you are using `ruby.wasm` without `stdlib` you will not have `addEventListener`
|
26
|
+
# and other specialized functions defined. You can still acomplish many
|
27
|
+
# of the same things using `call` instead.
|
28
|
+
#
|
29
|
+
# == Example
|
30
|
+
#
|
31
|
+
# require 'js'
|
32
|
+
# JS.eval("return 1 + 2") # => 3
|
33
|
+
# JS.global[:document].call(:write, "Hello, world!")
|
34
|
+
# div = JS.global[:document].call(:createElement, "div")
|
35
|
+
# div[:innerText] = "click me"
|
36
|
+
# if body[:classList].call(:contains, "main") == JS::True
|
37
|
+
# body.appendChild(div)
|
38
|
+
# end
|
39
|
+
# div.call(:addEventListener, "click") do |event|
|
40
|
+
# puts event # => # [object MouseEvent]
|
41
|
+
# puts event[:detail] # => 1
|
42
|
+
# div[:innerText] = "clicked!"
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
module JS
|
46
|
+
Undefined = JS.eval("return undefined")
|
47
|
+
Null = JS.eval("return null")
|
48
|
+
|
49
|
+
# A boolean value in JavaScript is always a JS::Object instance from Ruby's point of view.
|
50
|
+
# If we use the boolean value returned by a JavaScript function as the condition for an if expression in Ruby,
|
51
|
+
# the if expression will always be true.
|
52
|
+
#
|
53
|
+
# == Bad Example
|
54
|
+
#
|
55
|
+
# searchParams = JS.global[:URLSearchParams].new(JS.global[:location][:search])
|
56
|
+
# if searchParams.has('phrase')
|
57
|
+
# # Always pass through here.
|
58
|
+
# ...
|
59
|
+
# else
|
60
|
+
# ...
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# Therefore, the JS::True constant is used to determine if the JavaScript function return value is true or false.
|
64
|
+
#
|
65
|
+
# == Good Example
|
66
|
+
#
|
67
|
+
# if searchParams.has('phrase') == JS::True
|
68
|
+
# ...
|
69
|
+
# end
|
70
|
+
True = JS.eval("return true;")
|
71
|
+
False = JS.eval("return false;")
|
72
|
+
|
73
|
+
class PromiseScheduler
|
74
|
+
def initialize(loop)
|
75
|
+
@loop = loop
|
76
|
+
end
|
77
|
+
|
78
|
+
def await(promise)
|
79
|
+
current = Fiber.current
|
80
|
+
promise.call(
|
81
|
+
:then,
|
82
|
+
->(value) { current.transfer(value, :success) },
|
83
|
+
->(value) { current.transfer(value, :failure) }
|
84
|
+
)
|
85
|
+
if @loop == current
|
86
|
+
raise (
|
87
|
+
"JS::Object#await can be called only from RubyVM#evalAsync or RbValue#callAsync JS API\n" +
|
88
|
+
"If you are using browser.script.iife.js, please ensure that you specify `data-eval=\"async\"` in your script tag\n" +
|
89
|
+
"e.g. <script type=\"text/ruby\" data-eval=\"async\">puts :hello</script>\n" +
|
90
|
+
"Or <script type=\"text/ruby\" data-eval=\"async\" src=\"path/to/script.rb\"></script>"
|
91
|
+
)
|
92
|
+
end
|
93
|
+
value, status = @loop.transfer
|
94
|
+
raise JS::Error.new(value) if status == :failure
|
95
|
+
value
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
@promise_scheduler = PromiseScheduler.new Fiber.current
|
100
|
+
|
101
|
+
def self.promise_scheduler
|
102
|
+
@promise_scheduler
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def self.__eval_async_rb(rb_code, future)
|
108
|
+
self.__async(future) do
|
109
|
+
JS::Object.wrap(Kernel.eval(rb_code.to_s, TOPLEVEL_BINDING, "eval_async"))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.__call_async_method(recv, method_name, future, *args)
|
114
|
+
self.__async(future) { recv.send(method_name.to_s, *args) }
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.__async(future, &block)
|
118
|
+
Fiber
|
119
|
+
.new do
|
120
|
+
future.resolve block.call
|
121
|
+
rescue => e
|
122
|
+
future.reject JS::Object.wrap(e)
|
123
|
+
end
|
124
|
+
.transfer
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class JS::Object
|
129
|
+
# Create a JavaScript object with the new method
|
130
|
+
#
|
131
|
+
# The below examples show typical usage in Ruby
|
132
|
+
#
|
133
|
+
# JS.global[:Object].new
|
134
|
+
# JS.global[:Number].new(1.23)
|
135
|
+
# JS.global[:String].new("string")
|
136
|
+
# JS.global[:Array].new(1, 2, 3)
|
137
|
+
# JS.global[:Date].new(2020, 1, 1)
|
138
|
+
# JS.global[:Error].new("error message")
|
139
|
+
# JS.global[:URLSearchParams].new(JS.global[:location][:search])
|
140
|
+
#
|
141
|
+
def new(*args)
|
142
|
+
JS.global[:Reflect].construct(self, args.to_js)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Converts +self+ to an Array:
|
146
|
+
#
|
147
|
+
# JS.eval("return [1, 2, 3]").to_a.map(&:to_i) # => [1, 2, 3]
|
148
|
+
# JS.global[:document].querySelectorAll("p").to_a # => [[object HTMLParagraphElement], ...
|
149
|
+
def to_a
|
150
|
+
as_array = JS.global[:Array].from(self)
|
151
|
+
Array.new(as_array[:length].to_i) { as_array[_1] }
|
152
|
+
end
|
153
|
+
|
154
|
+
# Provide a shorthand form for JS::Object#call
|
155
|
+
#
|
156
|
+
# This method basically calls the JavaScript method with the same
|
157
|
+
# name as the Ruby method name as is using JS::Object#call.
|
158
|
+
#
|
159
|
+
# Exceptions are the following cases:
|
160
|
+
# * If the method name ends with a question mark (?), the question mark is removed
|
161
|
+
# and the method is called as a predicate method. The return value is converted to
|
162
|
+
# a Ruby boolean value automatically.
|
163
|
+
#
|
164
|
+
# This shorthand is unavailable for the following cases and you need to use
|
165
|
+
# JS::Object#call instead:
|
166
|
+
# * If the method name is invalid as a Ruby method name (e.g. contains a hyphen, reserved word, etc.)
|
167
|
+
# * If the method name is already defined as a Ruby method under JS::Object
|
168
|
+
# * If the JavaScript method name ends with a question mark (?)
|
169
|
+
def method_missing(sym, *args, &block)
|
170
|
+
sym_str = sym.to_s
|
171
|
+
if sym_str.end_with?("?")
|
172
|
+
# When a JS method is called with a ? suffix, it is treated as a predicate method,
|
173
|
+
# and the return value is converted to a Ruby boolean value automatically.
|
174
|
+
self.call(sym_str[0..-2].to_sym, *args, &block) == JS::True
|
175
|
+
elsif self[sym].typeof == "function"
|
176
|
+
self.call(sym, *args, &block)
|
177
|
+
else
|
178
|
+
super
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# Check if a JavaScript method exists
|
183
|
+
#
|
184
|
+
# See JS::Object#method_missing for details.
|
185
|
+
def respond_to_missing?(sym, include_private)
|
186
|
+
return true if super
|
187
|
+
sym_str = sym.to_s
|
188
|
+
sym = sym_str[0..-2].to_sym if sym_str.end_with?("?")
|
189
|
+
self[sym].typeof == "function"
|
190
|
+
end
|
191
|
+
|
192
|
+
# Await a JavaScript Promise like `await` in JavaScript.
|
193
|
+
# This method looks like a synchronous method, but it actually runs asynchronously using fibers.
|
194
|
+
# In other words, the next line to the `await` call at Ruby source will be executed after the
|
195
|
+
# promise will be resolved. However, it does not block JavaScript event loop, so the next line
|
196
|
+
# to the RubyVM.evalAsync` (in the case when no `await` operator before the call expression)
|
197
|
+
# at JavaScript source will be executed without waiting for the promise.
|
198
|
+
#
|
199
|
+
# The below example shows how the execution order goes. It goes in the order of "step N"
|
200
|
+
#
|
201
|
+
# # In JavaScript
|
202
|
+
# const response = vm.evalAsync(`
|
203
|
+
# puts "step 1"
|
204
|
+
# JS.global.fetch("https://example.com").await
|
205
|
+
# puts "step 3"
|
206
|
+
# `) // => Promise
|
207
|
+
# console.log("step 2")
|
208
|
+
# await response
|
209
|
+
# console.log("step 4")
|
210
|
+
#
|
211
|
+
# The below examples show typical usage in Ruby
|
212
|
+
#
|
213
|
+
# JS.eval("return new Promise((ok) => setTimeout(() => ok(42), 1000))").await # => 42 (after 1 second)
|
214
|
+
# JS.global.fetch("https://example.com").await # => [object Response]
|
215
|
+
# JS.eval("return 42").await # => 42
|
216
|
+
# JS.eval("return new Promise((ok, err) => err(new Error())").await # => raises JS::Error
|
217
|
+
def await
|
218
|
+
# Promise.resolve wrap a value or flattens promise-like object and its thenable chain
|
219
|
+
promise = JS.global[:Promise].resolve(self)
|
220
|
+
JS.promise_scheduler.await(promise)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# A wrapper class for JavaScript Error to allow the Error to be thrown in Ruby.
|
225
|
+
class JS::Error
|
226
|
+
def initialize(exception)
|
227
|
+
@exception = exception
|
228
|
+
super
|
229
|
+
end
|
230
|
+
|
231
|
+
def message
|
232
|
+
stack = @exception[:stack]
|
233
|
+
if stack.typeof == "string"
|
234
|
+
# Error.stack contains the error message also
|
235
|
+
stack.to_s
|
236
|
+
else
|
237
|
+
@exception.to_s
|
238
|
+
end
|
239
|
+
end
|
5
240
|
end
|
metadata
CHANGED
@@ -1,53 +1,70 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 2.5.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
|
-
-
|
7
|
+
- Yuta Saito
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2024-01-28 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
|
-
description:
|
13
|
+
description: JavaScript bindings for ruby.wasm. This gem provides a way to use JavaScript
|
14
|
+
functionalities from Ruby through WebAssembly.
|
15
15
|
email:
|
16
|
-
-
|
16
|
+
- kateinoigakukun@gmail.com
|
17
17
|
executables: []
|
18
|
-
extensions:
|
18
|
+
extensions:
|
19
|
+
- ext/js/extconf.rb
|
20
|
+
- ext/witapi/extconf.rb
|
19
21
|
extra_rdoc_files: []
|
20
22
|
files:
|
21
|
-
-
|
22
|
-
-
|
23
|
-
-
|
24
|
-
-
|
25
|
-
-
|
23
|
+
- ext/js/bindgen/.clang-format
|
24
|
+
- ext/js/bindgen/rb-js-abi-host.c
|
25
|
+
- ext/js/bindgen/rb-js-abi-host.h
|
26
|
+
- ext/js/bindgen/rb-js-abi-host.wit
|
27
|
+
- ext/js/depend
|
28
|
+
- ext/js/extconf.rb
|
29
|
+
- ext/js/js-core.c
|
30
|
+
- ext/witapi/bindgen/.clang-format
|
31
|
+
- ext/witapi/bindgen/rb-abi-guest.c
|
32
|
+
- ext/witapi/bindgen/rb-abi-guest.h
|
33
|
+
- ext/witapi/bindgen/rb-abi-guest.wit
|
34
|
+
- ext/witapi/depend
|
35
|
+
- ext/witapi/extconf.rb
|
36
|
+
- ext/witapi/witapi-core.c
|
26
37
|
- js.gemspec
|
27
38
|
- lib/js.rb
|
39
|
+
- lib/js/array.rb
|
40
|
+
- lib/js/hash.rb
|
41
|
+
- lib/js/nil_class.rb
|
42
|
+
- lib/js/require_remote.rb
|
43
|
+
- lib/js/require_remote/evaluator.rb
|
44
|
+
- lib/js/require_remote/url_resolver.rb
|
28
45
|
- lib/js/version.rb
|
29
|
-
homepage:
|
30
|
-
licenses:
|
46
|
+
homepage: https://github.com/ruby/ruby.wasm
|
47
|
+
licenses:
|
48
|
+
- MIT
|
49
|
+
metadata:
|
50
|
+
source_code_uri: https://github.com/ruby/ruby.wasm/tree/main/packages/gems/js
|
31
51
|
post_install_message:
|
32
52
|
rdoc_options: []
|
33
53
|
require_paths:
|
34
54
|
- lib
|
35
55
|
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
-
none: false
|
37
56
|
requirements:
|
38
|
-
- -
|
57
|
+
- - ">="
|
39
58
|
- !ruby/object:Gem::Version
|
40
59
|
version: '0'
|
41
60
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
61
|
requirements:
|
44
|
-
- -
|
62
|
+
- - ">="
|
45
63
|
- !ruby/object:Gem::Version
|
46
64
|
version: '0'
|
47
65
|
requirements: []
|
48
|
-
|
49
|
-
rubygems_version: 1.8.24
|
66
|
+
rubygems_version: 3.5.3
|
50
67
|
signing_key:
|
51
|
-
specification_version:
|
52
|
-
summary:
|
68
|
+
specification_version: 4
|
69
|
+
summary: JavaScript bindings for ruby.wasm
|
53
70
|
test_files: []
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/LICENSE.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2012 Charles Lowell
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# js.rb - Embed JavasScript into Ruby
|
2
|
-
|
3
|
-
js.rb harnesses the power of JavaScript inside your Ruby application
|
4
|
-
|
5
|
-
## Synopsis
|
6
|
-
|
7
|
-
evaluate some simple JavaScript
|
8
|
-
|
9
|
-
cxt = JS::Context.new
|
10
|
-
cxt.eval('7 * 6') #=> 42
|
11
|
-
|
12
|
-
embed values into the scope of your context
|
13
|
-
|
14
|
-
cxt['foo'] = "bar"
|
15
|
-
cxt.eval('foo') # => "bar"
|
16
|
-
|
17
|
-
embed Ruby code into your scope and call it from JavaScript
|
18
|
-
|
19
|
-
cxt["say"] = lambda {|this, word, times| word * times}
|
20
|
-
cxt.eval("say('Hello', 3)") #=> HelloHelloHello
|
21
|
-
|
22
|
-
## Installation
|
23
|
-
|
24
|
-
Add this line to your application's Gemfile:
|
25
|
-
|
26
|
-
gem 'js'
|
27
|
-
|
28
|
-
And then execute:
|
29
|
-
|
30
|
-
$ bundle
|
31
|
-
|
32
|
-
Or install it yourself as:
|
33
|
-
|
34
|
-
$ gem install js
|
35
|
-
|
data/Rakefile
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|