mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
add native object wrapper for easy access to js objects from ruby
This commit is contained in:
parent
20493a6c48
commit
33ef76f85e
6 changed files with 143 additions and 15 deletions
|
@ -6,4 +6,5 @@ module Rhino
|
|||
VERSION = '1.72.0'
|
||||
require 'rhino/java'
|
||||
require 'rhino/context'
|
||||
require 'rhino/native_object'
|
||||
end
|
|
@ -7,6 +7,25 @@ module Rhino
|
|||
class Context
|
||||
|
||||
class << self
|
||||
def open
|
||||
J::ContextFactory.new.call do |native|
|
||||
yield new(native)
|
||||
end
|
||||
end
|
||||
|
||||
def to_scriptable(object)
|
||||
case object
|
||||
when NativeObject then object.j
|
||||
when J::Scriptable then object
|
||||
else
|
||||
#wrap ruby object into ScriptableRubyObject
|
||||
end
|
||||
end
|
||||
|
||||
def to_ruby(object)
|
||||
object.class <= J::Scriptable ? NativeObject.new(object) : object
|
||||
end
|
||||
|
||||
private :new
|
||||
end
|
||||
|
||||
|
@ -14,15 +33,19 @@ module Rhino
|
|||
@native = native
|
||||
end
|
||||
|
||||
def self.open
|
||||
J::ContextFactory.new.call do |native|
|
||||
yield new(native)
|
||||
def init_standard_objects(options = {})
|
||||
NativeObject.new(@native.initStandardObjects(nil, options[:sealed] == true)).tap do |objects|
|
||||
unless options[:java]
|
||||
for package in ["Packages", "java", "org", "com"]
|
||||
objects.j.delete(package)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def evaljs(str, scope = @native.initStandardObjects())
|
||||
begin
|
||||
@native.evaluateString(scope, str, "<eval>", 1, nil)
|
||||
Context.to_ruby(@native.evaluateString(Context.to_scriptable(scope), str, "<eval>", 1, nil))
|
||||
rescue J::RhinoException => e
|
||||
raise Rhino::RhinoError, e
|
||||
end
|
||||
|
@ -55,7 +78,7 @@ module Rhino
|
|||
end
|
||||
|
||||
def javascript_backtrace
|
||||
@native.script_stack_trace
|
||||
@native.getScriptStackTrace()
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,3 +6,12 @@ module Rhino
|
|||
import "org.mozilla.javascript"
|
||||
end
|
||||
end
|
||||
|
||||
unless Object.method_defined?(:tap)
|
||||
class Object
|
||||
def tap
|
||||
yield self
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
19
lib/rhino/native_object.rb
Normal file
19
lib/rhino/native_object.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
module Rhino
|
||||
class NativeObject
|
||||
attr_reader :j
|
||||
def initialize(j)
|
||||
@j = j
|
||||
end
|
||||
|
||||
def [](k)
|
||||
if v = @j.get(k.to_s,@j)
|
||||
v == J::Scriptable::NOT_FOUND ? nil : Context.to_ruby(v)
|
||||
end
|
||||
end
|
||||
|
||||
def []=(k,v)
|
||||
@j.put(k.to_s,@j,v)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,25 +1,71 @@
|
|||
require File.dirname(__FILE__) + '/../spec_helper'
|
||||
|
||||
include Rhino
|
||||
|
||||
describe Rhino::Context do
|
||||
include Rhino
|
||||
|
||||
it "can evaluate some javascript" do
|
||||
Rhino::Context.open do |cxt|
|
||||
Context.open do |cxt|
|
||||
cxt.evaljs("5 + 3").should == 8
|
||||
end
|
||||
end
|
||||
|
||||
it "can embed ruby object into javascript" do
|
||||
Rhino::Context.open do |cxt|
|
||||
cxt.standard do |scope|
|
||||
scope.put("foo", scope, "Hello World")
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects.tap do |scope|
|
||||
scope["foo"] = "Hello World"
|
||||
cxt.evaljs("foo", scope).should == "Hello World"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Initalizing Standard Javascript Objects" do
|
||||
it "provides the standard objects without java integration by default" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects.tap do |scope|
|
||||
scope["Object"].should_not be_nil
|
||||
scope["Math"].should_not be_nil
|
||||
scope["String"].should_not be_nil
|
||||
scope["Function"].should_not be_nil
|
||||
scope["Packages"].should be_nil
|
||||
scope["java"].should be_nil
|
||||
scope["org"].should be_nil
|
||||
scope["com"].should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "provides unsealed standard object by default" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects.tap do |scope|
|
||||
cxt.evaljs("Object.foop = 'blort'", scope)
|
||||
scope["Object"]['foop'].should == 'blort'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "allows you to seal the standard objects so that they cannot be modified" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects(:sealed => true).tap do |scope|
|
||||
lambda {
|
||||
cxt.evaljs("Object.foop = 'blort'", scope)
|
||||
}.should raise_error(Rhino::RhinoError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "allows java integration to be turned on when initializing standard objects" do
|
||||
Context.open do |cxt|
|
||||
cxt.init_standard_objects(:java => true).tap do |scope|
|
||||
scope["Packages"].should_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
it "can call ruby functions from javascript" do
|
||||
Rhino::Context.open do |cxt|
|
||||
Context.open do |cxt|
|
||||
cxt.standard do |scope|
|
||||
scope.put("say", scope, function {|word, times| word * times})
|
||||
cxt.evaljs("say('Hello',2)", scope).should == "HelloHello"
|
||||
|
@ -29,8 +75,7 @@ describe Rhino::Context do
|
|||
|
||||
it "has a private constructor" do
|
||||
lambda {
|
||||
Rhino::Context.new(nil)
|
||||
Context.new(nil)
|
||||
}.should raise_error
|
||||
end
|
||||
|
||||
end
|
31
spec/rhino/native_object_spec.rb
Normal file
31
spec/rhino/native_object_spec.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
require File.dirname(__FILE__) + '/../spec_helper'
|
||||
|
||||
include Rhino
|
||||
|
||||
describe Rhino::NativeObject do
|
||||
|
||||
before(:each) do
|
||||
@j = J::NativeObject.new
|
||||
@o = NativeObject.new(@j)
|
||||
end
|
||||
|
||||
it "wraps a native javascript object" do
|
||||
@o["foo"] = 'bar'
|
||||
@j.get("foo", @j).should == "bar"
|
||||
@j.put("blue",@j, "blam")
|
||||
@o["blue"].should == "blam"
|
||||
end
|
||||
|
||||
it "doesn't matter if you use a symbol or a string to set a value" do
|
||||
@o[:foo] = "bar"
|
||||
@o['foo'].should == "bar"
|
||||
@o['baz'] = "bang"
|
||||
@o[:baz].should == "bang"
|
||||
end
|
||||
|
||||
it "returns nil when the value is null, null, or not defined" do
|
||||
@o[:foo].should be_nil
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue