opal-browser 0.2.0.beta1 → 0.3.2

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 (218) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/build.yml +95 -0
  3. data/.gitignore +3 -0
  4. data/CHANGELOG.md +8 -0
  5. data/Gemfile +17 -3
  6. data/LICENSE +2 -1
  7. data/README.md +183 -52
  8. data/Rakefile +29 -1
  9. data/config.ru +20 -3
  10. data/docs/polyfills.md +24 -0
  11. data/examples/2048/Gemfile +6 -0
  12. data/examples/2048/README.md +13 -0
  13. data/examples/2048/app/application.rb +169 -0
  14. data/examples/2048/config.ru +9 -0
  15. data/examples/canvas/Gemfile +6 -0
  16. data/examples/canvas/README.md +9 -0
  17. data/examples/canvas/app/application.rb +55 -0
  18. data/examples/canvas/config.ru +9 -0
  19. data/examples/component/Gemfile +6 -0
  20. data/examples/component/README.md +10 -0
  21. data/examples/component/app/application.rb +66 -0
  22. data/examples/component/config.ru +9 -0
  23. data/examples/integrations/README.md +24 -0
  24. data/examples/integrations/dynamic-rack-opal-sprockets-server/Gemfile +6 -0
  25. data/examples/integrations/dynamic-rack-opal-sprockets-server/README.md +16 -0
  26. data/examples/integrations/dynamic-rack-opal-sprockets-server/app/application.rb +6 -0
  27. data/examples/integrations/dynamic-rack-opal-sprockets-server/config.ru +9 -0
  28. data/examples/integrations/dynamic-roda-roda-sprockets/.gitignore +1 -0
  29. data/examples/integrations/dynamic-roda-roda-sprockets/Gemfile +7 -0
  30. data/examples/integrations/dynamic-roda-roda-sprockets/README.md +22 -0
  31. data/examples/integrations/dynamic-roda-roda-sprockets/Rakefile +4 -0
  32. data/examples/integrations/dynamic-roda-roda-sprockets/app/application.rb +6 -0
  33. data/examples/integrations/dynamic-roda-roda-sprockets/app.rb +32 -0
  34. data/examples/integrations/dynamic-roda-roda-sprockets/config.ru +3 -0
  35. data/examples/integrations/dynamic-roda-tilt/.gitignore +1 -0
  36. data/examples/integrations/dynamic-roda-tilt/Gemfile +8 -0
  37. data/examples/integrations/dynamic-roda-tilt/README.md +17 -0
  38. data/examples/integrations/dynamic-roda-tilt/Rakefile +6 -0
  39. data/examples/integrations/dynamic-roda-tilt/app/application.rb +6 -0
  40. data/examples/integrations/dynamic-roda-tilt/app.rb +50 -0
  41. data/examples/integrations/dynamic-roda-tilt/config.ru +3 -0
  42. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/Gemfile +7 -0
  43. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/README.md +16 -0
  44. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/app/application.rb +6 -0
  45. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/config.ru +29 -0
  46. data/examples/integrations/static-bash/.gitignore +2 -0
  47. data/examples/integrations/static-bash/Gemfile +3 -0
  48. data/examples/integrations/static-bash/README.md +8 -0
  49. data/examples/integrations/static-bash/app/application.rb +6 -0
  50. data/examples/integrations/static-bash/build.sh +4 -0
  51. data/examples/integrations/static-bash/index.html +10 -0
  52. data/examples/integrations/static-bash-opal-parser/.gitignore +3 -0
  53. data/examples/integrations/static-bash-opal-parser/Gemfile +3 -0
  54. data/examples/integrations/static-bash-opal-parser/README.md +10 -0
  55. data/examples/integrations/static-bash-opal-parser/build.sh +4 -0
  56. data/examples/integrations/static-bash-opal-parser/index.html +19 -0
  57. data/examples/integrations/static-rake/.gitignore +1 -0
  58. data/examples/integrations/static-rake/Gemfile +4 -0
  59. data/examples/integrations/static-rake/README.md +7 -0
  60. data/examples/integrations/static-rake/Rakefile +10 -0
  61. data/examples/integrations/static-rake/app/application.rb +6 -0
  62. data/examples/integrations/static-rake/index.html +9 -0
  63. data/examples/integrations/static-rake-guard/.gitignore +1 -0
  64. data/examples/integrations/static-rake-guard/Gemfile +6 -0
  65. data/examples/integrations/static-rake-guard/Guardfile +3 -0
  66. data/examples/integrations/static-rake-guard/README.md +10 -0
  67. data/examples/integrations/static-rake-guard/Rakefile +10 -0
  68. data/examples/integrations/static-rake-guard/app/application.rb +6 -0
  69. data/examples/integrations/static-rake-guard/index.html +9 -0
  70. data/examples/svg/.gitignore +1 -0
  71. data/examples/svg/Gemfile +4 -0
  72. data/examples/svg/README.md +7 -0
  73. data/examples/svg/Rakefile +10 -0
  74. data/examples/svg/app/application.rb +11 -0
  75. data/examples/svg/index.html +17 -0
  76. data/examples/svg/index.svg +6 -0
  77. data/index.html.erb +8 -6
  78. data/lib/opal-browser.rb +1 -0
  79. data/opal/browser/animation_frame.rb +26 -1
  80. data/opal/browser/audio/node.rb +121 -0
  81. data/opal/browser/audio/param_schedule.rb +43 -0
  82. data/opal/browser/audio.rb +66 -0
  83. data/opal/browser/blob.rb +94 -0
  84. data/opal/browser/canvas/data.rb +1 -11
  85. data/opal/browser/canvas/gradient.rb +1 -11
  86. data/opal/browser/canvas/style.rb +3 -11
  87. data/opal/browser/canvas/text.rb +1 -11
  88. data/opal/browser/canvas.rb +17 -13
  89. data/opal/browser/console.rb +3 -1
  90. data/opal/browser/cookies.rb +78 -42
  91. data/opal/browser/crypto.rb +79 -0
  92. data/opal/browser/css/declaration.rb +1 -1
  93. data/opal/browser/css/rule.rb +1 -1
  94. data/opal/browser/css/style_sheet.rb +2 -2
  95. data/opal/browser/css.rb +23 -7
  96. data/opal/browser/database/sql.rb +193 -0
  97. data/opal/browser/delay.rb +41 -7
  98. data/opal/browser/dom/attribute.rb +13 -12
  99. data/opal/browser/dom/builder.rb +31 -17
  100. data/opal/browser/dom/document.rb +174 -42
  101. data/opal/browser/dom/document_fragment.rb +18 -0
  102. data/opal/browser/dom/document_or_shadow_root.rb +19 -0
  103. data/opal/browser/dom/element/attributes.rb +111 -0
  104. data/opal/browser/dom/element/button.rb +31 -0
  105. data/opal/browser/dom/element/custom.rb +177 -0
  106. data/opal/browser/dom/element/data.rb +82 -0
  107. data/opal/browser/dom/element/editable.rb +47 -0
  108. data/opal/browser/dom/element/form.rb +38 -0
  109. data/opal/browser/dom/element/iframe.rb +37 -0
  110. data/opal/browser/dom/element/image.rb +2 -0
  111. data/opal/browser/dom/element/input.rb +48 -1
  112. data/opal/browser/dom/element/media.rb +17 -0
  113. data/opal/browser/dom/element/offset.rb +5 -0
  114. data/opal/browser/dom/element/position.rb +11 -2
  115. data/opal/browser/dom/element/scroll.rb +123 -24
  116. data/opal/browser/dom/element/select.rb +42 -0
  117. data/opal/browser/dom/element/size.rb +17 -0
  118. data/opal/browser/dom/element/template.rb +11 -0
  119. data/opal/browser/dom/element/textarea.rb +26 -0
  120. data/opal/browser/dom/element.rb +468 -238
  121. data/opal/browser/dom/mutation_observer.rb +4 -4
  122. data/opal/browser/dom/node.rb +142 -60
  123. data/opal/browser/dom/node_set.rb +73 -44
  124. data/opal/browser/dom/shadow_root.rb +12 -0
  125. data/opal/browser/dom/text.rb +2 -2
  126. data/opal/browser/dom.rb +40 -16
  127. data/opal/browser/effects.rb +180 -3
  128. data/opal/browser/event/all.rb +26 -0
  129. data/opal/browser/{dom/event → event}/animation.rb +4 -2
  130. data/opal/browser/{dom/event → event}/audio_processing.rb +4 -2
  131. data/opal/browser/{dom/event → event}/base.rb +98 -9
  132. data/opal/browser/{dom/event → event}/before_unload.rb +4 -2
  133. data/opal/browser/{dom/event → event}/clipboard.rb +11 -2
  134. data/opal/browser/{dom/event → event}/close.rb +4 -2
  135. data/opal/browser/{dom/event → event}/composition.rb +4 -2
  136. data/opal/browser/{dom/event → event}/custom.rb +3 -3
  137. data/opal/browser/event/data_transfer.rb +95 -0
  138. data/opal/browser/{dom/event → event}/device_light.rb +4 -2
  139. data/opal/browser/{dom/event → event}/device_motion.rb +4 -2
  140. data/opal/browser/{dom/event → event}/device_orientation.rb +4 -2
  141. data/opal/browser/{dom/event → event}/device_proximity.rb +4 -2
  142. data/opal/browser/{dom/event → event}/drag.rb +11 -7
  143. data/opal/browser/{dom/event → event}/focus.rb +4 -2
  144. data/opal/browser/{dom/event → event}/gamepad.rb +5 -3
  145. data/opal/browser/{dom/event → event}/hash_change.rb +4 -2
  146. data/opal/browser/{dom/event → event}/keyboard.rb +16 -3
  147. data/opal/browser/{dom/event → event}/message.rb +4 -2
  148. data/opal/browser/{dom/event → event}/mouse.rb +12 -8
  149. data/opal/browser/{dom/event → event}/page_transition.rb +4 -2
  150. data/opal/browser/{dom/event → event}/pop_state.rb +4 -2
  151. data/opal/browser/{dom/event → event}/progress.rb +4 -2
  152. data/opal/browser/{dom/event → event}/sensor.rb +4 -2
  153. data/opal/browser/{dom/event → event}/storage.rb +4 -2
  154. data/opal/browser/{dom/event → event}/touch.rb +4 -2
  155. data/opal/browser/{dom/event → event}/ui.rb +2 -2
  156. data/opal/browser/{dom/event → event}/wheel.rb +4 -2
  157. data/opal/browser/event.rb +163 -0
  158. data/opal/browser/event_source.rb +2 -2
  159. data/opal/browser/form_data.rb +225 -0
  160. data/opal/browser/history.rb +4 -8
  161. data/opal/browser/http/binary.rb +1 -0
  162. data/opal/browser/http/headers.rb +16 -2
  163. data/opal/browser/http/request.rb +46 -48
  164. data/opal/browser/http/response.rb +5 -1
  165. data/opal/browser/http.rb +25 -2
  166. data/opal/browser/immediate.rb +9 -5
  167. data/opal/browser/interval.rb +34 -11
  168. data/opal/browser/location.rb +7 -1
  169. data/opal/browser/navigator.rb +127 -7
  170. data/opal/browser/polyfill/visual_viewport.rb +216 -0
  171. data/opal/browser/screen.rb +3 -3
  172. data/opal/browser/setup/base.rb +6 -0
  173. data/opal/browser/setup/full.rb +13 -0
  174. data/opal/browser/setup/large.rb +17 -0
  175. data/opal/browser/setup/mini.rb +8 -0
  176. data/opal/browser/setup/traditional.rb +10 -0
  177. data/opal/browser/socket.rb +8 -4
  178. data/opal/browser/storage.rb +53 -35
  179. data/opal/browser/support.rb +72 -5
  180. data/opal/browser/utils.rb +94 -14
  181. data/opal/browser/version.rb +1 -1
  182. data/opal/browser/visual_viewport.rb +39 -0
  183. data/opal/browser/window/size.rb +31 -3
  184. data/opal/browser/window/view.rb +15 -0
  185. data/opal/browser/window.rb +46 -25
  186. data/opal/browser.rb +1 -10
  187. data/opal/opal-browser.rb +1 -0
  188. data/opal-browser.gemspec +3 -3
  189. data/spec/database/sql_spec.rb +139 -0
  190. data/spec/delay_spec.rb +41 -0
  191. data/spec/dom/attribute_spec.rb +49 -0
  192. data/spec/dom/builder_spec.rb +25 -8
  193. data/spec/dom/document_spec.rb +22 -0
  194. data/spec/dom/element/attributes_spec.rb +52 -0
  195. data/spec/dom/element/custom_spec.rb +106 -0
  196. data/spec/dom/element/subclass_spec.rb +144 -0
  197. data/spec/dom/element_spec.rb +181 -4
  198. data/spec/dom/mutation_observer_spec.rb +12 -8
  199. data/spec/dom/node_set_spec.rb +44 -0
  200. data/spec/dom/node_spec.rb +48 -0
  201. data/spec/dom_spec.rb +8 -0
  202. data/spec/event_source_spec.rb +15 -12
  203. data/spec/{dom/event_spec.rb → event_spec.rb} +44 -15
  204. data/spec/history_spec.rb +23 -19
  205. data/spec/http_spec.rb +19 -31
  206. data/spec/immediate_spec.rb +5 -4
  207. data/spec/interval_spec.rb +59 -0
  208. data/spec/native_cached_wrapper_spec.rb +46 -0
  209. data/spec/runner.rb +62 -69
  210. data/spec/socket_spec.rb +16 -12
  211. data/spec/spec_helper.rb +2 -5
  212. data/spec/spec_helper_promise.rb.erb +25 -0
  213. data/spec/storage_spec.rb +1 -1
  214. metadata +172 -50
  215. data/.travis.yml +0 -60
  216. data/opal/browser/dom/event.rb +0 -253
  217. data/opal/browser/http/parameters.rb +0 -8
  218. data/opal/browser/window/scroll.rb +0 -59
