opal-browser 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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