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,9 +1,5 @@
1
- require 'browser/interval'
2
- require 'browser/delay'
3
-
4
1
  require 'browser/window/view'
5
2
  require 'browser/window/size'
6
- require 'browser/window/scroll'
7
3
 
8
4
  module Browser
9
5
 
@@ -33,7 +29,12 @@ class Window
33
29
  }
34
30
  end
35
31
 
36
- include Native
32
+ include Browser::NativeCachedWrapper
33
+ include Event::Target
34
+
35
+ target {|value|
36
+ $window if `#{value} == window`
37
+ }
37
38
 
38
39
  # Alert the passed string.
39
40
  def alert(value)
@@ -43,8 +44,8 @@ class Window
43
44
  end
44
45
 
45
46
  # Display a prompt dialog with the passed string as text.
46
- def prompt(value)
47
- `#@native.prompt(value) || nil`
47
+ def prompt(value, default=nil)
48
+ `#@native.prompt(value, #{default || ""}) || nil`
48
49
  end
49
50
 
50
51
  # Display a confirmation dialog with the passed string as text.
@@ -52,41 +53,61 @@ class Window
52
53
  `#@native.confirm(value) || false`
53
54
  end
54
55
 
56
+ # @!attribute [r] parent
57
+ # @return [Window] parent of the current window or subframe
58
+ def parent
59
+ @parent ||= Browser::Window.new(`#@native.parent`)
60
+ end
61
+
62
+ # @!attribute [r] top
63
+ # @return [Window] reference to the topmost window in the window hierarchy
64
+ def top
65
+ @top ||= Browser::Window.new(`#@native.top`)
66
+ end
67
+
68
+ # @!attribute [r] opener
69
+ # @return [Window] reference to the window that opened the window using `open`
70
+ def opener
71
+ @opener ||= Browser::Window.new(`#@native.opener`)
72
+ end
73
+
55
74
  # Get the {View} for the window.
56
75
  #
57
76
  # @return [View]
58
77
  def view
59
- View.new(self)
78
+ @view ||= View.new(self)
60
79
  end
61
80
 
62
81
  # Get the {Size} for this window.
63
82
  #
64
83
  # @return [Size]
65
84
  def size
66
- Size.new(self)
85
+ @size ||= Size.new(self)
67
86
  end
68
87
 
69
- # Get the {Scroll} for this window.
88
+ # Get the {DOM::Element::Scroll} for this window.
70
89
  #
71
- # @return [Scroll]
90
+ # @return [DOM::Element::Scroll]
72
91
  def scroll
73
- Scroll.new(self)
92
+ @scroll ||= DOM::Element::Scroll.new(self)
74
93
  end
75
94
 
76
- # Send a message to the window.
77
- #
78
- # @param message [String] the message
79
- # @param options [Hash] optional `to: target`
80
- def send!(message, options = {})
81
- `#@native.postMessage(#{message}, #{options[:to] || '*'})`
95
+ if Browser.supports? 'Window.send'
96
+ def send(message, options = {})
97
+ `#@native.postMessage(#{message}, #{options[:to] || '*'})`
98
+ end
99
+ else
100
+ # Send a message to the window.
101
+ #
102
+ # @param message [String] the message
103
+ # @param options [Hash] optional `to: target`
104
+ def send(message, options = {})
105
+ raise NotImplementedError, 'message sending unsupported'
106
+ end
82
107
  end
83
108
 
84
109
  def close
85
- %x{
86
- return (window.open('', '_self', '') && window.close()) ||
87
- (window.opener = null && window.close()) ||
88
- (window.opener = '' && window.close());
89
- }
110
+ `#{@native}.close()`
90
111
  end
91
112
  end
92
113
 
@@ -101,8 +122,8 @@ module Kernel
101
122
  end
102
123
 
103
124
  # (see Browser::Window#prompt)
104
- def prompt(value)
105
- $window.prompt(value)
125
+ def prompt(value, default=nil)
126
+ $window.prompt(value, default)
106
127
  end
107
128
 
108
129
  # (see Browser::Window#confirm)
