class JS::Proxy
def [](index)
def [](index) val = native[index] wrap_result(val) end
def []=(k, v)
def []=(k, v) native[k] = v wrap_result(native) end
def each
def each return enum_for(:each) unless respond_to?(:length) length = self.length (0...length).each do |i| yield self[i] end end
def existing_property?(property)
def existing_property?(property) `#{property} in #{to_n}` end
def initialize(native)
def initialize(native) @native = Native(native) end
def length
def length native.length end
def method_missing(name, *args, &block)
def method_missing(name, *args, &block) js_name = to_js_name(name) unless existing_property?(js_name) || js_name.end_with?("=") raise NoMethodError, "undefined method `#{name}` for #{self}" end if js_name.end_with?("=") prop = js_name[0..-2] native[prop] = args.first else val = native[js_name] if `typeof val === 'function'` js_args = args.dup if block js_callback = %x{ function() { let args = Array.prototype.slice.call(arguments); return #{block.call(self.class.new(`this`), *args)}; } } js_args << js_callback end result = `val.apply(#{to_n}, #{js_args.to_n})` wrap_result(result) elsif `typeof val === 'object' && val !== null` wrap_result(val) else val end end end
def respond_to_missing?(name, include_private = false)
def respond_to_missing?(name, include_private = false) true end
def to_js_name(name)
def to_js_name(name) name.to_s.split('_').map.with_index do |part, index| if IRREGULARS.include? part.gsub("=", "").downcase part.upcase else index.zero? ? part : part.capitalize end end.join end
def to_n
def to_n native.to_n end
def to_rb_name(name)
def to_rb_name(name) name .to_s .gsub(/([A-Z]+)/) { "_#{$1.downcase}" } .sub(/^_/, '') end
def to_str
def to_str `#{to_n}.toString()` end