opal-browser 0.1.0.beta1 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (257) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/build.yml +95 -0
  3. data/.gitignore +3 -0
  4. data/.yardopts +1 -1
  5. data/Gemfile +22 -3
  6. data/LICENSE +20 -0
  7. data/README.md +200 -20
  8. data/Rakefile +29 -1
  9. data/config.ru +20 -2
  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 +24 -0
  78. data/lib/opal-browser.rb +1 -0
  79. data/opal/browser/animation_frame.rb +92 -10
  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 +2 -12
  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 +86 -28
  89. data/opal/browser/console.rb +6 -38
  90. data/opal/browser/cookies.rb +90 -27
  91. data/opal/browser/crypto.rb +79 -0
  92. data/opal/browser/css/declaration.rb +1 -6
  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 +94 -0
  98. data/opal/browser/dom/attribute.rb +16 -9
  99. data/opal/browser/dom/builder.rb +35 -25
  100. data/opal/browser/dom/character_data.rb +43 -7
  101. data/opal/browser/dom/document.rb +171 -37
  102. data/opal/browser/dom/document_fragment.rb +18 -0
  103. data/opal/browser/dom/document_or_shadow_root.rb +19 -0
  104. data/opal/browser/dom/element/attributes.rb +111 -0
  105. data/opal/browser/dom/element/button.rb +31 -0
  106. data/opal/browser/dom/element/custom.rb +177 -0
  107. data/opal/browser/dom/element/data.rb +82 -0
  108. data/opal/browser/dom/element/editable.rb +47 -0
  109. data/opal/browser/dom/element/form.rb +38 -0
  110. data/opal/browser/dom/element/iframe.rb +37 -0
  111. data/opal/browser/dom/element/image.rb +25 -0
  112. data/opal/browser/dom/element/input.rb +48 -1
  113. data/opal/browser/dom/element/media.rb +17 -0
  114. data/opal/browser/dom/element/offset.rb +32 -10
  115. data/opal/browser/dom/element/position.rb +11 -2
  116. data/opal/browser/dom/element/scroll.rb +139 -20
  117. data/opal/browser/dom/element/select.rb +42 -0
  118. data/opal/browser/dom/element/size.rb +46 -0
  119. data/opal/browser/dom/element/template.rb +11 -0
  120. data/opal/browser/dom/element/textarea.rb +26 -0
  121. data/opal/browser/dom/element.rb +496 -168
  122. data/opal/browser/dom/mutation_observer.rb +69 -9
  123. data/opal/browser/dom/node.rb +270 -83
  124. data/opal/browser/dom/node_set.rb +74 -41
  125. data/opal/browser/dom/shadow_root.rb +12 -0
  126. data/opal/browser/dom/text.rb +18 -3
  127. data/opal/browser/dom.rb +40 -18
  128. data/opal/browser/effects.rb +180 -3
  129. data/opal/browser/event/all.rb +26 -0
  130. data/opal/browser/event/animation.rb +40 -0
  131. data/opal/browser/{dom/event → event}/audio_processing.rb +10 -6
  132. data/opal/browser/event/base.rb +461 -0
  133. data/opal/browser/event/before_unload.rb +17 -0
  134. data/opal/browser/event/clipboard.rb +37 -0
  135. data/opal/browser/event/close.rb +49 -0
  136. data/opal/browser/event/composition.rb +52 -0
  137. data/opal/browser/event/custom.rb +65 -0
  138. data/opal/browser/event/data_transfer.rb +95 -0
  139. data/opal/browser/event/device_light.rb +25 -0
  140. data/opal/browser/{dom/event → event}/device_motion.rb +21 -6
  141. data/opal/browser/event/device_orientation.rb +50 -0
  142. data/opal/browser/{dom/event → event}/device_proximity.rb +10 -6
  143. data/opal/browser/event/drag.rb +123 -0
  144. data/opal/browser/event/focus.rb +41 -0
  145. data/opal/browser/event/gamepad.rb +62 -0
  146. data/opal/browser/{dom/event → event}/hash_change.rb +10 -6
  147. data/opal/browser/event/keyboard.rb +128 -0
  148. data/opal/browser/event/message.rb +72 -0
  149. data/opal/browser/{dom/event → event}/mouse.rb +37 -32
  150. data/opal/browser/event/page_transition.rb +25 -0
  151. data/opal/browser/event/pop_state.rb +35 -0
  152. data/opal/browser/event/progress.rb +45 -0
  153. data/opal/browser/event/sensor.rb +17 -0
  154. data/opal/browser/{dom/event → event}/storage.rb +10 -6
  155. data/opal/browser/{dom/event → event}/touch.rb +14 -21
  156. data/opal/browser/event/ui.rb +38 -0
  157. data/opal/browser/{dom/event → event}/wheel.rb +6 -4
  158. data/opal/browser/event.rb +163 -0
  159. data/opal/browser/event_source.rb +7 -4
  160. data/opal/browser/form_data.rb +225 -0
  161. data/opal/browser/history.rb +53 -21
  162. data/opal/browser/http/binary.rb +1 -0
  163. data/opal/browser/http/headers.rb +21 -2
  164. data/opal/browser/http/request.rb +83 -55
  165. data/opal/browser/http/response.rb +5 -1
  166. data/opal/browser/http.rb +47 -9
  167. data/opal/browser/immediate.rb +128 -10
  168. data/opal/browser/interval.rb +41 -23
  169. data/opal/browser/location.rb +20 -4
  170. data/opal/browser/navigator.rb +136 -13
  171. data/opal/browser/polyfill/visual_viewport.rb +216 -0
  172. data/opal/browser/screen.rb +34 -8
  173. data/opal/browser/setup/base.rb +6 -0
  174. data/opal/browser/setup/full.rb +13 -0
  175. data/opal/browser/setup/large.rb +17 -0
  176. data/opal/browser/setup/mini.rb +8 -0
  177. data/opal/browser/setup/traditional.rb +10 -0
  178. data/opal/browser/socket.rb +16 -8
  179. data/opal/browser/storage.rb +155 -52
  180. data/opal/browser/support.rb +299 -0
  181. data/opal/browser/utils.rb +116 -18
  182. data/opal/browser/version.rb +1 -1
  183. data/opal/browser/visual_viewport.rb +39 -0
  184. data/opal/browser/window/size.rb +47 -9
  185. data/opal/browser/window/view.rb +37 -4
  186. data/opal/browser/window.rb +46 -26
  187. data/opal/browser.rb +1 -10
  188. data/opal/opal-browser.rb +1 -0
  189. data/opal-browser.gemspec +10 -12
  190. data/spec/database/sql_spec.rb +139 -0
  191. data/spec/delay_spec.rb +41 -0
  192. data/spec/dom/attribute_spec.rb +49 -0
  193. data/spec/dom/builder_spec.rb +36 -19
  194. data/spec/dom/document_spec.rb +28 -6
  195. data/spec/dom/element/attributes_spec.rb +52 -0
  196. data/spec/dom/element/custom_spec.rb +106 -0
  197. data/spec/dom/element/subclass_spec.rb +144 -0
  198. data/spec/dom/element_spec.rb +184 -7
  199. data/spec/dom/mutation_observer_spec.rb +13 -9
  200. data/spec/dom/node_set_spec.rb +44 -0
  201. data/spec/dom/node_spec.rb +87 -27
  202. data/spec/dom_spec.rb +19 -9
  203. data/spec/event_source_spec.rb +18 -15
  204. data/spec/{dom/event_spec.rb → event_spec.rb} +55 -26
  205. data/spec/history_spec.rb +32 -19
  206. data/spec/http_spec.rb +25 -36
  207. data/spec/immediate_spec.rb +10 -7
  208. data/spec/interval_spec.rb +59 -0
  209. data/spec/native_cached_wrapper_spec.rb +46 -0
  210. data/spec/runner.rb +107 -0
  211. data/spec/socket_spec.rb +18 -14
  212. data/spec/spec_helper.rb +2 -4
  213. data/spec/spec_helper_promise.rb.erb +25 -0
  214. data/spec/storage_spec.rb +7 -7
  215. data/spec/wgxpath.install.js +49 -0
  216. data/spec/window_spec.rb +2 -2
  217. metadata +181 -93
  218. data/opal/browser/compatibility/animation_frame.rb +0 -93
  219. data/opal/browser/compatibility/dom/document/window.rb +0 -15
  220. data/opal/browser/compatibility/dom/element/css.rb +0 -15
  221. data/opal/browser/compatibility/dom/element/matches.rb +0 -31
  222. data/opal/browser/compatibility/dom/element/offset.rb +0 -20
  223. data/opal/browser/compatibility/dom/element/scroll.rb +0 -25
  224. data/opal/browser/compatibility/dom/element/style.rb +0 -15
  225. data/opal/browser/compatibility/dom/mutation_observer.rb +0 -47
  226. data/opal/browser/compatibility/http/request.rb +0 -15
  227. data/opal/browser/compatibility/immediate.rb +0 -107
  228. data/opal/browser/compatibility/window/scroll.rb +0 -27
  229. data/opal/browser/compatibility/window/size.rb +0 -13
  230. data/opal/browser/compatibility/window/view.rb +0 -13
  231. data/opal/browser/compatibility.rb +0 -59
  232. data/opal/browser/dom/compatibility.rb +0 -8
  233. data/opal/browser/dom/event/animation.rb +0 -26
  234. data/opal/browser/dom/event/base.rb +0 -207
  235. data/opal/browser/dom/event/before_unload.rb +0 -13
  236. data/opal/browser/dom/event/clipboard.rb +0 -26
  237. data/opal/browser/dom/event/close.rb +0 -35
  238. data/opal/browser/dom/event/composition.rb +0 -38
  239. data/opal/browser/dom/event/custom.rb +0 -30
  240. data/opal/browser/dom/event/device_light.rb +0 -21
  241. data/opal/browser/dom/event/device_orientation.rb +0 -36
  242. data/opal/browser/dom/event/drag.rb +0 -113
  243. data/opal/browser/dom/event/focus.rb +0 -23
  244. data/opal/browser/dom/event/gamepad.rb +0 -47
  245. data/opal/browser/dom/event/keyboard.rb +0 -93
  246. data/opal/browser/dom/event/message.rb +0 -50
  247. data/opal/browser/dom/event/page_transition.rb +0 -21
  248. data/opal/browser/dom/event/pop_state.rb +0 -21
  249. data/opal/browser/dom/event/progress.rb +0 -31
  250. data/opal/browser/dom/event/sensor.rb +0 -13
  251. data/opal/browser/dom/event/ui.rb +0 -22
  252. data/opal/browser/dom/event.rb +0 -240
  253. data/opal/browser/http/compatibility.rb +0 -1
  254. data/opal/browser/http/parameters.rb +0 -8
  255. data/opal/browser/timeout.rb +0 -60
  256. data/opal/browser/window/compatibility.rb +0 -3
  257. data/opal/browser/window/scroll.rb +0 -49
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'browser/delay'
3
+
4
+ describe Browser::Window do
5
+ describe '#after' do
6
+ it 'calls the block after the given time' do
7
+ promise = Browser::Promise.new
8
+ $window.after 0.3 do
9
+ expect(true).to be_truthy
10
+ promise.resolve
11
+ end
12
+ promise.for_rspec
13
+ end
14
+ end
15
+ end
16
+
17
+ describe Kernel do
18
+ describe '#after' do
19
+ it 'calls the block after the given time' do
20
+ promise = Browser::Promise.new
21
+ after 0.3 do
22
+ expect(true).to be_truthy
23
+ promise.resolve
24
+ end
25
+ promise.for_rspec
26
+ end
27
+ end
28
+ end
29
+
30
+ describe Proc do
31
+ describe '#after' do
32
+ it 'calls the block after the given time' do
33
+ promise = Browser::Promise.new
34
+ -> {
35
+ expect(true).to be_truthy
36
+ promise.resolve
37
+ }.after 0.3
38
+ promise.for_rspec
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Browser::DOM::Attribute do
4
+ html <<-HTML
5
+ <div id="lol" class="hue" something="wat"></div>
6
+ HTML
7
+
8
+ describe '#name' do
9
+ it 'gets the right name' do
10
+ attr = $document['lol'].attribute_nodes.find { |a| a.name == :id }
11
+
12
+ expect(attr.name).to eq(:id)
13
+ end
14
+ end
15
+
16
+ describe '#value' do
17
+ it 'gets the right value' do
18
+ attr = $document['lol'].attribute_nodes.find { |a| a.name == :id }
19
+
20
+ expect(attr.name).to eq(:id)
21
+ expect(attr.value).to eq(:lol)
22
+ end
23
+ end
24
+
25
+ describe '#value=' do
26
+ it 'sets the value' do
27
+ attr = $document['lol'].attribute_nodes.find { |a| a.name == :id }
28
+
29
+ expect(attr.name).to eq(:id)
30
+ expect(attr.value).to eq(:lol)
31
+ attr.value = :omg
32
+ expect(attr.value).to eq(:omg)
33
+ end
34
+ end
35
+
36
+ describe '#id?' do
37
+ it 'is true for an id attribute' do
38
+ attr = $document['lol'].attribute_nodes.find { |a| a.name == :id }
39
+
40
+ expect(attr.id?).to be_truthy
41
+ end
42
+
43
+ it 'is false for any other attribute' do
44
+ attr = $document['lol'].attribute_nodes.find { |a| a.name == :class }
45
+
46
+ expect(attr.id?).to be_falsy
47
+ end
48
+ end
49
+ end
@@ -2,27 +2,35 @@ require 'spec_helper'
2
2
 
