opal-browser 0.1.0.beta1

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 (127) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +11 -0
  5. data/README.md +106 -0
  6. data/Rakefile +5 -0
  7. data/config.ru +63 -0
  8. data/lib/opal/browser.rb +4 -0
  9. data/opal-browser.gemspec +23 -0
  10. data/opal/browser.rb +10 -0
  11. data/opal/browser/animation_frame.rb +29 -0
  12. data/opal/browser/canvas.rb +277 -0
  13. data/opal/browser/canvas/data.rb +73 -0
  14. data/opal/browser/canvas/gradient.rb +37 -0
  15. data/opal/browser/canvas/style.rb +123 -0
  16. data/opal/browser/canvas/text.rb +55 -0
  17. data/opal/browser/compatibility.rb +59 -0
  18. data/opal/browser/compatibility/animation_frame.rb +93 -0
  19. data/opal/browser/compatibility/dom/document/window.rb +15 -0
  20. data/opal/browser/compatibility/dom/element/css.rb +15 -0
  21. data/opal/browser/compatibility/dom/element/matches.rb +31 -0
  22. data/opal/browser/compatibility/dom/element/offset.rb +20 -0
  23. data/opal/browser/compatibility/dom/element/scroll.rb +25 -0
  24. data/opal/browser/compatibility/dom/element/style.rb +15 -0
  25. data/opal/browser/compatibility/dom/mutation_observer.rb +47 -0
  26. data/opal/browser/compatibility/http/request.rb +15 -0
  27. data/opal/browser/compatibility/immediate.rb +107 -0
  28. data/opal/browser/compatibility/window/scroll.rb +27 -0
  29. data/opal/browser/compatibility/window/size.rb +13 -0
  30. data/opal/browser/compatibility/window/view.rb +13 -0
  31. data/opal/browser/console.rb +137 -0
  32. data/opal/browser/cookies.rb +79 -0
  33. data/opal/browser/css.rb +24 -0
  34. data/opal/browser/css/declaration.rb +88 -0
  35. data/opal/browser/css/rule.rb +48 -0
  36. data/opal/browser/css/rule/style.rb +16 -0
  37. data/opal/browser/css/style_sheet.rb +83 -0
  38. data/opal/browser/css/unit.rb +188 -0
  39. data/opal/browser/dom.rb +95 -0
  40. data/opal/browser/dom/attribute.rb +19 -0
  41. data/opal/browser/dom/builder.rb +97 -0
  42. data/opal/browser/dom/cdata.rb +9 -0
  43. data/opal/browser/dom/character_data.rb +37 -0
  44. data/opal/browser/dom/comment.rb +9 -0
  45. data/opal/browser/dom/compatibility.rb +8 -0
  46. data/opal/browser/dom/document.rb +83 -0
  47. data/opal/browser/dom/document_fragment.rb +7 -0
  48. data/opal/browser/dom/element.rb +290 -0
  49. data/opal/browser/dom/element/input.rb +17 -0
  50. data/opal/browser/dom/element/offset.rb +67 -0
  51. data/opal/browser/dom/element/position.rb +37 -0
  52. data/opal/browser/dom/element/scroll.rb +49 -0
  53. data/opal/browser/dom/event.rb +240 -0
  54. data/opal/browser/dom/event/animation.rb +26 -0
  55. data/opal/browser/dom/event/audio_processing.rb +31 -0
  56. data/opal/browser/dom/event/base.rb +207 -0
  57. data/opal/browser/dom/event/before_unload.rb +13 -0
  58. data/opal/browser/dom/event/clipboard.rb +26 -0
  59. data/opal/browser/dom/event/close.rb +35 -0
  60. data/opal/browser/dom/event/composition.rb +38 -0
  61. data/opal/browser/dom/event/custom.rb +30 -0
  62. data/opal/browser/dom/event/device_light.rb +21 -0
  63. data/opal/browser/dom/event/device_motion.rb +38 -0
  64. data/opal/browser/dom/event/device_orientation.rb +36 -0
  65. data/opal/browser/dom/event/device_proximity.rb +31 -0
  66. data/opal/browser/dom/event/drag.rb +113 -0
  67. data/opal/browser/dom/event/focus.rb +23 -0
  68. data/opal/browser/dom/event/gamepad.rb +47 -0
  69. data/opal/browser/dom/event/hash_change.rb +26 -0
  70. data/opal/browser/dom/event/keyboard.rb +93 -0
  71. data/opal/browser/dom/event/message.rb +50 -0
  72. data/opal/browser/dom/event/mouse.rb +253 -0
  73. data/opal/browser/dom/event/page_transition.rb +21 -0
  74. data/opal/browser/dom/event/pop_state.rb +21 -0
  75. data/opal/browser/dom/event/progress.rb +31 -0
  76. data/opal/browser/dom/event/sensor.rb +13 -0
  77. data/opal/browser/dom/event/storage.rb +41 -0
  78. data/opal/browser/dom/event/touch.rb +69 -0
  79. data/opal/browser/dom/event/ui.rb +22 -0
  80. data/opal/browser/dom/event/wheel.rb +49 -0
  81. data/opal/browser/dom/mutation_observer.rb +118 -0
  82. data/opal/browser/dom/node.rb +317 -0
  83. data/opal/browser/dom/node_set.rb +88 -0
  84. data/opal/browser/dom/text.rb +21 -0
  85. data/opal/browser/effects.rb +39 -0
  86. data/opal/browser/event_source.rb +67 -0
  87. data/opal/browser/history.rb +54 -0
  88. data/opal/browser/http.rb +129 -0
  89. data/opal/browser/http/binary.rb +57 -0
  90. data/opal/browser/http/compatibility.rb +1 -0
  91. data/opal/browser/http/headers.rb +90 -0
  92. data/opal/browser/http/parameters.rb +8 -0
  93. data/opal/browser/http/request.rb +331 -0
  94. data/opal/browser/http/response.rb +115 -0
  95. data/opal/browser/immediate.rb +43 -0
  96. data/opal/browser/interval.rb +93 -0
  97. data/opal/browser/location.rb +77 -0
  98. data/opal/browser/navigator.rb +151 -0
  99. data/opal/browser/screen.rb +40 -0
  100. data/opal/browser/socket.rb +115 -0
  101. data/opal/browser/storage.rb +149 -0
  102. data/opal/browser/timeout.rb +60 -0
  103. data/opal/browser/utils.rb +56 -0
  104. data/opal/browser/version.rb +3 -0
  105. data/opal/browser/window.rb +113 -0
  106. data/opal/browser/window/compatibility.rb +3 -0
  107. data/opal/browser/window/scroll.rb +49 -0
  108. data/opal/browser/window/size.rb +35 -0
  109. data/opal/browser/window/view.rb +18 -0
  110. data/spec/dom/builder_spec.rb +69 -0
  111. data/spec/dom/document_spec.rb +40 -0
  112. data/spec/dom/element_spec.rb +46 -0
  113. data/spec/dom/event_spec.rb +127 -0
  114. data/spec/dom/mutation_observer_spec.rb +37 -0
  115. data/spec/dom/node_spec.rb +154 -0
  116. data/spec/dom_spec.rb +13 -0
  117. data/spec/event_source_spec.rb +42 -0
  118. data/spec/history_spec.rb +48 -0
  119. data/spec/http_spec.rb +87 -0
  120. data/spec/immediate_spec.rb +12 -0
  121. data/spec/json2.js +486 -0
  122. data/spec/sizzle.js +5 -0
  123. data/spec/socket_spec.rb +43 -0
  124. data/spec/spec_helper.rb +37 -0
  125. data/spec/storage_spec.rb +26 -0
  126. data/spec/window_spec.rb +10 -0
  127. metadata +240 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 67a9bf1ea4b1b5b2f0b9850b39a8e7da1b464806
