execjs 1.3.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -11,13 +11,8 @@ ExecJS supports these runtimes:
11
11
  embedded within Ruby
12
12
  * [therubyrhino](https://github.com/cowboyd/therubyrhino) - Mozilla
13
13
  Rhino embedded within JRuby
14
- * [Johnson](https://github.com/jbarnette/johnson) - Mozilla
15
- SpiderMonkey embedded within Ruby
16
- * [Mustang](https://github.com/nu7hatch/mustang) - Mustang V8
17
- embedded within Ruby
18
14
  * [Node.js](http://nodejs.org/)
19
15
  * Apple JavaScriptCore - Included with Mac OS X
20
- * [Mozilla SpiderMonkey](http://www.mozilla.org/js/spidermonkey/)
21
16
  * [Microsoft Windows Script Host](http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx) (JScript)
22
17
 
23
18
  A short example:
@@ -1,5 +1,7 @@
1
+ require "execjs/runtime"
2
+
1
3
  module ExecJS
2
- class DisabledRuntime
4
+ class DisabledRuntime < Runtime
3
5
  def name
4
6
  "Disabled"
5
7
  end
@@ -16,6 +18,10 @@ module ExecJS
16
18
  raise Error, "ExecJS disabled"
17
19
  end
18
20
 
21
+ def deprecated?
22
+ true
23
+ end
24
+
19
25
  def available?
20
26
  true
21
27
  end
@@ -0,0 +1,33 @@
1
+ module ExecJS
2
+ # Encodes strings as UTF-8
3
+ module Encoding
4
+ if "".respond_to?(:encode)
5
+ if RUBY_ENGINE == 'jruby' || RUBY_ENGINE == 'rbx'
6
+ # workaround for jruby bug http://jira.codehaus.org/browse/JRUBY-6588
7
+ # workaround for rbx bug https://github.com/rubinius/rubinius/issues/1729
8
+ def encode(string)
9
+ if string.encoding.name == 'ASCII-8BIT'
10
+ data = string.dup
11
+ data.force_encoding('UTF-8')
12
+
13
+ unless data.valid_encoding?
14
+ raise ::Encoding::UndefinedConversionError, "Could not encode ASCII-8BIT data #{string.dump} as UTF-8"
15
+ end
16
+ else
17
+ data = string.encode('UTF-8')
18
+ end
19
+ data
20
+ end
21
+ else
22
+ def encode(string)
23
+ string.encode('UTF-8')
24
+ end
25
+ end
26
+ else
27
+ # Define no-op on 1.8
28
+ def encode(string)
29
+ string
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,27 +1,27 @@
1
- require "multi_json"
2
1
  require "shellwords"
3
2
  require "tempfile"
3
+ require "execjs/runtime"
4
4
 
5
5
  module ExecJS
6
- class ExternalRuntime
7
- class Context
6
+ class ExternalRuntime < Runtime
7
+ class Context < Runtime::Context
8
8
  def initialize(runtime, source = "")
9
- source = source.encode('UTF-8') if source.respond_to?(:encode)
9
+ source = encode(source)
10
10
 
11
11
  @runtime = runtime
12
12
  @source = source
13
13
  end
14
14
 
15
15
  def eval(source, options = {})
16
- source = source.encode('UTF-8') if source.respond_to?(:encode)
16
+ source = encode(source)
17
17
 
18
18
  if /\S/ =~ source
19
- exec("return eval(#{json_encode("(#{source})")})")
19
+ exec("return eval(#{JSON.encode("(#{source})")})")
20
20
  end
21
21
  end
22
22
 
23
23
  def exec(source, options = {})
24
- source = source.encode('UTF-8') if source.respond_to?(:encode)
24
+ source = encode(source)
25
25
  source = "#{@source}\n#{source}" if @source
26
26
 
27
27
  compile_to_tempfile(source) do |file|
@@ -30,7 +30,7 @@ module ExecJS
30
30
  end
31
31
 
32
32
  def call(identifier, *args)
33
- eval "#{identifier}.apply(this, #{json_encode(args)})"
33
+ eval "#{identifier}.apply(this, #{JSON.encode(args)})"
34
34
  end
35
35
 
36
36
  protected
@@ -50,7 +50,7 @@ module ExecJS
50
50
  end
51
51
  output.sub!('#{encoded_source}') do
52
52
  encoded_source = encode_unicode_codepoints(source)
53
- json_encode("(function(){ #{encoded_source} })()")
53
+ JSON.encode("(function(){ #{encoded_source} })()")
54
54
  end
55
55
  output.sub!('#{json2_source}') do
56
56
  IO.read(ExecJS.root + "/support/json2.js")
@@ -59,7 +59,7 @@ module ExecJS
59
59
  end
60
60
 
61
61
  def extract_result(output)
62
- status, value = output.empty? ? [] : json_decode(output)
62
+ status, value = output.empty? ? [] : JSON.decode(output)
63
63
  if status == "ok"
64
64
  value
65
65
  elsif value =~ /SyntaxError:/
@@ -84,24 +84,6 @@ module ExecJS
84
84
  end
85
85
  end
86
86
  end
87
-
88
- if MultiJson.respond_to?(:dump)
89
- def json_decode(obj)
90
- MultiJson.load(obj)
91
- end
92
-
93
- def json_encode(obj)
94
- MultiJson.dump(obj)
95
- end
96
- else
97
- def json_decode(obj)
98
- MultiJson.decode(obj)
99
- end
100
-
101
- def json_encode(obj)
102
- MultiJson.encode(obj)
103
- end
104
- end
105
87
  end
106
88
 
107
89
  attr_reader :name
@@ -113,27 +95,19 @@ module ExecJS
113
95
  @test_args = options[:test_args]
114
96
  @test_match = options[:test_match]
115
97
  @encoding = options[:encoding]
98
+ @deprecated = !!options[:deprecated]
116
99
  @binary = nil
117
100
  end
118
101
 
119
- def exec(source)
120
- context = Context.new(self)
121
- context.exec(source)
122
- end
123
-
124
- def eval(source)
125
- context = Context.new(self)
126
- context.eval(source)
127
- end
128
-
129
- def compile(source)
130
- Context.new(self, source)
131
- end
132
-
133
102
  def available?
103
+ require "execjs/json"
134
104
  binary ? true : false
135
105
  end
136
106
 
107
+ def deprecated?
108
+ @deprecated
109
+ end
110
+
137
111
  private
138
112
  def binary
139
113
  @binary ||= locate_binary
@@ -195,7 +169,7 @@ module ExecJS
195
169
  def sh(command)
196
170
  output, options = nil, {}
197
171
  options[:external_encoding] = @encoding if @encoding
198
- options[:internal_encoding] = Encoding.default_internal || 'UTF-8'
172
+ options[:internal_encoding] = ::Encoding.default_internal || 'UTF-8'
199
173
  IO.popen(command, options) { |f| output = f.read }
200
174
  output
201
175
  end
@@ -1,13 +1,17 @@
1
+ require "execjs/runtime"
2
+
1
3
  module ExecJS
2
- class JohnsonRuntime
3
- class Context
4
- def initialize(source = "")
4
+ class JohnsonRuntime < Runtime
5
+ class Context < Runtime::Context
6
+ def initialize(runtime, source = "")
7
+ source = encode(source)
8
+
5
9
  @runtime = Johnson::Runtime.new
6
10
  @runtime.evaluate(source)
7
11
  end
8
12
 
9
13
  def exec(source, options = {})
10
- source = source.encode('UTF-8') if source.respond_to?(:encode)
14
+ source = encode(source)
11
15
 
12
16
  if /\S/ =~ source
13
17
  eval "(function(){#{source}})()", options
@@ -15,7 +19,7 @@ module ExecJS
15
19
  end
16
20
 
17
21
  def eval(source, options = {})
18
- source = source.encode('UTF-8') if source.respond_to?(:encode)
22
+ source = encode(source)
19
23
 
20
24
  if /\S/ =~ source
21
25
  unbox @runtime.evaluate("(#{source})")
@@ -88,25 +92,15 @@ module ExecJS
88
92
  "Johnson (SpiderMonkey)"
89
93
  end
90
94
 
91
- def exec(source)
92
- context = Context.new
93
- context.exec(source)
94
- end
95
-
96
- def eval(source)
97
- context = Context.new
98
- context.eval(source)
99
- end
100
-
101
- def compile(source)
102
- Context.new(source)
103
- end
104
-
105
95
  def available?
106
96
  require "johnson"
107
97
  true
108
98
  rescue LoadError
109
99
  false
110
100
  end
101
+
102
+ def deprecated?
103
+ true
104
+ end
111
105
  end
112
106
  end
@@ -0,0 +1,23 @@
1
+ require "multi_json"
2
+
3
+ module ExecJS
4
+ module JSON
5
+ if MultiJson.respond_to?(:dump)
6
+ def self.decode(obj)
7
+ MultiJson.load(obj)
8
+ end
9
+
10
+ def self.encode(obj)
11
+ MultiJson.dump(obj)
12
+ end
13
+ else
14
+ def self.decode(obj)
15
+ MultiJson.decode(obj)
16
+ end
17
+
18
+ def self.encode(obj)
19
+ MultiJson.encode(obj)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,15 +1,17 @@
1
+ require "execjs/runtime"
2
+
1
3
  module ExecJS
2
- class MustangRuntime
3
- class Context
4
- def initialize(source = "")
5
- source = source.encode('UTF-8') if source.respond_to?(:encode)
4
+ class MustangRuntime < Runtime
5
+ class Context < Runtime::Context
6
+ def initialize(runtime, source = "")
7
+ source = encode(source)
6
8
 
7
9
  @v8_context = ::Mustang::Context.new
8
10
  @v8_context.eval(source)
9
11
  end
10
12
 
11
13
  def exec(source, options = {})
12
- source = source.encode('UTF-8') if source.respond_to?(:encode)
14
+ source = encode(source)
13
15
 
14
16
  if /\S/ =~ source
15
17
  eval "(function(){#{source}})()", options
@@ -17,7 +19,7 @@ module ExecJS
17
19
  end
18
20
 
19
21
  def eval(source, options = {})
20
- source = source.encode('UTF-8') if source.respond_to?(:encode)
22
+ source = encode(source)
21
23
 
22
24
  if /\S/ =~ source
23
25
  unbox @v8_context.eval("(#{source})")
@@ -60,25 +62,15 @@ module ExecJS
60
62
  "Mustang (V8)"
61
63
  end
62
64
 
63
- def exec(source)
64
- context = Context.new
65
- context.exec(source)
66
- end
67
-
68
- def eval(source)
69
- context = Context.new
70
- context.eval(source)
71
- end
72
-
73
- def compile(source)
74
- Context.new(source)
75
- end
76
-
77
65
  def available?
78
66
  require "mustang"
79
67
  true
80
68
  rescue LoadError
81
69
  false
82
70
  end
71
+
72
+ def deprecated?
73
+ true
74
+ end
83
75
  end
84
76
  end
@@ -1,8 +1,10 @@
1
+ require "execjs/runtime"
2
+
1
3
  module ExecJS
2
- class RubyRacerRuntime
3
- class Context
4
- def initialize(source = "")
5
- source = source.encode('UTF-8') if source.respond_to?(:encode)
4
+ class RubyRacerRuntime < Runtime
5
+ class Context < Runtime::Context
6
+ def initialize(runtime, source = "")
7
+ source = encode(source)
6
8
 
7
9
  lock do
8
10
  @v8_context = ::V8::Context.new
@@ -11,7 +13,7 @@ module ExecJS
11
13
  end
12
14
 
13
15
  def exec(source, options = {})
14
- source = source.encode('UTF-8') if source.respond_to?(:encode)
16
+ source = encode(source)
15
17
 
16
18
  if /\S/ =~ source
17
19
  eval "(function(){#{source}})()", options
@@ -19,7 +21,7 @@ module ExecJS
19
21
  end
20
22
 
21
23
  def eval(source, options = {})
22
- source = source.encode('UTF-8') if source.respond_to?(:encode)
24
+ source = encode(source)
23
25
 
24
26
  if /\S/ =~ source
25
27
  lock do
@@ -27,9 +29,9 @@ module ExecJS
27
29
  unbox @v8_context.eval("(#{source})")
28
30
  rescue ::V8::JSError => e
29
31
  if e.value["name"] == "SyntaxError"
30
- raise RuntimeError, e.message
32
+ raise RuntimeError, e.value.to_s
31
33
  else
32
- raise ProgramError, e.message
34
+ raise ProgramError, e.value.to_s
33
35
  end
34
36
  end
35
37
  end
@@ -42,9 +44,9 @@ module ExecJS
42
44
  unbox @v8_context.eval(properties).call(*args)
43
45
  rescue ::V8::JSError => e
44
46
  if e.value["name"] == "SyntaxError"
45
- raise RuntimeError, e.message
47
+ raise RuntimeError, e.value.to_s
46
48
  else
47
- raise ProgramError, e.message
49
+ raise ProgramError, e.value.to_s
48
50
  end
49
51
  end
50
52
  end
@@ -93,20 +95,6 @@ module ExecJS
93
95
  "therubyracer (V8)"
94
96
  end
95
97
 
96
- def exec(source)
97
- context = Context.new
98
- context.exec(source)
99
- end
100
-
101
- def eval(source)
102
- context = Context.new
103
- context.eval(source)
104
- end
105
-
106
- def compile(source)
107
- Context.new(source)
108
- end
109
-
110
98
  def available?
111
99
  require "v8"
112
100
  true
@@ -1,8 +1,10 @@
1
+ require "execjs/runtime"
2
+
1
3
  module ExecJS
2
- class RubyRhinoRuntime
3
- class Context
4
- def initialize(source = "")
5
- source = source.encode('UTF-8') if source.respond_to?(:encode)
4
+ class RubyRhinoRuntime < Runtime
5
+ class Context < Runtime::Context
6
+ def initialize(runtime, source = "")
7
+ source = encode(source)
6
8
 
7
9
  @rhino_context = ::Rhino::Context.new
8
10
  fix_memory_limit! @rhino_context
@@ -10,7 +12,7 @@ module ExecJS
10
12
  end
11
13
 
12
14
  def exec(source, options = {})
13
- source = source.encode('UTF-8') if source.respond_to?(:encode)
15
+ source = encode(source)
14
16
 
15
17
  if /\S/ =~ source
16
18
  eval "(function(){#{source}})()", options
@@ -18,13 +20,13 @@ module ExecJS
18
20
  end
19
21
 
20
22
  def eval(source, options = {})
21
- source = source.encode('UTF-8') if source.respond_to?(:encode)
23
+ source = encode(source)
22
24
 
23
25
  if /\S/ =~ source
24
26
  unbox @rhino_context.eval("(#{source})")
25
27
  end
26
- rescue ::Rhino::JavascriptError => e
27
- if e.message == "syntax error"
28
+ rescue ::Rhino::JSError => e
29
+ if e.message =~ /^syntax error/
28
30
  raise RuntimeError, e.message
29
31
  else
30
32
  raise ProgramError, e.message
@@ -33,7 +35,7 @@ module ExecJS
33
35
 
34
36
  def call(properties, *args)
35
37
  unbox @rhino_context.eval(properties).call(*args)
36
- rescue ::Rhino::JavascriptError => e
38
+ rescue ::Rhino::JSError => e
37
39
  if e.message == "syntax error"
38
40
  raise RuntimeError, e.message
39
41
  else
@@ -42,13 +44,13 @@ module ExecJS
42
44
  end
43
45
 
44
46
  def unbox(value)
45
- case value = ::Rhino::To.ruby(value)
46
- when ::Rhino::NativeFunction
47
+ case value = ::Rhino::to_ruby(value)
48
+ when Java::OrgMozillaJavascript::NativeFunction
47
49
  nil
48
- when ::Rhino::NativeObject
50
+ when Java::OrgMozillaJavascript::NativeObject
49
51
  value.inject({}) do |vs, (k, v)|
50
52
  case v
51
- when ::Rhino::NativeFunction, ::Rhino::J::Function
53
+ when Java::OrgMozillaJavascript::NativeFunction, ::Rhino::JS::Function
52
54
  nil
53
55
  else
54
56
  vs[k] = unbox(v)
@@ -77,20 +79,6 @@ module ExecJS
77
79
  "therubyrhino (Rhino)"
78
80
  end
79
81
 
80
- def exec(source)
81
- context = Context.new
82
- context.exec(source)
83
- end
84
-
85
- def eval(source)
86
- context = Context.new
87
- context.eval(source)
88
- end
89
-
90
- def compile(source)
91
- Context.new(source)
92
- end
93
-
94
82
  def available?
95
83
  require "rhino"
96
84
  true
@@ -0,0 +1,55 @@
1
+ require "execjs/encoding"
2
+
3
+ module ExecJS
4
+ # Abstract base class for runtimes
5
+ class Runtime
6
+ class Context
7
+ include Encoding
8
+
9
+ def initialize(runtime, source = "")
10
+ end
11
+
12
+ def exec(source, options = {})
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def eval(source, options = {})
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def call(properties, *args)
21
+ raise NotImplementedError
22
+ end
23
+ end
24
+
25
+ def name
26
+ raise NotImplementedError
27
+ end
28
+
29
+ def context_class
30
+ self.class::Context
31
+ end
32
+
33
+ def exec(source)
34
+ context = context_class.new(self)
35
+ context.exec(source)
36
+ end
37
+
38
+ def eval(source)
39
+ context = context_class.new(self)
40
+ context.eval(source)
41
+ end
42
+
43
+ def compile(source)
44
+ context_class.new(self, source)
45
+ end
46
+
47
+ def deprecated?
48
+ false
49
+ end
50
+
51
+ def available?
52
+ raise NotImplementedError
53
+ end
54
+ end
55
+ end
@@ -34,7 +34,8 @@ module ExecJS
34
34
  SpiderMonkey = Spidermonkey = ExternalRuntime.new(
35
35
  :name => "SpiderMonkey",
36
36
  :command => "js",
37
- :runner_path => ExecJS.root + "/support/spidermonkey_runner.js"
37
+ :runner_path => ExecJS.root + "/support/spidermonkey_runner.js",
38
+ :deprecated => true
38
39
  )
39
40
 
40
41
  JScript = ExternalRuntime.new(
@@ -52,7 +53,7 @@ module ExecJS
52
53
  end
53
54
 
54
55
  def self.best_available
55
- runtimes.find(&:available?)
56
+ runtimes.reject(&:deprecated?).find(&:available?)
56
57
  end
57
58
 
58
59
  def self.from_environment
@@ -1,4 +1,4 @@
1
- (function(program, execJS) { execJS(program) })(function(module, exports, require) { #{source}
1
+ (function(program, execJS) { execJS(program) })(function(module, exports, require, console) { #{source}
2
2
  }, function(program) {
3
3
  var output, print = function(string) {
4
4
  process.stdout.write('' + string);
@@ -1,3 +1,3 @@
1
1
  module ExecJS
2
- VERSION = "1.3.2"
2
+ VERSION = "1.4.0"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: execjs
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 3
9
- - 2
10
- version: 1.3.2
8
+ - 4
9
+ - 0
10
+ version: 1.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sam Stephenson
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2012-05-07 00:00:00 Z
19
+ date: 2012-05-20 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: multi_json
@@ -34,7 +34,7 @@ dependencies:
34
34
  type: :runtime
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: johnson
37
+ name: rake
38
38
  prerelease: false
39
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
@@ -47,63 +47,7 @@ dependencies:
47
47
  version: "0"
48
48
  type: :development
49
49
  version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: mustang
52
- prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
54
- none: false
55
- requirements:
56
- - - ">="
57
- - !ruby/object:Gem::Version
58
- hash: 3
59
- segments:
60
- - 0
61
- version: "0"
62
- type: :development
63
- version_requirements: *id003
64
- - !ruby/object:Gem::Dependency
65
- name: rake
66
- prerelease: false
67
- requirement: &id004 !ruby/object:Gem::Requirement
68
- none: false
69
- requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- hash: 3
73
- segments:
74
- - 0
75
- version: "0"
76
- type: :development
77
- version_requirements: *id004
78
- - !ruby/object:Gem::Dependency
79
- name: therubyracer
80
- prerelease: false
81
- requirement: &id005 !ruby/object:Gem::Requirement
82
- none: false
83
- requirements:
84
- - - ">="
85
- - !ruby/object:Gem::Version
86
- hash: 3
87
- segments:
88
- - 0
89
- version: "0"
90
- type: :development
91
- version_requirements: *id005
92
- - !ruby/object:Gem::Dependency
93
- name: therubyrhino
94
- prerelease: false
95
- requirement: &id006 !ruby/object:Gem::Requirement
96
- none: false
97
- requirements:
98
- - - ">="
99
- - !ruby/object:Gem::Version
100
- hash: 3
101
- segments:
102
- - 0
103
- version: "0"
104
- type: :development
105
- version_requirements: *id006
106
- description: " ExecJS lets you run JavaScript code from Ruby.\n"
50
+ description: ExecJS lets you run JavaScript code from Ruby.
107
51
  email:
108
52
  - sstephenson@gmail.com
109
53
  - josh@joshpeek.com
@@ -117,12 +61,15 @@ files:
117
61
  - README.md
118
62
  - LICENSE
119
63
  - lib/execjs/disabled_runtime.rb
64
+ - lib/execjs/encoding.rb
120
65
  - lib/execjs/external_runtime.rb
121
66
  - lib/execjs/johnson_runtime.rb
67
+ - lib/execjs/json.rb
122
68
  - lib/execjs/module.rb
123
69
  - lib/execjs/mustang_runtime.rb
124
70
  - lib/execjs/ruby_racer_runtime.rb
125
71
  - lib/execjs/ruby_rhino_runtime.rb
72
+ - lib/execjs/runtime.rb
126
73
  - lib/execjs/runtimes.rb
127
74
  - lib/execjs/support/jsc_runner.js
128
75
  - lib/execjs/support/jscript_runner.js