mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
135 lines
3.4 KiB
Ruby
135 lines
3.4 KiB
Ruby
|
|
||
|
# The base class for all JavaScript objects.
|
||
|
class Java::OrgMozillaJavascript::ScriptableObject
|
||
|
|
||
|
import "org.mozilla.javascript"
|
||
|
|
||
|
# get a property from this javascript object, where +k+ is a string or symbol
|
||
|
# corresponding to the property name e.g.
|
||
|
#
|
||
|
# jsobject = Context.open do |cxt|
|
||
|
# cxt.eval('({foo: 'bar', 'Take me to': 'a funky town'})')
|
||
|
# end
|
||
|
# jsobject[:foo] # => 'bar'
|
||
|
# jsobject['foo'] # => 'bar'
|
||
|
# jsobject['Take me to'] # => 'a funky town'
|
||
|
#
|
||
|
def [](name)
|
||
|
Rhino::To.to_ruby ScriptableObject.getProperty(self, name.to_s)
|
||
|
end
|
||
|
|
||
|
# set a property on the javascript object, where +k+ is a string or symbol corresponding
|
||
|
# to the property name, and +v+ is the value to set. e.g.
|
||
|
#
|
||
|
# jsobject = eval_js "new Object()"
|
||
|
# jsobject['foo'] = 'bar'
|
||
|
# Context.open(:with => jsobject) do |cxt|
|
||
|
# cxt.eval('foo') # => 'bar'
|
||
|
# end
|
||
|
#
|
||
|
def []=(key, value)
|
||
|
scope = self
|
||
|
ScriptableObject.putProperty(self, key.to_s, Rhino::To.to_javascript(value, scope))
|
||
|
end
|
||
|
|
||
|
# enumerate the key value pairs contained in this javascript object. e.g.
|
||
|
#
|
||
|
# eval_js("{foo: 'bar', baz: 'bang'}").each do |key,value|
|
||
|
# puts "#{key} -> #{value} "
|
||
|
# end
|
||
|
#
|
||
|
# outputs foo -> bar baz -> bang
|
||
|
#
|
||
|
def each
|
||
|
getAllIds.each { |id| yield id, Rhino::To.to_ruby(get(id, self)) }
|
||
|
end
|
||
|
|
||
|
def each_key
|
||
|
getAllIds.each { |id| yield id }
|
||
|
end
|
||
|
|
||
|
def each_value
|
||
|
getAllIds.each { |id| yield Rhino::To.to_ruby(get(id, self)) }
|
||
|
end
|
||
|
|
||
|
def keys
|
||
|
keys = []
|
||
|
each_key { |key| keys << key }
|
||
|
keys
|
||
|
end
|
||
|
|
||
|
def values
|
||
|
vals = []
|
||
|
each_value { |val| vals << val }
|
||
|
vals
|
||
|
end
|
||
|
|
||
|
# Converts the native object to a hash. This isn't really a stretch since it's
|
||
|
# pretty much a hash in the first place.
|
||
|
def to_h
|
||
|
hash = {}
|
||
|
each do |key, val|
|
||
|
hash[key] = val.is_a?(ScriptableObject) ? val.to_h : val
|
||
|
end
|
||
|
hash
|
||
|
end
|
||
|
|
||
|
# Convert this javascript object into a json string.
|
||
|
def to_json(*args)
|
||
|
to_h.to_json(*args)
|
||
|
end
|
||
|
|
||
|
# Delegate methods to JS object if possible when called from Ruby.
|
||
|
def method_missing(name, *args)
|
||
|
if ScriptableObject.hasProperty(self, name.to_s)
|
||
|
begin
|
||
|
context = Context.enter
|
||
|
js_args = Rhino::To.args_to_javascript(args, self) # scope == self
|
||
|
ScriptableObject.callMethod(context, self, name.to_s, js_args)
|
||
|
ensure
|
||
|
Context.exit
|
||
|
end
|
||
|
else
|
||
|
super
|
||
|
end
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
class Java::OrgMozillaJavascript::NativeObject
|
||
|
|
||
|
# re-implement Map#put
|
||
|
def []=(key, value)
|
||
|
scope = self
|
||
|
ScriptableObject.putProperty(self, key.to_s, Rhino::To.to_javascript(value, scope))
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
# The base class for all JavaScript function objects.
|
||
|
class Java::OrgMozillaJavascript::BaseFunction
|
||
|
|
||
|
import "org.mozilla.javascript"
|
||
|
|
||
|
alias_method :__call__, :call # Rhino's Function#call(a1, a2, a3, a4)
|
||
|
|
||
|
# make JavaScript functions callable Ruby style e.g. `fn.call('42')`
|
||
|
def call(*args)
|
||
|
context = Context.enter
|
||
|
scope = getParentScope || context.initStandardObjects
|
||
|
__call__(context, scope, scope, Rhino::To.args_to_javascript(args, scope))
|
||
|
ensure
|
||
|
Context.exit
|
||
|
end
|
||
|
|
||
|
# use JavaScript functions constructors from Ruby as `fn.new`
|
||
|
def new(*args)
|
||
|
context = Context.enter
|
||
|
scope = getParentScope || context.initStandardObjects
|
||
|
construct(context, scope, Rhino::To.args_to_javascript(args, scope))
|
||
|
ensure
|
||
|
Context.exit
|
||
|
end
|
||
|
|
||
|
end
|