3
3
  describe Browser::DOM::Builder do
4
4
  it 'builds an element' do
5
- DOM {
5
+ res = DOM {
6
6
  div
7
- }.name.should == 'DIV'
7
+ }
8
+
9
+ expect(res.name).to eq('DIV')
8
10
  end
9
11
 
10
12
  it 'builds an element with text content' do
11
- DOM {
13
+ res = DOM {
12
14
  div "foo bar"
13
- }.text.should == "foo bar"
15
+ }
14
16
 
15
- DOM {
17
+ expect(res.text).to eq('foo bar')
18
+
19
+ res = DOM {
16
20
  div {
17
21
  "foo bar"
18
22
  }
19
- }.text.should == "foo bar"
23
+ }
24
+
25
+ expect(res.text).to eq('foo bar')
20
26
  end
21
27
 
22
28
  it 'builds an element with attributes' do
23
- DOM {
29
+ res = DOM {
24
30
  div class: :wut
25
- }.class_name.should == :wut
31
+ }
32
+
33
+ expect(res.class_name).to eq(:wut)
26
34
  end
27
35
 
28
36
  it 'builds deeper trees' do
@@ -34,15 +42,15 @@ describe Browser::DOM::Builder do
34
42
  }
35
43
  }
36
44
 
37
- res.name.should == 'DIV'
38
- res.child.name.should == 'SPAN'
39
- res.child.text.should == 'wut'
45
+ expect(res.name).to eq('DIV')
46
+ expect(res.child.name).to eq('SPAN')
47
+ expect(res.child.text).to eq('wut')
40
48
  end
