harmony 0.5

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.
Files changed (118) hide show
  1. data/.gitignore +5 -0
  2. data/LICENSE +19 -0
  3. data/Manifest +117 -0
  4. data/README.md +155 -0
  5. data/Rakefile +39 -0
  6. data/docs.watchr +25 -0
  7. data/harmony.gemspec +18 -0
  8. data/lib/harmony.rb +5 -0
  9. data/lib/harmony/page.rb +123 -0
  10. data/specs.watchr +36 -0
  11. data/test/harmony_test.rb +8 -0
  12. data/test/page_test.rb +73 -0
  13. data/test/test_helper.rb +13 -0
  14. data/vendor/README +1 -0
  15. data/vendor/envjs/README +36 -0
  16. data/vendor/envjs/bin/envjsrb +255 -0
  17. data/vendor/envjs/bin/jquery-1.2.6-test.js +33 -0
  18. data/vendor/envjs/bin/jquery-1.3.1-test.js +33 -0
  19. data/vendor/envjs/bin/jquery-1.3.2-test.js +106 -0
  20. data/vendor/envjs/bin/prototype-1.6.0.3-test.js +82 -0
  21. data/vendor/envjs/bin/prototype_1.6.0.3_tmpl.txt +27 -0
  22. data/vendor/envjs/bin/test-jquery.sh +58 -0
  23. data/vendor/envjs/bin/test-prototype.sh +54 -0
  24. data/vendor/envjs/bin/tidy +0 -0
  25. data/vendor/envjs/lib/envjs.rb +23 -0
  26. data/vendor/envjs/lib/envjs/env.js +21665 -0
  27. data/vendor/envjs/lib/envjs/net.rb +3 -0
  28. data/vendor/envjs/lib/envjs/net/cgi.rb +94 -0
  29. data/vendor/envjs/lib/envjs/net/file.rb +75 -0
  30. data/vendor/envjs/lib/envjs/options.rb +11 -0
  31. data/vendor/envjs/lib/envjs/runtime.rb +351 -0
  32. data/vendor/envjs/lib/envjs/tempfile.rb +24 -0
  33. data/vendor/envjs/test/base64.js +80 -0
  34. data/vendor/envjs/test/call-load-test.js +15 -0
  35. data/vendor/envjs/test/data.js +45 -0
  36. data/vendor/envjs/test/debug.js +53 -0
  37. data/vendor/envjs/test/firebug/errorIcon.png +0 -0
  38. data/vendor/envjs/test/firebug/firebug.css +209 -0
  39. data/vendor/envjs/test/firebug/firebug.html +23 -0
  40. data/vendor/envjs/test/firebug/firebug.js +672 -0
  41. data/vendor/envjs/test/firebug/firebugx.js +10 -0
  42. data/vendor/envjs/test/firebug/infoIcon.png +0 -0
  43. data/vendor/envjs/test/firebug/warningIcon.png +0 -0
  44. data/vendor/envjs/test/fixtures/html/events.html +171 -0
  45. data/vendor/envjs/test/fixtures/html/iframe1.html +46 -0
  46. data/vendor/envjs/test/fixtures/html/iframe1a.html +46 -0
  47. data/vendor/envjs/test/fixtures/html/iframe2.html +45 -0
  48. data/vendor/envjs/test/fixtures/html/iframe3.html +28 -0
  49. data/vendor/envjs/test/fixtures/html/iframeN.html +57 -0
  50. data/vendor/envjs/test/fixtures/html/malformed.html +181 -0
  51. data/vendor/envjs/test/fixtures/html/scope.html +81 -0
  52. data/vendor/envjs/test/fixtures/html/trivial.html +19 -0
  53. data/vendor/envjs/test/fixtures/html/with_js.html +26 -0
  54. data/vendor/envjs/test/fixtures/images/icon-blue.png +0 -0
  55. data/vendor/envjs/test/fixtures/js/external_script.js +1 -0
  56. data/vendor/envjs/test/fixtures/js/script.js +1 -0
  57. data/vendor/envjs/test/fixtures/js/script_error.js +2 -0
  58. data/vendor/envjs/test/html/events.html +171 -0
  59. data/vendor/envjs/test/html/iframe1.html +46 -0
  60. data/vendor/envjs/test/html/iframe1a.html +46 -0
  61. data/vendor/envjs/test/html/iframe2.html +45 -0
  62. data/vendor/envjs/test/html/iframe3.html +30 -0
  63. data/vendor/envjs/test/html/iframeN.html +57 -0
  64. data/vendor/envjs/test/html/malformed.html +181 -0
  65. data/vendor/envjs/test/html/scope.html +87 -0
  66. data/vendor/envjs/test/html/script.js +1 -0
  67. data/vendor/envjs/test/html/trivial.html +19 -0
  68. data/vendor/envjs/test/html/with_js.html +26 -0
  69. data/vendor/envjs/test/index.html +328 -0
  70. data/vendor/envjs/test/java-prototype.js +9 -0
  71. data/vendor/envjs/test/primary-tests.js +24 -0
  72. data/vendor/envjs/test/prototype-test.js +13 -0
  73. data/vendor/envjs/test/qunit.js +61 -0
  74. data/vendor/envjs/test/qunit/qunit/qunit.css +17 -0
  75. data/vendor/envjs/test/qunit/qunit/qunit.js +997 -0
  76. data/vendor/envjs/test/scope.rb +25 -0
  77. data/vendor/envjs/test/specs/dist/env.spec.js +1534 -0
  78. data/vendor/envjs/test/specs/envjs.spec.css +46 -0
  79. data/vendor/envjs/test/specs/parser/html.js +31 -0
  80. data/vendor/envjs/test/specs/parser/spec.html +40 -0
  81. data/vendor/envjs/test/specs/parser/xml.js +31 -0
  82. data/vendor/envjs/test/specs/qunit.bdd.js +210 -0
  83. data/vendor/envjs/test/specs/qunit.css +17 -0
  84. data/vendor/envjs/test/specs/qunit.js +997 -0
  85. data/vendor/envjs/test/specs/template/spec-0.js +31 -0
  86. data/vendor/envjs/test/specs/template/spec-1.js +31 -0
  87. data/vendor/envjs/test/specs/template/spec.html +40 -0
  88. data/vendor/envjs/test/specs/window/css.js +23 -0
  89. data/vendor/envjs/test/specs/window/dialog.js +25 -0
  90. data/vendor/envjs/test/specs/window/document.js +23 -0
  91. data/vendor/envjs/test/specs/window/event.js +25 -0
  92. data/vendor/envjs/test/specs/window/history.js +34 -0
  93. data/vendor/envjs/test/specs/window/location.js +34 -0
  94. data/vendor/envjs/test/specs/window/navigator.js +71 -0
  95. data/vendor/envjs/test/specs/window/screen.js +42 -0
  96. data/vendor/envjs/test/specs/window/spec.html +48 -0
  97. data/vendor/envjs/test/specs/window/timer.js +26 -0
  98. data/vendor/envjs/test/specs/window/window.js +53 -0
  99. data/vendor/envjs/test/specs/xhr/spec.html +47 -0
  100. data/vendor/envjs/test/specs/xhr/xhr.js +31 -0
  101. data/vendor/envjs/test/test.js +10 -0
  102. data/vendor/envjs/test/unit/dom.js +44 -0
  103. data/vendor/envjs/test/unit/elementmembers.js +60 -0
  104. data/vendor/envjs/test/unit/events.js +195 -0
  105. data/vendor/envjs/test/unit/fixtures/external_script.js +1 -0
  106. data/vendor/envjs/test/unit/iframe.js +234 -0
  107. data/vendor/envjs/test/unit/multi-window.js +212 -0
  108. data/vendor/envjs/test/unit/nu.validator.js +34 -0
  109. data/vendor/envjs/test/unit/onload.js +90 -0
  110. data/vendor/envjs/test/unit/parser.js +121 -0
  111. data/vendor/envjs/test/unit/prototypecompat.js +22 -0
  112. data/vendor/envjs/test/unit/proxy.js +6 -0
  113. data/vendor/envjs/test/unit/scope.js +209 -0
  114. data/vendor/envjs/test/unit/timer.js +115 -0
  115. data/vendor/envjs/test/unit/window.js +41 -0
  116. data/vendor/envjs/test/vendor/jQuery/README +2 -0
  117. data/vendor/envjs/test/vendor/prototype-1.6.0.3.js +4320 -0
  118. metadata +200 -0
