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
@@ -1,39 +1,216 @@
1
+ require 'browser/animation_frame'
2
+
1
3
  module Browser; module DOM
2
4
 
3
5
  class Document < Element
6
+ # @!attribute [r] active_element
7
+ # @return [Element] the element with focus
4
8
  def active_element
5
9
  DOM(`#@native.activeElement`)
6
10
  end
7
11
  end
8
12
 
9
13
  class Element
14
+ # Show the element.
15
+ #
16
+ # @param what [Symbol] how to display it
10
17
  def show(what = :block)
11
18
  style[:display] = what
19
+ self
12
20
  end
13
21
 
22
+ # Hide the element.
14
23
  def hide
15
24
  style[:display] = :none
25
+ self
16
26
  end
17
27
 
18
- def toggle
19
- if style![:display] == :none
20
- show
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
21
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?
22
42
  hide
43
+ else
44
+ show(what)
23
45
  end
46
+ self
24
47
  end
25
48
 
49
+ # Set the focus on the element.
26
50
  def focus
27
51
  `#@native.focus()`
52
+ self
28
53
  end
29
54
 
55
+ # Blur the focus from the element.
30
56
  def blur
31
57
  `#@native.blur()`
58
+ self
32
59
  end
33
60
 
61
+ # Check if the element is focused.
34
62
  def focused?
35
63
  `#@native.hasFocus`
36
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
37
214
  end
38
215
 
39
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'
@@ -1,6 +1,8 @@
1
- module Browser; module DOM; class Event
1
+ module Browser; class Event
2
2
 
3
3
  class Animation < Event
4
+ handles 'animationend', 'animationiteration', 'animationstart'
5
+
4
6
  def self.supported?
5
7
  Browser.supports? 'Event.Animation'
6
8
  end
@@ -35,4 +37,4 @@ class Animation < Event
35
37
  alias_native :elapsed, :elapsedTime
36
38
  end
37
39
 
38
- end; end; end
40
+ end; end
@@ -1,6 +1,8 @@
1
- module Browser; module DOM; class Event
1
+ module Browser; class Event
2
2
 
3
3
  class AudioProcessing < Event
4
+ handles 'audioprocess'
5
+
4
6
  def self.supported?
5
7
  Browser.supports? 'Event.AudioProcessing'
6
8
  end
@@ -30,4 +32,4 @@ class AudioProcessing < Event
30
32
  alias_native :output, :outputBuffer
31
33
  end
32
34
 
33
- end; end; end
35
+ end; end
@@ -1,11 +1,13 @@
1
- module Browser; module DOM
1
+ module Browser
2
2
 
3
3
  class Event
4
- include Native
4
+ include Native::Wrapper
5
5
 
6
+ # @see https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
6
7
  class Definition
7
- include Native
8
+ include Native::Wrapper
8
9
 
10
+ # @private
9
11
  def self.new(&block)
10
12
  data = super(`{ bubbles: true, cancelable: true }`)
11
13
  block.call(data) if block
@@ -13,10 +15,12 @@ class Event
13
15
  data.to_n
14
16
  end
15
17
 
18
+ # Set the event as bubbling.
16
19
  def bubbles=(value)
17
20
  `#@native.bubbles = #{value}`
18
21
  end
19
22
 
23
+ # Set the event as cancelable.
20
24
  def cancelable=(value)
21
25
  `#@native.cancelable = #{value}`
22
26
  end
@@ -49,7 +53,7 @@ class Event
49
53
  def self.included(klass)
50
54
  klass.instance_eval {
51
55
  def self.target(&block)
52
- DOM::Event::Target.register(&block)
56
+ Event::Target.register(&block)
53
57
  end
54
58
  }
55
59
  end
@@ -57,6 +61,7 @@ class Event
57
61
  class Callback
58
62
  attr_reader :target, :name, :selector
59
63
 
64
+ # @private
60
65
  def initialize(target, name, selector = nil, &block)
61
66
  @target = target
62
67
  @name = name
@@ -64,10 +69,14 @@ class Event
64
69
  @block = block
