opal 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (325) hide show
  1. data/.gitignore +5 -10
  2. data/LICENSE +75 -0
  3. data/README.md +55 -3
  4. data/Rakefile +62 -139
  5. data/bin/opal +7 -10
  6. data/gems/core/README.md +5 -0
  7. data/gems/core/Rakefile +7 -0
  8. data/gems/core/core.gemspec +13 -0
  9. data/gems/core/lib/core.rb +33 -0
  10. data/gems/core/lib/core/array.rb +1470 -0
  11. data/gems/core/lib/core/basic_object.rb +15 -0
  12. data/gems/core/lib/core/class.rb +31 -0
  13. data/gems/core/lib/core/dir.rb +26 -0
  14. data/gems/core/lib/core/error.rb +43 -0
  15. data/gems/core/lib/core/false_class.rb +21 -0
  16. data/gems/core/lib/core/file.rb +54 -0
  17. data/gems/core/lib/core/hash.rb +725 -0
  18. data/gems/core/lib/core/kernel.rb +240 -0
  19. data/gems/core/lib/core/module.rb +98 -0
  20. data/gems/core/lib/core/nil_class.rb +41 -0
  21. data/gems/core/lib/core/numeric.rb +370 -0
  22. data/gems/core/lib/core/proc.rb +11 -0
  23. data/gems/core/lib/core/range.rb +17 -0
  24. data/gems/core/lib/core/regexp.rb +18 -0
  25. data/gems/core/lib/core/string.rb +328 -0
  26. data/gems/core/lib/core/symbol.rb +15 -0
  27. data/gems/core/lib/core/top_self.rb +8 -0
  28. data/gems/core/lib/core/true_class.rb +20 -0
  29. data/gems/core/lib/core/vm.rb +16 -0
  30. data/{opals/opal/opal → gems/core}/spec/core/array/append_spec.rb +0 -0
  31. data/{opals/opal/opal → gems/core}/spec/core/array/assoc_spec.rb +0 -0
  32. data/{opals/opal/opal → gems/core}/spec/core/array/at_spec.rb +0 -0
  33. data/{opals/opal/opal → gems/core}/spec/core/array/clear_spec.rb +1 -1
  34. data/{opals/opal/opal → gems/core}/spec/core/array/collect_bang_spec.rb +0 -0
  35. data/{opals/opal/opal → gems/core}/spec/core/array/collect_spec.rb +0 -0
  36. data/gems/core/spec/core/array/compact_spec.rb +41 -0
  37. data/{opals/opal/opal → gems/core}/spec/core/array/concat_spec.rb +0 -0
  38. data/{opals/opal/opal → gems/core}/spec/core/array/constructor_spec.rb +0 -0
  39. data/{opals/opal/opal → gems/core}/spec/core/array/each_spec.rb +0 -0
  40. data/{opals/opal/opal → gems/core}/spec/core/array/element_reference_spec.rb +0 -0
  41. data/{opals/opal/opal → gems/core}/spec/core/array/first_spec.rb +1 -1
  42. data/{opals/opal/opal → gems/core}/spec/core/array/include_spec.rb +0 -0
  43. data/gems/core/spec/core/array/join_spec.rb +6 -0
  44. data/gems/core/spec/core/array/last_spec.rb +51 -0
  45. data/gems/core/spec/core/array/length_spec.rb +6 -0
  46. data/{opals/opal/opal → gems/core}/spec/core/array/map_spec.rb +2 -0
  47. data/gems/core/spec/core/array/reverse_spec.rb +6 -0
  48. data/{opals/opal/opal → gems/core}/spec/core/builtin_constants/builtin_constants_spec.rb +0 -0
  49. data/{opals/opal/opal → gems/core}/spec/core/false/and_spec.rb +0 -0
  50. data/{opals/opal/opal → gems/core}/spec/core/false/inspect_spec.rb +0 -0
  51. data/{opals/opal/opal → gems/core}/spec/core/false/or_spec.rb +0 -0
  52. data/{opals/opal/opal → gems/core}/spec/core/false/to_s_spec.rb +0 -0
  53. data/{opals/opal/opal → gems/core}/spec/core/false/xor_spec.rb +0 -0
  54. data/{opals/opal/opal → gems/core}/spec/core/file/join_spec.rb +1 -1
  55. data/gems/core/spec/core/hash/assoc_spec.rb +32 -0
  56. data/{opals/opal/opal → gems/core}/spec/core/kernel/instance_eval_spec.rb +0 -0
  57. data/{opals/opal/opal → gems/core}/spec/core/kernel/loop_spec.rb +0 -0
  58. data/{opals/opal/opal → gems/core}/spec/core/kernel/raise_spec.rb +0 -0
  59. data/{opals/opal/opal → gems/core}/spec/core/module/attr_accessor_spec.rb +0 -0
  60. data/{opals/opal/opal → gems/core}/spec/core/number/lt_spec.rb +0 -0
  61. data/gems/core/spec/core/string/sub_spec.rb +24 -0
  62. data/{opals/opal/opal → gems/core}/spec/core/true/and_spec.rb +0 -0
  63. data/{opals/opal/opal → gems/core}/spec/core/true/inspect_spec.rb +0 -0
  64. data/{opals/opal/opal → gems/core}/spec/core/true/or_spec.rb +0 -0
  65. data/{opals/opal/opal → gems/core}/spec/core/true/to_s_spec.rb +0 -0
  66. data/{opals/opal/opal → gems/core}/spec/core/true/xor_spec.rb +0 -0
  67. data/{opals/opal/opal → gems/core}/spec/language/and_spec.rb +2 -3
  68. data/{opals/opal/opal → gems/core}/spec/language/array_spec.rb +21 -5
  69. data/gems/core/spec/language/block_spec.rb +38 -0
  70. data/{opals/opal/opal → gems/core}/spec/language/break_spec.rb +0 -0
  71. data/gems/core/spec/language/case_spec.rb +103 -0
  72. data/{opals/opal/opal → gems/core}/spec/language/def_spec.rb +11 -1
  73. data/{opals/opal/opal → gems/core}/spec/language/eigenclass_spec.rb +0 -0
  74. data/gems/core/spec/language/file_spec.rb +13 -0
  75. data/gems/core/spec/language/fixtures/block.rb +21 -0
  76. data/gems/core/spec/language/fixtures/super.rb +293 -0
  77. data/{opals/opal/opal → gems/core}/spec/language/hash_spec.rb +0 -0
  78. data/{opals/opal/opal → gems/core}/spec/language/if_spec.rb +0 -0
  79. data/{opals/opal/opal → gems/core}/spec/language/loop_spec.rb +0 -0
  80. data/gems/core/spec/language/metaclass_spec.rb +21 -0
  81. data/{opals/opal/opal → gems/core}/spec/language/method_spec.rb +60 -0
  82. data/{opals/opal/opal → gems/core}/spec/language/next_spec.rb +0 -0
  83. data/{opals/opal/opal → gems/core}/spec/language/or_spec.rb +0 -0
  84. data/{opals/opal/opal → gems/core}/spec/language/redo_spec.rb +0 -0
  85. data/gems/core/spec/language/regexp_spec.rb +26 -0
  86. data/{opals/opal/opal → gems/core}/spec/language/rescue_spec.rb +0 -0
  87. data/{opals/opal/opal → gems/core}/spec/language/return_spec.rb +0 -0
  88. data/{opals/opal/opal → gems/core}/spec/language/string_spec.rb +0 -0
  89. data/gems/core/spec/language/super_spec.rb +32 -0
  90. data/{opals/opal/opal → gems/core}/spec/language/until_spec.rb +47 -47
  91. data/gems/core/spec/language/variables_spec.rb +155 -0
  92. data/{opals/opal/opal → gems/core}/spec/language/while_spec.rb +47 -47
  93. data/{opals/opal/opal → gems/core}/spec/spec_helper.rb +1 -1
  94. data/gems/core_fs/README.md +19 -0
  95. data/gems/dev/Rakefile +5 -0
  96. data/gems/dev/lib/dev.js +99 -0
  97. data/gems/dev/lib/dev/generator.js +1264 -0
  98. data/gems/dev/lib/dev/parser.js +979 -0
  99. data/gems/dev/lib/dev/ruby_parser.js +1088 -0
  100. data/gems/dev/lib/dev/ruby_parser.y +1267 -0
  101. data/gems/dev/lib/dev/string_scanner.js +38 -0
  102. data/gems/dev/tools/racc2js/README.md +39 -0
  103. data/gems/dev/tools/racc2js/math_parser.js +222 -0
  104. data/gems/dev/tools/racc2js/math_parser.rb +133 -0
  105. data/gems/dev/tools/racc2js/math_parser.y +28 -0
  106. data/gems/dev/tools/racc2js/parser.js +218 -0
  107. data/gems/dev/tools/racc2js/racc2js.rb +153 -0
  108. data/gems/json/README.md +4 -0
  109. data/gems/json/json.gemspec +14 -0
  110. data/gems/json/lib/json.rb +64 -0
  111. data/gems/json/lib/json/ext.rb +51 -0
  112. data/{opals/opal/browser/lib/browser/json_parse.js → gems/json/lib/json/json2.js} +197 -37
  113. data/gems/ospec/README.md +0 -0
  114. data/gems/ospec/lib/ospec.rb +6 -0
  115. data/gems/ospec/lib/ospec/autorun.rb +3 -0
  116. data/gems/ospec/lib/ospec/dsl.rb +15 -0
  117. data/gems/ospec/lib/ospec/example.rb +11 -0
  118. data/gems/ospec/lib/ospec/example/before_and_after_hooks.rb +56 -0
  119. data/gems/ospec/lib/ospec/example/errors.rb +17 -0
  120. data/gems/ospec/lib/ospec/example/example_group.rb +12 -0
  121. data/gems/ospec/lib/ospec/example/example_group_factory.rb +21 -0
  122. data/gems/ospec/lib/ospec/example/example_group_hierarchy.rb +20 -0
  123. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/example/example_group_methods.rb +26 -68
  124. data/gems/ospec/lib/ospec/example/example_group_proxy.rb +14 -0
  125. data/gems/ospec/lib/ospec/example/example_methods.rb +46 -0
  126. data/gems/ospec/lib/ospec/example/example_proxy.rb +18 -0
  127. data/gems/ospec/lib/ospec/expectations.rb +19 -0
  128. data/gems/ospec/lib/ospec/expectations/errors.rb +8 -0
  129. data/gems/ospec/lib/ospec/expectations/fail_with.rb +8 -0
  130. data/gems/ospec/lib/ospec/expectations/handler.rb +27 -0
  131. data/gems/ospec/lib/ospec/matchers.rb +24 -0
  132. data/{opals/opal/Rakefile → gems/ospec/lib/ospec/matchers/be.rb} +0 -0
  133. data/gems/ospec/lib/ospec/matchers/generated_descriptions.rb +20 -0
  134. data/gems/ospec/lib/ospec/matchers/operator_matcher.rb +52 -0
  135. data/gems/ospec/lib/ospec/runner.rb +40 -0
  136. data/gems/ospec/lib/ospec/runner/example_group_runner.rb +44 -0
  137. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/formatter/html_formatter.rb +31 -40
  138. data/gems/ospec/lib/ospec/runner/formatter/terminal_formatter.rb +48 -0
  139. data/gems/ospec/lib/ospec/runner/options.rb +36 -0
  140. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/reporter.rb +23 -55
  141. data/gems/ospec/ospec.gemspec +0 -0
  142. data/gems/rquery/README.md +9 -0
  143. data/gems/rquery/lib/rquery.rb +10 -0
  144. data/gems/rquery/lib/rquery/ajax.rb +4 -0
  145. data/gems/rquery/lib/rquery/css.rb +96 -0
  146. data/gems/rquery/lib/rquery/document.rb +25 -0
  147. data/gems/rquery/lib/rquery/element.rb +292 -0
  148. data/gems/rquery/lib/rquery/event.rb +108 -0
  149. data/gems/rquery/lib/rquery/jquery.js +8177 -0
  150. data/gems/rquery/lib/rquery/request.rb +138 -0
  151. data/gems/rquery/lib/rquery/response.rb +49 -0
  152. data/gems/rquery/rquery.gemspec +16 -0
  153. data/lib/opal.js +1597 -0
  154. data/lib/opal.rb +6 -69
  155. data/lib/opal/builder.rb +115 -0
  156. data/lib/opal/bundle.rb +131 -0
  157. data/lib/opal/command.rb +11 -0
  158. data/lib/opal/context.rb +69 -0
  159. data/lib/opal/context/console.rb +12 -0
  160. data/lib/opal/context/file_system.rb +19 -0
  161. data/lib/opal/context/loader.rb +117 -0
  162. data/lib/opal/gem.rb +153 -0
  163. data/lib/opal/ruby/nodes.rb +1302 -0
  164. data/lib/opal/ruby/parser.rb +780 -0
  165. data/lib/opal/ruby/ruby_parser.rb +5170 -0
  166. data/lib/opal/ruby/ruby_parser.y +1298 -0
  167. data/opal.gemspec +11 -256
  168. metadata +179 -240
  169. data/.gitmodules +0 -6
  170. data/Opalfile +0 -384
  171. data/VERSION +0 -1
  172. data/demos/apps/browser_demo/index.html +0 -11
  173. data/demos/apps/browser_demo/lib/browser_demo.rb +0 -31
  174. data/demos/apps/simple_opal/Opalfile +0 -13
  175. data/demos/apps/simple_opal/index.html +0 -11
  176. data/demos/apps/simple_opal/lib/app_controller.rb +0 -62
  177. data/demos/apps/simple_opal/lib/main_window.rb +0 -146
  178. data/demos/browser/request/index.html +0 -52
  179. data/demos/browser/request/request.rb +0 -48
  180. data/gen/browser/__PROJECT_NAME__/Rakefile +0 -12
  181. data/gen/browser/__PROJECT_NAME__/index.html +0 -11
  182. data/gen/browser/__PROJECT_NAME__/javascripts/opal.debug.js +0 -4687
  183. data/gen/browser/__PROJECT_NAME__/javascripts/opal.min.js +0 -175
  184. data/gen/browser/__PROJECT_NAME__/lib/__PROJECT_NAME__.rb +0 -1
  185. data/lib/opal/builders/base.rb +0 -50
  186. data/lib/opal/builders/css.rb +0 -46
  187. data/lib/opal/builders/javascript.rb +0 -44
  188. data/lib/opal/builders/opal.rb +0 -79
  189. data/lib/opal/builders/ruby.rb +0 -50
  190. data/lib/opal/builders/ruby/generate.rb +0 -1851
  191. data/lib/opal/builders/ruby/nodes.rb +0 -210
  192. data/lib/opal/builders/ruby/ruby.rb +0 -916
  193. data/lib/opal/builders/ruby/ruby_parser.rb +0 -6008
  194. data/lib/opal/builders/ruby/ruby_parser.rb.y +0 -1451
  195. data/lib/opal/models/build_item.rb +0 -104
  196. data/lib/opal/models/hash_struct.rb +0 -40
  197. data/lib/opal/models/project.rb +0 -252
  198. data/lib/opal/models/struct_accessors.rb +0 -58
  199. data/lib/opal/models/target.rb +0 -176
  200. data/lib/opal/opal/build.rb +0 -169
  201. data/lib/opal/opal/env/console.rb +0 -66
  202. data/lib/opal/opal/env/fs.rb +0 -98
  203. data/lib/opal/opal/env/object.rb +0 -48
  204. data/lib/opal/opal/environment.rb +0 -139
  205. data/lib/opal/opal/gen.rb +0 -62
  206. data/lib/opal/opal/opal.rb +0 -75
  207. data/lib/opal/opal/repl.rb +0 -38
  208. data/lib/opal/opalfile/dsl.rb +0 -62
  209. data/lib/opal/opalfile/opalfile.rb +0 -133
  210. data/lib/opal/opalfile/task.rb +0 -96
  211. data/lib/opal/opalfile/task_manager.rb +0 -63
  212. data/lib/opal/opalfile/task_scope.rb +0 -52
  213. data/lib/opal/rack/app_server.rb +0 -119
  214. data/lib/opal/rake/opal_task.rb +0 -34
  215. data/opals/opal/README.md +0 -37
  216. data/opals/opal/browser/Opalfile +0 -11
  217. data/opals/opal/browser/README.md +0 -146
  218. data/opals/opal/browser/SIZZLE_LICESNSE.txt +0 -148
  219. data/opals/opal/browser/lib/browser.rb +0 -118
  220. data/opals/opal/browser/lib/browser/builder.rb +0 -41
  221. data/opals/opal/browser/lib/browser/canvas_context.rb +0 -115
  222. data/opals/opal/browser/lib/browser/dimensions.rb +0 -50
  223. data/opals/opal/browser/lib/browser/document.rb +0 -146
  224. data/opals/opal/browser/lib/browser/element.rb +0 -487
  225. data/opals/opal/browser/lib/browser/element/attributes.rb +0 -88
  226. data/opals/opal/browser/lib/browser/element/css.rb +0 -290
  227. data/opals/opal/browser/lib/browser/element/form.rb +0 -146
  228. data/opals/opal/browser/lib/browser/event/dom_events.rb +0 -81
  229. data/opals/opal/browser/lib/browser/event/event.rb +0 -177
  230. data/opals/opal/browser/lib/browser/event/trigger_events.rb +0 -53
  231. data/opals/opal/browser/lib/browser/geometry.rb +0 -97
  232. data/opals/opal/browser/lib/browser/json.rb +0 -32
  233. data/opals/opal/browser/lib/browser/request/request.rb +0 -201
  234. data/opals/opal/browser/lib/browser/sizzle.js +0 -1068
  235. data/opals/opal/browser/lib/browser/string.rb +0 -42
  236. data/opals/opal/browser/lib/browser/touch.rb +0 -37
  237. data/opals/opal/browser/lib/browser/vml_context.js +0 -33
  238. data/opals/opal/browser/lib/browser/window.rb +0 -36
  239. data/opals/opal/browser/spec/browser/browser_detection_spec.rb +0 -7
  240. data/opals/opal/browser/spec/document/aref_spec.rb +0 -110
  241. data/opals/opal/browser/spec/document/ready_spec.rb +0 -16
  242. data/opals/opal/browser/spec/element/body_spec.rb +0 -11
  243. data/opals/opal/browser/spec/element/clear_spec.rb +0 -26
  244. data/opals/opal/browser/spec/element/empty_spec.rb +0 -29
  245. data/opals/opal/browser/spec/element/has_class_spec.rb +0 -40
  246. data/opals/opal/browser/spec/element/hidden_spec.rb +0 -23
  247. data/opals/opal/browser/spec/element/hide_spec.rb +0 -31
  248. data/opals/opal/browser/spec/element/remove_spec.rb +0 -25
  249. data/opals/opal/browser/spec/element/show_spec.rb +0 -31
  250. data/opals/opal/browser/spec/element/style_spec.rb +0 -69
  251. data/opals/opal/browser/spec/element/toggle_spec.rb +0 -31
  252. data/opals/opal/browser/spec/element/visible_spec.rb +0 -23
  253. data/opals/opal/browser/spec/spec_helper.rb +0 -1
  254. data/opals/opal/opal/Opalfile +0 -14
  255. data/opals/opal/opal/spec/core/array/compact_spec.rb +0 -15
  256. data/opals/opal/opal/spec/fixtures/super.rb +0 -70
  257. data/opals/opal/opal/spec/language/____temp_remove_this.rb +0 -12
  258. data/opals/opal/opal/spec/language/block_spec.rb +0 -18
  259. data/opals/opal/opal/spec/language/case_spec.rb +0 -103
  260. data/opals/opal/opal/spec/language/metaclass_spec.rb +0 -21
  261. data/opals/opal/opal/spec/language/super_spec.rb +0 -26
  262. data/opals/opal/runtime/Opalfile +0 -78
  263. data/opals/opal/runtime/README.md +0 -12
  264. data/opals/opal/runtime/docs/debugging.md +0 -51
  265. data/opals/opal/runtime/lib/array.rb +0 -1516
  266. data/opals/opal/runtime/lib/basic_object.rb +0 -49
  267. data/opals/opal/runtime/lib/class.rb +0 -54
  268. data/opals/opal/runtime/lib/dir.rb +0 -36
  269. data/opals/opal/runtime/lib/error.rb +0 -49
  270. data/opals/opal/runtime/lib/false_class.rb +0 -52
  271. data/opals/opal/runtime/lib/file.rb +0 -79
  272. data/opals/opal/runtime/lib/hash.rb +0 -791
  273. data/opals/opal/runtime/lib/io.rb +0 -39
  274. data/opals/opal/runtime/lib/kernel.rb +0 -288
  275. data/opals/opal/runtime/lib/match_data.rb +0 -36
  276. data/opals/opal/runtime/lib/module.rb +0 -109
  277. data/opals/opal/runtime/lib/nil_class.rb +0 -69
  278. data/opals/opal/runtime/lib/number.rb +0 -398
  279. data/opals/opal/runtime/lib/proc.rb +0 -77
  280. data/opals/opal/runtime/lib/range.rb +0 -63
  281. data/opals/opal/runtime/lib/regexp.rb +0 -111
  282. data/opals/opal/runtime/lib/ruby.rb +0 -30
  283. data/opals/opal/runtime/lib/string.rb +0 -328
  284. data/opals/opal/runtime/lib/symbol.rb +0 -40
  285. data/opals/opal/runtime/lib/top_self.rb +0 -33
  286. data/opals/opal/runtime/lib/true_class.rb +0 -45
  287. data/opals/opal/runtime/runtime/browser.js +0 -287
  288. data/opals/opal/runtime/runtime/debug.js +0 -180
  289. data/opals/opal/runtime/runtime/opal.js +0 -1008
  290. data/opals/opal/runtime/runtime/post_opal.js +0 -1
  291. data/opals/opal/runtime/runtime/pre_opal.js +0 -2
  292. data/opals/opal/runtime/runtime/server_side.js +0 -50
  293. data/opals/opal/spec/LICENSE.txt +0 -26
  294. data/opals/opal/spec/Opalfile +0 -5
  295. data/opals/opal/spec/bin/spec.rb +0 -43
  296. data/opals/opal/spec/lib/spec.rb +0 -33
  297. data/opals/opal/spec/lib/spec/dsl.rb +0 -41
  298. data/opals/opal/spec/lib/spec/example.rb +0 -35
  299. data/opals/opal/spec/lib/spec/example/before_and_after_hooks.rb +0 -81
  300. data/opals/opal/spec/lib/spec/example/errors.rb +0 -42
  301. data/opals/opal/spec/lib/spec/example/example_group.rb +0 -37
  302. data/opals/opal/spec/lib/spec/example/example_group_factory.rb +0 -43
  303. data/opals/opal/spec/lib/spec/example/example_group_hierarchy.rb +0 -45
  304. data/opals/opal/spec/lib/spec/example/example_group_proxy.rb +0 -41
  305. data/opals/opal/spec/lib/spec/example/example_methods.rb +0 -73
  306. data/opals/opal/spec/lib/spec/example/example_proxy.rb +0 -48
  307. data/opals/opal/spec/lib/spec/expectations.rb +0 -46
  308. data/opals/opal/spec/lib/spec/expectations/errors.rb +0 -35
  309. data/opals/opal/spec/lib/spec/expectations/fail_with.rb +0 -37
  310. data/opals/opal/spec/lib/spec/expectations/handler.rb +0 -48
  311. data/opals/opal/spec/lib/spec/matchers.rb +0 -50
  312. data/opals/opal/spec/lib/spec/matchers/be.rb +0 -26
  313. data/opals/opal/spec/lib/spec/matchers/generated_descriptions.rb +0 -47
  314. data/opals/opal/spec/lib/spec/matchers/operator_matcher.rb +0 -66
  315. data/opals/opal/spec/lib/spec/runner.rb +0 -48
  316. data/opals/opal/spec/lib/spec/runner/example_group_runner.rb +0 -71
  317. data/opals/opal/spec/lib/spec/runner/formatter/terminal_formatter.rb +0 -82
  318. data/opals/opal/spec/lib/spec/runner/options.rb +0 -63
  319. data/opals/opal/spec/resources/index.html +0 -25
  320. data/opals/opal/spec/resources/spec.css +0 -132
  321. data/spec/cherry_kit/iseq_spec.rb +0 -38
  322. data/spec/spec_helper.rb +0 -16
  323. data/spec/vienna_spec.rb +0 -7
  324. data/yard/index.html +0 -43
  325. data/yard/style.css +0 -765