@@ -0,0 +1,2 @@
1
+ /application.js
2
+ /opal-browser.js
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "opal-browser", path: "../../.."
@@ -0,0 +1,8 @@
1
+ Static compilation example
2
+ ==========================
3
+
4
+ This is an example from README.
5
+
6
+ To compile everything, run:
7
+
8
+ $ ./build.sh
@@ -0,0 +1,6 @@
1
+ require 'opal'
2
+ require 'native'
3
+ require 'promise'
4
+ require 'browser/setup/full'
5
+
6
+ $document.body << "Hello world!"
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ bundle install
3
+ bundle exec opal -c -q opal-browser -p native -p promise -p browser/setup/full -e '#' -E > opal-browser.js
4
+ bundle exec opal -Oc -s opal -s native -s promise -s browser/setup/full app/application.rb > application.js
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>My Application</title>
5
+ </head>
6
+ <body>
7
+ <script src='opal-browser.js' onload='Opal.require("native"); Opal.require("promise"); Opal.require("browser/setup/full");'></script>
8
+ <script src='application.js'></script>
9
+ </body>
10
+ </html>
@@ -0,0 +1,3 @@
1
+ /opal-browser.js
2
+ /opal-parser.js
3
+
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "opal-browser", path: "../../.."
@@ -0,0 +1,10 @@
1
+ Opal-Parser compilation example
2
+ ===============================
3
+
4
+ To compile everything, run:
5
+
6
+ $ ./build.sh
7
+
8
+ NOTE: This kind of integration, while cool, is highly unrecommended for production purposes.
9
+ You would rather want to compile your application from Ruby to JavaScript yourself (on a server
10
+ or whatnot), than let it be compiled in a web browser.
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ bundle install
3
+ bundle exec opal -c -q opal-browser -p native -p promise -p browser/setup/full -e '#' -E > opal-browser.js
4
+ bundle exec opal -Oc -p opal-parser -e '#' -E > opal-parser.js
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>My Application</title>
5
+
6
+ <script src='opal-browser.js'></script>
7
+ <script src='opal-parser.js' onload='Opal.require("opal-parser")'></script>
8
+ </head>
9
+ <body>
10
+ <script type='text/ruby'>
11
+ require 'native'
12
+ require 'promise'
13
+ require 'browser/setup/full'
14
+
15
+ # Your Opal code here
16
+ $document.body << "Hello world!"
17
+ </script>
18
+ </body>
19
+ </html>
@@ -0,0 +1 @@
1
+ /application.js
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "opal-browser", path: "../../.."
4
+ gem "rake"
@@ -0,0 +1,7 @@
1
+ Static compilation example with Rake
2
+ ====================================
3
+
4
+ To compile everything, run:
5
+
6
+ $ bundle install
7
+ $ bundle exec rake
@@ -0,0 +1,10 @@
1
+ task :build do
2
+ require 'opal'
3
+ require 'opal-browser'
4
+
5
+ Opal.append_path "app"
6
+
7
+ File.binwrite "application.js", Opal::Builder.build("application").to_s
8
+ end
9
+
10
+ task :default => :build
@@ -0,0 +1,6 @@
1
+ require 'opal'
2
+ require 'native'
3
+ require 'promise'
4
+ require 'browser/setup/full'
5
+
6
+ $document.body << "Hello world!"
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>My Application</title>
5
+ </head>
6
+ <body>
7
+ <script src='application.js'></script>
8
+ </body>
9
+ </html>
@@ -0,0 +1 @@
1
+ /application.js
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "opal-browser", path: "../../.."
4
+ gem "rake"
5
+ gem "guard"
6
+ gem "guard-rake"
@@ -0,0 +1,3 @@
1
+ guard :rake, task: "build", all_on_start: true do
2
+ watch %r{^app/}
3
+ end
@@ -0,0 +1,10 @@
1
+ Static compilation example with Rake and Guard
2
+ ==============================================
3
+
4
+ To install, run:
5
+
6
+ $ bundle install
7
+
8
+ To automatically rebuild the artifact on files change, run:
9
+
10
+ $ bundle exec guard
@@ -0,0 +1,10 @@
1
+ require 'opal'
2
+ require 'opal-browser'
3
+
4
+ Opal.append_path "app"
5
+
6
+ task :build do
7
+ File.binwrite "application.js", Opal::Builder.build("application").to_s
8
+ end
9
+
10
+ task :default => :build
@@ -0,0 +1,6 @@
1
+ require 'opal'
2
+ require 'native'
3
+ require 'promise'
4
+ require 'browser/setup/full'
5
+
6
+ $document.body << "Hello world!"
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>My Application</title>
5
+ </head>
6
+ <body>
7
+ <script src='application.js'></script>
8
+ </body>
9
+ </html>
@@ -0,0 +1 @@
1
+ /application.js
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "opal-browser", path: "../.."
4
+ gem "rake"
@@ -0,0 +1,7 @@
1
+ SVG example with Rake
2
+ =====================
3
+
4
+ To compile everything, run:
5
+
6
+ $ bundle install
7
+ $ bundle exec rake
@@ -0,0 +1,10 @@
1
+ task :build do
2
+ require 'opal'
3
+ require 'opal-browser'
4
+
5
+ Opal.append_path "app"
6
+
7
+ File.binwrite "application.js", Opal::Builder.build("application").to_s
8
+ end
9
+
10
+ task :default => :build
@@ -0,0 +1,11 @@
1
+ require 'opal'
2
+ require 'native'
3
+ require 'promise'
4
+ require 'browser/setup/full'
5
+
6
+ elem = $document.at_css("ellipse")
7
+
8
+ $document.on :mousemove do |e|
9
+ elem[:cx] = e.page.x
10
+ elem[:cy] = e.page.y
11
+ end
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>My Application</title>
5
+
6
+ <style>
7
+ body { margin: 0px; padding: 0px; overflow: hidden; }
8
+ svg { width: 100%; height: 100vh; }
9
+ </style>
10
+ </head>
11
+ <body>
12
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
13
+ <ellipse cx="50" cy="50" rx="10" ry="10" stroke="#000" stroke-width=".253"/>
14
+ </svg>
15
+ <script src='application.js'></script>
16
+ </body>
17
+ </html>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
3
+ <ellipse cx="50" cy="50" rx="10" ry="10" stroke="#000" stroke-width=".253"/>
4
+
5
+ <script href='application.js'></script>
6
+ </svg>
data/index.html.erb CHANGED
@@ -2,20 +2,22 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Opal Browser - RSpec Runner</title>
5
-
5
+ </head>
6
+ <body>
6
7
  <script>
