atome-opal-browser 0.3.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile +33 -0
  4. data/Gemfile.lock +122 -0
  5. data/LICENSE +20 -0
  6. data/README.md +301 -0
  7. data/Rakefile +63 -0
  8. data/bin/rake +7 -0
  9. data/bin/setup +8 -0
  10. data/config.ru +81 -0
  11. data/docs/polyfills.md +24 -0
  12. data/examples/2048/Gemfile +13 -0
  13. data/examples/2048/Gemfile.lock +41 -0
  14. data/examples/2048/README.md +13 -0
  15. data/examples/2048/app/application.rb +169 -0
  16. data/examples/2048/config.ru +9 -0
  17. data/examples/canvas/Gemfile +9 -0
  18. data/examples/canvas/README.md +9 -0
  19. data/examples/canvas/app/application.rb +55 -0
  20. data/examples/canvas/config.ru +9 -0
  21. data/examples/component/Gemfile +9 -0
  22. data/examples/component/Gemfile.lock +45 -0
  23. data/examples/component/README.md +10 -0
  24. data/examples/component/app/application.rb +66 -0
  25. data/examples/component/config.ru +9 -0
  26. data/examples/integrations/README.md +24 -0
  27. data/examples/integrations/dynamic-rack-opal-sprockets-server/Gemfile +7 -0
  28. data/examples/integrations/dynamic-rack-opal-sprockets-server/README.md +16 -0
  29. data/examples/integrations/dynamic-rack-opal-sprockets-server/app/application.rb +6 -0
  30. data/examples/integrations/dynamic-rack-opal-sprockets-server/config.ru +9 -0
  31. data/examples/integrations/dynamic-roda-roda-sprockets/.gitignore +1 -0
  32. data/examples/integrations/dynamic-roda-roda-sprockets/Gemfile +8 -0
  33. data/examples/integrations/dynamic-roda-roda-sprockets/README.md +22 -0
  34. data/examples/integrations/dynamic-roda-roda-sprockets/Rakefile +4 -0
  35. data/examples/integrations/dynamic-roda-roda-sprockets/app/application.rb +6 -0
  36. data/examples/integrations/dynamic-roda-roda-sprockets/app.rb +32 -0
  37. data/examples/integrations/dynamic-roda-roda-sprockets/config.ru +3 -0
  38. data/examples/integrations/dynamic-roda-tilt/.gitignore +1 -0
  39. data/examples/integrations/dynamic-roda-tilt/Gemfile +9 -0
  40. data/examples/integrations/dynamic-roda-tilt/README.md +17 -0
  41. data/examples/integrations/dynamic-roda-tilt/Rakefile +6 -0
  42. data/examples/integrations/dynamic-roda-tilt/app/application.rb +6 -0
  43. data/examples/integrations/dynamic-roda-tilt/app.rb +50 -0
  44. data/examples/integrations/dynamic-roda-tilt/config.ru +3 -0
  45. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/Gemfile +10 -0
  46. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/README.md +16 -0
  47. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/app/application.rb +6 -0
  48. data/examples/integrations/dynamic-sinatra-opal-sprockets-server/config.ru +29 -0
  49. data/examples/integrations/static-bash/.gitignore +2 -0
  50. data/examples/integrations/static-bash/Gemfile +3 -0
  51. data/examples/integrations/static-bash/README.md +8 -0
  52. data/examples/integrations/static-bash/app/application.rb +6 -0
  53. data/examples/integrations/static-bash/build.sh +4 -0
  54. data/examples/integrations/static-bash/index.html +10 -0
  55. data/examples/integrations/static-bash-opal-parser/.gitignore +3 -0
  56. data/examples/integrations/static-bash-opal-parser/Gemfile +3 -0
  57. data/examples/integrations/static-bash-opal-parser/README.md +10 -0
  58. data/examples/integrations/static-bash-opal-parser/build.sh +4 -0
  59. data/examples/integrations/static-bash-opal-parser/index.html +19 -0
  60. data/examples/integrations/static-rake/.gitignore +1 -0
  61. data/examples/integrations/static-rake/Gemfile +7 -0
  62. data/examples/integrations/static-rake/README.md +7 -0
  63. data/examples/integrations/static-rake/Rakefile +10 -0
  64. data/examples/integrations/static-rake/app/application.rb +6 -0
  65. data/examples/integrations/static-rake/index.html +9 -0
  66. data/examples/integrations/static-rake-guard/.gitignore +1 -0
  67. data/examples/integrations/static-rake-guard/Gemfile +9 -0
  68. data/examples/integrations/static-rake-guard/Gemfile.lock +69 -0
  69. data/examples/integrations/static-rake-guard/Guardfile +3 -0
  70. data/examples/integrations/static-rake-guard/README.md +10 -0
  71. data/examples/integrations/static-rake-guard/Rakefile +10 -0
  72. data/examples/integrations/static-rake-guard/app/application.rb +6 -0
  73. data/examples/integrations/static-rake-guard/index.html +9 -0
  74. data/examples/svg/.gitignore +1 -0
  75. data/examples/svg/Gemfile +4 -0
  76. data/examples/svg/README.md +7 -0
  77. data/examples/svg/Rakefile +10 -0
  78. data/examples/svg/app/application.rb +11 -0
  79. data/examples/svg/index.html +17 -0
  80. data/examples/svg/index.svg +6 -0
  81. data/index.html.erb +24 -0
  82. data/lib/opal/browser.rb +4 -0
  83. data/lib/opal-browser.rb +1 -0
  84. data/opal/browser/animation_frame.rb +111 -0
  85. data/opal/browser/audio/node.rb +121 -0
  86. data/opal/browser/audio/param_schedule.rb +43 -0
  87. data/opal/browser/audio.rb +66 -0
  88. data/opal/browser/blob.rb +94 -0
  89. data/opal/browser/canvas/data.rb +63 -0
  90. data/opal/browser/canvas/gradient.rb +27 -0
  91. data/opal/browser/canvas/style.rb +115 -0
  92. data/opal/browser/canvas/text.rb +45 -0
  93. data/opal/browser/canvas.rb +335 -0
  94. data/opal/browser/console.rb +105 -0
  95. data/opal/browser/cookies.rb +171 -0
  96. data/opal/browser/crypto.rb +79 -0
  97. data/opal/browser/css/declaration.rb +83 -0
  98. data/opal/browser/css/rule/style.rb +16 -0
  99. data/opal/browser/css/rule.rb +48 -0
  100. data/opal/browser/css/style_sheet.rb +83 -0
  101. data/opal/browser/css/unit.rb +188 -0
  102. data/opal/browser/css.rb +40 -0
  103. data/opal/browser/database/sql.rb +193 -0
  104. data/opal/browser/delay.rb +94 -0
  105. data/opal/browser/dom/attribute.rb +26 -0
  106. data/opal/browser/dom/builder.rb +107 -0
  107. data/opal/browser/dom/cdata.rb +9 -0
  108. data/opal/browser/dom/character_data.rb +73 -0
  109. data/opal/browser/dom/comment.rb +9 -0
  110. data/opal/browser/dom/document.rb +217 -0
  111. data/opal/browser/dom/document_fragment.rb +25 -0
  112. data/opal/browser/dom/document_or_shadow_root.rb +19 -0
  113. data/opal/browser/dom/element/attributes.rb +111 -0
  114. data/opal/browser/dom/element/button.rb +31 -0
  115. data/opal/browser/dom/element/custom.rb +177 -0
  116. data/opal/browser/dom/element/data.rb +82 -0
  117. data/opal/browser/dom/element/editable.rb +47 -0
  118. data/opal/browser/dom/element/form.rb +38 -0
  119. data/opal/browser/dom/element/iframe.rb +37 -0
  120. data/opal/browser/dom/element/image.rb +25 -0
  121. data/opal/browser/dom/element/input.rb +64 -0
  122. data/opal/browser/dom/element/media.rb +43 -0
  123. data/opal/browser/dom/element/offset.rb +89 -0
  124. data/opal/browser/dom/element/position.rb +46 -0
  125. data/opal/browser/dom/element/scroll.rb +168 -0
  126. data/opal/browser/dom/element/select.rb +42 -0
  127. data/opal/browser/dom/element/size.rb +46 -0
  128. data/opal/browser/dom/element/template.rb +11 -0
  129. data/opal/browser/dom/element/textarea.rb +26 -0
  130. data/opal/browser/dom/element.rb +618 -0
  131. data/opal/browser/dom/mutation_observer.rb +178 -0
  132. data/opal/browser/dom/node.rb +504 -0
  133. data/opal/browser/dom/node_set.rb +121 -0
  134. data/opal/browser/dom/shadow_root.rb +12 -0
  135. data/opal/browser/dom/text.rb +36 -0
  136. data/opal/browser/dom.rb +124 -0
  137. data/opal/browser/effects.rb +216 -0
  138. data/opal/browser/event/all.rb +26 -0
  139. data/opal/browser/event/animation.rb +40 -0
  140. data/opal/browser/event/audio_processing.rb +35 -0
  141. data/opal/browser/event/base.rb +461 -0
  142. data/opal/browser/event/before_unload.rb +17 -0
  143. data/opal/browser/event/clipboard.rb +37 -0
  144. data/opal/browser/event/close.rb +49 -0
  145. data/opal/browser/event/composition.rb +52 -0
  146. data/opal/browser/event/custom.rb +65 -0
  147. data/opal/browser/event/data_transfer.rb +95 -0
  148. data/opal/browser/event/device_light.rb +25 -0
  149. data/opal/browser/event/device_motion.rb +53 -0
  150. data/opal/browser/event/device_orientation.rb +50 -0
  151. data/opal/browser/event/device_proximity.rb +35 -0
  152. data/opal/browser/event/drag.rb +123 -0
  153. data/opal/browser/event/focus.rb +41 -0
  154. data/opal/browser/event/gamepad.rb +62 -0
  155. data/opal/browser/event/hash_change.rb +30 -0
  156. data/opal/browser/event/keyboard.rb +128 -0
  157. data/opal/browser/event/message.rb +72 -0
  158. data/opal/browser/event/mouse.rb +258 -0
  159. data/opal/browser/event/page_transition.rb +25 -0
  160. data/opal/browser/event/pop_state.rb +35 -0
  161. data/opal/browser/event/progress.rb +45 -0
  162. data/opal/browser/event/sensor.rb +17 -0
  163. data/opal/browser/event/storage.rb +45 -0
  164. data/opal/browser/event/touch.rb +62 -0
  165. data/opal/browser/event/ui.rb +38 -0
  166. data/opal/browser/event/wheel.rb +51 -0
  167. data/opal/browser/event.rb +162 -0
  168. data/opal/browser/event_source.rb +70 -0
  169. data/opal/browser/form_data.rb +225 -0
  170. data/opal/browser/history.rb +86 -0
  171. data/opal/browser/http/binary.rb +58 -0
  172. data/opal/browser/http/headers.rb +109 -0
  173. data/opal/browser/http/request.rb +359 -0
  174. data/opal/browser/http/response.rb +119 -0
  175. data/opal/browser/http.rb +167 -0
  176. data/opal/browser/immediate.rb +161 -0
  177. data/opal/browser/interval.rb +111 -0
  178. data/opal/browser/location.rb +93 -0
  179. data/opal/browser/navigator.rb +274 -0
  180. data/opal/browser/polyfill/visual_viewport.rb +216 -0
  181. data/opal/browser/screen.rb +66 -0
  182. data/opal/browser/setup/base.rb +6 -0
  183. data/opal/browser/setup/full.rb +13 -0
  184. data/opal/browser/setup/large.rb +17 -0
  185. data/opal/browser/setup/mini.rb +8 -0
  186. data/opal/browser/setup/traditional.rb +10 -0
  187. data/opal/browser/socket.rb +123 -0
  188. data/opal/browser/storage.rb +252 -0
  189. data/opal/browser/support.rb +299 -0
  190. data/opal/browser/utils.rb +154 -0
  191. data/opal/browser/version.rb +3 -0
  192. data/opal/browser/visual_viewport.rb +39 -0
  193. data/opal/browser/window/size.rb +73 -0
  194. data/opal/browser/window/view.rb +51 -0
  195. data/opal/browser/window.rb +133 -0
  196. data/opal/browser.rb +1 -0
  197. data/opal/opal-browser.rb +1 -0
  198. data/opal-browser.gemspec +27 -0
  199. data/spec/database/sql_spec.rb +139 -0
  200. data/spec/delay_spec.rb +41 -0
  201. data/spec/dom/attribute_spec.rb +49 -0
  202. data/spec/dom/builder_spec.rb +86 -0
  203. data/spec/dom/document_spec.rb +62 -0
  204. data/spec/dom/element/attributes_spec.rb +52 -0
  205. data/spec/dom/element/custom_spec.rb +106 -0
  206. data/spec/dom/element/subclass_spec.rb +144 -0
  207. data/spec/dom/element_spec.rb +223 -0
  208. data/spec/dom/mutation_observer_spec.rb +41 -0
  209. data/spec/dom/node_set_spec.rb +44 -0
  210. data/spec/dom/node_spec.rb +214 -0
  211. data/spec/dom_spec.rb +23 -0
  212. data/spec/event_source_spec.rb +45 -0
  213. data/spec/event_spec.rb +156 -0
  214. data/spec/history_spec.rb +61 -0
  215. data/spec/http_spec.rb +76 -0
  216. data/spec/immediate_spec.rb +15 -0
  217. data/spec/interval_spec.rb +59 -0
  218. data/spec/json2.js +486 -0
  219. data/spec/native_cached_wrapper_spec.rb +46 -0
  220. data/spec/runner.rb +107 -0
  221. data/spec/sizzle.js +5 -0
  222. data/spec/socket_spec.rb +47 -0
  223. data/spec/spec_helper.rb +35 -0
  224. data/spec/spec_helper_promise.rb.erb +25 -0
  225. data/spec/storage_spec.rb +26 -0
  226. data/spec/wgxpath.install.js +49 -0
  227. data/spec/window_spec.rb +10 -0
  228. metadata +500 -0
