opal 0.2.2 → 0.3.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.
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
@@ -1,75 +1,12 @@
1
- #
2
- # vienna.rb
3
- # vienna
4
- #
5
- # Created by Adam Beynon.
6
- # Copyright 2010 Adam Beynon.
7
- #
8
- # Permission is hereby granted, free of charge, to any person obtaining a copy
9
- # of this software and associated documentation files (the "Software"), to deal
10
- # in the Software without restriction, including without limitation the rights
11
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- # copies of the Software, and to permit persons to whom the Software is
13
- # furnished to do so, subject to the following conditions:
14
- #
15
- # The above copyright notice and this permission notice shall be included in
16
- # all copies or substantial portions of the Software.
17
- #
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- # THE SOFTWARE.
25
- #
26
-
27
- require 'fileutils'
28
- require 'base64'
29
1
  require 'rubygems'
30
2
 
31
- module Vienna
32
-
33
- # :stopdoc:
34
- VERSION = '0.2.0'
35
- LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
36
- PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
37
- # :startdoc:
38
-
39
- # Returns the version string for the library.
40
- #
41
- def self.version
42
- VERSION
43
- end
44
-
45
- # Returns the library path for the module. If any arguments are given,
46
- # they will be joined to the end of the libray path using
47
- # <tt>File.join</tt>.
48
- #
49
- def self.libpath( *args )
50
- args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
51
- end
3
+ module Opal
52
4
 
53
- # Returns the lpath for the module. If any arguments are given,
54
- # they will be joined to the end of the path using
55
- # <tt>File.join</tt>.
56
- #
57
- def self.path( *args )
58
- args.empty? ? PATH : ::File.join(PATH, args.flatten)
59
- end
5
+ end
60
6
 