41
49
 
42
50
  it 'sets classes with methods' do
43
- DOM {
51
+ expect(DOM {
44
52
  div.nice.element
45
- }.class_names.should == %w[nice element]
53
+ }.class_names).to eq(%w[nice element])
46
54
  end
47
55
 
48
56
  it 'nests when setting classes' do
@@ -52,10 +60,10 @@ describe Browser::DOM::Builder do
52
60
  }
53
61
  }
54
62
 
55
- res.name.should == 'DIV'
56
- res.class_names.should == %w[nice element]
57
- res.child.name.should == 'SPAN'
58
- res.child.class_names.should == %w[nicer]
63
+ expect(res.name).to eq('DIV')
64
+ expect(res.class_names).to eq(%w[nice element])
65
+ expect(res.child.name).to eq('SPAN')
66
+ expect(res.child.class_names).to eq(%w[nicer])
59
67
  end
60
68
 
61
69
  it 'joins class name properly' do
@@ -63,7 +71,16 @@ describe Browser::DOM::Builder do
63
71
  i.icon[:legal]
64
72
  }
65
73
 
66
- res.name.should == 'I'
67
- res.class_names.should == %w[icon-legal]
74
+ expect(res.name).to eq('I')
75
+ expect(res.class_names).to eq(%w[icon-legal])
76
+ end
77
+
78
+ it 'sets the id' do
79
+ res = DOM {
80
+ div.omg!
81
+ }
82
+
83
+ expect(res.name).to eq('DIV')
84
+ expect(res.id).to eq('omg')
68
85
  end