7
8
  window.onerror = function(msg, url, line) {
8
9
  var error = document.createElement("div");
9
10
  error.setAttribute("id", "rspec-error");
10
- error.innerHTML = "Error: " + msg + "<br/>";
11
- error.innerHTML += "Line: " + line + "<br/>";
12
- error.innerHTML += "URL: " + url + "<br/>";
11
+ error.appendChild(document.createTextNode(msg));
13
12
 
14
13
  document.body.appendChild(error);
15
14
  }
16
15
  </script>
17
- </head>
18
- <body>
16
+
17
+ <script src="spec/json2.js"></script>
18
+ <script src="spec/sizzle.js"></script>
19
+ <script src="spec/wgxpath.install.js"></script>
20
+
19
21
  <%= javascript_include_tag @server.main %>
20
22
  </body>
21
23
  </html>
@@ -0,0 +1 @@
1
+ require 'opal/browser'
@@ -1,6 +1,22 @@
1
1
  module Browser
2
2
 
3
+ # Allows you to wrap a block to use in an animation rendering cycle.
4
+ #
5
+ # @see https://developer.mozilla.org/en/docs/Web/API/window.requestAnimationFrame
3
6
  class AnimationFrame
7
+ def self.supported?
8
+ ['Animation.request',
9
+ 'Animation.request (Chrome)',
10
+ 'Animation.request (Firefox)',
11
+ 'Animation.request (Opera)',
12
+ 'Animation.request (Internet Explorer)'].any? {|feature|
13
+ Browser.supports? feature
14
+ }
15
+ end
16
+
17
+ # Execute the block to update an animation before the next repaint.
18
+ #
19
+ # @param window [Window] the window to request the frame on
4
20
  def initialize(window, &block)
