Module: JS
- Defined in:
- lib/js.rb,
lib/js/version.rb,
lib/js/require_remote.rb,
lib/js/require_remote/evaluator.rb,
lib/js/require_remote/url_resolver.rb,
ext/js/js-core.c
Overview
The JS module provides a way to interact with JavaScript from Ruby.
Example
require 'js'
JS.eval("return 1 + 2") # => 3
JS.global[:document].write("Hello, world!")
div = JS.global[:document].createElement("div")
div[:innerText] = "click me"
body = JS.global[:document][:body]
if body[:classList].contains?("main")
body.appendChild(div)
end
div.addEventListener("click") do |event|
puts event # => # [object MouseEvent]
puts event[:detail] # => 1
div[:innerText] = "clicked!"
end
If you are using ruby.wasm without stdlib you will not have addEventListener and other specialized functions defined. You can still acomplish many of the same things using call instead.
Example
require 'js'
JS.eval("return 1 + 2") # => 3
JS.global[:document].call(:write, "Hello, world!")
div = JS.global[:document].call(:createElement, "div")
div[:innerText] = "click me"
if body[:classList].call(:contains, "main") == JS::True
body.appendChild(div)
end
div.call(:addEventListener, "click") do |event|
puts event # => # [object MouseEvent]
puts event[:detail] # => 1
div[:innerText] = "clicked!"
end
Defined Under Namespace
Classes: Error, Object, PromiseScheduler, RequireRemote
Constant Summary collapse
- Undefined =
JS.eval("return undefined")
- Null =
JS.eval("return null")
- True =
A boolean value in JavaScript is always a JS::Object instance from Ruby’s point of view. If we use the boolean value returned by a JavaScript function as the condition for an if expression in Ruby, the if expression will always be true.
Bad Example
searchParams = JS.global[:URLSearchParams].new(JS.global[:location][:search]) if searchParams.has('phrase') # Always pass through here. ... else ... endTherefore, the JS::True constant is used to determine if the JavaScript function return value is true or false.
Good Example
if searchParams.has('phrase') == JS::True ... end JS.eval("return true;")
- False =
JS.eval("return false;")
- VERSION =
"2.8.1"
Class Method Summary collapse
- .__async(future, &block) ⇒ Object
- .__call_async_method(recv, method_name, future, *args) ⇒ Object
- .__eval_async_rb(rb_code, future) ⇒ Object
-
.eval(code) ⇒ JS::Object
Evaluates the given JavaScript code, returning the result as a JS::Object.
-
.global ⇒ JS::Object
Returns
globalThisJavaScript object. -
.is_a?(js_obj, js_class) ⇒ Boolean
Returns
trueif js_class is the instance of js_obj, otherwise returnsfalse. - .promise_scheduler ⇒ Object
-
.try_convert(obj) ⇒ JS::Object?
Try to convert the given object to a JS::Object using
to_jsmethod.
Class Method Details
.__async(future, &block) ⇒ Object
117 118 119 120 121 122 123 124 125 |
# File 'lib/js.rb', line 117 def self.__async(future, &block) Fiber .new do future.resolve block.call rescue => e future.reject JS::Object.wrap(e) end .transfer end |
.__call_async_method(recv, method_name, future, *args) ⇒ Object
113 114 115 |
# File 'lib/js.rb', line 113 def self.__call_async_method(recv, method_name, future, *args) self.__async(future) { recv.send(method_name.to_s, *args) } end |
.__eval_async_rb(rb_code, future) ⇒ Object
107 108 109 110 111 |
# File 'lib/js.rb', line 107 def self.__eval_async_rb(rb_code, future) self.__async(future) do JS::Object.wrap(Kernel.eval(rb_code.to_s, TOPLEVEL_BINDING, "eval_async")) end end |
.eval(code) ⇒ JS::Object
Evaluates the given JavaScript code, returning the result as a JS::Object.
p JS.eval("return 1 + 1").to_i # => 2
p JS.eval("return new Object()").is_a?(JS.global[:Object]) # => true
99 100 101 102 103 104 105 106 |
# File 'ext/js/js-core.c', line 99 static VALUE _rb_js_eval_js(VALUE _, VALUE code_str) { rb_js_abi_host_string_t abi_str; rstring_to_abi_string(code_str, &abi_str); rb_js_abi_host_js_abi_result_t ret; rb_js_abi_host_eval_js(&abi_str, &ret); raise_js_error_if_failure(&ret); return jsvalue_s_new(ret.val.success); } |
.global ⇒ JS::Object
Returns globalThis JavaScript object.
p JS.global
p JS.global[:document]
181 182 183 |
# File 'ext/js/js-core.c', line 181 static VALUE _rb_js_global_this(VALUE _) { return jsvalue_s_new(rb_js_abi_host_global_this()); } |
.is_a?(js_obj, js_class) ⇒ Boolean
Returns true if js_class is the instance of
<i>js_obj</i>, otherwise returns <code>false</code>.
Comparison is done using the <code>instanceof</code> in JavaScript.
p JS.is_a?(JS.global, JS.global[:Object]) #=> true
p JS.is_a?(JS.global, Object) #=> false
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'ext/js/js-core.c', line 149 static VALUE _rb_js_is_kind_of(int argc, VALUE *argv, VALUE self) { if (argc == 1) { // If the second argument is not given, behaves as `Module#is_a?`. return rb_obj_is_kind_of(self, argv[0]); } if (argc != 2) { rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 2)", argc); } VALUE obj = argv[0]; VALUE klass = argv[1]; if (!IS_JSVALUE(obj)) { return Qfalse; } struct jsvalue *val = DATA_PTR(obj); VALUE js_klass_v = _rb_js_try_convert(self, klass); struct jsvalue *js_klass = DATA_PTR(js_klass_v); return RBOOL(rb_js_abi_host_instance_of(val->abi, js_klass->abi)); } |
.promise_scheduler ⇒ Object
101 102 103 |
# File 'lib/js.rb', line 101 def self.promise_scheduler @promise_scheduler end |
.try_convert(obj) ⇒ JS::Object?
Try to convert the given object to a JS::Object using to_js
method. Returns <code>nil</code> if the object cannot be converted.
p JS.try_convert(1) # => JS::Object
p JS.try_convert("foo") # => JS::Object
p JS.try_convert(Object.new) # => nil
p JS.try_convert(JS::Object.wrap(Object.new)) # => JS::Object
128 129 130 131 132 133 134 135 136 |
# File 'ext/js/js-core.c', line 128 VALUE _rb_js_try_convert(VALUE klass, VALUE obj) { if (_rb_js_is_js(klass, obj)) { return obj; } else if (rb_respond_to(obj, i_to_js)) { return rb_funcallv(obj, i_to_js, 0, NULL); } else { return Qnil; } } |