@@ -0,0 +1,138 @@
1
+ # The Request class wraps the native XMLHttpRequest object in the
2
+ # browser and makes use of jQuery's ajax facilities to make requests.
3
+ class Request
4
+
5
+ # Default options used by all Requests. Unless an option here is
6
+ # overrideen, then these defaults will be used on each request. This
7
+ # is not a full list of all options that can be used; these are just
8
+ # the bare essentials and useful defaults.
9
+ DEFAULT_OPTIONS = {
10
+ :url => '',
11
+ :type => 'GET'
12
+ }
13
+
14
+ # Creates a new Request object. The passed options are merged with
15
+ # DEFAULT_OPTIONS and will be used as the base options for each
16
+ # request. Request specific options may be passed to {#send}, and
17
+ # these will be used in preference to the options passed here.
18
+ #
19
+ # Most of the options that can be set also have their own designated
20
+ # getters and setters as instance methods on this class. This allows
21
+ # for options to be set in a more independant manner instead of
22
+ # collecting all options into the initialization hash.
23
+ #
24
+ # @param [Hash] options request options
25
+ # @return [Request] returns new request instance
26
+ def initialize(options = {})
27
+ @options = DEFAULT_OPTIONS.merge options
28
+ @complete_action = nil
29
+ @failure_action = nil
30
+ @success_action = nil
31
+ end
32
+
33
+ # Creates attribute reader and writers for the given options that will
34
+ # set/retrieve the values from the options hash belonging to this
35
+ # instance. Each of these options may also be overriden by the final
36
+ # values sent to {#send}, or one of its aliases: {#get}, {#post},
37
+ # {#put} or {#delete}.
38
+ #
39
+ # @param [String, Symbol] names option names to set
40
+ def self.option_accessor(*names)
41
+ names.each do |name|
42
+ # define option getter
43
+ define_method(name) { @options[name] }
44
+ # define option setter
45
+ define_method("#{name}=") { |value| @options[name] = value }
46
+ end
47
+ end
48
+
49
+ # By default all requests will be sent async, to avoid locking up the
50
+ # browser. Set this to `false` to send requests in a sync fashion.
51
+ # This defaults to `true` to send by async by default.
52
+ option_accessor :async
53
+
54
+ # Gets the type of the request, which is "GET" by default. This value
55
+ # may be "GET" or "POST", as they are well supported by the browser,
56
+ # but "PUT" and "DELETE" may also be used, but they are not supported
57
+ # within the browser.
58
+ option_accessor :type
59
+
60
+ # Holds the string representing the URL to which the request is sent.
61
+ # By default this is an empty string, so it needs to be set to get any
62
+ # useful requests back.
63
+ option_accessor :url
64
+
65
+ # Sets the username to use when accessing the HTTP authentication
66
+ # requests.
67
+ option_accessor :username
68
+
69
+ # Sets the relevant password used in the HTTP authentication requests.
70
+ option_accessor :password
71
+
72
+ # Sends the request with the specified options. These options are
73
+ # merged with the options given to {#initialize}. There are also
74
+ # aliases for this method for automatically setting the request
75
+ # type; {#put}, {#post}, {#get} and {#delete} will automatically
76
+ # set the correct request type to avoid the need to set it in the
77
+ # options.
78
+ #
79
+ # @param [Hash] options the request options
80
+ # @return [Request] returns the receiver
81
+ def send(options = {})
82
+ `options = #{@options.merge options};
83
+
84
+ // native options object
85
+ var opts = {};
86
+
87
+ // we must have a url
88
+ opts.url = #{options[:url]}
89
+
90
+ // request type
91
+ opts.type = #{options[:type]}
92
+
93
+ // success callback
94
+ if (#{@success_action} != nil) {
95
+ opts.success = function(data, textStatus, jqXHR) {
96
+ var response = #{Response.new `jqXHR`};
97
+ #{@success_action.call `response`};
98
+ };
99
+ }
100
+
101
+ $.ajax(opts);
102
+
103
+ return self;`
104
+ end
105
+
106
+ def get(options = {})
107
+ options[:type] = 'GET'
108
+ send options
109
+ end
110
+
111
+ def post(options = {})
112
+ options[:type] = 'POST'
113
+ send options
114
+ end
115
+
116
+ def put(options = {})
117
+ options[:type] = 'PUT'
118
+ send options
119
+ end
120
+
121
+ def delete(options = {})
122
+ options[:type] = 'DELETE'
123
+ send options
124
+ end
125
+
126
+ # Register a block that will be called if the request succeeds.
127
+ def success(&block)
128
+ @success_action = block
129
+ end
130
+
131
+ # Register a block that will be called if the request fails
132
+
133
+ def failure(&block)
134
+ @failure_action = block
135
+ end
136
+ end
137
+
138
+
@@ -0,0 +1,49 @@
1
+ # Instances of Response are automatically created by Request, so you do
2
+ # not need to make them yourself. This is the object that will be passed
3
+ # to each of the callbacks for a Request object. For this reason, this
4
+ # object will be created if the request succeeds, or indeed fails.
5
+ class Response
6
+ # Private initializer. This handles a native jquery requets object, so
7
+ # this should all probably be private.
8
+ def initialize(request)
9
+ `self.$xhr = request`
10
+ end
11
+
12
+ # Returns the numeric status code for the response.
13
+ #
14
+ # @return [Numeric]
15
+ def status
16
+ `return self.$xhr.status;`
17
+ end
18
+
19
+ # Returns the string status message for the response.
20
+ #
21
+ # @return [String]
22
+ def status_text
23
+ `return self.$xhr.statusText;`
24
+ end
25
+
26
+ # Returns the response text from the request.
27
+ #
28
+ # @return [String]
29
+ def text
30
+ `return self.$xhr.responseText;`
31
+ end
32
+
33
+ # Returns `true` if the response represents a successfull request,
34
+ # `false` otherwise.
35
+ #
36
+ # @return [true, false]
37
+ def success?
38
+ `return (self.$xhr.status >= 200 && self.$xhr.status < 300) ? Qtrue : Qfalse;`
39
+ end
40
+
41
+ # Returns `false` if the response was the result of an unsuccessful
42
+ # request, `true` otherwise.
43
+ #
44
+ # @return [true, false]
45
+ def failure?
46
+ !success?
47
+ end
48
+ end
49
+
@@ -0,0 +1,16 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "rquery"
5
+ s.version = "0.0.1"
6
+ s.authors = ["Adam Beynon"]
7
+ s.email = ["adam@adambeynon.com"]
8
+ s.homepage = "http://github.com/adambeynon/opal"
9
+ s.summary = "Rquery DOM library for ruby/opal"
10
+
11
+ s.files = Dir.glob("{bin,lib}/**/*") + %w[README.md]
12
+ s.require_path = "lib"
13
+
14
+ s.add_dependency "json"
15
+ end
16
+
@@ -0,0 +1,1597 @@
1
+ /**
2
+ Incase we are in browser, wrap body to avoid global vars. Just opal can become
3
+ a top level var. We treat opal as our exports in nodejs, as we reassign them
4
+ at the bottom of this file.
5
+ */
6
+ var opal = {};
7
+
8
+ (function() {
9
+
10
+ // So we can minimize
11
+ var Op = opal;
12
+
13
+ /**
14
+ Core runtime classes, objects and literals.
15
+ */
16
+ var cBasicObject, cObject, cModule, cClass,
17
+ mKernel, cNilClass, cTrueClass, cFalseClass,
18
+ cFile, cProc, cNumeric, cArray,
19
+ cHash, cString, cSymbol, cRange,
20
+ cRegexp, cMatch, Qself, Qnil,
21
+ Qfalse, Qtrue;
22
+
23
+ /**
24
+ Exception classes. Some of these are used by runtime so they are here for
25
+ convenience.
26
+ */
27
+ var eException, eStandardError, eLocalJumpError, eNameError,
28
+ eNoMethodError, eArgError, eScriptError, eLoadError,
29
+ eRuntimeError, eTypeError, eIndexError, eKeyError,
30
+ eRangeError;
31
+
32
+ /**
33
+ Standard jump exceptions to save re-creating them everytime they are needed
34
+ */
35
+ var rb_vm_return_instance,
36
+ rb_vm_loop_return_instance,
37
+ rb_vm_next_instance,
38
+ rb_vm_break_instance;
39
+
40
+ // ..........................................................
41
+ // VIRTUAL MACHINE
42
+ //
43
+
44
+ /**
45
+ This is the VM param that gets given to all files in opal. This contains
46
+ just the VM methods for opal, to keep the global opal namespace cleaner as
47
+ it is used just for external access.
48
+ */
49
+ Op.vm = {};
50
+
51
+ // for minimizng
52
+ var Vm = Op.vm;
53
+ Vm.opal = Op;
54
+
55
+ /**
56
+ Core object type flags. Added as local variables, and onto Opal prototype.
57
+ */
58
+ var T_CLASS = Vm.T_CLASS = 1,
59
+ T_MODULE = Vm.T_MODULE = 2,
60
+ T_OBJECT = Vm.T_OBJECT = 4,
61
+ T_BOOLEAN = Vm.T_BOOLEAN = 8,
62
+ T_STRING = Vm.T_STRING = 16,
63
+ T_ARRAY = Vm.T_ARRAY = 32,
64
+ T_NUMBER = Vm.T_NUMBER = 64,
65
+ T_PROC = Vm.T_PROC = 128,
66
+ T_SYMBOL = Vm.T_SYMBOL = 256,
67
+ T_HASH = Vm.T_HASH = 512,
68
+ T_RANGE = Vm.T_RANGE = 1024,
69
+ T_ICLASS = Vm.T_ICLASS = 2056,
70
+ FL_SINGLETON = Vm.FL_SINGLETON = 4112;
71
+
72
+ /**
73
+ For setting up method_missing methods. Each ruby file that has been compiled
74
+ with call this method with an array of all method_ids that it makes use of.
75
+ These only need to be from method calls. This allows us to make sure this
76
+ method exists on the base prototype, and is set to simply call method_missing
77
+ for the receiver. This adds overhead to the beginning of each file being
78
+ loaded, but is more more efficient than having to check for method_missing on
79
+ every method call in the file for the entirety of its lifetime.
80
+
81
+ @param {Array<String>} method_ids An array of method_ids to register
82
+ */
83
+ Vm.mm = function(method_ids) {
84
+ var prototype = cBasicObject.$m_prototype_tbl;
85
+
86
+ for (var i = 0, ii = method_ids.length; i < ii; i++) {
87
+ var method_id = method_ids[i];
88
+ // only add fake method if not already defined
89
+ if (!prototype.hasOwnProperty(method_id)) {
90
+ // our fake method implementation
91
+ var imp = (function(method_id) {
92
+ return function(self) {
93
+ var args = [].slice.call(arguments, 1);
94
+ args.unshift(Vm.Y(method_id));
95
+ args.unshift(self);
96
+ return self.$m.method_missing.apply(null, args);
97
+ };
98
+ })(method_id);
99
+ // mark as a fake method to help respond_to? and send, etc.
100
+ imp.$rbMM = true;
101
+ prototype[method_id] = imp;
102
+ }
103
+ }
104
+ };
105
+
106
+ /**
107
+ Define methods. Public method for defining a method on the given base.
108
+
109
+ @param {RObject} base The base to define method on
110
+ @param {String} method_id Ruby mid
111
+ @param {Function} body The method implementation
112
+ @param {Boolean} singleton Singleton or Normal method. true for singleton
113
+ */
114
+
115
+ Vm.dm = function(base, method_id, body, singleton) {
116
+ if (singleton) {
117
+ define_singleton_method(base, method_id, body);
118
+ } else {
119
+ // should this instead do a rb_singleton_method?? probably..
120
+ if (base.$flags & T_OBJECT) {
121
+ base = base.$klass;
122
+ }
123
+
124
+ define_method(base, method_id, body);
125
+ }
126
+
127
+ return Qnil;
128
+ };
129
+
130
+ /**
131
+ Define classes. This is the public API for defining classes, shit classes
132
+ and modules.
133
+
134
+ @param {RObject} base
135
+ @param {RClass} super_class
136
+ @param {String} id
137
+ @param {Function} body
138
+ @param {Number} flag
139
+ */
140
+ Vm.dc = function(base, super_class, id, body, flag) {
141
+ var klass;
142
+
143
+ switch (flag) {
144
+ case 0:
145
+ if (base.$flags & T_OBJECT) {
146
+ base = class_real(base.$klass);
147
+ }
148
+
149
+ if (super_class == Qnil) {
150
+ super_class = cObject;
151
+ }
152
+
153
+ klass = define_class_under(base, id, super_class);
154
+ break;
155
+
156
+ case 1:
157
+ klass = singleton_class(base);
158
+ break;
159
+
160
+ case 2:
161
+ if (base.$flags & T_OBJECT) {
162
+ base = class_real(base.$klass);
163
+ }
164
+ klass = define_module_under(base, id);
165
+ break;
166
+
167
+ default:
168
+ raise(eException, "define_class got a unknown flag " + flag);
169
+ }
170
+
171
+ return body.call(klass);
172
+ };
173
+
174
+ /**
175
+ Returns a new RHash instance constructed from the given arguments of
176
+ alternate key, value pairs.
177
+ */
178
+ Vm.H = function() {
179
+ return new RHash(Array.prototype.slice.call(arguments));
180
+ };
181
+
182
+ /**
183
+ Returns a new ruby symbol with the given intern value. Symbols are made
184
+ using the new String() constructor, and just have its klass and method
185
+ table reassigned. This makes dealing with strings/symbols internally
186
+ easier as both can be used as a string within opal.
187
+
188
+ @param {String} intern Symbol value
189
+ @return {RSymbol} symbol
190
+ */
191
+ Vm.Y = function(intern) {
192
+ if (symbol_table.hasOwnProperty(intern)) {
193
+ return symbol_table[intern];
194
+ }
195
+
196
+ var res = new String(intern);
197
+ res.$klass = cSymbol;
198
+ res.$m = cSymbol.$m_tbl;
199
+ symbol_table[intern] = res;
200
+ return res;
201
+ };
202
+
203
+ /**
204
+ Returns a new ruby range. 'G' for range... yeah.
205
+
206
+ @param {RObject} beg The start item for the range
207
+ @param {RObject} end The finish item for the range
208
+ @param {true, false} exclude_end Whether or not the range excludes the last item
209
+ @return {RRange} Returns the new range instance
210
+ */
211
+ Vm.G = function(beg, end, exclude_end) {
212
+ return new RRange(beg, end, exclude_end);
213
+ };
214
+
215
+ /**
216
+ Ruby break statement with the given value. When no break value is needed, nil
217
+ should be passed here. An undefined/null value is not valid and will cause an
218
+ internal error.
219
+
220
+ @param {RObject} value The break value.
221
+ */
222
+ Vm.B = function(value) {
223
+ rb_vm_break_instance.$value = value;
224
+ throw rb_vm_break_instance;
225
+ };
226
+
227
+ /**
228
+ Ruby return, with the given value. The func is the reference function which
229
+ represents the method that this statement must return from.
230
+ */
231
+ Vm.R = function(value, func) {
232
+ rb_vm_return_instance.$value = value;
233
+ rb_vm_return_instance.$func = func;
234
+ throw rb_vm_return_instance;
235
+ };
236
+
237
+ /**
238
+ Block passing. This holds the current block info for the runtime.
239
+
240
+ f: function
241
+ p: block
242
+ y: yield error
243
+
244
+ */
245
+ Vm.P = {
246
+ f: null,
247
+ p: null,
248
+ y: function() {
249
+ throw new Error("LocalJumpError - opal.P.y - no block given");
250
+ }
251
+ };
252
+
253
+ /**
254
+ Define a toll free bridged class.
255
+
256
+ @param {Object} prototype Native prototype to extend
257
+ @param {Number} flags The flags for instances of class
258
+ @param {String} id Class id
259
+ @param {RClass} super_klass
260
+ */
261
+ Vm.bridged_class = function(prototype, flags, id, super_klass) {
262
+ return bridge_class(prototype, flags || T_OBJECT, id, super_klass);
263
+ };
264
+
265
+ /**
266
+ Sets the constant value `val` on the given `klass` as `id`.
267
+
268
+ @param {RClass} klass
269
+ @param {String} id
270
+ @param {Object} val
271
+ @return {Object} returns the set value
272
+ */
273
+ function const_set(klass, id, val) {
274
+ klass.$c_prototype[id] = val;
275
+ return val;
276
+ }
277
+
278
+ /**
279
+ Lookup a constant named `id` on the `klass`. This will throw an error if
280
+ the constant cannot be found.
281
+
282
+ @param {RClass} klass
283
+ @param {String} id
284
+ */
285
+ function const_get(klass, id) {
286
+ if (klass.$c[id]) {
287
+ return (klass.$c[id]);
288
+ }
289
+
290
+ var parent = klass.$parent;
291
+
292
+ while (parent && parent != cObject) {
293
+ if (parent.$c[id]) {
294
+ return parent.$c[id];
295
+ }
296
+
297
+ parent = parent.$parent;
298
+ }
299
+
300
+ raise(eNameError, 'uninitialized constant ' + id);
301
+ };
302
+
303
+ /**
304
+ Returns true or false depending whether a constant named `id` is defined
305
+ on the receiver `klass`.
306
+
307
+ @param {RClass} klass
308
+ @param {String} id
309
+ @return {true, false}
310
+ */
311
+ function const_defined(klass, id) {
312
+ if (klass.$c[id]) {
313
+ return true;
314
+ }
315
+
316
+ return false;
317
+ };
318
+
319
+ /**
320
+ Set an instance variable on the receiver.
321
+ */
322
+ function ivar_set(obj, id, val) {
323
+ obj[id] = val;
324
+ return val;
325
+ };
326
+
327
+ /**
328
+ Return an instance variable set on the receiver, or nil if one does not
329
+ exist.
330
+ */
331
+ function ivar_get(obj, id) {
332
+ return obj.hasOwnProperty(id) ? obj[id] : Qnil;
333
+ };
334
+
335
+ /**
336
+ Determines whether and instance variable has been set on the receiver.
337
+ */
338
+ function ivar_defined(obj, id) {
339
+ return obj.hasOwnProperty(id) ? true : false;
340
+ };
341
+
342
+ /**
343
+ This table holds all the global variables accessible from ruby.
344
+
345
+ Entries are mapped by their global id => an object that contains the
346
+ given keys:
347
+
348
+ - name
349
+ - value
350
+ - getter
351
+ - setter
352
+ */
353
+ var global_tbl = {};
354
+
355
+ /**
356
+ Defines a hooked/global variable.
357
+
358
+ @param {String} name The global name (e.g. '$:')
359
+ @param {Function} getter The getter function to return the variable
360
+ @param {Function} setter The setter function used for setting the var
361
+ @return {null}
362
+ */
363
+ function define_hooked_variable(name, getter, setter) {
364
+ var entry = {
365
+ "name": name,
366
+ "value": Qnil,
367
+ "getter": getter,
368
+ "setter": setter
369
+ };
370
+
371
+ global_tbl[name] = entry;
372
+ };
373
+
374
+ /**
375
+ A default read only getter for a global variable. This will simply throw a
376
+ name error with the given id. This can be used for variables that should
377
+ not be altered.
378
+ */
379
+ function gvar_readonly_setter(id, value) {
380
+ raise(eNameError, id + " is a read-only variable");
381
+ };
382
+
383
+ /**
384
+ Retrieve a global variable. This will use the assigned getter.
385
+ */
386
+ function gvar_get(id) {
387
+ var entry = global_tbl[id];
388
+ if (!entry) { return Qnil; }
389
+ return entry.getter(id);
390
+ };
391
+
392
+ /**
393
+ Set a global. If not already set, then we assign basic getters and setters.
394
+ */
395
+ function gvar_set(id, value) {
396
+ var entry = global_tbl[id];
397
+ if (entry) { return entry.setter(id, value); }
398
+
399
+ define_hooked_variable(id,
400
+
401
+ function(id) {
402
+ return global_tbl[id].value;
403
+ },
404
+
405
+ function(id, value) {
406
+ return (global_tbl[id].value = value);
407
+ }
408
+ );
409
+
410
+ return gvar_set(id, value);
411
+ };
412
+
413
+ /**
414
+ Every object has a unique id. This count is used as the next id for the
415
+ next created object. Therefore, first ruby object has id 0, next has 1 etc.
416
+ */
417
+ var hash_yield = 0;
418
+
419
+ /**
420
+ Yield the next object id, updating the count, and returning it.
421
+ */
422
+ function yield_hash() {
423
+ return hash_yield++;
424
+ };
425
+
426
+ /**
427
+ The root class. Every class in opal is an instance of RClass.
428
+
429
+ @constructor
430
+ @param {RClass} klass
431
+ @param {RClass} super_klass
432
+ */
433
+ var RClass = Vm.RClass = function(klass, super_klass) {
434
+ this.$id = yield_hash();
435
+ this.$super = super_klass;
436
+
437
+ if (super_klass) {
438
+ var ctor = function() {};
439
+ ctor.prototype = super_klass.$m_prototype_tbl;
440
+
441
+ var m_ctor = function() {};
442
+ m_ctor.prototype = new ctor();
443
+
444
+ this.$m_tbl = new m_ctor();
445
+ this.$m_prototype_tbl = m_ctor.prototype;
446
+
447
+ var cctor = function() {};
448
+ cctor.prototype = super_klass.$c_prototype;
449
+
450
+ var c_ctor = function() {};
451
+ c_ctor.prototype = new cctor();
452
+
453
+ this.$c = new c_ctor();
454
+ this.$c_prototype = c_ctor.prototype;
455
+ }
456
+ else {
457
+ var m_ctor = function() {};
458
+ this.$m_tbl = new m_ctor();
459
+ this.$m_prototype_tbl = m_ctor.prototype;
460
+
461
+ var c_ctor = function() {};
462
+ this.$c = new c_ctor();
463
+ this.$c_prototype = c_ctor.prototype;
464
+ }
465
+
466
+ this.$method_table = {};
467
+ return this;
468
+ };
469
+
470
+ // RClass protoype for minimizing
471
+ var Rp = RClass.prototype;
472
+
473
+ /**
474
+ Flags. Every RClass instance is simply a T_CLASS, so mark as so.
475
+ */
476
+ Rp.$flags = T_CLASS;
477
+
478
+ /**
479
+ RTest/truthiness - every RClass instance is true.
480
+ */
481
+ Rp.$r = true;
482
+
483
+ /**
484
+ The root object. Every object in opal (apart from toll free bridged classes
485
+ like array, string etc) are an instance of RObject.
486
+
487
+ @param {RClass} klass
488
+ */
489
+ var RObject = Vm.RObject = function(klass) {
490
+ this.$id = yield_hash();
491
+ this.$klass = klass;
492
+ this.$m = klass.$m_tbl;
493
+ return this;
494
+ };
495
+
496
+ // For minimizing
497
+ var Bp = RObject.prototype;
498
+
499
+ /**
500
+ Flags - every RObject instance is simply a T_OBJECT
501
+ */
502
+ Bp.$flags = T_OBJECT;
503
+
504
+ /**
505
+ RTest - every RObject instance is true.
506
+ */
507
+ Bp.$r = true;
508
+
509
+ /**
510
+ The hash of a class or object in ruby is simply it's id, as all objects and
511
+ classes have unique ids.
512
+ */
513
+ Bp.$hash = Rp.$hash = function() {
514
+ return this.$id;
515
+ };
516
+
517
+ /**
518
+ Internal method for defining a method.
519
+
520
+ @param {RClass} klass The klass to define the method on
521
+ @param {String} name The method id
522
+ @param {Function} body Method implementation
523
+ @return {Qnil}
524
+ */
525
+ function define_method(klass, name, body) {
526
+ klass.$m_prototype_tbl[name] = body;
527
+ klass.$method_table[name] = body;
528
+
529
+ if (klass.$included_in) {
530
+ for (var i = 0; i < klass.$included_in.length; i++) {
531
+ klass.$included_in[i].$m_prototype_tbl[name] = body;
532
+ klass.$included_in[i].$method_table[name] = body;
533
+ }
534
+ }
535
+
536
+ if (!body.$rbName) {
537
+ body.$rbName = name;
538
+ }
539
+
540
+ return Qnil;
541
+ };
542
+
543
+ Vm.define_method = define_method;
544
+
545
+ function define_singleton_method(klass, name, body) {
546
+ define_method(singleton_class(klass), name, body);
547
+ };
548
+
549
+ function define_alias(base, new_name, old_name) {
550
+ define_method(base, new_name, base.$m_tbl[old_name]);
551
+ return Qnil;
552
+ };
553
+
554
+ /**
555
+ Implementation for Class#allocate
556
+ */
557
+ function obj_alloc(klass) {
558
+ var result = new RObject(klass, T_OBJECT);
559
+ return result;
560
+ };
561
+
562
+ /**
563
+ Raise the exception class with the given string message.
564
+ */
565
+ function raise(exc, str) {
566
+ if (str === undefined) {
567
+ str = exc;
568
+ exc = eException;
569
+ }
570
+ var exception = exc.$m.allocate(exc);
571
+ exception.message = str;
572
+ vm_raise(exception);
573
+ };
574
+
575
+ /**
576
+ Raise an exception instance (DO NOT pass strings to this)
577
+ */
578
+ function vm_raise(exc) {
579
+ throw exc;
580
+ };
581
+
582
+ Vm.raise = vm_raise;
583
+
584
+ /**
585
+ Throw an argument error when the wrong number of arguments were given to a
586
+ method.
587
+
588
+ @param {Number} given The number of arguments actually given
589
+ @param {Number} expected The number of arguments we expected to have
590
+ */
591
+ function arg_error(given, expected) {
592
+ raise(eArgError,
593
+ "wrong number of arguments(" + given + " for " + expected + ")");
594
+ };
595
+
596
+ /**
597
+ Call a super method.
598
+
599
+ callee is the function that actually called super(). We use this to find
600
+ the right place in the tree to find the method that actually called super.
601
+ This is actually done in super_find.
602
+ */
603
+ Vm.S = function(callee, self, args) {
604
+ var mid = callee.$rbName;
605
+ var func = super_find(self.$klass, callee, callee.$rbName);
606
+
607
+ if (!func) {
608
+ raise(eNoMethodError, "super: no superclass method for " + mid);
609
+ raise(eNoMethodError, "super: no super class method `" + mid + "`" +
610
+ " for " + self.$m.inspect(self));
611
+ }
612
+
613
+ var args_to_send = [self, mid].concat(args);
614
+ return func.apply(null, args_to_send);
615
+ };
616
+
617
+ /**
618
+ Actually find super impl to call. Returns null if cannot find it.
619
+ */
620
+ function super_find(klass, callee, mid) {
621
+ var cur_method;
622
+
623
+ while (klass) {
624
+ if (klass.$method_table[mid]) {
625
+ if (klass.$method_table[mid] == callee) {
626
+ break;
627
+ }
628
+ }
629
+ klass = klass.$super;
630
+ }
631
+
632
+ if (!klass) { return null; }
633
+
634
+ klass = klass.$super;
635
+
636
+ while (klass) {
637
+ if (klass.$method_table[mid]) {
638
+ return klass.$method_table[mid];
639
+ }
640
+
641
+ klass = klass.$super;
642
+ }
643
+
644
+ return null;
645
+ };
646
+
647
+ /**
648
+ VM method to get a contant from the given base.
649
+
650
+ @global
651
+ */
652
+ rb_vm_cg = function(base, id) {
653
+ if (base.$flags & T_OBJECT) {
654
+ base = class_real(base.$klass);
655
+ }
656
+ return const_get(base, id);
657
+ };
658
+
659
+ /**
660
+ VM method to set a contant in base.
661
+
662
+ @global
663
+ */
664
+ rb_vm_cs = function(base, id, val) {
665
+ if (base.$flags & T_OBJECT) {
666
+ base = class_real(base.$klass);
667
+ }
668
+ return const_set(base, id, val);
669
+ };
670
+
671
+ /**
672
+ Get global by id
673
+ */
674
+ Vm.gg = function(id) {
675
+ return gvar_get(id);
676
+ };
677
+
678
+ /**
679
+ Set global by id
680
+ */
681
+ Vm.gs = function(id, value) {
682
+ return gvar_set(id, value);
683
+ };
684
+
685
+ /**
686
+ Getter method for getting the load path for opal.
687
+
688
+ @param {String} id The globals id being retrieved.
689
+ @return {Array} Load paths
690
+ */
691
+ function load_path_getter(id) {
692
+ return opal.loader.paths;
693
+ };
694
+
695
+ /**
696
+ Getter method to get all loaded features.
697
+
698
+ @param {String} id Feature global id
699
+ @return {Array} Loaded features
700
+ */
701
+ function loaded_feature_getter(id) {
702
+ return loaded_features;
703
+ };
704
+
705
+ /**
706
+ Main init method. This is called once this file has fully loaded. It setups
707
+ all the core objects and classes and required runtime features.
708
+ */
709
+ function init() {
710
+
711
+ var metaclass;
712
+
713
+ Vm.BasicObject = cBasicObject = boot_defrootclass('BasicObject');
714
+ Vm.Object = cObject = boot_defclass('Object', cBasicObject);
715
+ Vm.Module = cModule = boot_defclass('Module', cObject);
716
+ Vm.Class = cClass = boot_defclass('Class', cModule);
717
+
718
+ const_set(cObject, 'BasicObject', cBasicObject);
719
+
720
+ metaclass = make_metaclass(cBasicObject, cClass);
721
+ metaclass = make_metaclass(cObject, metaclass);
722
+ metaclass = make_metaclass(cModule, metaclass);
723
+ metaclass = make_metaclass(cClass, metaclass);
724
+
725
+ boot_defmetametaclass(cModule, metaclass);
726
+ boot_defmetametaclass(cObject, metaclass);
727
+ boot_defmetametaclass(cBasicObject, metaclass);
728
+
729
+ define_method(cBasicObject, "!", obj_not);
730
+ define_method(cBasicObject, "!=", obj_not_equal);
731
+
732
+ mKernel = define_module('Kernel');
733
+
734
+ include_module(cObject, mKernel);
735
+
736
+ define_method(cClass, "allocate", obj_alloc);
737
+ define_method(cClass, "new", class_new_instance);
738
+ define_method(cClass, "initialize", class_initialize);
739
+ define_singleton_method(cClass, "new", class_s_new);
740
+
741
+ define_method(mKernel, "puts", obj_puts);
742
+
743
+ Qself = obj_alloc(cObject);
744
+ Vm.top = Qself;
745
+
746
+ cNilClass = define_class('NilClass', cObject);
747
+ Vm.Qnil = Qnil = obj_alloc(cNilClass);
748
+ Qnil.$r = false;
749
+
750
+ cTrueClass = define_class('TrueClass', cObject);
751
+ Vm.Qtrue = Qtrue = obj_alloc(cTrueClass);
752
+
753
+ cFalseClass = define_class('FalseClass', cObject);
754
+ Vm.Qfalse = Qfalse = obj_alloc(cFalseClass);
755
+ Qfalse.$r = false;
756
+
757
+ cArray = bridge_class(Array.prototype,
758
+ T_OBJECT | T_ARRAY, 'Array', cObject);
759
+
760
+ Array.prototype.$hash = function() {
761
+ return (this.$id || (this.$id = yield_hash()));
762
+ };
763
+
764
+ cNumeric = bridge_class(Number.prototype,
765
+ T_OBJECT | T_NUMBER, 'Numeric', cObject);
766
+
767
+ cHash = bridge_class(RHash.prototype,
768
+ T_OBJECT | T_HASH, 'Hash', cObject);
769
+
770
+ RHash.prototype.$hash = function() {
771
+ return (this.$id || (this.$id = yield_hash()));
772
+ };
773
+
774
+ define_singleton_method(cHash, '[]', hash_s_create);
775
+
776
+ cRegexp = bridge_class(RegExp.prototype, T_OBJECT,
777
+ 'Regexp', cObject);
778
+
779
+ define_hooked_variable('$:', load_path_getter, gvar_readonly_setter);
780
+ define_hooked_variable('$LOAD_PATH', load_path_getter, gvar_readonly_setter);
781
+
782
+ const_set(cObject, 'ARGV', []);
783
+
784
+ eException = bridge_class(Error.prototype, T_OBJECT, 'Exception', cObject);
785
+
786
+ eStandardError = define_class("StandardError", eException);
787
+ eRuntimeError = define_class("RuntimeError", eException);
788
+ eLocalJumpError = define_class("LocalJumpError", eStandardError);
789
+ eTypeError = define_class("TypeError", eStandardError);
790
+ eNameError = define_class("NameError", eStandardError);
791
+ eNoMethodError = define_class('NoMethodError', eNameError);
792
+ eArgError = define_class('ArgumentError', eStandardError);
793
+ eScriptError = define_class('ScriptError', eException);
794
+ eLoadError = define_class('LoadError', eScriptError);
795
+
796
+ eIndexError = define_class("IndexError", eStandardError);
797
+ eKeyError = define_class("KeyError", eIndexError);
798
+ eRangeError = define_class("RangeError", eStandardError);
799
+
800
+ rb_vm_break_instance = new Error('unexpected break');
801
+ rb_vm_break_instance.$klass = eLocalJumpError;
802
+ rb_vm_break_instance.$keyword = 2;
803
+
804
+ rb_vm_return_instance = new Error('unexpected return');
805
+ rb_vm_return_instance.$klass = eLocalJumpError;
806
+ rb_vm_return_instance.$keyword = 1;
807
+
808
+ rb_vm_next_instance = new Error('unexpected next');
809
+ rb_vm_next_instance.$klass = eLocalJumpError;
810
+ rb_vm_next_instance.$keyword = 3;
811
+
812
+ cString = bridge_class(String.prototype,
813
+ T_OBJECT | T_STRING, 'String', cObject);
814
+
815
+ cSymbol = define_class('Symbol', cObject);
816
+
817
+ cProc = bridge_class(Function.prototype,
818
+ T_OBJECT | T_PROC, 'Proc', cObject);
819
+
820
+ Function.prototype.$hash = function() {
821
+ return (this.$id || (this.$id = yield_hash()));
822
+ };
823
+
824
+ cRange = bridge_class(RRange.prototype, T_OBJECT | T_RANGE,
825
+ 'Range', cObject);
826
+
827
+ RRange.prototype.$hash = function() {
828
+ return (this.$id || (this.$id = yield_hash()));
829
+ };
830
+
831
+ const_set(cObject, 'RUBY_PLATFORM', 'opal');
832
+ };
833
+
834
+ /**
835
+ Define a top level module with the given id
836
+ */
837
+ function define_module(id) {
838
+ return define_module_under(cObject, id);
839
+ };
840
+
841
+ function define_module_under(base, id) {
842
+ var module;
843
+
844
+ if (const_defined(base, id)) {
845
+ module = const_get(base, id);
846
+ if (module.$flags & T_MODULE) {
847
+ return module;
848
+ }
849
+
850
+ throw id + " is not a module.";
851
+ }
852
+
853
+ module = define_module_id(id);
854
+ const_set(base, id, module);
855
+ module.$parent = base;
856
+ return module;
857
+ };
858
+
859
+ function define_module_id(id) {
860
+ var module = define_class_id(id, cModule);
861
+ module.$flags = T_MODULE;
862
+ name_class(module, id);
863
+ return module;
864
+ };
865
+
866
+ function mod_create() {
867
+ return class_boot(cModule);
868
+ };
869
+
870
+ function include_module(klass, module) {
871
+
872
+ if (!klass.$included_modules) {
873
+ klass.$included_modules = [];
874
+ }
875
+
876
+ if (klass.$included_modules.indexOf(module) != -1) {
877
+ return;
878
+ }
879
+ klass.$included_modules.push(module);
880
+
881
+ if (!module.$included_in) {
882
+ module.$included_in = [];
883
+ }
884
+
885
+ module.$included_in.push(klass);
886
+
887
+ for (var method in module.$method_table) {
888
+ if (module.$method_table.hasOwnProperty(method)) {
889
+ define_method(klass, method, module.$method_table[method]);
890
+ }
891
+ }
892
+ };
893
+
894
+ Vm.include_module = include_module;
895
+
896
+ function extend_module(klass, module) {
897
+ if (!klass.$extended_modules) {
898
+ klass.$extended_modules = [];
899
+ }
900
+
901
+ if (klass.$extended_modules.indexOf(module) != -1) {
902
+ return;
903
+ }
904
+ klass.$extended_modules.push(module);
905
+
906
+ if (!module.$extended_in) {
907
+ module.$extended_in = [];
908
+ }
909
+
910
+ module.$extended_in.push(klass);
911
+
912
+ var meta = klass.$klass;
913
+
914
+ for (var method in module.$method_table) {
915
+ if (module.$method_table.hasOwnProperty(method)) {
916
+ define_method(meta, method, module.$method_table[method]);
917
+ }
918
+ }
919
+ };
920
+
921
+ Vm.extend_module = extend_module;
922
+
923
+ /**
924
+ Boot a base class (only used for very core object classes)
925
+ */
926
+ function boot_defclass(id, super_klass) {
927
+ var result = class_boot(super_klass);
928
+ name_class(result, id);
929
+ const_set((cObject || result), id, result);
930
+ return result;
931
+ };
932
+
933
+ /**
934
+ Like boot_defclass, but for root object only (i.e. basicobject)
935
+ */
936
+ function boot_defrootclass(id) {
937
+ var result = new RClass(null, null);
938
+ result.$flags = T_CLASS;
939
+ name_class(result, id);
940
+ const_set((cObject || result), id, result);
941
+ return result;
942
+ };
943
+
944
+ function class_boot(super_class) {
945
+ if (super_class) {
946
+ var ctor = function() {};
947
+ ctor.prototype = super_class.constructor.prototype;
948
+
949
+ var result = function() {
950
+ RClass.call(this, null, super_class);
951
+ return this;
952
+ };
953
+ result.prototype = new ctor();
954
+
955
+ var klass = new result();
956
+ klass.$klass = cClass;
957
+ return klass;
958
+ }
959
+ else {
960
+ var result = new RClass(null, null);
961
+ return result;
962
+ }
963
+ };
964
+
965
+ /**
966
+ @global
967
+ */
968
+ function class_real(klass) {
969
+ while (klass.$flags & FL_SINGLETON) { klass = klass.$super; }
970
+ return klass;
971
+ };
972
+
973
+ Vm.class_real = class_real;
974
+
975
+ /**
976
+ Name the class with the given id.
977
+ */
978
+ function name_class(klass, id) {
979
+ klass.__classid__ = id;
980
+ };
981
+
982
+ /**
983
+ Make metaclass for the given class
984
+ */
985
+ function make_metaclass(klass, super_class) {
986
+ if ((klass.$flags & T_CLASS) && (klass.$flags & FL_SINGLETON)) {
987
+ return make_metametaclass(klass);
988
+ }
989
+ else {
990
+ var meta = class_boot(super_class);
991
+ meta.$flags |= FL_SINGLETON;
992
+ klass.$klass = meta;
993
+ klass.$m = meta.$m_tbl;
994
+ meta.$c = klass.$c;
995
+ singleton_class_attached(meta, klass);
996
+
997
+ return meta;
998
+ }
999
+ };
1000
+
1001
+ function singleton_class_attached(klass, obj) {
1002
+ if (klass.$flags & FL_SINGLETON) {
1003
+ ivar_set(klass, '__attached__', obj);
1004
+ }
1005
+ };
1006
+
1007
+ function make_metametaclass(metaclass) {
1008
+ var metametaclass, super_of_metaclass;
1009
+
1010
+ if (metaclass.$klass == metaclass) {
1011
+ metametaclass = class_boot(null);
1012
+ metametaclass.$klass = metametaclass;
1013
+ }
1014
+ else {
1015
+ metametaclass = class_boot(null);
1016
+ metametaclass.$klass = metaclass.$klass.$klass == metaclass.$klass
1017
+ ? make_metametaclass(metaclass.$klass)
1018
+ : metaclass.$klass.$klass;
1019
+ }
1020
+
1021
+ metametaclass.$flags |= FL_SINGLETON;
1022
+
1023
+ singleton_class_attached(metametaclass, metaclass);
1024
+ metaclass.$klass = metametaclass;
1025
+ metaclass.$m = metametaclass.$m_tbl;
1026
+ super_of_metaclass = metaclass.$super;
1027
+
1028
+ metametaclass.$super = ivar_get(super_of_metaclass.$klass, '__attached__')
1029
+ == super_of_metaclass
1030
+ ? super_of_metaclass.$klass
1031
+ : make_metametaclass(super_of_metaclass);
1032
+
1033
+ return metametaclass;
1034
+ };
1035
+
1036
+ function boot_defmetametaclass(klass, metametaclass) {
1037
+ klass.$klass.$klass = metametaclass;
1038
+ };
1039
+
1040
+ /**
1041
+ Define toll free bridged class
1042
+ */
1043
+ function bridge_class(prototype, flags, id, super_class) {
1044
+ var klass = define_class(id, super_class);
1045
+
1046
+ prototype.$klass = klass;
1047
+ prototype.$m = klass.$m_tbl;
1048
+ prototype.$flags = flags;
1049
+ prototype.$r = true;
1050
+
1051
+ prototype.$hash = function() {
1052
+ return flags + '_' + this;
1053
+ };
1054
+
1055
+ return klass;
1056
+ };
1057
+
1058
+ /**
1059
+ Define a new class (normal way), with the given id and superclass. Will be
1060
+ top level.
1061
+ */
1062
+ function define_class(id, super_klass) {
1063
+ return define_class_under(cObject, id, super_klass);
1064
+ };
1065
+
1066
+ function define_class_under(base, id, super_klass) {
1067
+ var klass;
1068
+
1069
+ if (const_defined(base, id)) {
1070
+ return const_get(base, id);
1071
+ }
1072
+
1073
+ klass = define_class_id(id, super_klass);
1074
+
1075
+ name_class(klass, id);
1076
+ const_set(base, id, klass);
1077
+ klass.$parent = base;
1078
+ return klass;
1079
+ };
1080
+
1081
+ /**
1082
+ Actually create class
1083
+ */
1084
+ function define_class_id(id, super_klass) {
1085
+ var klass;
1086
+
1087
+ if (!super_klass) {
1088
+ super_klass = cObject;
1089
+ }
1090
+ klass = class_create(super_klass);
1091
+ name_class(klass, id);
1092
+ make_metaclass(klass, super_klass.$klass);
1093
+ return klass;
1094
+ };
1095
+
1096
+ function class_create(super_klass) {
1097
+ return class_boot(super_klass);
1098
+ };
1099
+
1100
+ /**
1101
+ Get singleton class of obj
1102
+ */
1103
+ function singleton_class(obj) {
1104
+ var obj;
1105
+
1106
+ if ((obj.$klass.$flags & FL_SINGLETON)&& ivar_get(obj.$klass, '__attached__') == obj) {
1107
+ klass = obj.$klass;
1108
+ }
1109
+ else {
1110
+ var class_id = obj.$klass.__classid__;
1111
+ klass = make_metaclass(obj, obj.$klass);
1112
+ }
1113
+
1114
+ return klass;
1115
+ };
1116
+
1117
+ function RHash(args) {
1118
+ var k, v;
1119
+ this.$keys = [];
1120
+ this.$assocs = {};
1121
+ this.$default = Qnil;
1122
+
1123
+ for (var i = 0; i < args.length; i++) {
1124
+ k = args[i];
1125
+ v = args[i+1];
1126
+ i++;
1127
+ this.$keys.push(k);
1128
+ this.$assocs[k.$hash()] = v;
1129
+ }
1130
+ return this;
1131
+ };
1132
+
1133
+ /**
1134
+ Symbol table. All symbols are stored here.
1135
+ */
1136
+ var symbol_table = { };
1137
+
1138
+ /**
1139
+ Range ruby object
1140
+ */
1141
+ function RRange(beg, end, exclude_end) {
1142
+ this.$beg = beg;
1143
+ this.$end = end;
1144
+ this.$exc = exclude_end;
1145
+ return this;
1146
+ };
1147
+
1148
+ /**
1149
+ Creates a new hash populated with the given objects. Equivalent to the
1150
+ literal `{ key => value, ... }`.
1151
+
1152
+ @example
1153
+ Hash["a", 100, "b", 200]
1154
+ # => {"a" =>100, "b"=>200}
1155
+
1156
+ @return [Hash]
1157
+ */
1158
+ function hash_s_create(obj, mid) {
1159
+ return opalhash.apply(null, Array.prototype.slice.call(arguments, 2));
1160
+ };
1161
+
1162
+ function class_s_new(cls, sup) {
1163
+ var klass = define_class_id("AnonClass", sup || cObject);
1164
+ return klass;
1165
+ };
1166
+
1167
+ function class_new_instance(cls) {
1168
+ var obj = cls.$m.allocate(cls);
1169
+ var args = Array.prototype.slice.call(arguments, 1);
1170
+ args.unshift(obj);
1171
+
1172
+ if (Vm.P.f == arguments.callee) {
1173
+ VM.P.f = obj.$m.initialize;
1174
+ }
1175
+
1176
+ obj.$m.initialize.apply(obj, args);
1177
+ return obj;
1178
+ };
1179
+
1180
+ function class_initialize(cla, mid, sup) {
1181
+ var klass = define_class_id('', sup || cObject);
1182
+ return klass;
1183
+ };
1184
+
1185
+ /**
1186
+ Prints each argument in turn to the browser console. Currently there is no
1187
+ use of `$stdout`, so it is hardcoded into this method to write to the
1188
+ console directly.
1189
+
1190
+ @param {Object} args objects to print using `inspect`
1191
+ @return {nil}
1192
+ */
1193
+ function obj_puts(obj) {
1194
+ var args = Array.prototype.slice.call(arguments, 1);
1195
+
1196
+ for (var i = 0; i < args.length; i++) {
1197
+ console.log((args[i].$m.to_s(args[i])).toString());
1198
+ }
1199
+
1200
+ return Qnil;
1201
+ };
1202
+
1203
+ /**
1204
+ @example
1205
+ !obj # => true or false
1206
+ */
1207
+ function obj_not(obj, mid) {
1208
+ return obj.$r ? Qfalse : Qtrue;
1209
+ };
1210
+
1211
+ /**
1212
+ @example
1213
+ obj != obj2 # => true or false
1214
+ */
1215
+ function obj_not_equal(obj1, mid, obj2) {
1216
+ var res = obj1.$m['=='](obj1, obj2);
1217
+ return res.$r ? Qfalse : Qtrue;
1218
+ };
1219
+
1220
+ // ..........................................................
1221
+ // FILESYSTEM
1222
+ //
1223
+
1224
+ // added to main opal namespace, and Fs for minimizing here.
1225
+ var Fs = Op.fs = {};
1226
+
1227
+ /**
1228
+ Regular expression used for splitting filenames into their dirname,
1229
+ basename and extension. This is unix style only, as filenames inside
1230
+ opal in the browser will only ever have this style of filename. The gem
1231
+ fs support will depend on the platform being run.
1232
+ **/
1233
+ var PATH_RE = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
1234
+
1235
+ /**
1236
+ Holds the current working directory for the application. This is '/' by
1237
+ default, but is usually set to the base directory of the main gem.
1238
+
1239
+ @type {String}
1240
+ */
1241
+ Fs.cwd = '/';
1242
+
1243
+ /**
1244
+ Join the given args using the default seperator. The path returned is not
1245
+ expanded.
1246
+
1247
+ @param {arguments<String<} args The arguments to join
1248
+ @return {String}
1249
+ */
1250
+ var file_join = Fs.join = function() {
1251
+ var parts = [].slice.call(arguments, 0);
1252
+ return parts.join('/');
1253
+ };
1254
+
1255
+ /**
1256
+ Normalize the path by removing '..' and '.' parts, remove '//' etc to
1257
+ return a nice normalized path.
1258
+
1259
+ @param {String} path The path needing normalization
1260
+ @param {String} base Optional base to normalize to
1261
+ @return {String} Normalized path
1262
+ */
1263
+ var file_expand_path = Fs.expand_path = function(path, base) {
1264
+ path = file_join(base || Fs.cwd, path);
1265
+
1266
+ var parts = path.split('/'), result = [], part;
1267
+
1268
+ // initial /
1269
+ if (parts[0] === '') result.push('');
1270
+
1271
+ for (var i = 0, ii = parts.length; i < ii; i++) {
1272
+ part = parts[i];
1273
+
1274
+ if (part == '..') {
1275
+ result.pop();
1276
+ }
1277
+ else if (part == '.' || part == '') {
1278
+
1279
+ }
1280
+ else {
1281
+ result.push(part);
1282
+ }
1283
+ }
1284
+
1285
+ return result.join('/');
1286
+ };
1287
+
1288
+ /**
1289
+ Returns all of the components of the given `file_name` except for the last
1290
+ one.
1291
+
1292
+ @param {String} file_name
1293
+ @return {String}
1294
+ */
1295
+ var file_dirname = Fs.dirname = function(file_name) {
1296
+ var dirname = PATH_RE.exec(file_name)[1];
1297
+
1298
+ if (!dirname) return '.';
1299
+ else if (dirname === '/') return dirname;
1300
+ else return dirname.substring(0, dirname.length - 1);
1301
+ };
1302
+
1303
+ /**
1304
+ Returns the file extension of the given `file_name`.
1305
+
1306
+ @param {String} file_name
1307
+ @return {String}
1308
+ */
1309
+ Fs.extname = function(file_name) {
1310
+ var extname = PATH_RE.exec(file_name)[3];
1311
+
1312
+ if (!extname || extname === '.') return '';
1313
+ else return extname;
1314
+ };
1315
+
1316
+
1317
+ // ..........................................................
1318
+ // LOADER
1319
+ //
1320
+
1321
+ /**
1322
+ Require a module.
1323
+
1324
+ @param {String} id The module id
1325
+ @return {Object} returns the exports
1326
+ */
1327
+ Op.require = function(id, parent) {
1328
+ var resolved = Op.loader.resolve_module(id, null);
1329
+ var cached = Op.cache[resolved];
1330
+
1331
+ if (cached) {
1332
+ return true;
1333
+ }
1334
+
1335
+ Op.cache[resolved] = true;
1336
+ // try/catch?
1337
+ load_file(Op.loader, resolved);
1338
+
1339
+ return true;
1340
+ };
1341
+
1342
+ // Virtual machine must also be able to require..
1343
+ Vm.require = Op.require;
1344
+
1345
+ /**
1346
+ Register a package with the given package info.
1347
+
1348
+ This will probably (definately??) always be done only in the browser.
1349
+
1350
+ @param {String} name The package name
1351
+ @param {Object} info The package info
1352
+ */
1353
+ Op.register = function(name, info) {
1354
+
1355
+ // make sure we get a string name
1356
+ if (typeof name !== 'string') {
1357
+ throw new Error("Cannot register a package without a proper name");
1358
+ }
1359
+
1360
+ // registering a single module/file
1361
+ if (typeof info === 'string' || typeof info === 'function') {
1362
+ register_module(name, info);
1363
+ }
1364
+ // make sure info is a proper package
1365
+ else if (typeof info === 'object') {
1366
+ register_package(name, info);
1367
+ }
1368
+ // else, we have an error.. we can only register packages or modules
1369
+ else {
1370
+ throw new Error("Invalid package.json data for '" + name + "'");
1371
+ }
1372
+ };
1373
+
1374
+ /**
1375
+ Private method to actually register the package. This is private to
1376
+ avoid external interferance. This will be called from {opal#register}.
1377
+
1378
+ @param {String} name The package name
1379
+ @param {Object} info The package information
1380
+ */
1381
+ var register_package = function(name, info) {
1382
+ var factories = Op.loader.factories,
1383
+ paths = Op.loader.paths;
1384
+
1385
+ // register all files
1386
+ var files = info.files || {};
1387
+
1388
+ // root dir for package is /package_name
1389
+ var root_dir = '/' + name;
1390
+
1391
+ // assume './lib' dir for lib files (for now.. should be dynamic)
1392
+ var lib_dir = './lib';
1393
+
1394
+ // add lib dir to paths
1395
+ paths.unshift(file_expand_path(file_join(root_dir, lib_dir)));
1396
+
1397
+ for (var file in files) {
1398
+ if (files.hasOwnProperty(file)) {
1399
+ // full path to file; we use the root dir
1400
+ var file_path = file_expand_path(file_join(root_dir, file));
1401
+
1402
+ factories[file_path] = files[file];
1403
+ }
1404
+ }
1405
+
1406
+ ////////////////////////////////////////
1407
+ // Autobooting. Basically, autoload opal.
1408
+ //
1409
+ if (name === 'opal') {
1410
+ Op.require(name);
1411
+ }
1412
+ };
1413
+
1414
+ /**
1415
+ Private method to register a single module. These modules are added to the
1416
+ very top level dir: /module_name.js
1417
+ */
1418
+ var register_module = function(name, factory) {
1419
+ // name gets preceeded with a '/' for root files
1420
+ var factory_name = '/' + name;
1421
+
1422
+ Op.loader.factories[factory_name] = factory;
1423
+ };
1424
+
1425
+
1426
+ // valid extensions for loading
1427
+ var load_extensions = {};
1428
+
1429
+ load_extensions['.js'] = function(loader, filename) {
1430
+ var source = loader.module_contents(filename);
1431
+ return execute_file(loader, source, filename);
1432
+ };
1433
+
1434
+ load_extensions['.rb'] = function(loader, filename) {
1435
+ var source = loader.ruby_module_contents(filename);
1436
+ return execute_file(loader, source, filename);
1437
+ };
1438
+
1439
+ /**
1440
+ The loader is the core machinery used for loading and executing modules
1441
+ within opal. An instance of opal will have a .loader property, which
1442
+ is an instance of this Loader class. A Loader is responsible for finding,
1443
+ opening and reading the contents of modules on disk. Within the browser,
1444
+ which is the default environment, a loader will use XHR requests or cached
1445
+ modules from JSON to load the required modules.
1446
+
1447
+ Within the browser, the loader, currently, just looks at its opal
1448
+ instance for registered files and packages and uses them as needed.
1449
+ opal also has 'built in' packages from commonjs, like 'system' etc, so
1450
+ all loaders must check opal first for registered packages.
1451
+
1452
+ @param {opal} opal The opal instance for this loader
1453
+ */
1454
+ var Loader = function(opal) {
1455
+ this.opal = opal;
1456
+ this.paths = [''];
1457
+
1458
+ this.factories = {};
1459
+
1460
+
1461
+ return this;
1462
+ };
1463
+
1464
+ // Loader prototype
1465
+ var Lp = Loader.prototype;
1466
+
1467
+ /**
1468
+ The paths property is an array of disk paths in which to search for
1469
+ required modules. In the browser this functionality isn't really used.
1470
+
1471
+ This array is created within the constructor method for uniqueness
1472
+ between instances for correct sandboxing.
1473
+ */
1474
+ Lp.paths = null;
1475
+
1476
+ /**
1477
+ factories of registered packages, paths => function/string. This is
1478
+ generic, but in reality only the browser uses this, and it is treated
1479
+ as the mini filesystem. Not just factories can go here, anything can!
1480
+ Images, text, json, whatever.
1481
+ */
1482
+ Lp.factories = {};
1483
+
1484
+ /**
1485
+ Valid factory format for use in require();
1486
+ */
1487
+ Lp.valid_extensions = ['.js', '.rb'];
1488
+
1489
+ /**
1490
+ Resolves the path to the module, which can then be used to load. This
1491
+ method will throw an error if the module cannot be found. If this method
1492
+ returns a successful filename, then subsequent methods like load_module
1493
+ should be successful and should not throw errors.
1494
+
1495
+ @param {String} id The id to look for
1496
+ @param {Module} parent The module that has requested the id
1497
+ */
1498
+ Lp.resolve_module = function(id, parent) {
1499
+ var resolved = this.find_module(id, this.paths);
1500
+
1501
+ if (!resolved) {
1502
+ throw new Error("Cannot find module '" + id + "'");
1503
+ }
1504
+
1505
+ return resolved;
1506
+ };
1507
+
1508
+ Lp.find_module = function(id, paths) {
1509
+ var extensions = this.valid_extensions, factories = this.factories, candidate;
1510
+
1511
+ for (var i = 0, ii = paths.length; i < ii; i++) {
1512
+ for (var j = 0, jj = extensions.length; j < jj; j++) {
1513
+ candidate = file_join(paths[i], id + extensions[j]);
1514
+
1515
+ console.log(candidate);
1516
+ if (factories[candidate]) {
1517
+ return candidate;
1518
+ }
1519
+ }
1520
+ }
1521
+
1522
+ return null;
1523
+ };
1524
+
1525
+ /**
1526
+ Module contents
1527
+ */
1528
+ Lp.module_contents = function(filename) {
1529
+ return this.factories[filename];
1530
+ };
1531
+
1532
+ /**
1533
+ Actually load the file with the given resolved filename. This filename has
1534
+ been checked, and is known to exist.
1535
+ */
1536
+ function load_file(loader, filename) {
1537
+ var extension = load_extensions[PATH_RE.exec(filename)[3] || '.js'];
1538
+
1539
+ if (!extension) {
1540
+ throw new Error("Loader.load - Bad extension for resolved path");
1541
+ }
1542
+
1543
+ extension(loader, filename);
1544
+ };
1545
+
1546
+ /**
1547
+ Run content, which by now must be javascript. If the content is a string,
1548
+ then it is simply evaluated. Within the browser it might be a function, so
1549
+ we call it, passing our standard args.
1550
+
1551
+ The arguments we pass are standardised as:
1552
+
1553
+ VM - Our opal vm variable which exposes runtime methods
1554
+ Qself - the top level ruby object, which is the 'self' for files
1555
+ filename - the Filename to run the file as for __FILE__
1556
+
1557
+ @param {String, Function} content The javascript content to be run.
1558
+ @param {String} filename Filename to run content as.
1559
+ */
1560
+ function execute_file(loader, content, filename) {
1561
+
1562
+ var args = [Vm, Qself, filename];
1563
+
1564
+ if (typeof content === 'function') {
1565
+ return content.apply(Op, args);
1566
+
1567
+ } else if (typeof content === 'string') {
1568
+ var func = loader.wrap(content, filename);
1569
+ return func.apply(Op, args);
1570
+
1571
+ } else {
1572
+ throw new Error(
1573
+ "Loader.execute - bad content sent for '" + filename + "'");
1574
+ }
1575
+ };
1576
+
1577
+ // ..........................................................
1578
+ // FINAL INITILIZATION
1579
+ //
1580
+
1581
+ // init ruby runtime
1582
+ init();
1583
+
1584
+ // browser based loader - overriden by v8 context
1585
+ Op.loader = new Loader(Op);
1586
+
1587
+ // cache of filenames already evaluated
1588
+ Op.cache = {};
1589
+
1590
+ })();
1591
+
1592
+ // if in a commonjs system already (node etc), exports become our opal
1593
+ // object. Otherwise, in the browser, we just get a top level opal var
1594
+ if ((typeof require !== 'undefined') && (typeof module !== 'undefined')) {
1595
+ module.exports = opal;
1596
+ }
1597
+