4
+ data.tar.gz: 021fa0a9e5ed6d1ab1b3d64f85d68c4860696c79
5
+ SHA512:
6
+ metadata.gz: 7fc4300cbb533f11e140ea654de6bf4742bbfca85041d6f6e2bc3f69cb352c4ff20e4cc42c54ffa15320e53ae094abb502b52d023e8701581caec38e53a6dba2
7
+ data.tar.gz: 3d27cd50d48f61dc21a4d838d502e212ff0e25ff8cfb2e8db264b439068a14f79a4d19630ac64f173c2d48d6ac1969e45aabd75c2c29349d114672fece6fe0b2
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ Gemfile.lock
2
+ vendor
3
+ .bundle
4
+ copycat
5
+ doc
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --no-private opal/**/*.rb
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'rake'
5
+ gem 'rack'
6
+ gem 'sinatra'
7
+ gem 'sinatra-websocket'
8
+
9
+ gem 'opal', github: 'opal/opal'
10
+ gem 'opal-rspec', '0.3.0.beta2'
11
+ gem 'paggio', github: 'meh/paggio'
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ Browser support for Opal
2
+ ========================
3
+ This library aims to be a full-blown wrapper for all the browser API including
4
+ HTML5.
5
+
6
+ Features
7
+ ========
8
+ This is a list of the currently wrapped features and some details on them.
9
+
10
+ DOM
11
+ ---
12
+ DOM support is complete as far as I know, it has a very Nokogiri feel to it
13
+ with obvious differences where relevant (for instance, event handling).
14
+
15
+ ```ruby
16
+ $document.on :load do
17
+ alert "yo dawg, I'm all loaded up in here"
18
+ end
19
+ ```
20
+
21
+ It also supports a markaby inspired builder DSL which generates DOM nodes
22
+ directly instead of creating a string.
23
+
24
+ ```ruby
25
+ $document.on :load do
26
+ DOM {
27
+ div.info {
28
+ span.red "I'm all cooked up."
29
+ }
30
+ }.append_to($document.body)
31
+ end
32
+ ```
33
+
34
+ CSSOM
35
+ -----
36
+ CSSOM support is still incomplete but the useful parts are implemented, this
37
+ includes a DSL for generating a CSS style and the same DSL is also used to
38
+ change style declarations (which can either belong to a `DOM::Element` or a
39
+ `CSS::Rule::Style`).
40
+
41
+ ```ruby
42
+ $document.body.style.apply {
43
+ background color: 'black'
44
+ color 'white'
45
+ font family: 'Verdana'
46
+ }
47
+ ```
48
+
49
+ AJAX & SJAX
50
+ -----------
51
+ The `XMLHttpRequest` API has been wrapped completely, it also optionally
52
+ supports binary results as typed-arrays.
53
+
54
+ It easily allows for synchronous and asynchronous requests.
55
+
56
+ ```ruby
57
+ Browser::HTTP.get "/something.json" do
58
+ on :success do |res|
59
+ alert res.json.inspect
60
+ end
61
+ end
62
+ ```
63
+
64
+ WebSocket
65
+ ---------
66
+ Websockets have been fully wrapped and they are easily configurable with
67
+ blocks.
68
+
69
+ ```ruby
70
+ Browser::Socket.new 'ws://echo.websocket.org' do
71
+ on :open do
72
+ every 1 do
73
+ puts "ping"
74
+ end
75
+ end
76
+
77
+ on :message do |e|
78
+ log "Received #{e.data}"
79
+ end
80
+ end
81
+ ```
82
+
83
+ EventSource
84
+ -----------
85
+ Event sources have been implemented and are easily configurable with blocks.
86
+
87
+ History
88
+ -------
89
+ The HTML5 History API has been fully wrapped.
90
+
91
+ Storage
92
+ -------
93
+ The HTML5 Storage API has been wrapped and it exports a single Storage class
94
+ that uses the most appropriate and available API to store data locally.
95
+
96
+ Cross-browser compatibility
97
+ ===========================
98
+ Right now all features are implemented with the stable or working-drafts API
99
+ which aren't implemented everywhere.
100
+
101
+ The current approach is to have a file for each method in the `compatibility`
102
+ directory where alternatives based on functional-presence are implemented.
103
+
104
+ You can see an example for the matches selector API [here][1].
105
+
106
+ [1]: https://github.com/opal/opal-browser/blob/master/opal/browser/compatibility/dom/element/matches.rb
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+
4
+ require 'opal/rspec/rake_task'
5
+ Opal::RSpec::RakeTask.new(:default)
data/config.ru ADDED
@@ -0,0 +1,63 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+
4
+ apps = []
5
+ apps << Opal::Server.new { |s|
6
+ s.main = 'opal/rspec/sprockets_runner'
7
+ s.append_path 'spec'
8
+ s.debug = false
9
+ }
10
+
11
+ apps << Class.new(Sinatra::Base) {
12
+ get '/http' do
13
+ "lol"
14
+ end
15
+
16
+ post '/http' do
17
+ if params['lol'] == 'wut'
18
+ "ok"
19
+ else
20
+ "fail"
21
+ end
22
+ end
23
+
24
+ put '/http' do
25
+ if params['lol'] == 'wut'
26
+ "ok"
27
+ else
28
+ "fail"
29
+ end
30
+ end
31
+
32
+ delete '/http' do
33
+ "lol"
34
+ end
35
+
36
+ get '/events' do
37
+ headers 'Content-Type' => 'text/event-stream'
38
+
39
+ stream do |out|
40
+ sleep 0.2
41
+
42
+ out << "data: lol\n" << "\n"
43
+ out << "event: custom\n" << "data: omg\n" << "\n"
44
+ out << "data: wut\n" << "\n"
45
+
46
+ sleep 10
47
+ end
48
+ end
49
+
50
+ get '/socket' do
51
+ request.websocket do |ws|
52
+ ws.onopen do
53
+ ws.send 'lol'
54
+ end
55
+
56
+ ws.onmessage do |msg|
57
+ ws.send msg
58
+ end
59
+ end
60
+ end
61
+ }
62
+
63
+ run Rack::Cascade.new(apps)
@@ -0,0 +1,4 @@
1
+ require 'opal'
2
+
3
+ Opal.append_path File.expand_path('../../../opal', __FILE__)
4
+ Opal.use_gem 'paggio'
@@ -0,0 +1,23 @@
1
+ $LOAD_PATH << File.expand_path('../opal', __FILE__)
2
+ require 'browser/version'
3
+
4
+ Gem::Specification.new {|s|
5
+ s.name = 'opal-browser'
6
+ s.version = Browser::VERSION
7
+ s.author = 'meh.'
8
+ s.email = 'meh@schizofreni.co'
9
+ s.homepage = 'http://github.com/opal/opal-browser'
10
+ s.platform = Gem::Platform::RUBY
11
+ s.summary = 'Browser support for Opal.'
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.require_paths = ['lib']
17
+
18
+ s.add_dependency 'opal', '>= 0.5.5'
19
+ s.add_dependency 'paggio'
20
+
21
+ s.add_development_dependency 'opal-rspec'
22
+ s.add_development_dependency 'rake'
23
+ }
data/opal/browser.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'native'
2
+ require 'paggio'
3
+
4
+ require 'browser/version'
5
+ require 'browser/utils'
6
+ require 'browser/compatibility'
7
+
8
+ require 'browser/window'
9
+ require 'browser/dom'
10
+ require 'browser/css'
@@ -0,0 +1,29 @@
1
+ require 'browser/compatibility/animation_frame'
2
+
3
+ module Browser
4
+
5
+ # FIXME: drop the method_defined? checks when require order is fixed
6
+ class AnimationFrame
7
+ def initialize(window, &block)
8
+ @window = window
9
+ @native = window.to_n
10
+ @id = request(block)
11
+ end
12
+
13
+ def request
14
+ raise NotImplementedError, 'window requestAnimationFrame unsupported'
15
+ end unless method_defined? :request
16
+
17
+ def cancel
18
+ raise NotImplementedError, 'window cancelAnimationFrame unsupported'
19
+ end unless method_defined? :cancel
20
+ end
21
+
22
+ end
23
+
24
+ class Proc
25
+ # Execute a block to update an animation before the next repaint.
26
+ def animation_frame
27
+ Browser::AnimationFrame.new($window, &self)
28
+ end
29
+ end
@@ -0,0 +1,277 @@
1
+ #--
2
+ # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
3
+ # Version 2, December 2004
4
+ #
5
+ # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
6
+ # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
7
+ #
8
+ # 0. You just DO WHAT THE FUCK YOU WANT TO.
9
+ #++
10
+
11
+ require 'browser/canvas/style'
12
+ require 'browser/canvas/text'
13
+ require 'browser/canvas/data'
14
+ require 'browser/canvas/gradient'
15
+
16
+ module Browser
17
+
18
+ class Canvas
19
+ include Native
20
+
21
+ attr_reader :element, :style, :text
22
+
23
+ def initialize(*args)
24
+ if DOM::Node === args.first
25
+ @element = args.shift
26
+ else
27
+ @element = $document.create_element('canvas')
28
+ @element[:width] = args.shift
29
+ @element[:height] = args.shift
30
+ end
31
+
32
+ if @element.node_name != 'CANVAS'
33
+ raise ArgumentError, "the element isn't a <canvas> element"
34
+ end
35
+
36
+ super(`#{@element.to_n}.getContext('2d')`)
37
+
38
+ @style = Style.new(self)
39
+ @text = Text.new(self)
40
+ end
41
+
42
+ def data(x = nil, y = nil, width = nil, height = nil)
43
+ x ||= 0
44
+ y ||= 0
45
+ width ||= self.width
46
+ height ||= self.height
47
+
48
+ Data.new(self, x, y, width, height)
49
+ end
50
+
51
+ def pattern(image, type = :repeat)
52
+ `#@native.createPattern(#{Element(image).to_n}, type)`
53
+ end
54
+
55
+ def gradient(*args, &block)
56
+ Gradient.new(self, *args, &block)
57
+ end
58
+
59
+ def clear(x = nil, y = nil, width = nil, height = nil)
60
+ x ||= 0
61
+ y ||= 0
62
+ width ||= self.width
63
+ height ||= self.height
64
+
65
+ `#@native.clearRect(x, y, width, height)`
66
+ end
67
+
68
+ def begin
69
+ `#@native.beginPath()`
70
+
71
+ self
72
+ end
73
+
74
+ def close
75
+ `#@native.closePath()`
76
+
77
+ self
78
+ end
79
+
80
+ def save
81
+ `#@native.save()`
82
+
83
+ self
84
+ end
85
+
86
+ def restore
87
+ `#@native.restore()`
88
+
89
+ self
90
+ end
91
+
92
+ def move_to(x, y)
93
+ `#@native.moveTo(x, y)`
94
+
95
+ self
96
+ end
97
+
98
+ alias move move_to
99
+
100
+ def line_to(x, y)
101
+ `#@native.lineTo(x, y)`
102
+
103
+ self
104
+ end
105
+
106
+ def line(x1, y1, x2, y2)
107
+ move_to x1, y1
108
+ line_to x2, y2
109
+ end
110
+
111
+ def rect(x, y, width, height)
112
+ `#@native.rect(x, y, width, height)`
113
+
114
+ self
115
+ end
116
+
117
+ def arc(x, y, radius, angle, clockwise = false)
118
+ `#@native.arc(x, y, radius, #{angle[:start]}, #{angle[:end]}, !clockwise)`
119
+
120
+ self
121
+ end
122
+
123
+ def quadratic_curve_to(cp1x, cp1y, x, y)
124
+ `#@native.quadraticCurveTo(cp1x, cp1y, x, y)`
125
+
126
+ self
127
+ end
128
+
129
+ def bezier_curve_to(cp1x, cp1y, cp2x, cp2y, x, y)
130
+ `#@native.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)`
131
+
132
+ self
133
+ end
134
+
135
+ def curve_to(*args)
136
+ case args.length
137
+ when 4 then quadratic_curve_to(*args)
138
+ when 6 then bezier_curve_to(*args)
139
+
140
+ else raise ArgumentError, "don't know where to dispatch"
141
+ end
142
+
143
+ self
144
+ end
145
+
146
+ def draw_image(*args)
147
+ image = Element(args.shift)
148
+
149
+ if args.first.is_a?(Hash)
150
+ source, destination = args
151
+
152
+ `#@native.drawImage(#{image.to_n}, #{source[:x]}, #{source[:y]}, #{source[:width]}, #{source[:height]}, #{destination[:x]}, #{destination[:y]}, #{destination[:width]}, #{destination[:height]})`
153
+ else
154
+ x, y, width, height = args
155
+
156
+ `#@native.drawImage(#{image.to_n}, #{x}, #{y}, #{width || `undefined`}, #{height || `undefined`})`
157
+ end
158
+
159
+ self
160
+ end
161
+
162
+ def translate(x, y, &block)
163
+ if block
164
+ save
165
+
166
+ `#@native.translate(x, y)`
167
+
168
+ instance_eval(&block)
169
+
170
+ restore
171
+ else
172
+ `#@native.translate(x, y)`
173
+ end
174
+
175
+ self
176
+ end
177
+
178
+ def rotate(angle, &block)
179
+ if block
180
+ save
181
+
182
+ `#@native.rotate(angle)`
183
+
184
+ instance_eval(&block)
185
+
186
+ restore
187
+ else
188
+ `#@native.rotate(angle)`
189
+ end
190
+
191
+ self
192
+ end
193
+
194
+ def scale(x, y, &block)
195
+ if block
196
+ save
197
+
198
+ `#@native.scale(x, y)`
199
+
200
+ instance_eval(&block)
201
+
202
+ restore
203
+ else
204
+ `#@native.scale(x, y)`
205
+ end
206
+
207
+ self
208
+ end
209
+
210
+ def transform(m11, m12, m21, m22, dx, dy, &block)
211
+ if block
212
+ save
213
+
214
+ `#@native.transform(m11, m12, m21, m22, dx, dy)`
215
+
216
+ instance_eval(&block)
217
+
218
+ restore
219
+ else
220
+ `#@native.transform(m11, m12, m21, m22, dx, dy)`
221
+ end
222
+
223
+ self
224
+ end
225
+
226
+ def path(&block)
227
+ `#@native.beginPath()`
228
+
229
+ instance_eval(&block)
230
+
231
+ `#@native.closePath()`
232
+
233
+ self
234
+ end
235
+
236
+ def fill(&block)
237
+ path(&block) if block
238
+
239
+ `#@native.fill()`
240
+
241
+ self
242
+ end
243
+
244
+ def stroke(&block)
245
+ path(&block) if block
246
+
247
+ `#@native.stroke()`
248
+
249
+ self
250
+ end
251
+
252
+ def clip(&block)
253
+ path(&block) if block
254
+
255
+ `#@native.clip()`
256
+
257
+ self
258
+ end
259
+
260
+ def point_in_path?(x, y)
261
+ `#@native.isPointInPath(x, y)`
262
+ end
263
+
264
+ def width
265
+ @element[:width]
266
+ end
267
+
268
+ def height
269
+ @element[:height]
270
+ end
271
+
272
+ def to_data(type = undefined)
273
+ `#{@element.to_n}.toDataUrl(type)`
274
+ end
275
+ end
276
+
277
+ end