therubyrhino 1.72.7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .idea
2
+ doc
3
+ *.gem
4
+ .rvmrc
5
+ .bundle
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "spec/redjs"]
2
+ path = spec/redjs
3
+ url = git@github.com:cowboyd/redjs.git
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,16 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ therubyrhino (1.72.7)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ rspec (1.3.0)
10
+
11
+ PLATFORMS
12
+ java
13
+
14
+ DEPENDENCIES
15
+ rspec
16
+ therubyrhino!
data/History.txt ADDED
@@ -0,0 +1,43 @@
1
+ === 1.72.7
2
+ * N major enhancements:
3
+ * N minor enhancements:
4
+
5
+ === 1.72.6 2009-11-30
6
+ * 2 major enhancements:
7
+ * evaluate an IO object such as a file or an socket input stream
8
+ * load javascript sources directly into the context with the file system
9
+
10
+ === 1.72.5 2009-11-12
11
+ * 2 major enhancements:
12
+ * evaluate javascript with a ruby object as it's scope using Context#open(:with => object)
13
+ * add eval_js() method to Object to evaluate in the context of that object
14
+
15
+ === 1.72.4 2009-11-12
16
+ * 3 major enhancements:
17
+ * automatically wrap/unwrap ruby and javascript arrays
18
+ * automatically convert ruby method objects and Proc objects into javascript functions
19
+ * Make functions defined in javascript callable from ruby
20
+
21
+ === 1.72.3 2009-11-11
22
+ * 4 major enhancements:
23
+ * greatly simplified interface to context by unifying context and scope
24
+ * remove Context#open_std()
25
+ * remove Context#standard
26
+ * remove Context#init_standard_objects
27
+
28
+ === 1.72.2 2009-11-10
29
+ * 1 major enhancement:
30
+ * ability to limit the instruction count for a context
31
+
32
+ === 1.72.1 2009-11-09
33
+ * 4 major enhancements:
34
+ * easily manipulate javascript objects from ruby (NativeObject)
35
+ * make NativeObject Enumerable
36
+ * to_h and to_json for NativeObject
37
+ * embed ruby instances and call methods from javascript
38
+
39
+ === 1.72.0 2009-09-24
40
+
41
+ * 2 major enhancements:
42
+ * evaluate javascript in jruby
43
+ * embed callable ruby objects in javascript
data/README.rdoc ADDED
@@ -0,0 +1,157 @@
1
+ = therubyrhino
2
+
3
+ * http://github.com/cowboyd/therubyrhino
4
+ * irc://irc.freenode.net/therubyrhino
5
+
6
+ == DESCRIPTION:
7
+
8
+ Embed the Mozilla Rhino Javascript interpreter into Ruby
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * Evaluate Javascript from with in Ruby
13
+ * Embed your Ruby objects into the Javascript world
14
+
15
+ == SYNOPSIS:
16
+
17
+ 1. Javascript goes into Ruby
18
+ 1. Ruby Objects goes into Javascript
19
+ 1. Our shark's in the Javascript!
20
+
21
+ require 'rhino'
22
+
23
+ # evaluate some simple javascript
24
+ eval_js "7 * 6" #=> 42
25
+
26
+ # that's quick and dirty, but if you want more control over your
27
+ # environment, use a Context:
28
+ Rhino::Context.open do |cxt|
29
+ cxt['foo'] = "bar"
30
+ cxt.eval('foo') # => "bar"
31
+ end
32
+
33
+ # evaluate a ruby function from javascript
34
+
35
+ Rhino::Context.open do |context|
36
+ context["say"] = lambda {|word, times| word * times}
37
+ context.eval("say("Hello", 3)") #=> HelloHelloHello
38
+ end
39
+
40
+ # embed a ruby object into your javascript environment
41
+
42
+ class MyMath
43
+ def plus(lhs, rhs)
44
+ lhs + rhs
45
+ end
46
+ end
47
+
48
+ Rhino::Context.open do |context|
49
+ context["math"] = MyMath.new
50
+ context.eval("math.plus(20,22)") #=> 42
51
+ end
52
+
53
+ # make a ruby object *be* your javascript environment
54
+ math = MyMath.new
55
+ Rhino::Context.open(:with => math) do |context|
56
+ context.eval("plus(20,22)") #=> 42
57
+ end
58
+
59
+ #or the equivalent
60
+
61
+ math.eval_js("plus(20,22)")
62
+
63
+ # Configure your embedding setup
64
+
65
+ # Make your standard objects (Object, String, etc...) immutable
66
+ Rhino::Context.open(:sealed => true) do |context|
67
+ context.eval("Object.prototype.toString = function() {}") # this is an error!
68
+ end
69
+
70
+ #Turn on Java integration from javascript (probably a bad idea)
71
+ Rhino::Context.open(:java => true) do |context|
72
+ context.eval("java.lang.System.exit()") #it's dangerous!
73
+ end
74
+
75
+ #limit the number of instructions that can be executed in order to prevent
76
+ #rogue scripts
77
+ Rhino::Context.open do |context|
78
+ context.instruction_limit = 100000
79
+ context.eval("while (true);") # => Error!
80
+ end
81
+
82
+ ==== Different ways of loading javascript source
83
+
84
+ In addition to just evaluating strings, you can also use streams such as files.
85
+
86
+ # evaluate bytes read from any File/IO object:
87
+ File.open("mysource.js") do |file|
88
+ eval_js file, "mysource.js"
89
+ end
90
+
91
+ # or load it by filename
92
+ Rhino::Context.open do |context|
93
+ context.load("mysource.js")
94
+ end
95
+
96
+ === Safe by default
97
+
98
+ The Ruby Rhino is designed to let you evaluate javascript as safely as possible unless you tell it to do something more
99
+ dangerous. The default context is a hermetically sealed javascript environment with only the standard javascript objects
100
+ and functions. Nothing from the ruby world is accessible at all.
101
+
102
+ For ruby objects that you explicitly embed into javascript, only the +public+ methods *defined in their classes* are
103
+ exposed by default. E.g.
104
+
105
+ class A
106
+ def a
107
+ "a"
108
+ end
109
+ end
110
+
111
+ class B < A
112
+ def b
113
+ "b"
114
+ end
115
+ end
116
+
117
+
118
+ Rhino::Context.open do |cxt|
119
+ cxt['a'] = A.new
120
+ cxt['b'] = B.new
121
+ cxt.eval("a.a()") # => 'a'
122
+ cxt.eval("b.b()") # => 'b'
123
+ cxt.eval("b.a()") # => 'TypeError: undefined property 'a' is not a function'
124
+ end
125
+
126
+ == REQUIREMENTS:
127
+
128
+ * JRuby >= 1.3.0
129
+
130
+ == INSTALL:
131
+
132
+ * jgem install therubyrhino
133
+
134
+ == LICENSE:
135
+
136
+ (The MIT License)
137
+
138
+ Copyright (c) 2009 Charles Lowell
139
+
140
+ Permission is hereby granted, free of charge, to any person obtaining
141
+ a copy of this software and associated documentation files (the
142
+ 'Software'), to deal in the Software without restriction, including
143
+ without limitation the rights to use, copy, modify, merge, publish,
144
+ distribute, sublicense, and/or sell copies of the Software, and to
145
+ permit persons to whom the Software is furnished to do so, subject to
146
+ the following conditions:
147
+
148
+ The above copyright notice and this permission notice shall be
149
+ included in all copies or substantial portions of the Software.
150
+
151
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
152
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
153
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
154
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
155
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
156
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
157
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler/setup'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ for file in Dir['tasks/*.rake']
5
+ load file
6
+ end
7
+
8
+ desc "remove all build artifacts"
9
+ task :clean do
10
+ sh "rm -rf pkg/"
11
+ end
@@ -0,0 +1,208 @@
1
+ require 'stringio'
2
+
3
+ module Rhino
4
+
5
+ # ==Overview
6
+ # All Javascript must be executed in a context which represents the execution environment in
7
+ # which scripts will run. The environment consists of the standard javascript objects
8
+ # and functions like Object, String, Array, etc... as well as any objects or functions which
9
+ # have been defined in it. e.g.
10
+ #
11
+ # Context.open do |cxt|
12
+ # cxt['num'] = 5
13
+ # cxt.eval('num + 5') #=> 10
14
+ # end
15
+ #
16
+ # == Multiple Contexts.
17
+ # The same object may appear in any number of contexts, but only one context may be executing javascript code
18
+ # in any given thread. If a new context is opened in a thread in which a context is already opened, the second
19
+ # context will "mask" the old context e.g.
20
+ #
21
+ # six = 6
22
+ # Context.open do |cxt|
23
+ # cxt['num'] = 5
24
+ # cxt.eval('num') # => 5
25
+ # Context.open do |cxt|
26
+ # cxt['num'] = 10
27
+ # cxt.eval('num') # => 10
28
+ # cxt.eval('++num') # => 11
29
+ # end
30
+ # cxt.eval('num') # => 5
31
+ # end
32
+ #
33
+ # == Notes
34
+ # While there are many similarities between Rhino::Context and Java::OrgMozillaJavascript::Context, they are not
35
+ # the same thing and should not be confused.
36
+
37
+ class Context
38
+ attr_reader :scope
39
+
40
+ class << self
41
+
42
+ # initalize a new context with a fresh set of standard objects. All operations on the context
43
+ # should be performed in the block that is passed.
44
+ def open(options = {}, &block)
45
+ new(options).open(&block)
46
+ end
47
+
48
+ def eval(javascript)
49
+ new.eval(javascript)
50
+ end
51
+
52
+ end
53
+
54
+ # Create a new javascript environment for executing javascript and ruby code.
55
+ # * <tt>:sealed</tt> - if this is true, then the standard objects such as Object, Function, Array will not be able to be modified
56
+ # * <tt>:with</tt> - use this ruby object as the root scope for all javascript that is evaluated
57
+ # * <tt>:java</tt> - if true, java packages will be accessible from within javascript
58
+ def initialize(options = {}) #:nodoc:
59
+ ContextFactory.new.call do |native|
60
+ @native = native
61
+ @global = NativeObject.new(@native.initStandardObjects(nil, options[:sealed] == true))
62
+ if with = options[:with]
63
+ @scope = To.javascript(with)
64
+ @scope.setParentScope(@global.j)
65
+ else
66
+ @scope = @global
67
+ end
68
+ unless options[:java]
69
+ for package in ["Packages", "java", "javax", "org", "com", "edu", "net"]
70
+ @global.j.delete(package)
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ # Read a value from the global scope of this context
77
+ def [](k)
78
+ @scope[k]
79
+ end
80
+
81
+ # Set a value in the global scope of this context. This value will be visible to all the
82
+ # javascript that is executed in this context.
83
+ def []=(k, v)
84
+ @scope[k] = v
85
+ end
86
+
87
+ # Evaluate a string of javascript in this context:
88
+ # * <tt>source</tt> - the javascript source code to evaluate. This can be either a string or an IO object.
89
+ # * <tt>source_name</tt> - associated name for this source code. Mainly useful for backtraces.
90
+ # * <tt>line_number</tt> - associate this number with the first line of executing source. Mainly useful for backtraces
91
+ def eval(source, source_name = "<eval>", line_number = 1)
92
+ self.open do
93
+ begin
94
+ scope = To.javascript(@scope)
95
+ if IO === source || StringIO === source
96
+ result = @native.evaluateReader(scope, IOReader.new(source), source_name, line_number, nil)
97
+ else
98
+ result = @native.evaluateString(scope, source.to_s, source_name, line_number, nil)
99
+ end
100
+ To.ruby result
101
+ rescue J::RhinoException => e
102
+ raise Rhino::JavascriptError, e
103
+ end
104
+ end
105
+ end
106
+
107
+ def evaluate(*args) # :nodoc:
108
+ self.eval(*args)
109
+ end
110
+
111
+ # Read the contents of <tt>filename</tt> and evaluate it as javascript. Returns the result of evaluating the
112
+ # javascript. e.g.
113
+ #
114
+ # Context.open do |cxt|
115
+ # cxt.load("path/to/some/lib.js")
116
+ # end
117
+ #
118
+ def load(filename)
119
+ File.open(filename) do |file|
120
+ evaluate file, filename, 1
121
+ end
122
+ end
123
+
124
+ # Set the maximum number of instructions that this context will execute.
125
+ # If this instruction limit is exceeded, then a Rhino::RunawayScriptError
126
+ # will be raised
127
+ def instruction_limit=(limit)
128
+ @native.setInstructionObserverThreshold(limit);
129
+ @native.factory.instruction_limit = limit
130
+ end
131
+
132
+ # Set the optimization level that this context will use. This is sometimes necessary
133
+ # in Rhino, if the bytecode size of the compiled javascript exceeds the 64KB limit.
134
+ # By using the -1 optimization level, you tell Rhino to run in interpretative mode,
135
+ # taking a hit to performance but escaping the Java bytecode limit.
136
+ def optimization_level=(level)
137
+ @native.setOptimizationLevel(level)
138
+ end
139
+
140
+ # Enter this context for operations. Some methods such as eval() will
141
+ # fail unless this context is open
142
+ def open
143
+ begin
144
+ @native.factory.enterContext(@native)
145
+ yield self
146
+ ensure
147
+ J::Context.exit()
148
+ end if block_given?
149
+ end
150
+
151
+ end
152
+
153
+ class IOReader < Java::JavaIo::Reader #:nodoc:
154
+
155
+ def initialize(io)
156
+ @io = io
157
+ end
158
+
159
+ def read(charbuffer, offset, length)
160
+ begin
161
+ str = @io.read(length)
162
+ if str.nil?
163
+ return -1
164
+ else
165
+ jstring = Java::JavaLang::String.new(str)
166
+ for i in 0 .. jstring.length - 1
167
+ charbuffer[i + offset] = jstring.charAt(i)
168
+ end
169
+ return jstring.length
170
+ end
171
+ rescue StandardError => e
172
+ raise Java::JavaIo::IOException.new, "Failed reading from ruby IO object"
173
+ end
174
+ end
175
+ end
176
+
177
+ class ContextFactory < J::ContextFactory # :nodoc:
178
+
179
+ def observeInstructionCount(cxt, count)
180
+ raise RunawayScriptError, "script exceeded allowable instruction count" if count > @limit
181
+ end
182
+
183
+ def instruction_limit=(count)
184
+ @limit = count
185
+ end
186
+ end
187
+
188
+ class ContextError < StandardError # :nodoc:
189
+
190
+ end
191
+
192
+ class JavascriptError < StandardError # :nodoc:
193
+ def initialize(native)
194
+ @native = native
195
+ end
196
+
197
+ def message
198
+ @native.cause.details
199
+ end
200
+
201
+ def javascript_backtrace
202
+ @native.getScriptStackTrace()
203
+ end
204
+ end
205
+
206
+ class RunawayScriptError < StandardError # :nodoc:
207
+ end
208
+ end
data/lib/rhino/java.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'java'
2
+ require 'rhino/rhino-1.7R2.jar'
3
+
4
+ module Rhino
5
+ # This module contains all the native Rhino objects implemented in Java
6
+ # e.g.
7
+ # Rhino::J::NativeObject # => org.mozilla.javascript.NativeObject
8
+ module J
9
+ import "org.mozilla.javascript"
10
+
11
+ module Regexp
12
+ import "org.mozilla.javascript.regexp"
13
+ end
14
+ end
15
+ end
16
+
17
+ unless Object.method_defined?(:tap)
18
+ class Object #:nodoc:
19
+ def tap
20
+ yield self
21
+ self
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+
2
+ module Rhino
3
+
4
+ # Wraps a function that has been defined in Javascript so that it can
5
+ # be referenced and called from javascript. e.g.
6
+ #
7
+ # plus = Rhino::Context.open do |cx|
8
+ # cx.eval('function(lhs, rhs) {return lhs + rhs}')
9
+ # end
10
+ # plus.call(5,4) # => 9
11
+ #
12
+ class NativeFunction < NativeObject
13
+ def call(*args)
14
+ begin
15
+ cxt = J::Context.enter()
16
+ scope = @j.getParentScope() || cxt.initStandardObjects()
17
+ @j.call(cxt, scope, scope, args.map {|o| To.javascript(o)})
18
+ ensure
19
+ J::Context.exit()
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,71 @@
1
+
2
+ module Rhino
3
+ # Wraps a javascript object and makes its properties available from ruby.
4
+ class NativeObject
5
+ include Enumerable
6
+
7
+ # The native java object wrapped by this NativeObject. This will generally
8
+ # be an instance of org.mozilla.javascript.Scriptable
9
+ attr_reader :j
10
+
11
+ def initialize(j=nil) # :nodoc:
12
+ @j = j || J::NativeObject.new
13
+ end
14
+
15
+ # get a property from this javascript object, where +k+ is a string or symbol
16
+ # corresponding to the property name
17
+ # e.g.
18
+ # jsobject = Context.open do |cxt|
19
+ # cxt.eval('({foo: 'bar', 'Take me to': 'a funky town'})')
20
+ # end
21
+ #
22
+ # jsobject[:foo] # => 'bar'
23
+ # jsobject['foo'] # => 'bar'
24
+ # jsobject['Take me to'] # => 'a funky town'
25
+ def [](k)
26
+ To.ruby J::ScriptableObject.getProperty(@j,k.to_s)
27
+ end
28
+
29
+ # set a property on the javascript object, where +k+ is a string or symbol corresponding
30
+ # to the property name, and +v+ is the value to set. e.g.
31
+ #
32
+ # jsobject = eval_js "new Object()"
33
+ # jsobject['foo'] = 'bar'
34
+ # Context.open(:with => jsobject) do |cxt|
35
+ # cxt.eval('foo') # => 'bar'
36
+ # end
37
+
38
+ def []=(k,v)
39
+ J::ScriptableObject.putProperty(@j, k.to_s, To.javascript(v))
40
+ end
41
+
42
+ # enumerate the key value pairs contained in this javascript object. e.g.
43
+ #
44
+ # eval_js("{foo: 'bar', baz: 'bang'}").each do |key,value|
45
+ # puts "#{key} -> #{value} "
46
+ # end
47
+ #
48
+ # outputs foo -> bar baz -> bang
49
+ def each
50
+ for id in @j.getAllIds() do
51
+ yield id,@j.get(id,@j)
52
+ end
53
+ end
54
+
55
+ # Converts the native object to a hash. This isn't really a stretch since it's
56
+ # pretty much a hash in the first place.
57
+ def to_h
58
+ {}.tap do |h|
59
+ each do |k,v|
60
+ v = To.ruby(v)
61
+ h[k] = self.class === v ? v.to_h : v
62
+ end
63
+ end
64
+ end
65
+
66
+ # Convert this javascript object into a json string.
67
+ def to_json(*args)
68
+ to_h.to_json(*args)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,8 @@
1
+
2
+ class Object
3
+ def eval_js(source, options = {})
4
+ Rhino::Context.open(options.merge(:with => self)) do |cxt|
5
+ cxt.eval(source)
6
+ end
7
+ end
8
+ end
Binary file
@@ -0,0 +1,14 @@
1
+
2
+ module Rhino
3
+ class RubyFunction < J::BaseFunction
4
+
5
+ def initialize(callable)
6
+ super()
7
+ @callable = callable
8
+ end
9
+
10
+ def call(cxt, scope, this, args)
11
+ To.javascript @callable.call(*args.map {|a| To.ruby(a)})
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,65 @@
1
+
2
+ module Rhino
3
+ class RubyObject < J::ScriptableObject
4
+ include J::Wrapper
5
+
6
+ def initialize(object)
7
+ super()
8
+ @ruby = object
9
+ end
10
+
11
+ def unwrap
12
+ @ruby
13
+ end
14
+
15
+ def getClassName()
16
+ @ruby.class.name
17
+ end
18
+
19
+ def getPrototype()
20
+ Prototype::Generic
21
+ end
22
+
23
+ def getIds()
24
+ puts "getIds()"
25
+ require 'java'
26
+ @ruby.public_methods(false).map {|m| m.gsub(/(.)_(.)/) {::JavaLang::String.new("#{$1}#{$2.upcase}")}}.tap {|ids| puts "ids: #{ids.inspect}"}.to_java
27
+ end
28
+
29
+ def to_s
30
+ "[Native #{@ruby.class.name}]"
31
+ end
32
+
33
+ alias_method :prototype, :getPrototype
34
+
35
+
36
+ class Prototype < J::ScriptableObject
37
+
38
+ def get(name, start)
39
+ robject = To.ruby(start)
40
+ if name == "toString"
41
+ return RubyFunction.new(lambda { "[Ruby #{robject.class.name}]"})
42
+ end
43
+ rb_name = name.gsub(/([a-z])([A-Z])/) {"#{$1}_#{$2.downcase}"}
44
+ if (robject.public_methods(false).include?(rb_name))
45
+ method = robject.method(rb_name)
46
+ if method.arity == 0
47
+ To.javascript(method.call)
48
+ else
49
+ RubyFunction.new(method)
50
+ end
51
+ else
52
+ super(name, start)
53
+ end
54
+ end
55
+
56
+ def has(name, start)
57
+ rb_name = name.gsub(/([a-z])([A-Z])/) {"#{$1}_#{$2.downcase}"}
58
+ To.ruby(start).public_methods(false).respond_to?(rb_name) ? true : super(name,start)
59
+ end
60
+
61
+ Generic = new
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module Rhino
3
+ VERSION = "1.72.7"
4
+ end
@@ -0,0 +1,36 @@
1
+
2
+ module Rhino
3
+ module To
4
+ JS_UNDEF = [J::Scriptable::NOT_FOUND, J::Undefined]
5
+
6
+ def ruby(object)
7
+ case object
8
+ when *JS_UNDEF then nil
9
+ when J::Wrapper then object.unwrap
10
+ when J::NativeArray then array(object)
11
+ when J::Regexp::NativeRegExp then object
12
+ when J::Function then NativeFunction.new(object)
13
+ when J::Scriptable then NativeObject.new(object)
14
+ else object
15
+ end
16
+ end
17
+
18
+ def javascript(object)
19
+ case object
20
+ when String,Numeric then object
21
+ when TrueClass,FalseClass then object
22
+ when Array then J::NativeArray.new(object.to_java)
23
+ when Proc,Method then RubyFunction.new(object)
24
+ when NativeObject then object.j
25
+ when J::Scriptable then object
26
+ else RubyObject.new(object)
27
+ end
28
+ end
29
+
30
+ def array(native)
31
+ native.length.times.map {|i| ruby(native.get(i,native))}
32
+ end
33
+
34
+ module_function :ruby, :javascript, :array
35
+ end
36
+ end
data/lib/rhino.rb ADDED
@@ -0,0 +1,15 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+
5
+ module Rhino
6
+ VERSION = '1.72.7'
7
+ require 'rhino/java'
8
+ require 'rhino/object'
9
+ require 'rhino/context'
10
+ require 'rhino/wormhole'
11
+ require 'rhino/ruby_object'
12
+ require 'rhino/ruby_function'
13
+ require 'rhino/native_object'
14
+ require 'rhino/native_function'
15
+ end
@@ -0,0 +1,5 @@
1
+
2
+ require File.dirname(__FILE__) + '/spec_helper.rb'
3
+
4
+ include Rhino
5
+
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include Rhino
4
+
5
+ describe Rhino::Context do
6
+
7
+ describe "Initalizing Standard Javascript Objects" do
8
+ it "provides the standard objects without java integration by default" do
9
+ Context.open do |cxt|
10
+ cxt["Object"].should_not be_nil
11
+ cxt["Math"].should_not be_nil
12
+ cxt["String"].should_not be_nil
13
+ cxt["Function"].should_not be_nil
14
+ cxt["Packages"].should be_nil
15
+ cxt["java"].should be_nil
16
+ cxt["org"].should be_nil
17
+ cxt["com"].should be_nil
18
+ end
19
+ end
20
+
21
+ it "provides unsealed standard object by default" do
22
+ Context.open do |cxt|
23
+ cxt.eval("Object.foop = 'blort'")
24
+ cxt["Object"]['foop'].should == 'blort'
25
+ end
26
+ end
27
+
28
+ it "allows you to seal the standard objects so that they cannot be modified" do
29
+ Context.open(:sealed => true) do |cxt|
30
+ lambda {
31
+ cxt.eval("Object.foop = 'blort'")
32
+ }.should raise_error(Rhino::RhinoError)
33
+
34
+ lambda {
35
+ cxt.eval("Object.prototype.toString = function() {}")
36
+ }.should raise_error(Rhino::RhinoError)
37
+ end
38
+ end
39
+
40
+ it "allows java integration to be turned on when initializing standard objects" do
41
+ Context.open(:java => true) do |cxt|
42
+ cxt["Packages"].should_not be_nil
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,135 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ include Rhino
4
+
5
+ describe Rhino::To do
6
+ describe "ruby translation" do
7
+ it "converts javascript NOT_FOUND to ruby nil" do
8
+ To.ruby(J::Scriptable::NOT_FOUND).should be_nil
9
+ end
10
+
11
+ it "converts javascript arrays to ruby arrays" do
12
+ J::NativeObject.new.tap do |o|
13
+ To.ruby(o).tap do |ruby_object|
14
+ ruby_object.should respond_to(:j)
15
+ ruby_object.j.should be(o)
16
+ end
17
+ end
18
+ end
19
+
20
+ it "wraps native javascript arrays into a ruby NativeArray wrapper" do
21
+ J::NativeArray.new([1,2,4].to_java).tap do |a|
22
+ To.ruby(a).should == [1,2,4]
23
+ end
24
+ end
25
+
26
+ it "wraps native javascript functions into a ruby NativeFunction wrapper" do
27
+
28
+ c = Class.new(J::BaseFunction).class_eval do
29
+ self.tap do
30
+ def call(cxt, scope, this, args)
31
+ args.join(',')
32
+ end
33
+ end
34
+ end
35
+
36
+ c.new.tap do |f|
37
+ To.ruby(f).tap do |o|
38
+ o.should_not be_nil
39
+ o.should be_kind_of(NativeObject)
40
+ o.should be_respond_to(:call)
41
+ o.call(1,2,3).should == "1,2,3"
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ it "leaves native ruby objects alone" do
48
+ Object.new.tap do |o|
49
+ To.ruby(o).should be(o)
50
+ end
51
+ end
52
+
53
+ it "it unwraps wrapped java objects" do
54
+ Context.open do |cx|
55
+ scope = cx.scope
56
+ Java::JavaLang::String.new("Hello World").tap do |str|
57
+ J::NativeJavaObject.new(scope.j, str, str.getClass()).tap do |o|
58
+ To.ruby(o).should == "Hello World"
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ it "converts javascript undefined into nil" do
65
+ To.ruby(J::Undefined.instance).should be_nil
66
+ end
67
+ end
68
+
69
+ describe "javascript translation" do
70
+
71
+ it "passes primitives through to the js layer to let jruby and rhino do he thunking" do
72
+ to(1).should be(1)
73
+ to(2.5).should == 2.5
74
+ to("foo").should == "foo"
75
+ to(true).should be(true)
76
+ to(false).should be(false)
77
+ end
78
+
79
+ it "unwraps wrapped ruby objects before passing them to the javascript runtime" do
80
+ J::NativeObject.new.tap do |o|
81
+ To.javascript(NativeObject.new(o)).should be(o)
82
+ end
83
+ end
84
+
85
+ it "leaves native javascript objects alone" do
86
+ J::NativeObject.new.tap do |o|
87
+ To.javascript(o).should be(o)
88
+ end
89
+ end
90
+
91
+ it "converts ruby arrays into javascript arrays" do
92
+ To.javascript([1,2,3,4,5]).tap do |a|
93
+ a.should be_kind_of(J::NativeArray)
94
+ a.get(0,a).should be(1)
95
+ a.get(1,a).should be(2)
96
+ a.get(2,a).should be(3)
97
+ a.get(3,a).should be(4)
98
+ end
99
+ end
100
+
101
+ it "converts procs and methods into native functions" do
102
+ to(lambda {|lhs,rhs| lhs * rhs}).tap do |f|
103
+ f.should be_kind_of(J::Function)
104
+ f.call(nil, nil, nil, [7,6]).should be(42)
105
+ end
106
+ to("foo,bar,baz".method(:split)).tap do |m|
107
+ m.should be_kind_of(J::Function)
108
+ To.ruby(m.call(nil, nil, nil, ',')).should == ['foo', 'bar', 'baz']
109
+ end
110
+ end
111
+
112
+ it "creates a prototype for the object based on its class" do
113
+ Class.new.tap do |c|
114
+ c.class_eval do
115
+ def foo(one, two)
116
+ "1: #{one}, 2: #{two}"
117
+ end
118
+ end
119
+
120
+ To.javascript(c.new).tap do |o|
121
+ o.should be_kind_of(RubyObject)
122
+ o.prototype.tap do |p|
123
+ p.should_not be_nil
124
+ p.get("foo", p).should_not be_nil
125
+ p.get("toString", p).should_not be_nil
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ def to(object)
133
+ To.javascript(object)
134
+ end
135
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'rhino'
data/tasks/jruby.rake ADDED
@@ -0,0 +1,7 @@
1
+ if RUBY_PLATFORM =~ /java/
2
+ require 'java'
3
+ else
4
+ puts "Java RubyGem only! You are not running within jruby."
5
+ puts "Try: jruby -S rake #{ARGV.join(' ')}"
6
+ exit(1)
7
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,13 @@
1
+ begin
2
+ require 'spec'
3
+ require 'spec/rake/spectask'
4
+ desc "Run the specs under spec/models"
5
+ Spec::Rake::SpecTask.new do |t|
6
+ t.spec_opts = ['--options', "spec/spec.opts"]
7
+ t.spec_files = FileList['spec/**/*_spec.rb']
8
+ end
9
+ rescue LoadError
10
+ desc "bundle install to run rspecs"
11
+ task :spec
12
+ end
13
+
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rhino/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{therubyrhino}
7
+ s.version = Rhino::VERSION
8
+ s.authors = ["Charles Lowell"]
9
+ s.description = %q{Call javascript code and manipulate javascript objects from ruby. Call ruby code and manipulate ruby objects from javascript.}
10
+ s.email = %q{cowboyd@thefrontside.net}
11
+ s.extra_rdoc_files = ["README.rdoc"]
12
+ s.files = `git ls-files`.split("\n")
13
+ s.homepage = %q{http://github.com/cowboyd/therubyrhino}
14
+ s.require_paths = ["lib"]
15
+ s.rubyforge_project = %q{therubyrhino}
16
+ s.summary = %q{Embed the Rhino JavaScript interpreter into JRuby}
17
+
18
+ s.add_development_dependency "rspec"
19
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: therubyrhino
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 72
8
+ - 7
9
+ version: 1.72.7
10
+ platform: ruby
11
+ authors:
12
+ - Charles Lowell
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-10 00:00:00 -06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ version_requirements: &id001 !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ segments:
27
+ - 0
28
+ version: "0"
29
+ requirement: *id001
30
+ prerelease: false
31
+ type: :development
32
+ description: Call javascript code and manipulate javascript objects from ruby. Call ruby code and manipulate ruby objects from javascript.
33
+ email: cowboyd@thefrontside.net
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - README.rdoc
40
+ files:
41
+ - .gitignore
42
+ - .gitmodules
43
+ - Gemfile
44
+ - Gemfile.lock
45
+ - History.txt
46
+ - README.rdoc
47
+ - Rakefile
48
+ - lib/rhino.rb
49
+ - lib/rhino/context.rb
50
+ - lib/rhino/java.rb
51
+ - lib/rhino/native_function.rb
52
+ - lib/rhino/native_object.rb
53
+ - lib/rhino/object.rb
54
+ - lib/rhino/rhino-1.7R2.jar
55
+ - lib/rhino/ruby_function.rb
56
+ - lib/rhino/ruby_object.rb
57
+ - lib/rhino/version.rb
58
+ - lib/rhino/wormhole.rb
59
+ - spec/redjs_helper.rb
60
+ - spec/rhino/context_spec.rb
61
+ - spec/rhino/wormhole_spec.rb
62
+ - spec/spec.opts
63
+ - spec/spec_helper.rb
64
+ - tasks/jruby.rake
65
+ - tasks/rspec.rake
66
+ - therubyrhino.gemspec
67
+ has_rdoc: true
68
+ homepage: http://github.com/cowboyd/therubyrhino
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options: []
73
+
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project: therubyrhino
93
+ rubygems_version: 1.3.6
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Embed the Rhino JavaScript interpreter into JRuby
97
+ test_files: []
98
+