69
86
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Browser::DOM::Document do
4
4
  describe '#title' do
5
5
  it 'should get the document title' do
6
- $document.title.should be_kind_of(String)
6
+ expect($document.title).to be_a(String)
7
7
  end
8
8
  end
9
9
 
@@ -11,7 +11,7 @@ describe Browser::DOM::Document do
11
11
  it 'should set the document title' do
12
12
  old = $document.title
13
13
  $document.title = 'lol'
14
- $document.title.should == 'lol'
14
+ expect($document.title).to eq('lol')
15
15
  $document.title = old
16
16
  end
17
17
  end
@@ -22,19 +22,41 @@ describe Browser::DOM::Document do
22
22
  HTML
23
23
 
24
24
  it "should get element by id" do
25
- $document["lol"].should == `#{$document.to_n}.getElementById('lol')`
25
+ expect($document["lol"]).to eq(`document.getElementById('lol')`)
26
26
  end
27
27
 
28
28
  it "should get element by css" do
29
- $document["lol"].should == `#{$document.to_n}.getElementById('lol')`
29
+ expect($document["#lol"]).to eq(`document.getElementById('lol')`)
30
30
  end
31
31
 
32
32
  it "should get element by xpath" do
33
- $document["//*[@id='lol']"].should == `#{$document.to_n}.getElementById('lol')`
33
+ expect($document["//*[@id='lol']"]).to eq(`document.getElementById('lol')`)
34
34
  end