65
70
  end
66
71
 
67
- def call(e)
68
- to_proc.call(e)
72
+ # Call the callback with the given event.
73
+ #
74
+ # @param event [native] the native event object
75
+ def call(event)
76
+ to_proc.call(event)
69
77
  end
70
78
 
79
+ # Get the native function linked to the callback.
71
80
  def to_proc
72
81
  @proc ||= -> event {
73
82
  %x{
@@ -86,10 +95,13 @@ class Event
86
95
  }
87
96
  end
88
97
 
98
+ # @!attribute [r] event
99
+ # @return [Class] the class for the event
89
100
  def event
90
101
  Event.class_for(@name)
91
102
  end
92
103
 
104
+ # Stop listening for the event linked to the callback.
93
105
  def off
94
106
  target.off(self)
95
107
  end
@@ -102,6 +114,7 @@ class Event
102
114
  @pair = pair
103
115
  end
104
116
 
117
+ # Stop listening for the event linked to the delegate.
105
118
  def off
106
119
  delegate = @target.delegated[@name]
107
120
  delegate.last.delete(@pair)
@@ -115,6 +128,26 @@ class Event
115
128
 
116
129
  Delegates = Struct.new(:callback, :handlers)
117
130
 
131
+ # @overload on(name, &block)
132
+ #
133
+ # Start listening for an event on the target.
134
+ #
135
+ # @param name [String] the event name
136
+ #
137
+ # @yieldparam event [Event] the event
138
+ #
139
+ # @return [Callback]
140
+ #
141
+ # @overload on(name, selector, &block)
142
+ #
143
+ # Start listening for an event on the target children.
144
+ #
145
+ # @param name [String] the event name
146
+ # @param selector [String] the CSS selector to trigger the event on
147
+ #
148
+ # @yieldparam event [Event] the event
149
+ #
150
+ # @return [Delegate]
118
151
  def on(name, selector = nil, &block)
119
152
  raise ArgumentError, 'no block has been given' unless block
120
153
 
@@ -152,6 +185,13 @@ class Event
152
185
  end
153
186
  end
154
187
 
188
+ # Start listening for an event in the capturing phase.
189
+ #
190
+ # @param name [String] the event name
191
+ #
192
+ # @yieldparam event [Event] the event
193
+ #
194
+ # @return [Callback]
155
195
  def on!(name, &block)
156
196
  raise ArgumentError, 'no block has been given' unless block
157
197
 
@@ -230,6 +270,44 @@ class Event
230
270
  end
231
271
  end
232
272
 
273
+ # @overload one(name, &block)
274
+ #
275
+ # Start listening for an event on the target. Remove the event after firing
276
+ # so that it is fired at most once.
277
+ #
278
+ # @param name [String] the event name
279
+ #
280
+ # @yieldparam event [Event] the event
281
+ #
282
+ # @return [Callback]
283
+ #
284
+ # @overload one(name, selector, &block)
285
+ #
286
+ # Start listening for an event on the target children. Remove the event after
287
+ # firing so that it is fired at most once.
288
+ #
289
+ # @param name [String] the event name
290
+ # @param selector [String] the CSS selector to trigger the event on
291
+ #
292
+ # @yieldparam event [Event] the event
293
+ #
294
+ # @return [Delegate]
295
+ def one (name, selector = nil, &block)
296
+ raise ArgumentError, 'no block has been given' unless block
297
+
298
+ cb = on name, selector do |*args|
299
+ out = block.call(*args)
300
+ cb.off
301
+ out
302
+ end
303
+ end
304
+ # @overload off()
305
+ # Stop listening for any event.
306
+ #
307
+ # @overload off(what)
308
+ # Stop listening for an event.
309
+ #
310
+ # @param what [Callback, String, Regexp] what to stop listening for
233
311
  def off(what = nil)
234
312
  case what
235
313
  when Callback
@@ -295,6 +373,12 @@ class Event
295
373
  end
296
374
  end
297
375
 
376
+ # Trigger an event on the target.
377
+ #
378
+ # @param event [String] the event name
379
+ # @param args [Array] optional arguments to the event callback
380
+ #
381
+ # @yieldparam definition [Definition] definition to customize the event
298
382
  def trigger(event, *args, &block)
299
383
  if event.is_a? String
300
384
  event = Event.create(event, *args, &block)
@@ -303,7 +387,12 @@ class Event
303
387
  dispatch(event)
304
388
  end
305
389
 
306
- # Trigger the event without bubbling.
390
+ # Trigger an event on the target without bubbling.
391
+ #
392
+ # @param event [String] the event name
393
+ # @param args [Array] optional arguments to the event callback
394
+ #
395
+ # @yieldparam definition [Definition] definition to customize the event
307
396
  def trigger!(event, *args, &block)
308
397
  trigger event, *args do |e|
309
398
  block.call(e) if block
@@ -356,7 +445,7 @@ class Event
356
445
  return if element.nil? || element == event.on
357
446
 
358
447
  delegates.handlers.each {|selector, block|
359
- if element.matches? selector
448
+ if element =~ selector
360
449
  new = event.dup
361
450
  new.on = element
362
451
 
@@ -369,4 +458,4 @@ class Event
369
458
  end
370
459
  end
371
460
 
372
- end; end
461
+ end
@@ -1,6 +1,8 @@
1
- module Browser; module DOM; class Event
1
+ module Browser; class Event
2
2
 
3
3
  class BeforeUnload < Event
4
+ handles 'beforeunload'
5
+
4
6
  def self.supported?
5
7
  Browser.supports? 'Event.BeforeUnload'
6
8
  end
@@ -12,4 +14,4 @@ class BeforeUnload < Event
12
14
  end if supported?
13
15
  end
14
16
 
15
- end; end; end
17
+ end; end
@@ -1,6 +1,8 @@
1
- module Browser; module DOM; class Event
1
+ module Browser; class Event
2
2
 
3
3
  class Clipboard < Event
4
+ handles 'copy', 'cut', 'paste'
5
+
4
6
  def self.supported?
5
7
  Browser.supports? 'Event.Clipboard'
6
8
  end
@@ -23,6 +25,13 @@ class Clipboard < Event
23
25
 
24
26
  alias_native :data
25
27
  alias_native :type, :dataType
28
+
29
+ # Returns a {DataTransfer} related to this event
30
+ #
31
+ # @see https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer
32
+ def transfer
33
+ DataTransfer.new(`#@native.clipboardData`)
34
+ end
26
35
  end
27
36
 
28
- end; end; end
37
+ end; end
@@ -1,6 +1,8 @@
1
- module Browser; module DOM; class Event
1
+ module Browser; class Event
2
2
 
3
3
  class Close < Event
4
+ handles 'close'
5
+
4
6
  def self.supported?
5
7
  Browser.supports? 'Event.Close'
6
8
  end
@@ -44,4 +46,4 @@ class Close < Event
44
46
  alias_native :clean?, :wasClean
45
47
  end
46
48
 
47
- end; end; end
49
+ end; end
@@ -1,6 +1,8 @@
1
- module Browser; module DOM; class Event
1
+ module Browser; class Event
2
2
 
3
3
  class Composition < UI
4
+ handles 'compositionend', 'compositionstart', 'compositionupdate'
5
+
4
6
  def self.supported?
5
7
  Browser.supports? 'Event.Composition'
6
8
  end
@@ -47,4 +49,4 @@ class Composition < UI
47
49
  end
48
50
  end
49
51
 
50
- end; end; end
52
+ end; end
@@ -1,6 +1,6 @@
1
1
  require 'ostruct'
2
2
 
3
- module Browser; module DOM; class Event
3
+ module Browser; class Event
4
4
 
5
5
  class Custom < Event
6
6
  def self.supported?
@@ -17,7 +17,7 @@ class Custom < Event
17
17
 
18
18
  if Browser.supports? 'Event.constructor'
19
19
  def self.construct(name, desc)
20
- `new CustomEvent(name, {
20
+ `return new CustomEvent(name, {
21
21
  bubbles: desc.bubbles,
22
22
  cancelable: desc.cancelable,
23
23
  detail: desc })`
@@ -62,4 +62,4 @@ class Custom < Event
62
62
  end
63
63
  end
64
64
 
65
- end; end; end
65
+ end; end
@@ -0,0 +1,95 @@
1
+ require 'browser/blob'
2
+
3
+ module Browser; class Event
4
+
5
+ # {DataTransfer} is an object which manages included data to
6
+ # an event of type {Event::Drag} or {Event::Clipboard}.
7
+ class DataTransfer
8
+ include NativeCachedWrapper
9
+
10
+ # @!attribute [rw] effect
11
+ # @return [Symbol] Effect of this drop operation.
12
+ # Must be one of: :none, :copy, :link or :move.
13
+ def effect
14
+ `#@native.dropEffect`
15
+ end
16
+
17
+ def effect= (effect)
18
+ `#@native.dropEffect = #{effect}`
19
+ end
20
+
21
+ # Extract some text data from this {DataTransfer} instance.
22
+ def [] (type)
23
+ `#@native.getData(#{type})`
24
+ end
25
+
26
+ # Embed some text data in this {DataTransfer} instance.
27
+ def []= (type, value)
28
+ `#@native.setData(#{type}, #{Native.convert(value)})`
29
+ end
30
+
31
+ # Clear some (or all, if type is not specified) text data from
32
+ # this {DataTransfer} instance.
33
+ def clear (type=nil)
34
+ `#@native.clearData(#{type.to_n})`
35
+ end
36
+
37
+ # @!attribute [w] drag_image
38
+ # Sets a drag image for this {DataTransfer}. Use some
39
+ # {DOM::Element::Image} or {Canvas} as a value.
40
+ def drag_image= (image)
41
+ `#@native.setDragImage(#{Native.convert(image)})`
42
+ end
43
+
44
+ # @!attribute [r] files
45
+ # @return [Array<File>] list of files attached to this {DataTransfer}
46
+ def files
47
+ Native::Array.new(`#@native.files`).map { |f| File.new(f.to_n) }
48
+ end
49
+
50
+ # @!attribute [r] items
51
+ # @return [Array<Item>] list of items attached to this {DataTransfer}
52
+ def items
53
+ Native::Array.new(`#@native.items`).map { |i| Item.new(i.to_n) }
54
+ end
55
+
56
+ # An instance of `DataTransferItem`
57
+ class Item
58
+ include NativeCachedWrapper
59
+
60
+ # @!attribute [r] kind
61
+ # @return [Symbol] kind of an item: :string or :file
62
+ def kind
63
+ `#@native.kind`
64
+ end
65
+
66
+ def string?; kind == 'string'; end
67
+ def file?; kind == 'file' && to_file; end # Some files can't be resolved...
68
+
69
+ # @!attribute [r] type
70
+ # @return [String] mime type of an item
71
+ def type
72
+ `#@native.type`
73
+ end
74
+
75
+ # Convert to string and call back once ready, or return a
76
+ # promise if a block isn't given.
77
+ def to_string(&block)
78
+ promise = nil
79
+ if !block
80
+ promise = Promise.new
81
+ block = proc { |i| promise.resolve(i) }
82
+ end
83
+ `#@native.getAsString(#{block.to_n})`
84
+ return promise
85
+ end
86
+
87
+ # Convert to file or return nil if impossible
88
+ def to_file
89
+ as_file = `#@native.getAsFile()`
90
+ File.new(as_file) if as_file
91
+ end
92
+ end
93
+ end
94
+
95
+ end; end
@@ -1,6 +1,8 @@
1
- module Browser; module DOM; class Event
1
+ module Browser; class Event
2
2
 
3
3
  class DeviceLight < Event
4
+ handles 'devicelight'
5
+
4
6
  def self.supported?
5
7
  Browser.supports? 'Event.DeviceLight'
6
8
  end
@@ -20,4 +22,4 @@ class DeviceLight < Event
20
22
  alias_native :value
21
23
  end
22
24
 
23
- end; end; end
25
+ end; end