opal-browser 0.1.0.beta1 → 0.2.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.
- checksums.yaml +4 -4
- data/.travis.yml +60 -0
- data/.yardopts +1 -1
- data/Gemfile +7 -2
- data/LICENSE +19 -0
- data/README.md +74 -10
- data/config.ru +2 -1
- data/index.html.erb +22 -0
- data/opal-browser.gemspec +9 -11
- data/opal/browser.rb +1 -1
- data/opal/browser/animation_frame.rb +66 -9
- data/opal/browser/canvas.rb +72 -18
- data/opal/browser/canvas/data.rb +1 -1
- data/opal/browser/console.rb +3 -37
- data/opal/browser/cookies.rb +80 -24
- data/opal/browser/css/declaration.rb +0 -5
- data/opal/browser/{timeout.rb → delay.rb} +13 -13
- data/opal/browser/dom.rb +0 -2
- data/opal/browser/dom/attribute.rb +6 -0
- data/opal/browser/dom/builder.rb +4 -8
- data/opal/browser/dom/character_data.rb +43 -7
- data/opal/browser/dom/document.rb +13 -11
- data/opal/browser/dom/element.rb +127 -29
- data/opal/browser/dom/element/image.rb +23 -0
- data/opal/browser/dom/element/offset.rb +27 -10
- data/opal/browser/dom/element/scroll.rb +32 -12
- data/opal/browser/dom/element/size.rb +29 -0
- data/opal/browser/dom/event.rb +88 -75
- data/opal/browser/dom/event/animation.rb +16 -4
- data/opal/browser/dom/event/audio_processing.rb +6 -4
- data/opal/browser/dom/event/base.rb +229 -64
- data/opal/browser/dom/event/before_unload.rb +6 -4
- data/opal/browser/dom/event/clipboard.rb +6 -4
- data/opal/browser/dom/event/close.rb +16 -4
- data/opal/browser/dom/event/composition.rb +16 -4
- data/opal/browser/dom/event/custom.rb +43 -8
- data/opal/browser/dom/event/device_light.rb +6 -4
- data/opal/browser/dom/event/device_motion.rb +17 -4
- data/opal/browser/dom/event/device_orientation.rb +16 -4
- data/opal/browser/dom/event/device_proximity.rb +6 -4
- data/opal/browser/dom/event/drag.rb +34 -28
- data/opal/browser/dom/event/focus.rb +21 -5
- data/opal/browser/dom/event/gamepad.rb +33 -20
- data/opal/browser/dom/event/hash_change.rb +6 -4
- data/opal/browser/dom/event/keyboard.rb +45 -23
- data/opal/browser/dom/event/message.rb +28 -8
- data/opal/browser/dom/event/mouse.rb +26 -25
- data/opal/browser/dom/event/page_transition.rb +6 -4
- data/opal/browser/dom/event/pop_state.rb +16 -4
- data/opal/browser/dom/event/progress.rb +16 -4
- data/opal/browser/dom/event/sensor.rb +6 -4
- data/opal/browser/dom/event/storage.rb +6 -4
- data/opal/browser/dom/event/touch.rb +10 -19
- data/opal/browser/dom/event/ui.rb +19 -3
- data/opal/browser/dom/event/wheel.rb +2 -2
- data/opal/browser/dom/mutation_observer.rb +65 -5
- data/opal/browser/dom/node.rb +164 -59
- data/opal/browser/dom/node_set.rb +4 -0
- data/opal/browser/dom/text.rb +16 -1
- data/opal/browser/event_source.rb +5 -2
- data/opal/browser/history.rb +51 -15
- data/opal/browser/http.rb +22 -7
- data/opal/browser/http/headers.rb +5 -0
- data/opal/browser/http/request.rb +40 -10
- data/opal/browser/immediate.rb +123 -9
- data/opal/browser/interval.rb +8 -13
- data/opal/browser/location.rb +13 -3
- data/opal/browser/navigator.rb +9 -6
- data/opal/browser/screen.rb +31 -5
- data/opal/browser/socket.rb +8 -4
- data/opal/browser/storage.rb +118 -33
- data/opal/browser/support.rb +232 -0
- data/opal/browser/utils.rb +24 -6
- data/opal/browser/version.rb +1 -1
- data/opal/browser/window.rb +1 -2
- data/opal/browser/window/scroll.rb +21 -11
- data/opal/browser/window/size.rb +16 -6
- data/opal/browser/window/view.rb +23 -5
- data/spec/dom/builder_spec.rb +19 -19
- data/spec/dom/document_spec.rb +6 -6
- data/spec/dom/element_spec.rb +5 -5
- data/spec/dom/event_spec.rb +20 -20
- data/spec/dom/mutation_observer_spec.rb +5 -5
- data/spec/dom/node_spec.rb +39 -27
- data/spec/dom_spec.rb +10 -8
- data/spec/event_source_spec.rb +12 -12
- data/spec/history_spec.rb +24 -15
- data/spec/http_spec.rb +18 -17
- data/spec/immediate_spec.rb +9 -7
- data/spec/runner.rb +114 -0
- data/spec/socket_spec.rb +8 -8
- data/spec/spec_helper.rb +1 -0
- data/spec/storage_spec.rb +6 -6
- data/spec/wgxpath.install.js +49 -0
- data/spec/window_spec.rb +2 -2
- metadata +21 -54
- data/opal/browser/compatibility.rb +0 -59
- data/opal/browser/compatibility/animation_frame.rb +0 -93
- data/opal/browser/compatibility/dom/document/window.rb +0 -15
- data/opal/browser/compatibility/dom/element/css.rb +0 -15
- data/opal/browser/compatibility/dom/element/matches.rb +0 -31
- data/opal/browser/compatibility/dom/element/offset.rb +0 -20
- data/opal/browser/compatibility/dom/element/scroll.rb +0 -25
- data/opal/browser/compatibility/dom/element/style.rb +0 -15
- data/opal/browser/compatibility/dom/mutation_observer.rb +0 -47
- data/opal/browser/compatibility/http/request.rb +0 -15
- data/opal/browser/compatibility/immediate.rb +0 -107
- data/opal/browser/compatibility/window/scroll.rb +0 -27
- data/opal/browser/compatibility/window/size.rb +0 -13
- data/opal/browser/compatibility/window/view.rb +0 -13
- data/opal/browser/dom/compatibility.rb +0 -8
- data/opal/browser/http/compatibility.rb +0 -1
- data/opal/browser/window/compatibility.rb +0 -3
data/opal/browser/interval.rb
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
module Browser
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Allows you to create an interval that executes the function every given
|
|
4
|
+
# seconds.
|
|
5
|
+
#
|
|
6
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/Window.setInterval
|
|
4
7
|
class Interval
|
|
5
8
|
# @!attribute [r] every
|
|
6
|
-
# @return [
|
|
9
|
+
# @return [Float] the seconds every which the block is called
|
|
7
10
|
attr_reader :every
|
|
8
11
|
|
|
9
12
|
# Create and start an interval.
|
|
10
13
|
#
|
|
11
14
|
# @param window [Window] the window to start the interval on
|
|
12
|
-
# @param time [
|
|
15
|
+
# @param time [Float] seconds every which to call the block
|
|
13
16
|
def initialize(window, time, &block)
|
|
14
17
|
@window = Native.convert(window)
|
|
15
18
|
@every = time
|
|
@@ -32,20 +35,14 @@ class Interval
|
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
# Abort the interval, it won't be possible to start it again.
|
|
35
|
-
#
|
|
36
|
-
# @return [self]
|
|
37
38
|
def abort
|
|
38
39
|
`#@window.clearInterval(#@id)`
|
|
39
40
|
|
|
40
41
|
@aborted = true
|
|
41
42
|
@id = nil
|
|
42
|
-
|
|
43
|
-
self
|
|
44
43
|
end
|
|
45
44
|
|
|
46
45
|
# Stop the interval, it will be possible to start it again.
|
|
47
|
-
#
|
|
48
|
-
# @return [self]
|
|
49
46
|
def stop
|
|
50
47
|
`#@window.clearInterval(#@id)`
|
|
51
48
|
|
|
@@ -54,16 +51,12 @@ class Interval
|
|
|
54
51
|
end
|
|
55
52
|
|
|
56
53
|
# Start the interval if it has been stopped.
|
|
57
|
-
#
|
|
58
|
-
# @return [self]
|
|
59
54
|
def start
|
|
60
55
|
raise "the interval has been aborted" if aborted?
|
|
61
56
|
|
|
62
57
|
return unless stopped?
|
|
63
58
|
|
|
64
59
|
@id = `#@window.setInterval(#{@block.to_n}, #@every * 1000)`
|
|
65
|
-
|
|
66
|
-
self
|
|
67
60
|
end
|
|
68
61
|
end
|
|
69
62
|
|
|
@@ -71,6 +64,7 @@ class Window
|
|
|
71
64
|
# Execute the block every given seconds.
|
|
72
65
|
#
|
|
73
66
|
# @param time [Float] the seconds between every call
|
|
67
|
+
#
|
|
74
68
|
# @return [Interval] the object representing the interval
|
|
75
69
|
def every(time, &block)
|
|
76
70
|
Interval.new(@native, time, &block)
|
|
@@ -80,6 +74,7 @@ end
|
|
|
80
74
|
end
|
|
81
75
|
|
|
82
76
|
class Proc
|
|
77
|
+
# (see Browser::Window#every)
|
|
83
78
|
def every(time)
|
|
84
79
|
$window.every(time, &self)
|
|
85
80
|
end
|
data/opal/browser/location.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
module Browser
|
|
2
2
|
|
|
3
|
+
# Allows manipulation of a location, usually from {Window} and {DOM::Document}.
|
|
4
|
+
#
|
|
5
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/Location
|
|
3
6
|
class Location
|
|
4
7
|
include Native
|
|
5
8
|
|
|
@@ -66,9 +69,16 @@ class Location
|
|
|
66
69
|
end
|
|
67
70
|
|
|
68
71
|
class Window
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
|
|
72
|
+
# @!attribute [r] location
|
|
73
|
+
# @return [Location] the location for the window
|
|
74
|
+
def location
|
|
75
|
+
Location.new(`#@native.location`) if `#@native.location`
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
class DOM::Document < DOM::Element
|
|
80
|
+
# @!attribute [r] location
|
|
81
|
+
# @return [Location] the location for the document
|
|
72
82
|
def location
|
|
73
83
|
Location.new(`#@native.location`) if `#@native.location`
|
|
74
84
|
end
|
data/opal/browser/navigator.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module Browser
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Representation of the navigator application.
|
|
4
|
+
#
|
|
5
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator
|
|
4
6
|
class Navigator
|
|
5
7
|
include Native
|
|
6
8
|
|
|
@@ -8,7 +10,7 @@ class Navigator
|
|
|
8
10
|
Product = Struct.new(:name, :version)
|
|
9
11
|
Vendor = Struct.new(:name, :version)
|
|
10
12
|
|
|
11
|
-
#
|
|
13
|
+
# Representation of a MIME type.
|
|
12
14
|
class MimeType
|
|
13
15
|
include Native
|
|
14
16
|
|
|
@@ -33,7 +35,9 @@ class Navigator
|
|
|
33
35
|
alias_native :type
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
#
|
|
38
|
+
# Representation of a navigator plugin.
|
|
39
|
+
#
|
|
40
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/Plugin
|
|
37
41
|
class Plugin < Native::Array
|
|
38
42
|
def initialize(plugin)
|
|
39
43
|
super plugin do |m|
|
|
@@ -140,9 +144,8 @@ class Navigator
|
|
|
140
144
|
end
|
|
141
145
|
|
|
142
146
|
class Window
|
|
143
|
-
#
|
|
144
|
-
#
|
|
145
|
-
# @return [Navigator]
|
|
147
|
+
# @!attribute [r] navigator
|
|
148
|
+
# @return [Navigator] the navigator
|
|
146
149
|
def navigator
|
|
147
150
|
Navigator.new(`#@native.navigator`) if `#@native.navigator`
|
|
148
151
|
end
|
data/opal/browser/screen.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
module Browser
|
|
2
2
|
|
|
3
|
+
# Representation of the screen the window is being rendered on.
|
|
4
|
+
#
|
|
5
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/Window.screen
|
|
3
6
|
class Screen
|
|
4
7
|
include Native
|
|
5
8
|
include DOM::Event::Target
|
|
@@ -8,30 +11,53 @@ class Screen
|
|
|
8
11
|
Screen.new(value) if Native.is_a?(value, `window.Screen`)
|
|
9
12
|
}
|
|
10
13
|
|
|
14
|
+
Depth = Struct.new(:color, :pixel)
|
|
15
|
+
|
|
16
|
+
# @!attribute [r] width
|
|
17
|
+
# @return [Integer] the width of the screen in pixels
|
|
11
18
|
alias_native :width
|
|
19
|
+
|
|
20
|
+
# @!attribute [r] height
|
|
21
|
+
# @return [Integer] the height of the screen in pixels
|
|
12
22
|
alias_native :height
|
|
13
23
|
|
|
24
|
+
# @!attribute [r] size
|
|
25
|
+
# @return [Size] the size in pixels
|
|
14
26
|
def size
|
|
15
27
|
Size.new(width, height)
|
|
16
28
|
end
|
|
17
29
|
|
|
30
|
+
# @!attribute [r] x
|
|
31
|
+
# @return [Integer] the offset from the top left corner of the screen in
|
|
32
|
+
# pixels
|
|
18
33
|
alias_native :x, :top
|
|
34
|
+
|
|
35
|
+
# @!attribute [r] y
|
|
36
|
+
# @return [Integer] the offset from the top left corner of the screen in
|
|
37
|
+
# pixels
|
|
19
38
|
alias_native :y, :left
|
|
20
39
|
|
|
40
|
+
# @!attribute [r] position
|
|
41
|
+
# @return [Position] the offset from the top left corner of the screen in
|
|
42
|
+
# pixels
|
|
21
43
|
def position
|
|
22
44
|
Position.new(x, y)
|
|
23
45
|
end
|
|
24
46
|
|
|
25
|
-
|
|
26
|
-
|
|
47
|
+
# @!attribute [r] depth
|
|
48
|
+
# @return [Depth] the screen depth
|
|
49
|
+
def depth
|
|
50
|
+
Depth.new(`#@native.colorDepth`, `#@native.pixelDepth`)
|
|
51
|
+
end
|
|
27
52
|
|
|
53
|
+
# @!attribute [r] orientation
|
|
54
|
+
# @return [String] the orientation of the screen
|
|
28
55
|
alias_native :orientation
|
|
29
56
|
end
|
|
30
57
|
|
|
31
58
|
class Window
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
# @return [Screen]
|
|
59
|
+
# @!attribute [r] screen
|
|
60
|
+
# @return [Screen] the screen for the window
|
|
35
61
|
def screen
|
|
36
62
|
Screen.new(`#@native.screen`)
|
|
37
63
|
end
|
data/opal/browser/socket.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
module Browser
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# A {Socket} allows the browser and a server to have a bidirectional data
|
|
4
|
+
# connection.
|
|
5
|
+
#
|
|
6
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
|
|
4
7
|
class Socket
|
|
5
8
|
def self.supported?
|
|
6
|
-
|
|
9
|
+
Browser.supports? :WebSocket
|
|
7
10
|
end
|
|
8
11
|
|
|
9
12
|
include Native
|
|
@@ -18,8 +21,9 @@ class Socket
|
|
|
18
21
|
#
|
|
19
22
|
# @param url [String] the URL to connect to
|
|
20
23
|
# @param protocol [String] the protocol to use
|
|
21
|
-
#
|
|
22
|
-
#
|
|
24
|
+
#
|
|
25
|
+
# @yield if the block has no parameters it's `instance_exec`d, otherwise it's
|
|
26
|
+
# called with `self`
|
|
23
27
|
def initialize(url, protocol = nil, &block)
|
|
24
28
|
if native?(url)
|
|
25
29
|
super(url)
|
data/opal/browser/storage.rb
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
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 'json'
|
|
12
2
|
require 'stringio'
|
|
13
3
|
|
|
14
4
|
module Browser
|
|
15
5
|
|
|
16
|
-
|
|
6
|
+
# A {Storage} allows you to store data across page loads and browser
|
|
7
|
+
# restarts.
|
|
8
|
+
#
|
|
9
|
+
# Compatibility
|
|
10
|
+
# -------------
|
|
11
|
+
# The compatibility layer will try various implementations in the following
|
|
12
|
+
# order.
|
|
13
|
+
#
|
|
14
|
+
# + [window.localStorage](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage#localStorage)
|
|
15
|
+
# + [window.globalStorage](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage#globalStorage)
|
|
16
|
+
# + [document.body.addBehavior](http://msdn.microsoft.com/en-us/library/ms531424(VS.85).aspx)
|
|
17
|
+
# + [document.cookie](https://developer.mozilla.org/en-US/docs/Web/API/document.cookie)
|
|
18
|
+
#
|
|
19
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage
|
|
20
|
+
# @todo remove method_defined? checks when require order is fixed
|
|
21
|
+
class Storage
|
|
17
22
|
def self.json_create(data)
|
|
18
23
|
data.delete(JSON.create_id)
|
|
19
24
|
|
|
@@ -22,47 +27,106 @@ class Storage < Hash
|
|
|
22
27
|
}]
|
|
23
28
|
end
|
|
24
29
|
|
|
30
|
+
include Enumerable
|
|
31
|
+
|
|
32
|
+
# @!attribute [r] name
|
|
33
|
+
# @return [String] the name of the storage
|
|
25
34
|
attr_reader :name
|
|
26
35
|
|
|
36
|
+
# Create a new storage on the given window with the given name.
|
|
37
|
+
#
|
|
38
|
+
# @param window [native] the window to save the storage to
|
|
39
|
+
# @param name [String] the name to use to discern different storages
|
|
27
40
|
def initialize(window, name)
|
|
28
41
|
super()
|
|
29
42
|
|
|
30
43
|
@window = window
|
|
31
44
|
@name = name
|
|
45
|
+
@data = {}
|
|
32
46
|
|
|
33
47
|
autosave!
|
|
34
|
-
|
|
35
|
-
init if respond_to? :init
|
|
48
|
+
init
|
|
36
49
|
end
|
|
37
50
|
|
|
51
|
+
# @!attribute [r] encoded_name
|
|
52
|
+
# @return [String] the generated name
|
|
38
53
|
def encoded_name
|
|
39
|
-
"$opal.storage
|
|
54
|
+
"$opal.storage.#@name"
|
|
40
55
|
end
|
|
41
56
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
# Check if autosaving is enabled.
|
|
58
|
+
#
|
|
59
|
+
# When autosaving is enabled the {Storage} is saved every time a change is
|
|
60
|
+
# made, otherwise you'll have to save it manually yourself.
|
|
61
|
+
def autosave?
|
|
62
|
+
@autosave
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Enable autosaving.
|
|
66
|
+
def autosave!
|
|
67
|
+
@autosave = true
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Disable autosaving.
|
|
71
|
+
def no_autosave!
|
|
72
|
+
@autosave = false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Iterate over the (key, value) pairs in the storage.
|
|
76
|
+
#
|
|
77
|
+
# @yield [key, value]
|
|
78
|
+
def each(&block)
|
|
79
|
+
return enum_for :each unless block
|
|
80
|
+
|
|
81
|
+
@data.each(&block)
|
|
82
|
+
|
|
83
|
+
self
|
|
84
|
+
end
|
|
45
85
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
86
|
+
# Get a value in the storage.
|
|
87
|
+
def [](key)
|
|
88
|
+
@data[key]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Set a value in the storage.
|
|
92
|
+
def []=(key, value)
|
|
93
|
+
@data[key] = value
|
|
94
|
+
|
|
95
|
+
save if autosave?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Delete a value from the storage.
|
|
99
|
+
def delete(key)
|
|
100
|
+
@data.delete(key).tap {
|
|
101
|
+
save if autosave
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Clear the storage.
|
|
106
|
+
def clear
|
|
107
|
+
@data.clear.tap {
|
|
108
|
+
save if autosave?
|
|
109
|
+
}
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Replace the current storage with the given one.
|
|
113
|
+
#
|
|
114
|
+
# @param new [Hash, String] if new is a {String} it will be parsed as JSON
|
|
115
|
+
def replace(new)
|
|
116
|
+
if String === new
|
|
117
|
+
@data.replace(JSON.parse(new))
|
|
49
118
|
else
|
|
50
|
-
|
|
119
|
+
@data.replace(new)
|
|
51
120
|
end
|
|
52
121
|
end
|
|
53
122
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# FIXME: remove the application when it's fixed
|
|
57
|
-
super(*args).tap {
|
|
58
|
-
save if autosave?
|
|
59
|
-
}
|
|
60
|
-
end
|
|
61
|
-
}
|
|
123
|
+
# @!method init
|
|
124
|
+
# @private
|
|
62
125
|
|
|
63
|
-
|
|
126
|
+
# @!method save
|
|
127
|
+
# Persist the current state to the storage.
|
|
64
128
|
|
|
65
|
-
if
|
|
129
|
+
if Browser.supports? 'Storage.local'
|
|
66
130
|
def init
|
|
67
131
|
replace `#@window.localStorage[#{encoded_name}] || '{}'`
|
|
68
132
|
end
|
|
@@ -70,7 +134,7 @@ class Storage < Hash
|
|
|
70
134
|
def save
|
|
71
135
|
`#@window.localStorage[#{encoded_name}] = #{JSON.dump(self)}`
|
|
72
136
|
end
|
|
73
|
-
elsif
|
|
137
|
+
elsif Browser.supports? 'Storage.global'
|
|
74
138
|
def init
|
|
75
139
|
replace `#@window.globalStorage[#@window.location.hostname][#{encoded_name}] || '{}'`
|
|
76
140
|
end
|
|
@@ -78,7 +142,7 @@ class Storage < Hash
|
|
|
78
142
|
def save
|
|
79
143
|
`#@window.globalStorage[#@window.location.hostname][#{encoded_name}] = #{JSON.dump(self)}`
|
|
80
144
|
end
|
|
81
|
-
elsif
|
|
145
|
+
elsif Browser.supports? 'Element.addBehavior'
|
|
82
146
|
def init
|
|
83
147
|
%x{
|
|
84
148
|
#@element = #@window.document.createElement('link');
|
|
@@ -110,6 +174,9 @@ class Storage < Hash
|
|
|
110
174
|
end
|
|
111
175
|
end
|
|
112
176
|
|
|
177
|
+
# Convert the storage to JSON.
|
|
178
|
+
#
|
|
179
|
+
# @return [String] the JSON representation
|
|
113
180
|
def to_json
|
|
114
181
|
io = StringIO.new("{")
|
|
115
182
|
|
|
@@ -126,7 +193,15 @@ class Storage < Hash
|
|
|
126
193
|
end
|
|
127
194
|
end
|
|
128
195
|
|
|
196
|
+
# A {SessionStorage} allows you to store data across page reloads, as long as the session
|
|
197
|
+
# is active.
|
|
198
|
+
#
|
|
199
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage#sessionStorage
|
|
129
200
|
class SessionStorage < Storage
|
|
201
|
+
def self.supported?
|
|
202
|
+
Browser.supports? 'Storage.session'
|
|
203
|
+
end
|
|
204
|
+
|
|
130
205
|
def init
|
|
131
206
|
replace `#@window.sessionStorage[#{encoded_name}] || '{}'`
|
|
132
207
|
end
|
|
@@ -137,10 +212,20 @@ class SessionStorage < Storage
|
|
|
137
212
|
end
|
|
138
213
|
|
|
139
214
|
class Window
|
|
215
|
+
# Get a storage with the given name.
|
|
216
|
+
#
|
|
217
|
+
# @param name [Symbol] the name of the storage
|
|
218
|
+
#
|
|
219
|
+
# @return [Storage]
|
|
140
220
|
def storage(name = :default)
|
|
141
221
|
Storage.new(to_n, name)
|
|
142
222
|
end
|
|
143
223
|
|
|
224
|
+
# Get a session storage with the given name.
|
|
225
|
+
#
|
|
226
|
+
# @param name [Symbol] the name of the storage
|
|
227
|
+
#
|
|
228
|
+
# @return [SessionStorage]
|
|
144
229
|
def session_storage(name = :default)
|
|
145
230
|
SessionStorage.new(to_n, name)
|
|
146
231
|
end
|