Module: JS

Defined in:
ext/js/lib/js.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

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
  ...
end

Therefore, 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;")

Class Method Summary collapse

Class Method Details

.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

Returns:



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);
}

.globalJS::Object

Returns globalThis JavaScript object.

p JS.global
p JS.global[:document]

Returns:



168
169
170
# File 'ext/js/js-core.c', line 168

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

Returns:

  • (Boolean)


149
150
151
152
153
154
155
156
157
# File 'ext/js/js-core.c', line 149

static VALUE _rb_js_is_kind_of(VALUE klass, VALUE obj, VALUE c) {
  if (!IS_JSVALUE(obj)) {
    return Qfalse;
  }
  struct jsvalue *val = DATA_PTR(obj);
  VALUE js_klass_v = _rb_js_try_convert(klass, c);
  struct jsvalue *js_klass = DATA_PTR(js_klass_v);
  return RBOOL(rb_js_abi_host_instance_of(val->abi, js_klass->abi));
}

.promise_schedulerObject



101
102
103
# File 'ext/js/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

Returns:



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;
  }
}