@@ -0,0 +1,121 @@
1
+ module Browser; module DOM
2
+
3
+ # Allows manipulation of a set of {Node}s.
4
+ class NodeSet
5
+ # Create a new {NodeSet} from the given nodes.
6
+ #
7
+ # Note that the nodes are flattened and converted with DOM automatically,
8
+ # this means you can pass {NodeSet}s and {Native::Array}s as well.
9
+ def self.[](*nodes)
10
+ new(nodes.flatten.map { |x| DOM(Native.convert(x)) }.uniq)
11
+ end
12
+
13
+ def initialize(literal)
14
+ @literal = literal
15
+ end
16
+
17
+ # Any other method will be called on every node in the set.
18
+ def method_missing(name, *args, &block)
19
+ unless @literal.respond_to? name
20
+ each {|el|
21
+ el.__send__(name, *args, &block)
22
+ }
23
+
24
+ return self
25
+ end
26
+
27
+ result = @literal.__send__ name, *args, &block
28
+
29
+ if `result === #@literal`
30
+ self
31
+ elsif Array === result
32
+ NodeSet.new(result)
33
+ else
34
+ result
35
+ end
36
+ end
37
+
38
+ def respond_to_missing?(name, *)
39
+ @literal.respond_to?(name)
40
+ end
41
+
42
+ # Get the first node matching the given CSS selectors.
43
+ #
44
+ # @param rules [Array<String>] the CSS selectors to match with
45
+ #
46
+ # @return [Node?]
47
+ def at_css(*rules)
48
+ each {|node|
49
+ if node = node.at_css(*rules)
50
+ return node
51
+ end
52
+ }
53
+
54
+ nil
55
+ end
56
+
57
+ # Get the first node matching the given XPath.
58
+ #
59
+ # @param paths [Array<String>] the XPath to match with
60
+ #
61
+ # @return [Node?]
62
+ def at_xpath(*paths)
63
+ each {|node|
64
+ if node = node.at_xpath(*paths)
65
+ return node
66
+ end
67
+ }
68
+
69
+ nil
70
+ end
71
+
72
+ # Query for children matching the given CSS selector.
73
+ #
74
+ # @param path [String] the CSS selector
75
+ #
76
+ # @return [NodeSet]
77
+ def css(path)
78
+ NodeSet[@literal.map {|node|
79
+ node.css(path)
80
+ }]
81
+ end
82
+
83
+ # Create another {NodeSet} with all the nodes that match the given
84
+ # expression.
85
+ #
86
+ # @param expression [String] a CSS selector
87
+ #
88
+ # @return [NodeSet] the new {NodeSet} with the matching nodes
89
+ def filter(expression)
90
+ NodeSet[@literal.select { |node| node =~ expression }]
91
+ end
92
+
93
+ # Search for multiple selectors
94
+ def search(*what)
95
+ NodeSet[@literal.map { |node| node.search(*what) }]
96
+ end
97
+
98
+ # Outer HTML of the entire nodeset
99
+ def outer_html
100
+ @literal.map(&:outer_html).join
101
+ end
102
+
103
+ # Query for children matching the given XPath.
104
+ #
105
+ # @param path [String] the XPath
106
+ #
107
+ # @return [NodeSet]
108
+ def xpath(path)
109
+ NodeSet[@literal.map {|node|
110
+ node.xpath(path)
111
+ }]
112
+ end
113
+
114
+ def to_ary
115
+ @literal
116
+ end
117
+
118
+ alias to_a to_ary
119
+ end
120
+
121
+ end; end
@@ -0,0 +1,12 @@
1
+ module Browser; module DOM
2
+
3
+ class ShadowRoot < DocumentFragment
4
+ include DocumentOrShadowRoot
5
+
6
+ # Use: Element#shadow
7
+ def self.create
8
+ raise ArgumentError
9
+ end
10
+ end
11
+
12
+ end; end
@@ -0,0 +1,36 @@
1
+ module Browser; module DOM
2
+
3
+ # Encapsulates a text node.
4
+ #
5
+ # @see https://developer.mozilla.org/en-US/docs/Web/API/Text
6
+ class Text < CharacterData
7
+ # (see Document#create_text)
8
+ def self.create(content)
9
+ $document.create_text(content)
10
+ end
11
+
12
+ # @!attribute [r] whole
13
+ # @return [String] the whole text
14
+ #
15
+ # @see https://developer.mozilla.org/en-US/docs/Web/API/Text.wholeText
16
+ def whole
17
+ `#@native.wholeText`
18
+ end
19
+
20
+ # Split the text node at a given offset.
21
+ #
22
+ # @param offset [Integer] the offset where to split the text node
23
+ #
24
+ # @return [Text] the newly created text node
25
+ #
26
+ # @see https://developer.mozilla.org/en-US/docs/Web/API/Text.splitText
27
+ def split(offset)
28
+ DOM(`#@native.splitText(offset)`)
29
+ end
30
+
31
+ def inspect
32
+ "#<DOM::Text: #{data}>"
33
+ end
34
+ end
35
+
36
+ end; end
@@ -0,0 +1,124 @@
1
+ require 'browser/dom/node_set'
2
+ require 'browser/dom/node'
3
+ require 'browser/dom/attribute'
4
+ require 'browser/dom/character_data'
5
+ require 'browser/dom/text'
6
+ require 'browser/dom/cdata'
7
+ require 'browser/dom/comment'
8
+ require 'browser/dom/element'
9
+ require 'browser/dom/document_or_shadow_root'
10
+ require 'browser/dom/document'
11
+ require 'browser/dom/document_fragment'
12
+ require 'browser/dom/shadow_root'
13
+ require 'browser/dom/mutation_observer'
14
+
15
+ module Kernel
16
+ # Parse an XML string into a DOM usable {Browser::DOM::Document}
17
+ #
18
+ # @param what [String] the string to parse
19
+ # @return [Browser::DOM::Document] the document
20
+ def XML(what)
21
+ %x{
22
+ var doc;
23
+
24
+ if (window.DOMParser) {
25
+ doc = new DOMParser().parseFromString(what, 'text/xml');
26
+ }
27
+ else {
28
+ doc = new ActiveXObject('Microsoft.XMLDOM');
29
+ doc.async = 'false';
30
+ doc.loadXML(what);
31
+ }
32
+ }
33
+
34
+ DOM(`doc`)
35
+ end
36
+
37
+ # @overload DOM(document = $document, &block)
38
+ #
39
+ # Create a DOM tree using the {Paggio::HTML} DSL.
40
+ #
41
+ # @param document [Browser::DOM::Document] the document instance
42
+ # we intend to use
43
+ #
44
+ # @return [Browser::DOM::Node, Browser::DOM::NodeSet]
45
+ #
46
+ # @overload DOM(string, document = $document)
47
+ #
48
+ # Create a DOM tree from a HTML string.
49
+ #
50
+ # @param string [String] the HTML string
51
+ # @param document [Browser::DOM::Document] the document instance
52
+ # we intend to use
53
+ #
54
+ # @return [Browser::DOM::Node]
55
+ #
56
+ # @overload DOM(native)
57
+ #
58
+ # Wrap a native element to create a DOM tree.
59
+ #
60
+ # @param native [Native] the Native node
61
+ #
62
+ # @return [Browser::DOM::Node]
63
+ #
64
+ def DOM(*args, &block)
65
+ if block
66
+ document = args.shift || $document
67
+ roots = Browser::DOM::Builder.new(document, &block).to_a
68
+
69
+ if roots.length == 1
70
+ roots.first
71
+ else
72
+ Browser::DOM::NodeSet.new(roots)
73
+ end
74
+ else
75
+ what = args.shift
76
+ document = args.shift || $document
77
+
78
+ what = what.to_dom(document) if Opal.respond_to? what, :to_dom
79
+
80
+ if `typeof(#{what}) === 'undefined' || #{what} === null`
81
+ raise ArgumentError, 'argument is null'
82
+ elsif native?(what)
83
+ Browser::DOM::Node.new(what)
84
+ elsif Browser::DOM::Node === what
85
+ what
86
+ elsif Opal.respond_to? what, :each # eg. NodeSet, Array
87
+ document.create_element("DIV").tap do |div|
88
+ div << what
89
+ end
90
+ elsif String === what
91
+ %x{
92
+ var doc = #{Native.try_convert(document)}.createElement('div');
93
+ doc.innerHTML = what;
94
+
95
+ return #{DOM(`doc.childNodes.length == 1 ? doc.childNodes[0] : doc`)};
96
+ }
97
+ else
98
+ raise ArgumentError, 'argument is not DOM convertible'
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ module Browser
105
+
106
+ class Window
107
+ # Get the {DOM::Document} for this window.
108
+ #
109
+ # @return [DOM::Document]
110
+ def document
111
+ DOM(`#@native.document`)
112
+ end
113
+ end
114
+
115
+ def self.window
116
+ $window
117
+ end
118
+
119
+ def self.window
120
+ $window.document
121
+ end
122
+ end
123
+
124
+ $document = $window.document
@@ -0,0 +1,216 @@
1
+ require 'browser/animation_frame'
2
+
3
+ module Browser; module DOM
4
+
5
+ class Document < Element
6
+ # @!attribute [r] active_element
7
+ # @return [Element] the element with focus
8
+ def active_element
9
+ DOM(`#@native.activeElement`)
10
+ end
11
+ end
12
+
13
+ class Element
14
+ # Show the element.
15
+ #
16
+ # @param what [Symbol] how to display it
17
+ def show(what = :block)
18
+ style[:display] = what
19
+ self
20
+ end
21
+
22
+ # Hide the element.
23
+ def hide
24
+ style[:display] = :none
25
+ self
26
+ end
27
+
28
+ def visible?
29
+ # Let's check if we want to lie about the real visibility of an element.
30
+ # It could be wise to lie about it when it's in a process of animation...
31
+ if !@virtually_visible.nil?
32
+ @virtually_visible
33
+ else
34
+ style![:display] != :none
35
+ end
36
+ end
37
+
38
+ # Toggle the visibility of the element, hide it if it's shown, show it if
39
+ # it's hidden.
40
+ def toggle(what = :block)
41
+ if visible?
42
+ hide
43
+ else
44
+ show(what)
45
+ end
46
+ self
47
+ end
48
+
49
+ # Set the focus on the element.
50
+ def focus
51
+ `#@native.focus()`
52
+ self
53
+ end
54
+
55
+ # Blur the focus from the element.
56
+ def blur
57
+ `#@native.blur()`
58
+ self
59
+ end
60
+
61
+ # Check if the element is focused.
62
+ def focused?
63
+ `#@native.hasFocus`
64
+ end
65
+
66
+ # Queue the block to happen when currently queued animations finish or during
67
+ # the next animation frame.
68
+ def animation_queue &block
69
+ promise = Promise.new
70
+
71
+ promise_resolve = proc do
72
+ @animation_promise = nil if @animation_promise == promise
73
+ promise.resolve
74
+ end
75
+
76
+ @animation_promise = (@animation_promise || Promise.value(true)).then do
77
+ animation_frame do
78
+ yield promise_resolve
79
+ end
80
+ promise
81
+ end
82
+ end
83
+
84
+ # Transform an element smoothly using CSS transitions, jQuery style. Yield
85
+ # a block afterwards if it's provided.
86
+ def animate(properties, duration: 0.4.s, easing: :ease, resolve: false, &block)
87
+ animation_queue(resolve) do |res|
88
+ duration = 0.6.s if duration == :slow
89
+ duration = 0.2.s if duration == :fast
90
+
91
+ original_value = style['transition']
92
+
93
+ style['transition'] = [original_value,
94
+ *properties.keys.map do |key|
95
+ "#{key} #{duration} #{easing}"
96
+ end].compact.join(", ")
97
+
98
+ properties.each do |key, value|
99
+ style[key] = value
100
+ end
101
+
102
+ promise = Promise.new
103
+
104
+ one :transitionend do |*args|
105
+ style['transition'] = original_value
106
+
107
+ yield(*args) if block_given?
108
+
109
+ res.call
110
+ end
111
+ end
112
+ self
113
+ end
114
+
115
+ # Show a hidden element with a "fade in" animation. Yield a block afterwards.
116
+ def fade_in(**kwargs, &block)
117
+ animation_queue do |resolve|
118
+ if !visible?
119
+ @virtually_visible = true
120
+ show
121
+
122
+ style[:opacity] = 0.0
123
+ animate opacity: 1.0, **kwargs do |*args|
124
+ @virtually_visible = nil
125
+ style[:opacity] = nil
126
+ yield(*args) if block_given?
127
+ end
128
+ end
129
+ resolve.call
130
+ end
131
+ self
132
+ end
133
+
134
+ # Hide a visible element with a "fade out" animation. Yield a block afterwards.
135
+ def fade_out(**kwargs, &block)
136
+ animation_queue do |resolve|
137
+ if visible?
138
+ @virtually_visible = false
139
+
140
+ style[:opacity] = 1.0
141
+ animate opacity: 0.0, **kwargs do |*args|
142
+ @virtually_visible = nil
143
+ style[:opacity] = nil
144
+ hide
145
+ yield(*args) if block_given?
146
+ end
147
+ end
148
+ resolve.call
149
+ end
150
+ self
151
+ end
152
+
153
+ # Toggle a visibility of an element with a "fade in"/"fade out" animation. Yield
154
+ # a block afterwards.
155
+ def fade_toggle(**kwargs, &block)
156
+ if visible?
157
+ fade_out(**kwargs, &block)
158
+ else
159
+ fade_in(**kwargs, &block)
160
+ end
161
+ self
162
+ end
163
+
164
+ # Show a hidden element with a "slide down" animation. Yield a block afterwards.
165
+ def slide_down(**kwargs, &block)
166
+ animation_queue do |resolve|
167
+ if !visible?
168
+ @virtually_visible = true
169
+ show
170
+ height = size.height
171
+ orig_height = style[:height]
172
+ style[:height] = 0.px
173
+
174
+ animate height: height.px, **kwargs do |*args|
175
+ @virtually_visible = nil
176
+ style[:height] = orig_height
177
+ yield(*args) if block_given?
178
+ end
179
+ end
180
+ resolve.call
181
+ end
182
+ self
183
+ end
184
+
185
+ # Hide a visible element with a "slide up" animation. Yield a block afterwards.
186
+ def slide_up(**kwargs, &block)
187
+ animation_queue do |resolve|
188
+ if visible?
189
+ @virtually_visible = false
190
+ orig_height = style[:height]
191
+
192
+ animate height: 0.px, **kwargs do |*args|
193
+ @virtually_visible = nil
194
+ style[:height] = orig_height
195
+ hide
196
+ yield(*args) if block_given?
197
+ end
198
+ end
199
+ resolve.call
200
+ end
201
+ self
202
+ end
203
+
204
+ # Toggle a visibility of an element with a "slide up"/"slide down" animation.
205
+ # Yield a block afterwards.
206
+ def slide_toggle(**kwargs, &block)
207
+ if visible?
208
+ slide_up(**kwargs, &block)
209
+ else
210
+ slide_down(**kwargs, &block)
211
+ end
212
+ self
213
+ end
214
+ end
215
+
216
+ end; end
@@ -0,0 +1,26 @@
1
+ # browser/event/all: Load support for all events
2
+
3
+ require 'browser/event/focus'
4
+ require 'browser/event/wheel'
5
+ require 'browser/event/data_transfer'
6
+ require 'browser/event/composition'
7
+ require 'browser/event/animation'
8
+ require 'browser/event/audio_processing'
9
+ require 'browser/event/before_unload'
10
+ require 'browser/event/composition'
11
+ require 'browser/event/clipboard'
12
+ require 'browser/event/device_light'
13
+ require 'browser/event/device_motion'
14
+ require 'browser/event/device_orientation'
15
+ require 'browser/event/device_proximity'
16
+ require 'browser/event/drag'
17
+ require 'browser/event/gamepad'
18
+ require 'browser/event/hash_change'
19
+ require 'browser/event/progress'
20
+ require 'browser/event/page_transition'
21
+ require 'browser/event/pop_state'
22
+ require 'browser/event/storage'
23
+ require 'browser/event/touch'
24
+ require 'browser/event/sensor'
25
+ require 'browser/event/message'
26
+ require 'browser/event/close'
@@ -0,0 +1,40 @@
1
+ module Browser; class Event
2
+
3
+ class Animation < Event
4
+ handles 'animationend', 'animationiteration', 'animationstart'
5
+
6
+ def self.supported?
7
+ Browser.supports? 'Event.Animation'
8
+ end
9
+
10
+ class Definition < Definition
11
+ def animation=(value)
12
+ `#@native.animationName = #{value}`
13
+ end
14
+
15
+ def elapsed=(value)
16
+ `#@native.elapsedTime = #{value}`
17
+ end
18
+ end
19
+
20
+ if Browser.supports? 'Event.constructor'
21
+ def self.construct(name, desc)
22
+ `new AnimationEvent(#{name}, #{desc})`
23
+ end
24
+ elsif Browser.supports? 'Event.create'
25
+ def self.construct(name, desc)
26
+ %x{
27
+ var event = document.createEvent("AnimationEvent");
28
+ event.initAnimationEvent(name, desc.bubbles, desc.cancelable,
29
+ desc.animationName, desc.elapsedTime);
30
+
31
+ return event;
32
+ }
33
+ end
34
+ end if supported?
35
+
36
+ alias_native :name, :animationName
37
+ alias_native :elapsed, :elapsedTime
38
+ end
39
+
40
+ end; end
@@ -0,0 +1,35 @@
1
+ module Browser; class Event
2
+
3
+ class AudioProcessing < Event
4
+ handles 'audioprocess'
5
+
6
+ def self.supported?
7
+ Browser.supports? 'Event.AudioProcessing'
8
+ end
9
+
10
+ class Definition < Definition
11
+ def time=(value)
12
+ `#@native.playbackTime = #{value}`
13
+ end
14
+
15
+ def input=(value)
16
+ `#@native.inputBuffer = #{value}`
17
+ end
18
+
19
+ def output=(value)
20
+ `#@native.outputBuffer = #{value}`
21
+ end
22
+ end
23
+
24
+ if Browser.supports? 'Event.constructor'
25
+ def self.construct(name, desc)
26
+ `new AudioProcessingEvent(#{name}, #{desc})`
27
+ end
28
+ end if supported?
29
+
30
+ alias_native :time, :playbackTime
31
+ alias_native :input, :inputBuffer
32
+ alias_native :output, :outputBuffer
33
+ end
34
+
35
+ end; end