61
- # Utility method used to require all files ending in .rb that lie in the
62
- # directory below this file that has the same name as the filename passed
63
- # in. Optionally, a specific _directory_ name can be passed in such that
64
- # the _filename_ does not have to be equivalent to the directory.
65
- #
66
- def self.require_all_libs_relative_to( fname, dir = nil )
67
- dir ||= ::File.basename(fname, '.*')
68
- search_me = ::File.expand_path(
69
- ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
7
+ require 'opal/ruby/parser'
70
8
 
71
- Dir.glob(search_me).sort.each {|rb| require rb}
72
- end
73
- end
9
+ require 'opal/gem'
10
+ require 'opal/bundle'
11
+ require 'opal/builder'
74
12
 
75
- Vienna.require_all_libs_relative_to(__FILE__)
@@ -0,0 +1,115 @@
1
+ require 'fileutils'
2
+
3
+ module Opal
4
+ # Builder is used for compiling simple ruby files into javascript files
5
+ # through the command line or a rake task. It is used for non bundle based
6
+ # building systems, and is meant for building small scale pages rather than
7
+ # applications.
8
+ class Builder
9
+ # Takes a hash of build options.
10
+ #
11
+ # :project_dir - The base directory to work in. If not given then cwd is used.
12
+ #
13
+ # :files - May be a single source, a directory, or an array of ruby/js src
14
+ #
15
+ # :out - The output file. All sources are built into a single output file.
16
+ # If this is not given, it will default to project_dir/javascripts/name.js
17
+ # where name is the basename of the given project_dir or cwd.
18
+ #
19
+ # :main - only useful when more than one input is given to determine which
20
+ # file is automatically loaded on running in the browser.
21
+ #
22
+ # :watch - watch all sources and automatically recompile if one changes
23
+ #
24
+ # Also, if no output is given, then one file will be used for all sources,
25
+ # and the files name will be taken as the basename of the root_dir/cwd.
26
+ #
27
+ # @param {Hash} options Build options to use
28
+ def initialize(options = {})
29
+ @project_dir = options[:project_dir] || Dir.getwd
30
+ @project_name = File.basename @project_dir
31
+
32
+ out = options[:out] || File.join('javascripts', "#@project_name.js")
33
+ @out = File.join @project_dir, out
34
+ FileUtils.mkdir_p File.dirname(@out)
35
+
36
+ files = options[:files] || []
37
+ @files = []
38
+
39
+ if Array === files
40
+ files.each do |file|
41
+ @files << file
42
+ end
43
+ else
44
+ Dir.glob(File.join(@project_dir, files)) do |file|
45
+ @files << file
46
+ end
47
+ end
48
+
49
+ @watch = options[:watch]
50
+
51
+ raise "Opal::Builder - No input files!" if @files.empty?
52
+ end
53
+
54
+ # Actually build the simple builder. This is simply used as a looper to
55
+ # rebuild if a source file changes. The trigger for a rebuild is when a
56
+ # source file changes. So on each loop, we check if any source file has
57
+ # a newer mtime than the destination file.
58
+ def build
59
+ rebuild
60
+ if @watch
61
+ puts "Watching for changes.."
62
+ loop do
63
+ out_mtime = File.stat(@out).mtime
64
+ @files.each do |file|
65
+ if File.stat(file).mtime > out_mtime
66
+ puts "#{Time.now} rebuilding - changes detected in #{file}"
67
+ rebuild
68
+ end
69
+ end
70
+
71
+ begin
72
+ sleep 1
73
+ rescue Interrupt
74
+ exit 0
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ # Does the actual rebuild of a project
81
+ def rebuild
82
+ File.open(@out, 'w') do |out|
83
+ @files.each do |file|
84
+ out.write wrap_source file
85
+ end
86
+ main = File.basename(@files.first).sub(/\.rb/, '')
87
+ out.write "opal.require('#{main}');\n"
88
+ end
89
+ end
90
+
91
+ # Returns the result of the compiled file ready for opal to load
92
+ #
93
+ # @return {String}
94
+ def wrap_source(path)
95
+ ext_name = File.extname path
96
+
97
+ content = case ext_name
98
+ when '.js'
99
+ source = File.read path
100
+ "function(VM, self, __FILE__) { #{source} }"
101
+
102
+ when '.rb'
103
+ source = Opal::RubyParser.new(File.read(path)).parse!.generate_top
104
+ path = path.sub(/\.rb/, '.js')
105
+ "function(VM, self, __FILE__) { #{source} }"
106
+
107
+ else
108
+ raise "Bad file type for wrapping. Must be ruby or javascript"
109
+ end
110
+
111
+ "opal.register('#{File.basename path}', #{content});\n"
112
+ end
113
+ end
114
+ end
115
+
@@ -0,0 +1,131 @@
1
+ module Opal
2
+
3
+ # The Bundle class is used to bundle a package, and optionally all of its
4
+ # dependencies and the base opal boot file into a js file ready for browser
5
+ # deployment. It takes a package, and a set of options, and simply returns a
6
+ # combined string of the built packages.
7
+ #
8
+ # This does not yet support building resources from the packages. Just the
9
+ # basic package building works.
10
+ #
11
+ # The following options are supported:
12
+ #
13
+ # - `:dependencies` - An array of additional dependencies to add that may not
14
+ # be listed in the .gemspec. This is used, for example, to include opalspec
15
+ # into test builds so that opalspec does not need to be a dependency in all
16
+ # build environments.
17
+ # - `:main` - The file to run in the browser. An example may be
18
+ # 'vienna/autorun'. Note this is not a bin file, and should be a simple lib
19
+ # file that will be in the load path.
20
+ # - `:bin` - Alternatively, a bin file listed within a gem that should be
21
+ # included, and then run within the browser. An example would be
22
+ # 'vienna/vienna', where the first part is the gem containing the bin file,
23
+ # which is named the second part.
24
+ # - `:standalone` - Exclude dependencies listed in the gemspec. This is false
25
+ # by default so all listed dependencies will be recursively added to the
26
+ # resulting file. If set to true, the gemspec dependencies will not be
27
+ # included. This does not affect the `:dependencies` option, which are
28
+ # included seperately to these dependencies.
29
+ # - `:to` - Usually this process will just return a string, but by passing a
30
+ # `:to` option, the result will be written to the file specified by the given
31
+ # name. This only works for simple bundling where no resources are needed.
32
+ class Bundle
33
+
34
+ # Ensure we keep a unique set of packages - we dont want duplications
35
+ attr_reader :handled_packages
36
+
37
+ # Queue of packages waiting to be built
38
+ attr_reader :package_queue
39
+
40
+ # The {Gem} instance to build with a set of optional options.
41
+ #
42
+ # @param [Gem] package The package to build
43
+ # @param {Hash} opts Build options
44
+ def initialize(package, opts = {})
45
+ @package = package
46
+ @options = opts
47
+
48
+ @handled_packages = []
49
+ @package_queue = []
50
+ end
51
+
52
+ # Actually build the bundle. Returns the result, for now, as a string.
53
+ #
54
+ # @return {String} bundled packages
55
+ def build
56
+ result = []
57
+ pkg = nil
58
+
59
+ @package_queue << @package
60
+ @handled_packages << @package.name
61
+
62
+ unless @options[:standalone]
63
+ add_dependency('core', @package)
64
+ end
65
+
66
+ while pkg = @package_queue.pop
67
+ puts pkg
68
+ # if this is our initial package and we are standalone, make sure we
69
+ # pass that option into build package
70
+ if pkg == @package && @options[:standalone]
71
+ puts "standalone #{pkg}"
72
+ result << build_package(pkg, true)
73
+ else
74
+ result << build_package(pkg)
75
+ end
76
+ end
77
+
78
+ unless @options[:standalone]
79
+ result.unshift opal_boot_content
80
+ end
81
+
82
+ if @options[:to]
83
+ File.open(@options[:to], 'w+') { |out| out.write result.join("\n") }
84
+ end
85
+
86
+ result.join "\n"
87
+ end
88
+
89
+ # Boot content for opal. This bootloader takes all the gems in the browser
90
+ # context and manages them. Opal self-loads in the bootloader.
91
+ #
92
+ # @return [String]
93
+ def opal_boot_content
94
+ path = File.expand_path File.join(__FILE__, '..', '..', '..', 'lib', 'opal.js')
95
+ File.read path
96
+ end
97
+
98
+ # Builds a single package. This will build the package, discover its
99
+ # dependencies, and then add them to the queue of packages to build. This
100
+ # method will then return the built package as a string.
101
+ #
102
+ # @param {Package} package The package to build
103
+ # @param {Boolean} standalone Whether to exclude gem dependencies.
104
+ # @return {String} Built package
105
+ def build_package(package, standalone = false)
106
+ # Work through each dependency and work out if we need it
107
+ unless standalone
108
+ package.dependencies.each do |dep|
109
+ add_dependency dep, package
110
+ end
111
+ end
112
+
113
+ package.to_bundle
114
+ end
115
+
116
+ def add_dependency(dep, package)
117
+
118
+ unless @handled_packages.include? dep
119
+ @handled_packages << dep
120
+
121
+ loc = package.find_dependency(dep)
122
+ raise "Cannot find dependency '#{dep}' for #{package}" unless loc
123
+
124
+ pkg = Gem.new loc
125
+ @package_queue << pkg
126
+ end
127
+ end
128
+
129
+ end
130
+ end
131
+
@@ -0,0 +1,11 @@
1
+ module Opal
2
+ module Command
3
+
4
+ def self.ruby_repl
5
+ require 'opal/context'
6
+ ctx = Opal::Context.new
7
+ ctx.start_repl
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,69 @@
1
+ # This file should only be required as needed. This file relies on v8,
2
+ # therubyracer. As this is not an essential feature of opal, this file
3
+ # will be loaded as needed, and when it is, an error is just thrown if
4
+ # the required gems are not installed.
5
+ begin
6
+ require 'v8'
7
+ rescue LoadError => e
8
+ abort "therubyracer is required for running javascript. Install it with `gem install therubyracer`"
9
+ end
10
+
11
+ require 'opal/context/loader'
12
+ require 'opal/context/console'
13
+ require 'opal/context/file_system'
14
+
15
+ module Opal
16
+ class Context < V8::Context
17
+
18
+ def initialize(opts = {})
19
+ super opts
20
+ setup_context
21
+ end
22
+
23
+ # Setup the context. This basically loads opal.js into our context, and
24
+ # replace the loader etc with our custom loader for a Ruby environment. The
25
+ # default "browser" loader cannot access files from disk.
26
+ def setup_context
27
+ self['console'] = Console.new
28
+ load opal_js_path
29
+
30
+ opal = self['opal']
31
+ opal['loader'] = Loader.new opal, self
32
+ # opal['fs'] = FileSystem.new opal, self
33
+
34
+ eval "opal.require('core');", "(opal)"
35
+ end
36
+
37
+ # Returns the path to our main opal.js file. This makes it easier as
38
+ # we will likely require this file more than once (once per context).
39
+ def opal_js_path
40
+ File.expand_path File.join(File.dirname(__FILE__), '..', '..', 'lib', 'opal.js')
41
+ end
42
+
43
+ # Start normal js repl
44
+ def start_repl
45
+ require 'readline'
46
+
47
+ loop do
48
+ line = Readline.readline '>> ', true
49
+ puts "=> #{eval_ruby line, '(opal)'}"
50
+ end
51
+ end
52
+
53
+ def eval_ruby(content, line = "")
54
+ begin
55
+ code = Opal::RubyParser.new(content).parse!.generate_top
56
+ code = "var VM = opal.vm, self = VM.top, __FILE__ = '(opal)';" + code
57
+ # puts code
58
+ self['$opal_irb_result'] = eval code, line
59
+ # self['$code'].to_s + "ww"
60
+ eval "$opal_irb_result.$m.inspect($opal_irb_result);"
61
+ rescue => e
62
+ puts e
63
+ puts("\t" + e.backtrace.join("\n\t"))
64
+ end
65
+ end
66
+ end
67
+
68
+ end
69
+
@@ -0,0 +1,12 @@
1
+
2
+ module Opal
3
+
4
+ class Console
5
+
6
+ def log(*str)
7
+ puts str.join("\n")
8
+ nil
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,19 @@
1
+
2
+ module Opal
3
+ class FileSystem
4
+
5
+ def initialize(opal, context)
6
+ @opal = opal
7
+ @ctx = context
8
+ end
9
+
10
+ def cwd
11
+ Dir.getwd
12
+ end
13
+
14
+ def glob(*arr)
15
+ Dir.glob(arr)
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,117 @@
1
+
2
+ module Opal
3
+ # Custom loader class, which an instance is set on the vienna.loader property
4
+ # to allow for disk based loading and access to modules/packages/gems.
5
+ #
6
+ # For now, this simply adds hard-coded paths to the load path. In future,
7
+ # dynamic package lookup will take place, but for now we just manually loop
8
+ # through gems/packages in this gems' dir, and the cwd dir (in ./vendor/) and
9
+ # add each of their lib/ dirs). Unil we add a custom package manager, this
10
+ # will make it the easiest way of managing packages for vienna.
11
+ class Loader
12
+
13
+ # Load paths. This is an array of all load paths
14
+ attr_reader :paths
15
+
16
+ # The vienna instance for the object
17
+ attr_reader :vienna
18
+
19
+ # @param vienna The js vienna object itself so we can talk to it
20
+ # @param {Vienna::Context} context The v8 context
21
+ def initialize(vienna, context)
22
+ @vienna = vienna
23
+ @ctx = context
24
+ @paths = []
25
+ hardcode_gems
26
+ end
27
+
28
+ # Register all gems - this is currently hardcoded while we don't have a
29
+ # proper package manager. This needs to be replaced to be more dynamic in
30
+ # lookup.
31
+ def hardcode_gems
32
+ core = File.expand_path(File.join(__FILE__, '..', '..', '..', '..', 'gems'))
33
+
34
+ Dir.open(core).each do |entry|
35
+ try_dir = File.join core, entry
36
+ if File.directory?(try_dir) && !['.', '..'].include?(entry)
37
+ add_hardcoded_gem try_dir
38
+ end
39
+ end
40
+ end
41
+
42
+ # Add an individual hardcoded gem by its path. We need to check it has a
43
+ # .gemspec in its dir, then add its lib directory to our path.
44
+ def add_hardcoded_gem(path)
45
+ # make sure gem dir has a gemspec
46
+ gemspec = File.join path, File.basename(path) + '.gemspec'
47
+ return unless File.exists? gemspec
48
+ # make sure gem dir has a lib dir
49
+ libpath = File.join path, 'lib'
50
+ return unless File.exists? libpath
51
+ # all is ok, so add to loadpath
52
+ @paths << libpath
53
+ end
54
+
55
+ # Valid extensions. This should be more dynamic for custom extensions
56
+ def valid_extensions
57
+ %w[.rb .js]
58
+ end
59
+
60
+ # Exposed as replacement method.
61
+ def resolve_module(id, parent)
62
+ resolved = find_module id, @paths
63
+ raise "Cannot find module '#{id}'" unless resolved
64
+ resolved
65
+ end
66
+
67
+ # Resolve the id requested with the given valid paths
68
+ def find_module(id, paths)
69
+ extensions = valid_extensions
70
+
71
+ @paths.each do |path|
72
+
73
+ extensions.each do |ext|
74
+ candidate = File.join(path, id + ext)
75
+
76
+ # if file exists, return it!
77
+ return candidate if File.exists? candidate
78
+ end
79
+ end
80
+
81
+ # if we cannot find it, just return nil
82
+ nil
83
+ end
84
+
85
+ # Returns the contents of the module. This, in ruby, reads from the disk,
86
+ # but the browser uses either XHR or a cached module reference. The
87
+ # method name is kept generic to reflect this.
88
+ #
89
+ # @param {String} filename The filename to load. This is a full filename,
90
+ # not just a module id.
91
+ def module_contents(filename)
92
+ File.read filename
93
+ end
94
+
95
+ # Special version of module contents that will compile the given ruby code
96
+ # at the file into javascript first, before returning it. This is exposed
97
+ # to vienna so that it makes it easier to compile and run ruby from the
98
+ # v8 context. The default implementation of this throws an error to say
99
+ # that in browser ruby code cannot be run.
100
+ def ruby_module_contents(filename)
101
+ parser = Opal::RubyParser.new File.read(filename)
102
+ result = parser.parse!.generate_top
103
+ result
104
+ end
105
+
106
+ # Wraps the content with the given filename. Basically, here we eval
107
+ # the code inside a function which takes our exports, module,
108
+ # require etc, and returns the function ready for calling. If an
109
+ # error occures (likely a parse error) it is just thrown as normal
110
+ def wrap(content, filename)
111
+ code = "(function(VM, self, __FILE__) { #{content} });"
112
+ # puts code
113
+ @ctx.eval code, filename
114
+ end
115
+ end
116
+ end
117
+