35
35
 
36
36
  it "should return nil if it can't find anything" do
37
- $document["doo-dah"].should be_nil
37
+ expect($document["doo-dah"]).to be_nil
38
+ end
39
+ end
40
+
41
+ describe "#ready" do
42
+ it "calls the block when the document is ready" do
43
+ promise = Browser::Promise.new
44
+ $document.ready do
45
+ expect(true).to be_truthy
46
+ promise.resolve
47
+ end
48
+ promise.for_rspec
49
+ end
50
+ end
51
+
52
+ describe "#ready?" do
53
+ it "is true inside a #ready block" do
54
+ promise = Browser::Promise.new
55
+ $document.ready do
56
+ expect($document.ready?).to be_truthy
57
+ promise.resolve
58
+ end
59
+ promise.for_rspec
38
60
  end
39
61
  end
40
62
  end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe Browser::DOM::Element::Attributes do
4
+ html <<-HTML
5
+ <label id="lol" class="name" for="hue"></label>
6
+ HTML
7
+
8
+ describe '#[]' do
9
+ it 'gets an attribute' do
10
+ expect($document[:lol].attributes[:id]).to eq(:lol)
11
+ end
12
+
13
+ it 'gets the class attribute' do
14
+ expect($document[:lol].attributes[:class]).to eq(:name)
15
+ end
16
+
17
+ it 'gets the for attribute' do
18
+ expect($document[:lol].attributes[:for]).to eq(:hue)
19
+ end
20
+ end
21
+
22
+ describe '#[]=' do
23
+ it 'sets an attribute' do
24
+ $document[:lol].attributes[:a] = :foo
25
+
26
+ expect($document[:lol].attributes[:a]).to eq(:foo)
27
+ end
28
+
29
+ it 'sets the class attribute' do
30
+ $document[:lol].attributes[:class] = :bar
31
+
32
+ expect($document[:lol].attributes[:class]).to eq(:bar)
33
+ end
34
+
35
+ it 'sets the for attribute' do
36
+ $document[:lol].attributes[:for] = :baz
37
+
38
+ expect($document[:lol].attributes[:for]).to eq(:baz)
39
+ end
40
+ end
41
+
42
+ describe '#each' do
43
+ it 'enumerates over the attributes' do
44
+ attributes = $document[:lol].attributes.select {|name, _|
45
+ %w[class for id].include?(name)
46
+ }
47
+
48
+ expect(attributes.sort).to eq \
49
+ [[:class, :name], [:for, :hue], [:id, :lol]]
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+ require 'browser/dom/element/custom'
3
+
4
+ describe Browser::DOM::Element::Custom do
5
+ before(:each) do
6
+ $scratchpad = Hash.new { false }
7
+ end
8
+
9
+ def create_custom_class(name, observed_attrs = [])
10
+ Class.new(Browser::DOM::Element::Custom) do
11
+ def initialize(node)
12
+ super
13
+ $scratchpad[:initialized] = true
14
+ end
15
+
16
+ def attached
17
+ $scratchpad[:attached] = true
18
+ end
19
+
20
+ def detached
21
+ $scratchpad[:detached] = true
22
+ end
23
+
24
+ def adopted
25
+ $scratchpad[:adopted] = true
26
+ end
27
+
28
+ def attribute_changed(attr, from, to)
29
+ $scratchpad[:attribute_changed] = [attr, from, to]
30
+ end
31
+
32
+ self.observed_attributes = observed_attrs
33
+
34
+ def_custom name
35
+ end
36
+ end
37
+
38
+ describe "upgrades" do
39
+ html <<-HTML
40
+ <app-ex1></app-ex1>
41
+ <app-ex2></app-ex2>
42
+ <app-ex7 prop="true"></app-ex7>
43
+ HTML
44
+
45
+ it "existing elements when they have been initialized before" do
46
+ expect($document.at_css("app-ex1").class).to eq(Browser::DOM::Element)
47
+ klass = create_custom_class("app-ex1")
48
+ expect($document.at_css("app-ex1").class).to eq(klass)
49
+ expect($scratchpad[:initialized]).to be(true)
50
+ expect($scratchpad[:attached]).to be(true)
51
+ end
52
+
53
+ it "existing elements when they have not been initialized before" do
54
+ klass = create_custom_class("app-ex2")
55
+ expect($scratchpad[:initialized]).to be(true)
56
+ expect($scratchpad[:attached]).to be(true)
57
+ expect($document.at_css("app-ex2").class).to eq(klass)
58
+ end
59
+
60
+ it "and fires property update events when upgraded" do
61
+ klass = create_custom_class("app-ex7", ["prop"])
62
+ expect($scratchpad[:attribute_changed]).to eq([:prop, nil, "true"])
63
+ end
64
+ end
65
+
66
+ it "creates and handles new elements correctly" do
67
+ klass = create_custom_class("app-ex3")
68
+ elem = klass.new
69
+ expect($scratchpad[:initialized]).to be(true)
70
+ expect($scratchpad[:attached]).to be(false)
71
+ $document.body << elem
72
+ expect($scratchpad[:detached]).to be(false)
73
+ expect($scratchpad[:attached]).to be(true)
74
+ elem.remove
75
+ expect($scratchpad[:detached]).to be(true)
76
+ end
77
+
78
+ it "correctly tracks updated properties" do
79
+ klass = create_custom_class("app-ex4")
80
+ elem = klass.new
81
+ expect($scratchpad[:attribute_changed]).to be(false)
82
+ elem[:untracked] = "test"
83
+ expect($scratchpad[:attribute_changed]).to be(false)
84
+
85
+ klass = create_custom_class("app-ex5", ["tracked"])
86
+ elem = klass.new
87
+ expect($scratchpad[:attribute_changed]).to be(false)
88
+ elem[:untracked] = "test"
89
+ expect($scratchpad[:attribute_changed]).to be(false)
90
+ elem[:tracked] = "test"
91
+ expect($scratchpad[:attribute_changed]).to eq([:tracked, nil, "test"])
92
+ end
93
+
94
+ it "allows creation of custom elements in various ways" do
95
+ klass = create_custom_class("app-ex6")
96
+
97
+ elem = klass.new
98
+ expect(elem).to be_a(klass)
99
+ elem = $document.create_element("app-ex6")
100
+ expect(elem).to be_a(klass)
101
+ elem = DOM("<app-ex6>")
102
+ expect(elem).to be_a(klass)
103
+ elem = DOM { e("app-ex6") }
104
+ expect(elem).to be_a(klass)
105
+ end
106
+ end
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Browser::DOM::Element subclassing" do
4
+ class1 = Class.new(Browser::DOM::Element) do
5
+ def_selector ".class1"
6
+
7
+ def hello
8
+ "world"
9
+ end
10
+ end
11
+
12
+ class2 = Class.new(Browser::DOM::Element::Input) do
13
+ def_selector "input.class2[type='text']"
14
+
15
+ def hello
16
+ "goodbye"
17
+ end
18
+ end
19
+
20
+ class3 = Class.new(class2) do
21
+ def_selector "input.class2.class3[type='text']"
22
+
23
+ def self.create(value)
24
+ super().tap { |elem| elem.value = value }
25
+ end
26
+ end
27
+
28
+ class4 = Class.new(Browser::DOM::Element) do
29
+ def_selector "custom-element"
30
+
31
+ def hello
32
+ text
33
+ end
34
+ end
35
+
36
+ html <<-HTML
37
+ <div class='class1' id='hiho'></div>
38
+ <input class='class2' type='text' id='hoho'></div>
39
+ <input class='class2' type='hidden' id='hehe'></div>
40
+ <custom-element id='class4'>value</custom-element>
41
+ HTML
42
+
43
+ it 'dispatches from DOM correctly' do
44
+ elem = $document.at_css('#hiho')
45
+ expect(elem.class).to eq(class1)
46
+ expect(elem.hello).to eq('world')
47
+
48
+ elem = $document.at_css('#hoho')
49
+ expect(elem.class).to eq(class2)
50
+ expect(elem.hello).to eq('goodbye')
51
+
52
+ elem = $document.at_css('#hehe')
53
+ expect(elem.class).to eq(Browser::DOM::Element::Input)
54
+ end
55
+
56
+ it 'supports creating elements correctly' do
57
+ elem = class1.create
58
+ expect(elem.class).to eq(class1)
59
+ expect(elem.class_name).to eq('class1')
60
+ expect(elem.name).to eq('DIV')
61
+ expect(elem.hello).to eq('world')
62
+
63
+ elem = class2.create
64
+ expect(elem.class).to eq(class2)
65
+ expect(elem.class_name).to eq('class2')
66
+ expect(elem.name).to eq('INPUT')
67
+ expect(elem.hello).to eq('goodbye')
68
+ expect(elem.type).to eq('text')
69
+ end
70
+
71
+ it 'supports nested subclassing and .create overloading' do
72
+ elem = class3.create('well')
73
+ expect(elem.class).to eq(class3)
74
+ expect(elem.class_name).to eq('class2 class3')
75
+ expect(elem.value).to eq('well')
76
+ expect(elem.hello).to eq('goodbye')
77
+ end
78
+
79
+ it 'supports custom elements' do
80
+ elem = $document.at_css('#class4')
81
+ expect(elem.class).to eq(class4)
82
+ expect(elem.name).to eq('CUSTOM-ELEMENT')
83
+ expect(elem.hello).to eq('value')
84
+
85
+ elem = class4.create
86
+ expect(elem.class).to eq(class4)
87
+ expect(elem.name).to eq('CUSTOM-ELEMENT')
88
+ expect(elem.hello).to eq('')
89
+ end
90
+
91
+ it 'works with Paggio' do
92
+ elem = DOM { div.class1 }
93
+ expect(elem.class).to eq(class1)
94
+ expect(elem.hello).to eq('world')
95
+ end
96
+
97
+ it 'works with Paggio with a .create/.new intializer' do
98
+ elems = DOM {
99
+ class1.create(self)
100
+ class1.new(self, attrs: { x: :y })
101
+ class1.new(self)
102
+ }
103
+ expect(elems.class).to eq(Browser::DOM::NodeSet)
104
+ expect(elems.length).to eq(3)
105
+ expect(elems[1][:x]).to eq(:y)
106
+ expect(elems.to_ary.map(&:class)).to eq([class1] * 3)
107
+ end
108
+
109
+ it 'works with Paggio, .create/.new and nested blocks' do
110
+ elem = DOM { |d|
111
+ class1.new(d) {
112
+ d.div.noticeme
113
+ class1.new(d) {
114
+ d.div.noticeme3
115
+ }
116
+ d.div.noticeme2
117
+ }
118
+ }
119
+ expect(elem.class).to eq(class1)
120
+ expect(elem.children.length).to eq(3)
121
+ expect(elem.children[1].class).to eq(class1)
122
+ expect(elem.children[1].children.length).to eq(1)
123
+ expect(elem.children[0].class).to eq(Browser::DOM::Element)
124
+ expect(elem.children[2].class).to eq(Browser::DOM::Element)
125
+ expect(elem.children[1].children[0].class).to eq(Browser::DOM::Element)
126
+ end
127
+
128
+ it 'works with Paggio, .create/.new, nested blocks and without DOM{}' do
129
+ elem = class1.new {
130
+ div.noticeme
131
+ class1.new(self) {
132
+ div.noticeme3
133
+ }
134
+ div.noticeme2
135
+ }
136
+ expect(elem.class).to eq(class1)
137
+ expect(elem.children.length).to eq(3)
138
+ expect(elem.children[1].class).to eq(class1)
139
+ expect(elem.children[1].children.length).to eq(1)
140
+ expect(elem.children[0].class).to eq(Browser::DOM::Element)
141
+ expect(elem.children[2].class).to eq(Browser::DOM::Element)
142
+ expect(elem.children[1].children[0].class).to eq(Browser::DOM::Element)
143
+ end
144
+ end