data/opal/browser.rb CHANGED
@@ -1,10 +1 @@
1
- require 'native'
2
- require 'paggio'
3
-
4
- require 'browser/version'
5
- require 'browser/utils'
6
- require 'browser/support'
7
-
8
- require 'browser/window'
9
- require 'browser/dom'
10
- require 'browser/css'
1
+ require 'browser/setup/traditional'
@@ -0,0 +1 @@
1
+ require 'browser'
data/opal-browser.gemspec CHANGED
@@ -4,7 +4,7 @@ require 'browser/version'
4
4
  Gem::Specification.new {|s|
5
5
  s.name = 'opal-browser'
6
6
  s.version = Browser::VERSION
7
- s.author = 'meh.'
7
+ s.author = ['meh.', 'hmdne']
8
8
  s.email = 'meh@schizofreni.co'
9
9
  s.homepage = 'http://github.com/opal/opal-browser'
10
10
  s.platform = Gem::Platform::RUBY
@@ -16,6 +16,6 @@ Gem::Specification.new {|s|
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
17
  s.require_paths = ['lib']
18
18
 
19
- s.add_dependency 'opal', '~> 0.6.0'
20
- s.add_dependency 'paggio'
19
+ s.add_dependency 'opal', ['>= 1.0', '< 2.0']
20
+ s.add_dependency 'paggio', '>= 0.3.0'
21
21
  }
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+ require 'browser/database/sql'
3
+
4
+ describe Browser::Database::SQL do
5
+ SQL = Browser::Database::SQL
6
+ SIZE = 1024 * 1024
7
+
8
+ describe '#new' do
9
+ it 'sets the attributes properly' do
10
+ sql = SQL.new('test', description: 'trains', size: SIZE)
11
+
12
+ expect(sql.name).to eq('test')
13
+ expect(sql.description).to eq('trains')
14
+ expect(sql.size).to eq(SIZE)
15
+ end
16
+
17
+ it 'sets the version properly' do
18
+ sql = SQL.new('test2', version: '1.0', size: SIZE)
19
+ expect(sql.version).to eq('1.0')
20
+
21
+ sql = SQL.new('test', size: SIZE)
22
+ expect(sql.version).to eq('')
23
+ end
24
+ end
25
+
26
+ describe '#transaction' do
27
+ it 'calls the block with the transaction' do
28
+ sql = SQL.new('test', size: SIZE)
29
+
30
+ promise = Browser::Promise.new
31
+ sql.transaction {|t|
32
+ expect(t).to be_a(SQL::Transaction)
33
+ promise.resolve
34
+ }
35
+ promise.for_rspec
36
+ end
37
+
38
+ it 'the transaction database is the right one' do
39
+ sql = SQL.new('test', size: SIZE)
40
+
41
+ promise = Browser::Promise.new
42
+ sql.transaction {|t|
43
+ expect(t.database).to eq(sql)
44
+ promise.resolve
45
+ }
46
+ promise.for_rspec
47
+ end
48
+ end
49
+
50
+ describe SQL::Transaction do
51
+ describe '#query' do
52
+ it 'returns a promise' do
53
+ sql = SQL.new('test', size: SIZE)
54
+
55
+ promise = Browser::Promise.new
56
+ sql.transaction {|t|
57
+ expect(t.query('hue')).to be_a(Promise)
58
+ promise.resolve
59
+ }
60
+ promise.for_rspec
61
+ end
62
+
63
+ it 'resolves on success' do
64
+ sql = SQL.new('test', size: SIZE)
65
+
66
+ promise = Browser::Promise.new
67
+ sql.transaction {|t|
68
+ t.query('CREATE TABLE IF NOT EXISTS test(ID INTEGER PRIMARY KEY ASC, a TEXT)').then {|r|
69
+ expect(r).to be_a(SQL::Result)
70
+ promise.resolve
71
+ }
72
+ }
73
+ promise.for_rspec
74
+ end
75
+
76
+ it 'rejects on failure' do
77
+ sql = SQL.new('test', size: SIZE)
78
+
79
+ promise = Browser::Promise.new
80
+ sql.transaction {|t|
81
+ t.query('huehue').rescue {|e|
82
+ expect(e).to be_a(SQL::Error::Syntax)
83
+ promise.resolve
84
+ }
85
+ }
86
+ promise.for_rspec
87
+ end
88
+ end
89
+ end
90
+
91
+ describe SQL::Result do
92
+ describe '#length' do
93
+ it 'has the proper length' do
94
+ sql = SQL.new('test', size: SIZE)
95
+
96
+ promise = Browser::Promise.new
97
+ sql.transaction {|t|
98
+ t.query('SELECT 1').then {|r|
99
+ expect(r.length).to eq(1)
100
+ promise.resolve
101
+ }
102
+ }
103
+ promise.for_rspec
104
+ end
105
+ end
106
+
107
+ describe '#[]' do
108
+ it 'returns a row' do
109
+ sql = SQL.new('test', size: SIZE)
110
+
111
+ promise = Browser::Promise.new
112
+ sql.transaction {|t|
113
+ t.query('SELECT 1, 2, 3').then {|r|
114
+ expect(r[0]).to be_a(SQL::Row)
115
+ expect(r[-1]).to be_a(SQL::Row)
116
+
117
+ expect(r[0]).to eq(r[-1])
118
+ promise.resolve
119
+ }
120
+ }
121
+ promise.for_rspec
122
+ end
123
+
124
+ it 'returns nil on missing row' do
125
+ sql = SQL.new('test', size: SIZE)
126
+
127
+ promise = Browser::Promise.new
128
+ sql.transaction {|t|
129
+ t.query('SELECT 1, 2, 3').then {|r|
130
+ expect(r[5]).to be_nil
131
+ expect(r[-5]).to be_nil
132
+ promise.resolve
133
+ }
134
+ }
135
+ promise.for_rspec
136
+ end
137
+ end
138
+ end
139
+ end if Browser::Database::SQL.supported?
@@ -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
- expect(DOM {
5
+ res = DOM {
6
6
  div
7
- }.name).to eq('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
- expect(DOM {
13
+ res = DOM {
12
14
  div "foo bar"
13
- }.text).to eq('foo bar')
15
+ }
14
16
 
15
- expect(DOM {
17
+ expect(res.text).to eq('foo bar')
18
+
19
+ res = DOM {
16
20
  div {
17
21
  "foo bar"
18
22
  }
19
- }.text).to eq('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
- expect(DOM {
29
+ res = DOM {
24
30
  div class: :wut
25
- }.class_name).to eq(:wut)
31
+ }
32
+
33
+ expect(res.class_name).to eq(:wut)
26
34
  end
27
35
 
28
36
  it 'builds deeper trees' do
@@ -66,4 +74,13 @@ describe Browser::DOM::Builder do
66
74
  expect(res.name).to eq('I')
67
75
  expect(res.class_names).to eq(%w[icon-legal])
68
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')
85
+ end
69
86
  end
@@ -37,4 +37,26 @@ describe Browser::DOM::Document do
37
37
  expect($document["doo-dah"]).to be_nil
38
38
  end
39
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
60
+ end
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