opal-browser 0.2.0.beta1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +22 -8
- data/Gemfile +1 -1
- data/README.md +59 -5
- data/index.html.erb +7 -4
- data/lib/opal-browser.rb +1 -0
- data/opal-browser.gemspec +1 -1
- data/opal/browser.rb +1 -0
- data/opal/browser/animation_frame.rb +26 -1
- data/opal/browser/canvas.rb +0 -10
- data/opal/browser/canvas/data.rb +0 -10
- data/opal/browser/canvas/gradient.rb +0 -10
- data/opal/browser/canvas/style.rb +0 -10
- data/opal/browser/canvas/text.rb +0 -10
- data/opal/browser/cookies.rb +6 -8
- data/opal/browser/database/sql.rb +194 -0
- data/opal/browser/delay.rb +25 -7
- data/opal/browser/dom.rb +2 -11
- data/opal/browser/dom/attribute.rb +12 -11
- data/opal/browser/dom/builder.rb +4 -9
- data/opal/browser/dom/document.rb +105 -41
- data/opal/browser/dom/element.rb +317 -231
- data/opal/browser/dom/element/attributes.rb +87 -0
- data/opal/browser/dom/element/data.rb +67 -0
- data/opal/browser/dom/element/input.rb +12 -1
- data/opal/browser/dom/element/offset.rb +5 -0
- data/opal/browser/dom/element/position.rb +11 -2
- data/opal/browser/dom/element/scroll.rb +77 -10
- data/opal/browser/dom/element/select.rb +36 -0
- data/opal/browser/dom/element/size.rb +5 -0
- data/opal/browser/dom/element/template.rb +9 -0
- data/opal/browser/dom/element/textarea.rb +24 -0
- data/opal/browser/dom/mutation_observer.rb +2 -2
- data/opal/browser/dom/node.rb +93 -51
- data/opal/browser/dom/node_set.rb +66 -48
- data/opal/browser/effects.rb +11 -0
- data/opal/browser/{dom/event.rb → event.rb} +32 -32
- data/opal/browser/{dom/event → event}/animation.rb +2 -2
- data/opal/browser/{dom/event → event}/audio_processing.rb +2 -2
- data/opal/browser/{dom/event → event}/base.rb +65 -7
- data/opal/browser/{dom/event → event}/before_unload.rb +2 -2
- data/opal/browser/{dom/event → event}/clipboard.rb +2 -2
- data/opal/browser/{dom/event → event}/close.rb +2 -2
- data/opal/browser/{dom/event → event}/composition.rb +2 -2
- data/opal/browser/{dom/event → event}/custom.rb +2 -2
- data/opal/browser/{dom/event → event}/device_light.rb +2 -2
- data/opal/browser/{dom/event → event}/device_motion.rb +2 -2
- data/opal/browser/{dom/event → event}/device_orientation.rb +2 -2
- data/opal/browser/{dom/event → event}/device_proximity.rb +2 -2
- data/opal/browser/{dom/event → event}/drag.rb +2 -2
- data/opal/browser/{dom/event → event}/focus.rb +2 -2
- data/opal/browser/{dom/event → event}/gamepad.rb +2 -2
- data/opal/browser/{dom/event → event}/hash_change.rb +2 -2
- data/opal/browser/{dom/event → event}/keyboard.rb +2 -2
- data/opal/browser/{dom/event → event}/message.rb +2 -2
- data/opal/browser/{dom/event → event}/mouse.rb +2 -2
- data/opal/browser/{dom/event → event}/page_transition.rb +2 -2
- data/opal/browser/{dom/event → event}/pop_state.rb +2 -2
- data/opal/browser/{dom/event → event}/progress.rb +2 -2
- data/opal/browser/{dom/event → event}/sensor.rb +2 -2
- data/opal/browser/{dom/event → event}/storage.rb +2 -2
- data/opal/browser/{dom/event → event}/touch.rb +2 -2
- data/opal/browser/{dom/event → event}/ui.rb +2 -2
- data/opal/browser/{dom/event → event}/wheel.rb +2 -2
- data/opal/browser/event_source.rb +1 -1
- data/opal/browser/http.rb +25 -0
- data/opal/browser/http/binary.rb +1 -0
- data/opal/browser/http/headers.rb +16 -2
- data/opal/browser/http/request.rb +14 -38
- data/opal/browser/immediate.rb +9 -3
- data/opal/browser/interval.rb +34 -11
- data/opal/browser/navigator.rb +23 -4
- data/opal/browser/screen.rb +1 -1
- data/opal/browser/socket.rb +5 -1
- data/opal/browser/storage.rb +51 -33
- data/opal/browser/support.rb +59 -4
- data/opal/browser/version.rb +1 -1
- data/opal/browser/window.rb +17 -9
- data/opal/browser/window/size.rb +17 -3
- data/opal/opal-browser.rb +1 -0
- data/spec/database/sql_spec.rb +131 -0
- data/spec/delay_spec.rb +38 -0
- data/spec/dom/attribute_spec.rb +49 -0
- data/spec/dom/builder_spec.rb +25 -8
- data/spec/dom/document_spec.rb +20 -0
- data/spec/dom/element/attributes_spec.rb +52 -0
- data/spec/dom/element_spec.rb +139 -4
- data/spec/dom/node_set_spec.rb +44 -0
- data/spec/interval_spec.rb +50 -0
- data/spec/runner.rb +46 -28
- data/spec/socket_spec.rb +1 -0
- data/spec/spec_helper.rb +0 -4
- data/spec/storage_spec.rb +1 -1
- metadata +57 -39
- data/opal/browser/http/parameters.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7da4f18bcba46ae940082055c721673e46573149
|
4
|
+
data.tar.gz: f70ab45c0391a6e9924b0b29a3a01923a7f1bcd2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e193b212a1d022644320910c25550cfb9f1db89667f07ea1c594ef5c70aff102a3184b68099f7cd7e9e0d8f6d4904e1dc429c678fbe6fb913d20df64c2c5f610
|
7
|
+
data.tar.gz: 03ed1d8246750cae5bae479b3146de89217ab57af51e5e95d1889247e74a7e6a4fdfad38447f1d0e8290b356924dfa4fd46c899469fa3b95c2bc568ad9c8d644
|
data/.travis.yml
CHANGED
@@ -16,10 +16,6 @@ env:
|
|
16
16
|
- SELENIUM_BROWSER=firefox SELENIUM_VERSION=25
|
17
17
|
- SELENIUM_BROWSER=firefox SELENIUM_VERSION=26
|
18
18
|
|
19
|
-
- SELENIUM_BROWSER=safari SELENIUM_VERSION=5.1
|
20
|
-
- SELENIUM_BROWSER=safari SELENIUM_VERSION=6.1
|
21
|
-
- SELENIUM_BROWSER=safari SELENIUM_VERSION=7.0
|
22
|
-
|
23
19
|
- SELENIUM_BROWSER=opera SELENIUM_VERSION=12.15
|
24
20
|
- SELENIUM_BROWSER=opera SELENIUM_VERSION=12.16
|
25
21
|
|
@@ -30,19 +26,37 @@ env:
|
|
30
26
|
- SELENIUM_BROWSER=ie SELENIUM_VERSION=10
|
31
27
|
- SELENIUM_BROWSER=ie SELENIUM_VERSION=11
|
32
28
|
|
29
|
+
- SELENIUM_BROWSER=safari SELENIUM_VERSION=5.1
|
30
|
+
- SELENIUM_BROWSER=safari SELENIUM_VERSION=6.1
|
31
|
+
- SELENIUM_BROWSER=safari SELENIUM_VERSION=7.0
|
32
|
+
|
33
|
+
- SELENIUM_BROWSER=ipad SELENIUM_DEVICE="iPad 2 (5.0)"
|
34
|
+
- SELENIUM_BROWSER=iphone SELENIUM_DEVICE="iPhone 4S"
|
35
|
+
- SELENIUM_BROWSER=iphone SELENIUM_DEVICE="iPhone 5"
|
36
|
+
- SELENIUM_BROWSER=iphone SELENIUM_DEVICE="iPhone 5S"
|
37
|
+
|
38
|
+
- SELENIUM_BROWSER=android SELENIUM_DEVICE="Samsung Galaxy Nexus"
|
39
|
+
- SELENIUM_BROWSER=android SELENIUM_DEVICE="Motorola Razr Maxx HD"
|
40
|
+
- SELENIUM_BROWSER=android SELENIUM_DEVICE="LG Nexus 4"
|
41
|
+
|
33
42
|
- SELENIUM_BROWSER=chrome SELENIUM_VERSION=30
|
34
43
|
- SELENIUM_BROWSER=chrome SELENIUM_VERSION=31
|
35
44
|
|
36
45
|
matrix:
|
37
46
|
allow_failures:
|
38
|
-
# I know these fail
|
39
|
-
- env: SELENIUM_BROWSER=ie SELENIUM_VERSION=6
|
40
|
-
- env: SELENIUM_BROWSER=ie SELENIUM_VERSION=7
|
41
|
-
|
42
47
|
# ChromeDriver be broken
|
43
48
|
- env: SELENIUM_BROWSER=chrome SELENIUM_VERSION=31
|
44
49
|
- env: SELENIUM_BROWSER=chrome SELENIUM_VERSION=30
|
45
50
|
|
51
|
+
# Something's fishy
|
52
|
+
- env: SELENIUM_BROWSER=ipad SELENIUM_DEVICE="iPad 2 (5.0)"
|
53
|
+
- env: SELENIUM_BROWSER=iphone SELENIUM_DEVICE="iPhone 5"
|
54
|
+
|
55
|
+
# Android's driver be broken
|
56
|
+
- env: SELENIUM_BROWSER=android SELENIUM_DEVICE="Samsung Galaxy Nexus"
|
57
|
+
- env: SELENIUM_BROWSER=android SELENIUM_DEVICE="Motorola Razr Maxx HD"
|
58
|
+
- env: SELENIUM_BROWSER=android SELENIUM_DEVICE="LG Nexus 4"
|
59
|
+
|
46
60
|
before_install:
|
47
61
|
- gem update bundler
|
48
62
|
- bundle --version
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,13 +1,34 @@
|
|
1
1
|
Browser support for Opal
|
2
2
|
========================
|
3
3
|
|
4
|
-
[![Build Status](https://secure.travis-ci.org/opal/opal-browser.
|
5
|
-
[![Gem Version](https://badge.fury.io/rb/opal-browser.
|
6
|
-
[![Code Climate](
|
4
|
+
[![Build Status](https://secure.travis-ci.org/opal/opal-browser.svg?branch=master)](http://travis-ci.org/opal/opal-browser)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/opal-browser.svg)](http://badge.fury.io/rb/opal-browser)
|
6
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/opal/opal-browser.svg)](https://codeclimate.com/github/opal/opal-browser)
|
7
|
+
|
7
8
|
|
8
9
|
This library aims to be a full-blown wrapper for all the browser API including
|
9
10
|
HTML5.
|
10
11
|
|
12
|
+
Usage
|
13
|
+
=====
|
14
|
+
|
15
|
+
_Server side (config.ru, Rakefile, Rails, Sinatra, etc.)_
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
require 'opal-browser'
|
19
|
+
# Your server code here
|
20
|
+
```
|
21
|
+
|
22
|
+
_Browser side_
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require 'opal'
|
26
|
+
require 'browser'
|
27
|
+
# Your Opal code here
|
28
|
+
```
|
29
|
+
|
30
|
+
|
31
|
+
|
11
32
|
Features
|
12
33
|
========
|
13
34
|
This is a list of the currently wrapped features and some details on them.
|
@@ -18,7 +39,7 @@ DOM support is complete as far as I know, it has a very Nokogiri feel to it
|
|
18
39
|
with obvious differences where relevant (for instance, event handling).
|
19
40
|
|
20
41
|
```ruby
|
21
|
-
$document.
|
42
|
+
$document.ready do
|
22
43
|
alert "yo dawg, I'm all loaded up in here"
|
23
44
|
end
|
24
45
|
```
|
@@ -27,7 +48,7 @@ It also supports a markaby inspired builder DSL which generates DOM nodes
|
|
27
48
|
directly instead of creating a string.
|
28
49
|
|
29
50
|
```ruby
|
30
|
-
$document.
|
51
|
+
$document.ready do
|
31
52
|
DOM {
|
32
53
|
div.info {
|
33
54
|
span.red "I'm all cooked up."
|
@@ -89,6 +110,18 @@ EventSource
|
|
89
110
|
-----------
|
90
111
|
Event sources have been implemented and are easily configurable with blocks.
|
91
112
|
|
113
|
+
```ruby
|
114
|
+
Browser::EventSource.new '/events' do |es|
|
115
|
+
es.on :message do |e|
|
116
|
+
alert e.data
|
117
|
+
end
|
118
|
+
|
119
|
+
es.on :custom do |e|
|
120
|
+
alert "custom #{e.data}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
92
125
|
History
|
93
126
|
-------
|
94
127
|
The HTML5 History API has been fully wrapped.
|
@@ -98,6 +131,27 @@ Storage
|
|
98
131
|
The HTML5 Storage API has been wrapped and it exports a single Storage class
|
99
132
|
that uses the most appropriate and available API to store data locally.
|
100
133
|
|
134
|
+
Database SQL
|
135
|
+
------------
|
136
|
+
WebSQL has been fully wrapped.
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
db = Browser::Database::SQL.new 'test'
|
140
|
+
db.transaction {|t|
|
141
|
+
t.query('CREATE TABLE test(ID INTEGER PRIMARY KEY ASC, text TEXT)').then {
|
142
|
+
t.query('INSERT INTO test (id, text) VALUES(?, ?)', 1, 'huehue')
|
143
|
+
}.then {
|
144
|
+
t.query('INSERT INTO test (id, text) VALUES(?, ?)', 2, 'jajaja')
|
145
|
+
}.then {
|
146
|
+
t.query('SELECT * FROM test')
|
147
|
+
}.then {|r|
|
148
|
+
r.each {|row|
|
149
|
+
alert row.inspect
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
```
|
154
|
+
|
101
155
|
Browser support
|
102
156
|
===============
|
103
157
|
|
data/index.html.erb
CHANGED
@@ -7,16 +7,19 @@
|
|
7
7
|
window.onerror = function(msg, url, line) {
|
8
8
|
var error = document.createElement("div");
|
9
9
|
error.setAttribute("id", "rspec-error");
|
10
|
-
error.
|
11
|
-
error.innerHTML += "Line: " + line + "<br/>";
|
12
|
-
error.innerHTML += "URL: " + url + "<br/>";
|
10
|
+
error.appendChild(document.createTextNode(msg));
|
13
11
|
|
14
12
|
document.body.appendChild(error);
|
15
13
|
}
|
16
14
|
</script>
|
15
|
+
|
16
|
+
<script src="spec/json2.js"></script>
|
17
|
+
<script src="spec/sizzle.js"></script>
|
18
|
+
<script src="spec/wgxpath.install.js"></script>
|
19
|
+
|
20
|
+
<%= javascript_include_tag @server.main %>
|
17
21
|
</head>
|
18
22
|
<body>
|
19
|
-
<%= javascript_include_tag @server.main %>
|
20
23
|
</body>
|
21
24
|
</html>
|
22
25
|
|
data/lib/opal-browser.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'opal/browser'
|
data/opal-browser.gemspec
CHANGED
data/opal/browser.rb
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
module Browser
|
2
2
|
|
3
|
+
# Allows you to wrap a block to use in an animation rendering cycle.
|
4
|
+
#
|
5
|
+
# @see https://developer.mozilla.org/en/docs/Web/API/window.requestAnimationFrame
|
3
6
|
class AnimationFrame
|
7
|
+
def self.supported?
|
8
|
+
['Animation.request',
|
9
|
+
'Animation.request (Chrome)',
|
10
|
+
'Animation.request (Firefox)',
|
11
|
+
'Animation.request (Opera)',
|
12
|
+
'Animation.request (Internet Explorer)'].any? {|feature|
|
13
|
+
Browser.supports? feature
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Execute the block to update an animation before the next repaint.
|
18
|
+
#
|
19
|
+
# @param window [Window] the window to request the frame on
|
4
20
|
def initialize(window, &block)
|
5
21
|
@window = window
|
6
22
|
@native = window.to_n
|
@@ -28,6 +44,7 @@ class AnimationFrame
|
|
28
44
|
`#@native.msRequestAnimationFrame(#{block.to_n})`
|
29
45
|
end
|
30
46
|
else
|
47
|
+
# Request the animation frame.
|
31
48
|
def request
|
32
49
|
raise NotImplementedError, 'window requestAnimationFrame unsupported'
|
33
50
|
end
|
@@ -70,6 +87,7 @@ class AnimationFrame
|
|
70
87
|
`#@native.msCancelRequestAnimationFrame(#@id)`
|
71
88
|
end
|
72
89
|
else
|
90
|
+
# Cancel the animation frame request.
|
73
91
|
def cancel
|
74
92
|
raise NotImplementedError, 'window cancelAnimationFrame unsupported'
|
75
93
|
end
|
@@ -78,8 +96,15 @@ end
|
|
78
96
|
|
79
97
|
end
|
80
98
|
|
99
|
+
module Kernel
|
100
|
+
# (see Browser::AnimationFrame.new)
|
101
|
+
def animation_frame(&block)
|
102
|
+
Browser::AnimationFrame.new($window, &block)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
81
106
|
class Proc
|
82
|
-
#
|
107
|
+
# (see Browser::AnimationFrame.new)
|
83
108
|
def animation_frame
|
84
109
|
Browser::AnimationFrame.new($window, &self)
|
85
110
|
end
|
data/opal/browser/canvas.rb
CHANGED
@@ -1,13 +1,3 @@
|
|
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
1
|
require 'promise'
|
12
2
|
|
13
3
|
require 'browser/canvas/style'
|
data/opal/browser/canvas/data.rb
CHANGED
@@ -1,13 +1,3 @@
|
|
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
1
|
module Browser; class Canvas
|
12
2
|
|
13
3
|
class Data
|
@@ -1,13 +1,3 @@
|
|
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
1
|
module Browser; class Canvas
|
12
2
|
|
13
3
|
class Gradient
|
@@ -1,13 +1,3 @@
|
|
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
1
|
module Browser; class Canvas
|
12
2
|
|
13
3
|
class StyleObject
|
data/opal/browser/canvas/text.rb
CHANGED
@@ -1,13 +1,3 @@
|
|
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
1
|
module Browser; class Canvas
|
12
2
|
|
13
3
|
class Text
|
data/opal/browser/cookies.rb
CHANGED
@@ -43,17 +43,15 @@ class Cookies
|
|
43
43
|
|
44
44
|
# Set a cookie.
|
45
45
|
#
|
46
|
-
# Options
|
47
|
-
# -------
|
48
|
-
# + **max_age** - the max age of the cookie in seconds
|
49
|
-
# + **expires** - the expire date as {Time}
|
50
|
-
# + **path** - the path where the cookie is valid on
|
51
|
-
# + **domain** - the domain where the cookie is valid on
|
52
|
-
# + **secure** - whether the cookie is secure or not
|
53
|
-
#
|
54
46
|
# @param name [String] the name of the cookie
|
55
47
|
# @param value [Object] the data to set
|
56
48
|
# @param options [Hash] the options for the cookie
|
49
|
+
#
|
50
|
+
# @option options [Integer] :max_age the max age of the cookie in seconds
|
51
|
+
# @option options [Time] :expires the expire date
|
52
|
+
# @option options [String] :path the path the cookie is valid on
|
53
|
+
# @option options [String] :domain the domain the cookie is valid on
|
54
|
+
# @option options [Boolean] :secure whether the cookie is secure or not
|
57
55
|
def []=(name, value, options = {})
|
58
56
|
`#@document.cookie = #{encode name, value.is_a?(String) ? value : JSON.dump(value), @options.merge(options)}`
|
59
57
|
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'promise'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Browser; module Database
|
5
|
+
|
6
|
+
class SQL
|
7
|
+
# Check if the browser supports WebSQL.
|
8
|
+
def self.supported?
|
9
|
+
Browser.supports? 'WebSQL'
|
10
|
+
end
|
11
|
+
|
12
|
+
class Error < StandardError
|
13
|
+
def self.new(error)
|
14
|
+
return super if self != Error
|
15
|
+
|
16
|
+
[Unknown, Database, Version, TooLarge, Quota, Syntax, Constraint, Timeout] \
|
17
|
+
[`error.code`].new(`error.message`)
|
18
|
+
end
|
19
|
+
|
20
|
+
Unknown = Class.new(self)
|
21
|
+
Database = Class.new(self)
|
22
|
+
Version = Class.new(self)
|
23
|
+
TooLarge = Class.new(self)
|
24
|
+
Quota = Class.new(self)
|
25
|
+
Syntax = Class.new(self)
|
26
|
+
Constraint = Class.new(self)
|
27
|
+
Timeout = Class.new(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
include Native
|
31
|
+
|
32
|
+
# @return [String] the name of the database
|
33
|
+
attr_reader :name
|
34
|
+
|
35
|
+
# @return [String] the description for the database
|
36
|
+
attr_reader :description
|
37
|
+
|
38
|
+
# @return [Integer] the size constraint in bytes
|
39
|
+
attr_reader :size
|
40
|
+
|
41
|
+
# Open a database with the given name and options.
|
42
|
+
#
|
43
|
+
# @param name [String] the name for the database
|
44
|
+
# @param options [Hash] options to open the database
|
45
|
+
#
|
46
|
+
# @option options [String] :description the description for the database
|
47
|
+
# @option options [String] :version ('') the expected version of the database
|
48
|
+
# @option options [Integer] :size (5 * 1024 * 1024) the size constraint in bytes
|
49
|
+
def initialize(name, options = {})
|
50
|
+
@name = name
|
51
|
+
@description = options[:description] || name
|
52
|
+
@version = options[:version] || ''
|
53
|
+
@size = options[:size] || 2 * 1024 * 1024
|
54
|
+
|
55
|
+
super(`window.openDatabase(#{name}, #{@version}, #{@description}, #{@size})`)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @overload version()
|
59
|
+
#
|
60
|
+
# Get the version of the database.
|
61
|
+
#
|
62
|
+
# @return [String]
|
63
|
+
#
|
64
|
+
# @overload version(from, to, &block)
|
65
|
+
#
|
66
|
+
# Migrate the database to a new version.
|
67
|
+
#
|
68
|
+
# @param from [String] the version you're migrating from
|
69
|
+
# @param to [String] the version you're migrating to
|
70
|
+
#
|
71
|
+
# @yieldparam transaction [Transaction] the transaction to work with
|
72
|
+
def version(from = nil, to = nil, &block)
|
73
|
+
return `#@native.version` unless block
|
74
|
+
|
75
|
+
`#@native.changeVersion(#{from}, #{to},
|
76
|
+
#{-> t { block.call(Transaction.new(self, t)) }})`
|
77
|
+
end
|
78
|
+
|
79
|
+
# Start a transaction on the database.
|
80
|
+
#
|
81
|
+
# @yieldparam transaction [Transaction] the transaction to work on
|
82
|
+
def transaction(&block)
|
83
|
+
raise ArgumentError, 'no block given' unless block
|
84
|
+
|
85
|
+
`#@native.transaction(#{-> t { block.call(Transaction.new(self, t)) }})`
|
86
|
+
end
|
87
|
+
|
88
|
+
# Allows you to make changes to the database or read data from it.
|
89
|
+
class Transaction
|
90
|
+
include Native
|
91
|
+
|
92
|
+
# @return [Database] the database the transaction has been created from
|
93
|
+
attr_reader :database
|
94
|
+
|
95
|
+
# @private
|
96
|
+
def initialize(database, transaction)
|
97
|
+
@database = database
|
98
|
+
|
99
|
+
super(transaction)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Query the database.
|
103
|
+
#
|
104
|
+
# @param query [String] the SQL query to send
|
105
|
+
# @param parameters [Array] optional bind parameters for the query
|
106
|
+
#
|
107
|
+
# @return [Promise]
|
108
|
+
def query(query, *parameters)
|
109
|
+
promise = Promise.new
|
110
|
+
|
111
|
+
`#@native.executeSql(#{query}, #{parameters},
|
112
|
+
#{-> _, r { promise.resolve(Result.new(self, r)) }},
|
113
|
+
#{-> _, e { promise.reject(Error.new(e)) }})`
|
114
|
+
|
115
|
+
promise
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Represents a row.
|
120
|
+
class Row < OpenStruct
|
121
|
+
# @private
|
122
|
+
def initialize(row)
|
123
|
+
super(Hash.new(row))
|
124
|
+
end
|
125
|
+
|
126
|
+
def inspect
|
127
|
+
"#<SQL::Row: #{Hash.new(@native).inspect}>"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class Result
|
132
|
+
include Native
|
133
|
+
|
134
|
+
# @return [Transaction] the transaction the result came from
|
135
|
+
attr_reader :transaction
|
136
|
+
|
137
|
+
# @return [SQL] the database the result came from
|
138
|
+
attr_reader :database
|
139
|
+
|
140
|
+
# @private
|
141
|
+
def initialize(transaction, result)
|
142
|
+
@transaction = transaction
|
143
|
+
@database = transaction.database
|
144
|
+
|
145
|
+
super(result)
|
146
|
+
end
|
147
|
+
|
148
|
+
include Enumerable
|
149
|
+
|
150
|
+
# Get a row from the result.
|
151
|
+
#
|
152
|
+
# @param index [Integer] the index for the row
|
153
|
+
#
|
154
|
+
# @return [Row]
|
155
|
+
def [](index)
|
156
|
+
if index < 0
|
157
|
+
index += length
|
158
|
+
end
|
159
|
+
|
160
|
+
unless index < 0 || index >= length
|
161
|
+
Row.new(`#@native.rows.item(index)`)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Enumerate over the rows.
|
166
|
+
#
|
167
|
+
# @yieldparam row [Row]
|
168
|
+
#
|
169
|
+
# @return [self]
|
170
|
+
def each(&block)
|
171
|
+
return enum_for :each unless block
|
172
|
+
|
173
|
+
%x{
|
174
|
+
for (var i = 0, length = #@native.rows.length; i < length; i++) {
|
175
|
+
#{block.call(self[`i`])};
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
self
|
180
|
+
end
|
181
|
+
|
182
|
+
# @!attribute [r] length
|
183
|
+
# @return [Integer] number of rows in the result
|
184
|
+
def length
|
185
|
+
`#@native.rows.length`
|
186
|
+
end
|
187
|
+
|
188
|
+
# @!attribute [r] affected
|
189
|
+
# @return [Integer] number of affected rows
|
190
|
+
alias_native :affected, :rowsAffected
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
end; end
|