5
21
  @window = window
6
22
  @native = window.to_n
@@ -28,6 +44,7 @@ class AnimationFrame
28
44
  `#@native.msRequestAnimationFrame(#{block.to_n})`
29
45
  end
30
46
  else
47
+ # Request the animation frame.
31
48
  def request
32
49
  raise NotImplementedError, 'window requestAnimationFrame unsupported'
33
50
  end
@@ -70,6 +87,7 @@ class AnimationFrame
70
87
  `#@native.msCancelRequestAnimationFrame(#@id)`
71
88
  end
72
89
  else
90
+ # Cancel the animation frame request.
73
91
  def cancel
74
92
  raise NotImplementedError, 'window cancelAnimationFrame unsupported'
75
93
  end
@@ -78,8 +96,15 @@ end
78
96
 
79
97
  end
80
98
 
99
+ module Kernel
100
+ # (see Browser::AnimationFrame.new)
101
+ def animation_frame(&block)
102
+ Browser::AnimationFrame.new($window, &block)
103
+ end
104
+ end
105
+
81
106
  class Proc
82
- # Execute a block to update an animation before the next repaint.
107
+ # (see Browser::AnimationFrame.new)
83
108
  def animation_frame
84
109
  Browser::AnimationFrame.new($window, &self)
85
110
  end