@@ -0,0 +1,3 @@
1
+ require 'envjs'
2
+
3
+ module Envjs::Net; end
@@ -0,0 +1,94 @@
1
+ require 'net/protocol'
2
+
3
+ require 'envjs/net'
4
+
5
+ class Envjs::Net::CGI
6
+
7
+ def save_and_set k, v
8
+ @saved[k] = ENV[k]
9
+ ENV[k] = v
10
+ end
11
+
12
+ def restore
13
+ @saved.keys.each do |k|
14
+ ENV[k] = @saved[k]
15
+ end
16
+ @saved = {}
17
+ end
18
+
19
+ def initialize xhr, data
20
+ if (match = %r((.*\.php)(\?(.*))?).match xhr.url).nil?
21
+ raise "Not CGI"
22
+ end
23
+
24
+ @saved = {}
25
+
26
+ begin
27
+
28
+ # p match[0]
29
+
30
+ path = match[1]
31
+ path.sub! %r(^file://), ""
32
+
33
+ save_and_set( "GATEWAY_INTERFACE", "CGI/1.1" )
34
+
35
+ save_and_set( "REQUEST_METHOD", xhr["method"] )
36
+ if ( match[3] )
37
+ save_and_set( "QUERY_STRING", match[3] )
38
+ end
39
+
40
+ if ct = xhr["headers"]["Content-Type"]
41
+ save_and_set( "CONTENT_TYPE", ct )
42
+ end
43
+
44
+ if data
45
+ save_and_set( "CONTENT_LENGTH", data.length.to_s )
46
+ end
47
+
48
+ xhr["headers"].each do |k,v|
49
+ k.gsub!("-","_")
50
+ k = "HTTP_" + k
51
+ save_and_set( k, v )
52
+ end
53
+
54
+ result = nil
55
+
56
+ save_and_set( "PATH_INFO", path )
57
+ save_and_set( "PATH_TRANSLATED", path )
58
+ save_and_set( "REDIRECT_STATUS", "200" )
59
+
60
+ open("|php-cgi", "r+") do |php|
61
+ if data
62
+ php.write data
63
+ php.flush
64
+ end
65
+ result = php.read
66
+ end
67
+
68
+ result && result = result.split("\r\n")
69
+ @headers = {}
70
+ while line = result.shift
71
+ break if line == ""
72
+ match = /([^:]*):\s*(.*)/.match line
73
+ @headers[match[1]]=match[2]
74
+ end
75
+ # p "q", result.join("\r\n")
76
+ @body = result.join("\r\n")
77
+ ensure
78
+ restore
79
+ end
80
+
81
+ end
82
+
83
+ def each
84
+ @headers.each do |k,v|
85
+ yield k, v
86
+ end
87
+ end
88
+
89
+ def finish
90
+ end
91
+
92
+ attr_reader :body
93
+
94
+ end
@@ -0,0 +1,75 @@
1
+ require 'net/protocol'
2
+
3
+ require 'envjs/net'
4
+
5
+ class Envjs::Net::File < Net::Protocol
6
+
7
+ class << self
8
+ attr_accessor :on_open
9
+ end
10
+
11
+ class Get
12
+ attr_accessor :path
13
+ def initialize path
14
+ @path = path
15
+ end
16
+ end
17
+
18
+ def initialize host, port
19
+ end
20
+
21
+ def self.start host, port
22
+ new( host, port ).start
23
+ end
24
+
25
+ def start
26
+ self
27
+ end
28
+
29
+ def finish
30
+ end
31
+
32
+ def request request
33
+ Response.new request.path
34
+ end
35
+
36
+ class Response
37
+ def initialize path
38
+ @path = path
39
+ on_open = Envjs::Net::File.on_open
40
+ on_open and on_open.call( path )
41
+ @file = File.new @path
42
+ @body = @file.read
43
+ @code = @file.nil? ? "404" : "200";
44
+ @file.close
45
+ end
46
+
47
+ def [] *args
48
+ nil
49
+ end
50
+
51
+ def each &block
52
+ end
53
+
54
+ def getHeaderFields
55
+ []
56
+ end
57
+
58
+ def getContentEncoding
59
+ nil
60
+ end
61
+
62
+ def getResponseCode
63
+ @file.nil? ? 404 : 200;
64
+ end
65
+
66
+
67
+ def getInputStream
68
+ self
69
+ end
70
+
71
+ attr_reader :body, :code
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,11 @@
1
+ require 'optparse'
2
+
3
+ $envjsrb_deps = nil
4
+
5
+ OptionParser.new do |o|
6
+
7
+ o.on("--deps path") do |path|
8
+ $envjsrb_deps = path
9
+ end
10
+
11
+ end.parse!
@@ -0,0 +1,351 @@
1
+ require 'envjs'
2
+ require "open-uri"
3
+ require 'pathname'
4
+ begin
5
+ require 'fsdb'
6
+ rescue LoadError; end
7
+ require 'envjs/net/file'
8
+
9
+ module Envjs::Runtime
10
+
11
+ def self.extended object
12
+ object.instance_eval do
13
+
14
+ evaluate <<'EOJS'
15
+ print = function() {
16
+ var l = arguments.length
17
+ for( var i = 0; i < l; i++ ) {
18
+ var s;
19
+ if ( arguments[i] === null ) {
20
+ s = "null";
21
+ } else if ( arguments[i] === undefined ) {
22
+ s = "undefined"
23
+ } else {
24
+ s = arguments[i].toString();
25
+ }
26
+ Ruby.print(s);
27
+ if( i < l-1 ) {
28
+ Ruby.print(" ");
29
+ }
30
+ }
31
+ Ruby.print("\n");
32
+ Ruby['$stdout'].flush();
33
+ };
34
+ EOJS
35
+
36
+ evaluate <<'EOJS'
37
+ debug = function() {
38
+ var l = arguments.length
39
+ for( var i = 0; i < l; i++ ) {
40
+ var s;
41
+ if ( arguments[i] === null ) {
42
+ s = "null";
43
+ } else if ( arguments[i] === undefined ) {
44
+ s = "undefined"
45
+ } else {
46
+ s = arguments[i].toString();
47
+ }
48
+ Ruby['$stderr'].print(s);
49
+ if( i < l-1 ) {
50
+ Ruby['$stderr'].print(" ");
51
+ }
52
+ }
53
+ Ruby['$stderr'].print("\n");
54
+ };
55
+ EOJS
56
+
57
+ evaluate <<'EOJS'
58
+ puts = function() {
59
+ var l = arguments.length
60
+ for( var i = 0; i < l; i++ ) {
61
+ var s;
62
+ if ( arguments[i] === null ) {
63
+ s = "null";
64
+ } else if ( arguments[i] === undefined ) {
65
+ s = "undefined"
66
+ } else {
67
+ s = arguments[i].toString();
68
+ }
69
+ Ruby.print(s);
70
+ Ruby.eval("$stdout.flush")
71
+ }
72
+ };
73
+ EOJS
74
+
75
+ master = global["$master"] = evaluate("new Object")
76
+ master.symbols = [ "Johnson", "Ruby", "print", "debug", "puts", "load", "reload", "whichInterpreter", "multiwindow" ]
77
+ master.symbols.each { |symbol| master[symbol] = global[symbol] }
78
+
79
+ master.whichInterpreter = "Johnson"
80
+
81
+ master.multiwindow = true
82
+
83
+ # calling this from JS is hosed; the ruby side is confused, maybe because HTTPHeaders is mixed in?
84
+ master.add_req_field = lambda { |r,k,v| r.add_field(k,v) }
85
+
86
+ db = lambda do
87
+ $envjsrb_deps && ( @db ||= FSDB::Database.new $envjsrb_deps )
88
+ end
89
+
90
+ top_level_js = nil
91
+
92
+ add_dep = nil
93
+
94
+ clear_deps = lambda do |w|
95
+ begin
96
+ if db.call
97
+ loc = w
98
+ begin loc = w.location; rescue; end
99
+ loc && ( loc = loc.to_s )
100
+ if ( loc !~ %r((http?s|file|about):) )
101
+ begin
102
+ loc = "file://" + Pathname(loc).realpath.to_s
103
+ rescue Errno::ENOENT; end
104
+ end
105
+ # $stderr.puts "clear", loc
106
+ if loc and loc != "about:blank"
107
+ paths = db.call[loc+".on.yml"] || []
108
+ paths.each do |path|
109
+ # $stderr.print "#{path} not by #{loc}\n";
110
+ db.call[path+".by.yml"].delete loc
111
+ end
112
+ # $stderr.print "#{loc} not on anything\n";
113
+ db.call.delete loc+".on.yml"
114
+ end
115
+ end
116
+ add_dep.call( nil, loc )
117
+ rescue Exception => e; $stderr.puts e, e.class; $stderr.puts e.backtrace; end
118
+ end
119
+
120
+ if $envjsrb_deps
121
+ Envjs::Net::File.on_open = clear_deps
122
+ end
123
+
124
+ add_dep = lambda do |w, f|
125
+ if db.call
126
+ loc = nil
127
+ begin loc = w.location; rescue Exception; end
128
+ loc && ( loc = loc.to_s )
129
+ if ( loc && loc !~ %r((http?s|file|about):) )
130
+ loc = "file://" + Pathname(loc).realpath.to_s
131
+ end
132
+ path = f
133
+ if ( path !~ %r((http?s|file|about):) )
134
+ begin
135
+ path = "file://" + Pathname(path).realpath.to_s
136
+ rescue Errno::ENOENT
137
+ return
138
+ end
139
+ end
140
+ if !loc || loc == "about:blank"
141
+ uri = URI.parse top_level_js
142
+ if uri.scheme == nil
143
+ uri.scheme = "file"
144
+ begin
145
+ uri.path = Pathname.new(uri.path).realpath.to_s
146
+ rescue Errno::ENOENT; end
147
+ uri = URI.parse uri.to_s
148
+ end
149
+ uri_s = uri.to_s.sub %r(^file:/([^/])), 'file:///\1'
150
+
151
+ # tll = "file://" + Pathname(top_level_js).realpath.to_s
152
+
153
+ tll = uri_s
154
+
155
+ if ( tll != path )
156
+ loc = tll
157
+ end
158
+ end
159
+ if loc and loc != "about:blank"
160
+ on = db.call[loc+".on.yml"] || []
161
+ on << path
162
+ on.uniq!
163
+ db.call[loc+".on.yml"] = on
164
+ by = db.call[path+".by.yml"] || []
165
+ by << loc
166
+ by.uniq!
167
+ db.call[path+".by.yml"] = by
168
+ # $stderr.print "#{loc} on #{path}: #{db.call[loc+'.on.yml'].join(' ')}\n"
169
+ # $stderr.print "#{path} by #{loc}: #{db.call[path+'.by.yml'].join(' ')}\n"
170
+ end
171
+ end
172
+ end
173
+
174
+ (class << self; self; end).send :define_method, :top_level_load do |path|
175
+ # $stderr.print "tll #{path}\n"
176
+ top_level_js = path
177
+ clear_deps.call( path )
178
+ end
179
+
180
+ master.load = lambda { |*files|
181
+ if files.length == 2 && !(String === files[1])
182
+ f = files[0]
183
+ w = files[1]
184
+
185
+ # Hmmm ...
186
+ uri = URI.parse f
187
+
188
+ if uri.scheme == nil
189
+ uri.scheme = "file"
190
+ begin
191
+ uri.path = Pathname.new(uri.path).realpath.to_s
192
+ rescue Errno::ENOENT; end
193
+ uri = URI.parse uri.to_s
194
+ end
195
+
196
+ uri_s = uri.to_s.sub %r(^file:/([^/])), 'file:///\1'
197
+
198
+ if uri.scheme == "file"
199
+ uri_s = uri.path
200
+ elsif uri.scheme == "data"
201
+ raise "implement 0"
202
+ end
203
+
204
+ v = open(uri_s).read.gsub(/\A#!.*$/, '')
205
+ loc = nil
206
+ add_dep.call w, f
207
+ evaluate(v, f, 1, w, w, f)
208
+ else
209
+ load *files
210
+ end
211
+ }
212
+
213
+ def load *files
214
+ files.map { |f|
215
+ # Hmmm ...
216
+
217
+ uri = URI.parse f
218
+ if uri.scheme == nil
219
+ uri.scheme = "file"
220
+ begin
221
+ uri.path = Pathname.new(uri.path).realpath.to_s
222
+ rescue Errno::ENOENT; end
223
+ uri = URI.parse uri.to_s
224
+ end
225
+ uri_s = uri.to_s.sub %r(^file:/([^/])), 'file:///\1'
226
+
227
+ if uri.scheme == "file"
228
+ super uri.path
229
+ elsif uri.scheme == "data"
230
+ raise "implement 1"
231
+ else
232
+ raise "hell 1"
233
+ end
234
+
235
+ # v = open(uri_s).read.gsub(/\A#!.*$/, '')
236
+ # loc = nil
237
+ # add_dep.call w, f
238
+ # evaluate(v, f, 1, w, w, f)
239
+ # evaluate(File.read(f).gsub(/\A#!.*$/, ''), f, 1)
240
+
241
+ }.last
242
+ end
243
+
244
+ master.reload = lambda { |*files|
245
+ if files.length == 2 && !(String === files[1])
246
+ f = files[0]
247
+ w = files[1]
248
+ v = open(f).read.gsub(/\A#!.*$/, '')
249
+ loc = nil
250
+ add_dep.call w, f
251
+ reevaluate(v, f, 1, w, w, f)
252
+ else
253
+ reload *files
254
+ end
255
+ }
256
+
257
+ master.evaluate = lambda { |v,w|
258
+ evaluate(v,"inline",1,w,w);
259
+ }
260
+
261
+ master.new_split_global_outer = lambda { new_split_global_outer }
262
+ master.new_split_global_inner = lambda { |outer,_| new_split_global_inner outer }
263
+
264
+ # create an proto window object and proxy
265
+
266
+ outer = new_split_global_outer
267
+ window = inner = new_split_global_inner( outer )
268
+
269
+ master.symbols.each do |symbol|
270
+ window[symbol] = master[symbol]
271
+ end
272
+
273
+ master.first_script_window = window
274
+
275
+ window["$master"] = master
276
+ window["$options"] = evaluate("new Object");
277
+ window["$options"].proxy = outer
278
+
279
+ window.evaluate = lambda { |s|
280
+ return master.evaluate.call(s,window);
281
+ }
282
+
283
+ window.load = lambda { |*files|
284
+ files.each do |f|
285
+ master.load.call f, window
286
+ end
287
+ }
288
+
289
+ window.reload = lambda { |*files|
290
+ files.each do |f|
291
+ master.reload.call f, window
292
+ end
293
+ }
294
+
295
+ ( class << self; self; end ).send :define_method, :wait do
296
+ master["finalize"] && master.finalize.call
297
+ master.timers && master.timers.wait
298
+ end
299
+
300
+ scripts = {}
301
+
302
+ ( class << self; self; end ).send :define_method, :become_first_script_window do
303
+ # p "heh", inner, master.first_script_window
304
+ inner = master.first_script_window
305
+ end
306
+
307
+ ( class << self; self; end ).send :define_method, :evaluate do |*args|
308
+ ( script, file, line, global, scope, fn ) = *args
309
+ # print "eval in " + script[0,50].inspect + (scope ? scope.toString() : "nil") + "\n"
310
+ global = nil
311
+ scope ||= inner
312
+ if fn
313
+ compiled_script = scripts[fn]
314
+ end
315
+ # compiled_script = compile(script, file, line, global)
316
+ compiled_script ||= compile(script, file, line, global)
317
+ if fn && !scripts[fn]
318
+ scripts[fn] = compiled_script
319
+ end
320
+ # p "?", script
321
+ evaluate_compiled_script(compiled_script,scope)
322
+ end
323
+
324
+ ( class << self; self; end ).send :define_method, :reevaluate do |*args|
325
+ ( script, file, line, global, scope, fn ) = *args
326
+ # print "eval in " + script[0,50].inspect + (scope ? scope.toString() : "nil") + "\n"
327
+ global = nil
328
+ scope ||= inner
329
+ compiled_script = compile(script, file, line, global)
330
+ if fn
331
+ scripts[fn] = compiled_script
332
+ end
333
+ evaluate_compiled_script(compiled_script,scope)
334
+ end
335
+
336
+ @envjs = inner
337
+
338
+ ( class << self; self; end ).send :define_method, :"[]" do |key|
339
+ key == "this" && evaluate("this") || @envjs[key]
340
+ end
341
+
342
+ ( class << self; self; end ).send :define_method, :"[]=" do |k,v|
343
+ @envjs[k] = v
344
+ end
345
+
346
+ load Envjs::ENVJS
347
+
348
+ end
349
+ end
350
+
351
+ end