@@ -0,0 +1,121 @@
1
+ module Browser; module Audio; module Node
2
+
3
+ class Base
4
+ include Native::Wrapper
5
+
6
+ def initialize(native)
7
+ @native = native
8
+ end
9
+
10
+ def method_missing(name, value = nil)
11
+ if name.end_with? '='
12
+ `#@native[#{name.delete '='}].value = value`
13
+ elsif value.nil? || value == true
14
+ `#@native[#{name}].value`
15
+ elsif value == false
16
+ `#@native[#{name}]`
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def respond_to_missing?(method, include_all = false)
23
+ `#@native[#{method.delete('=')}] != null`
24
+ end
25
+
26
+ def connect(destination)
27
+ `#@native.connect(#{Native.convert(destination)})`
28
+ end
29
+
30
+ def disconnect(destination = nil, options = {})
31
+ destination = Native.try_convert(destination)
32
+ output = options[:output] || 0
33
+ input = options[:input] || 0
34
+
35
+ if options.any?
36
+ `#@native.disconnect(#{destination}, #{output}, #{input}) || nil`
37
+ elsif destination
38
+ `#@native.disconnect(#{destination})`
39
+ else
40
+ `#@native.disconnect()`
41
+ end
42
+ end
43
+ end
44
+
45
+ class Gain < Base
46
+ def initialize(audio_context)
47
+ super `#{audio_context.to_n}.createGain()`
48
+ end
49
+ end
50
+
51
+ class Oscillator < Base
52
+ TYPES = %i(sine square sawtooth triangle custom)
53
+
54
+ alias_native :start
55
+ alias_native :stop
56
+
57
+ alias_native :periodic_wave=, :setPeriodicWave
58
+
59
+ def initialize(audio_context)
60
+ super `#{audio_context.to_n}.createOscillator()`
61
+ end
62
+
63
+ def type=(type)
64
+ unless TYPES.include?(type)
65
+ raise ArgumentError, "type #{type} doesn't exists"
66
+ end
67
+
68
+ `#@native.type = type`
69
+ end
70
+
71
+ def type
72
+ `#@native.type`
73
+ end
74
+ end
75
+
76
+ class Delay < Base
77
+ def initialize(audio_context, max_time = 1)
78
+ super `#{audio_context.to_n}.createDelay(max_time)`
79
+ end
80
+ end
81
+
82
+ class DynamicsCompressor < Base
83
+
84
+ alias_native :reduction
85
+
86
+ def initialize(audio_context)
87
+ super `#{audio_context.to_n}.createDynamicsCompressor()`
88
+ end
89
+ end
90
+
91
+ class BiquadFilter < Base
92
+
93
+ TYPES = %i(lowpass highpass bandpass lowshelf highshelf peaking notch allpass)
94
+
95
+ def initialize(audio_context)
96
+ super `#{audio_context.to_n}.createBiquadFilter()`
97
+ end
98
+
99
+ def type=(type)
100
+ unless TYPES.include?(type)
101
+ raise ArgumentError, "type #{type} doesn't exists"
102
+ end
103
+
104
+ `#@native.type = type`
105
+ end
106
+
107
+ def type
108
+ `#@native.type`
109
+ end
110
+ end
111
+
112
+ class StereoPanner < Base
113
+
114
+ alias_native :normalize
115
+
116
+ def initialize(audio_context)
117
+ super `#{audio_context.to_n}.createStereoPanner()`
118
+ end
119
+ end
120
+
121
+ end; end; end
@@ -0,0 +1,43 @@
1
+ module Browser; module Audio
2
+
3
+ class ParamSchedule
4
+ include Native::Wrapper
5
+
6
+ alias_native :cancel, :cancelScheduledValues
7
+
8
+ def initialize(audio_param, time = nil)
9
+ @time = time
10
+ @audio_param = audio_param
11
+ super Native.convert(audio_param)
12
+ end
13
+
14
+ def at(time)
15
+ new(@audio_param, time)
16
+ end
17
+
18
+ def value(value, time = nil)
19
+ @value = value
20
+ `#@native.setValueAtTime(#{@value}, #{@time || time})`
21
+ self
22
+ end
23
+
24
+ def linear_ramp_to(value = nil, time = nil)
25
+ `#@native.linearRampToValueAtTime(#{@value || value}, #{@time || time})`
26
+ self
27
+ end
28
+
29
+ def exponential_ramp_to(value = nil, time = nil)
30
+ `#@native.exponentialRampToValueAtTime(#{@value || value}, #{@time || time})`
31
+ self
32
+ end
33
+
34
+ def target(target, time_hash)
35
+ `#@native.setTargetAtTime(target, #{time_hash[:start_time]}, #{time_hash[:time_constant]})`
36
+ end
37
+
38
+ def curve(values, time_hash)
39
+ `#@native.setValueCurveAtTime(values, #{time_hash[:start_time]}, #{time_hash[:time_constant]})`
40
+ end
41
+ end
42
+
43
+ end; end
@@ -0,0 +1,66 @@
1
+ require 'browser/audio/node'
2
+
3
+ module Browser; module Audio
4
+
5
+ class Context
6
+ include Native::Wrapper
7
+
8
+ alias_native :destination
9
+ alias_native :listener
10
+ alias_native :state
11
+
12
+ alias_native :sample_rate, :sampleRate
13
+ alias_native :current_time, :currentTime
14
+
15
+ def self.supported?
16
+ Browser.support?('Audio') || Browser.support?('Audio (Chrome)')
17
+ end
18
+
19
+ if Browser.supports? 'Audio'
20
+ def initialize
21
+ super `new AudioContext()`
22
+ end
23
+ elsif Browser.supports? 'Audio (Chrome)'
24
+ def initialize
25
+ super `new webkitAudioContext()`
26
+ end
27
+ else
28
+ def initialize
29
+ raise NotImplementedError, 'Audio unsupported'
30
+ end
31
+ end
32
+
33
+ def gain
34
+ Node::Gain.new(self)
35
+ end
36
+
37
+ def oscillator
38
+ Node::Oscillator.new(self)
39
+ end
40
+
41
+ def delay(max_time)
42
+ Node::Delay.new(self, max_time)
43
+ end
44
+
45
+ def dynamics_compressor
46
+ Node::DynamicsCompressor.new(self)
47
+ end
48
+
49
+ def biquad_filter
50
+ Node::BiquadFilter.new(self)
51
+ end
52
+
53
+ def stereo_panner
54
+ Node::StereoPanner.new(self)
55
+ end
56
+
57
+ def periodic_wave(real, imaginary)
58
+ `#{@native}.createPeriodicWave(new Float32Array(#{real}), new Float32Array(#{imaginary}));`
59
+ end
60
+
61
+ alias_native :suspend
62
+ alias_native :resume
63
+ alias_native :close
64
+ end
65
+
66
+ end; end