opal-browser 0.1.0.beta1 → 0.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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/canvas/data.rb
CHANGED
data/opal/browser/console.rb
CHANGED
@@ -1,67 +1,43 @@
|
|
1
1
|
module Browser
|
2
2
|
|
3
|
-
#
|
3
|
+
# Manipulate the browser console.
|
4
|
+
#
|
5
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/console
|
4
6
|
class Console
|
5
7
|
include Native
|
6
8
|
|
7
9
|
# Clear the console.
|
8
|
-
#
|
9
|
-
# @return [self]
|
10
10
|
def clear
|
11
11
|
`#@native.clear()`
|
12
|
-
|
13
|
-
self
|
14
12
|
end
|
15
13
|
|
16
14
|
# Print a stacktrace from the call site.
|
17
|
-
#
|
18
|
-
# @return [self]
|
19
15
|
def trace
|
20
16
|
`#@native.trace()`
|
21
|
-
|
22
|
-
self
|
23
17
|
end
|
24
18
|
|
25
19
|
# Log the passed objects based on an optional initial format.
|
26
|
-
#
|
27
|
-
# @return [self]
|
28
20
|
def log(*args)
|
29
21
|
`#@native.log.apply(#@native, args)`
|
30
|
-
|
31
|
-
self
|
32
22
|
end
|
33
23
|
|
34
24
|
# Log the passed objects based on an optional initial format as informational
|
35
25
|
# log.
|
36
|
-
#
|
37
|
-
# @return [self]
|
38
26
|
def info(*args)
|
39
27
|
`#@native.info.apply(#@native, args)`
|
40
|
-
|
41
|
-
self
|
42
28
|
end
|
43
29
|
|
44
30
|
# Log the passed objects based on an optional initial format as warning.
|
45
|
-
#
|
46
|
-
# @return [self]
|
47
31
|
def warn(*args)
|
48
32
|
`#@native.warn.apply(#@native, args)`
|
49
|
-
|
50
|
-
self
|
51
33
|
end
|
52
34
|
|
53
35
|
# Log the passed objects based on an optional initial format as error.
|
54
|
-
#
|
55
|
-
# @return [self]
|
56
36
|
def error(*args)
|
57
37
|
`#@native.error.apply(#@native, args)`
|
58
|
-
|
59
|
-
self
|
60
38
|
end
|
61
39
|
|
62
40
|
# Time the given block with the given label.
|
63
|
-
#
|
64
|
-
# @return [self]
|
65
41
|
def time(label, &block)
|
66
42
|
raise ArgumentError, "no block given" unless block
|
67
43
|
|
@@ -76,13 +52,9 @@ class Console
|
|
76
52
|
ensure
|
77
53
|
`#@native.timeEnd()`
|
78
54
|
end
|
79
|
-
|
80
|
-
self
|
81
55
|
end
|
82
56
|
|
83
57
|
# Group the given block.
|
84
|
-
#
|
85
|
-
# @return [self]
|
86
58
|
def group(*args, &block)
|
87
59
|
raise ArgumentError, "no block given" unless block
|
88
60
|
|
@@ -97,13 +69,9 @@ class Console
|
|
97
69
|
ensure
|
98
70
|
`#@native.groupEnd()`
|
99
71
|
end
|
100
|
-
|
101
|
-
self
|
102
72
|
end
|
103
73
|
|
104
74
|
# Group the given block but collapse it.
|
105
|
-
#
|
106
|
-
# @return [self]
|
107
75
|
def group!(*args, &block)
|
108
76
|
return unless block_given?
|
109
77
|
|
@@ -118,8 +86,6 @@ class Console
|
|
118
86
|
ensure
|
119
87
|
`#@native.groupEnd()`
|
120
88
|
end
|
121
|
-
|
122
|
-
self
|
123
89
|
end
|
124
90
|
end
|
125
91
|
|
data/opal/browser/cookies.rb
CHANGED
@@ -1,25 +1,36 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
1
3
|
module Browser
|
2
4
|
|
5
|
+
# Allows manipulation of browser cookies.
|
6
|
+
#
|
7
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
|
3
8
|
class Cookies
|
9
|
+
# Default cookie options.
|
10
|
+
DEFAULT = {
|
11
|
+
expires: Time.now + 1.day,
|
12
|
+
secure: false
|
13
|
+
}
|
14
|
+
|
4
15
|
include Enumerable
|
5
16
|
|
17
|
+
attr_reader :options
|
18
|
+
|
19
|
+
# Create a new {Cookies} wrapper.
|
20
|
+
#
|
21
|
+
# @param document [native] the native document object
|
6
22
|
def initialize(document)
|
7
23
|
@document = document
|
8
|
-
|
9
|
-
@options = {
|
10
|
-
expires: Time.now + 1.day,
|
11
|
-
path: '',
|
12
|
-
domain: '',
|
13
|
-
secure: ''
|
14
|
-
}
|
15
|
-
end
|
16
|
-
|
17
|
-
def options (value = nil)
|
18
|
-
value ? @options.merge!(value) : @options
|
24
|
+
@options = DEFAULT.dup
|
19
25
|
end
|
20
26
|
|
21
|
-
|
22
|
-
|
27
|
+
# Access the cookie with the given name.
|
28
|
+
#
|
29
|
+
# @param name [String] the name of the cookie
|
30
|
+
#
|
31
|
+
# @return [Object]
|
32
|
+
def [](name)
|
33
|
+
matches = `#@document.cookie`.scan(/#{Regexp.escape(name.encode_uri_component)}=([^;]*)/)
|
23
34
|
|
24
35
|
return if matches.empty?
|
25
36
|
|
@@ -30,49 +41,94 @@ class Cookies
|
|
30
41
|
result.length == 1 ? result.first : result
|
31
42
|
end
|
32
43
|
|
33
|
-
|
44
|
+
# Set a cookie.
|
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
|
+
# @param name [String] the name of the cookie
|
55
|
+
# @param value [Object] the data to set
|
56
|
+
# @param options [Hash] the options for the cookie
|
57
|
+
def []=(name, value, options = {})
|
34
58
|
`#@document.cookie = #{encode name, value.is_a?(String) ? value : JSON.dump(value), @options.merge(options)}`
|
35
59
|
end
|
36
60
|
|
37
|
-
|
61
|
+
# Delete a cookie.
|
62
|
+
#
|
63
|
+
# @param name [String] the name of the cookie
|
64
|
+
def delete(name)
|
38
65
|
`#@document.cookie = #{encode name, '', expires: Time.now}`
|
39
66
|
end
|
40
67
|
|
68
|
+
# @!attribute [r] keys
|
69
|
+
# @return [Array<String>] all the cookie names
|
41
70
|
def keys
|
42
71
|
Array(`#@document.cookie.split(/; /)`).map {|cookie|
|
43
72
|
cookie.split(/\s*=\s*/).first
|
44
73
|
}
|
45
74
|
end
|
46
75
|
|
76
|
+
# @!attribute [r] values
|
77
|
+
# @return [Array] all the cookie values
|
47
78
|
def values
|
48
79
|
keys.map {|key|
|
49
80
|
self[key]
|
50
81
|
}
|
51
82
|
end
|
52
83
|
|
53
|
-
|
84
|
+
# Enumerate the cookies.
|
85
|
+
#
|
86
|
+
# @yieldparam key [String] the name of the cookie
|
87
|
+
# @yieldparam value [String] the value of the cookie
|
88
|
+
#
|
89
|
+
# @return [self]
|
90
|
+
def each(&block)
|
91
|
+
return enum_for :each unless block
|
92
|
+
|
54
93
|
keys.each {|key|
|
55
94
|
yield key, self[key]
|
56
95
|
}
|
96
|
+
|
97
|
+
self
|
57
98
|
end
|
58
99
|
|
100
|
+
# Delete all the cookies
|
101
|
+
#
|
102
|
+
# @return [self]
|
59
103
|
def clear
|
60
104
|
keys.each {|key|
|
61
105
|
delete key
|
62
106
|
}
|
107
|
+
|
108
|
+
self
|
63
109
|
end
|
64
110
|
|
65
111
|
protected
|
66
|
-
def encode
|
67
|
-
|
112
|
+
def encode(key, value, options = {})
|
113
|
+
io = StringIO.new
|
114
|
+
|
115
|
+
io << key.encode_uri_component << ?= << value.encode_uri_component << '; '
|
68
116
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
117
|
+
io << 'max-age=' << options[:max_age] << '; ' if options[:max_age]
|
118
|
+
io << 'expires=' << options[:expires].to_utc << '; ' if options[:expires]
|
119
|
+
io << 'path=' << options[:path] << '; ' if options[:path]
|
120
|
+
io << 'domain=' << options[:domain] << '; ' if options[:domain]
|
121
|
+
io << 'secure' if options[:secure]
|
122
|
+
|
123
|
+
io.string
|
124
|
+
end
|
125
|
+
end
|
74
126
|
|
75
|
-
|
127
|
+
class DOM::Document < DOM::Element
|
128
|
+
# @!attribute [r] cookies
|
129
|
+
# @return [Cookies] the cookies for the document
|
130
|
+
def cookies
|
131
|
+
Cookies.new(@native) if defined?(`#@native.cookie`)
|
76
132
|
end
|
77
133
|
end
|
78
134
|
|
@@ -18,21 +18,16 @@ class Declaration
|
|
18
18
|
|
19
19
|
def replace(string)
|
20
20
|
`#@native.cssText = #{string}`
|
21
|
-
|
22
|
-
self
|
23
21
|
end
|
24
22
|
|
25
23
|
def apply(&block)
|
26
24
|
Paggio::CSS::Definition.new(&block).each {|style|
|
27
|
-
# FIXME: use ternary operator when it's fixed
|
28
25
|
if style.important
|
29
26
|
`#@native.setProperty(#{style.name}, #{style.value}, "important")`
|
30
27
|
else
|
31
28
|
`#@native.setProperty(#{style.name}, #{style.value}, "")`
|
32
29
|
end
|
33
30
|
}
|
34
|
-
|
35
|
-
self
|
36
31
|
end
|
37
32
|
|
38
33
|
def delete(name)
|
@@ -1,15 +1,18 @@
|
|
1
1
|
module Browser
|
2
2
|
|
3
|
-
#
|
4
|
-
|
3
|
+
# Allows you to delay the call to a function which gets called after the
|
4
|
+
# given time.
|
5
|
+
#
|
6
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout
|
7
|
+
class Delay
|
5
8
|
# @!attribute [r] after
|
6
|
-
# @return [
|
9
|
+
# @return [Float] the seconds after which the block is called
|
7
10
|
attr_reader :after
|
8
11
|
|
9
12
|
# Create and start a timeout.
|
10
13
|
#
|
11
14
|
# @param window [Window] the window to start the timeout on
|
12
|
-
# @param time [
|
15
|
+
# @param time [Float] seconds after which the block is called
|
13
16
|
def initialize(window, time, &block)
|
14
17
|
@window = Native.convert(window)
|
15
18
|
@after = time
|
@@ -19,18 +22,13 @@ class Timeout
|
|
19
22
|
end
|
20
23
|
|
21
24
|
# Abort the timeout.
|
22
|
-
#
|
23
|
-
# @return [self]
|
24
25
|
def abort
|
25
26
|
`#@window.clearTimeout(#@id)`
|
26
|
-
|
27
|
-
self
|
28
27
|
end
|
29
28
|
|
29
|
+
# Start the delay.
|
30
30
|
def start
|
31
31
|
@id = `#@window.setTimeout(#{@block.to_n}, #@after * 1000)`
|
32
|
-
|
33
|
-
self
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
@@ -38,22 +36,24 @@ class Window
|
|
38
36
|
# Execute a block after the given seconds.
|
39
37
|
#
|
40
38
|
# @param time [Float] the seconds after it gets called
|
41
|
-
#
|
39
|
+
#
|
40
|
+
# @return [Delay] the object representing the timeout
|
42
41
|
def after(time, &block)
|
43
|
-
|
42
|
+
Delay.new(@native, time, &block)
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
46
|
end
|
48
47
|
|
49
48
|
class Proc
|
49
|
+
# (see Browser::Window#after)
|
50
50
|
def after(time)
|
51
51
|
$window.after(time, &self)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
55
|
module Kernel
|
56
|
-
# (see Browser::Window#
|
56
|
+
# (see Browser::Window#after)
|
57
57
|
def after(time, &block)
|
58
58
|
$window.after(time, &block)
|
59
59
|
end
|
data/opal/browser/dom.rb
CHANGED
@@ -1,16 +1,22 @@
|
|
1
1
|
module Browser; module DOM
|
2
2
|
|
3
|
+
# Encapsulates an {Element} attribute.
|
3
4
|
class Attribute
|
4
5
|
include Native
|
5
6
|
|
7
|
+
# Returns true if the attribute is an id.
|
6
8
|
def id?
|
7
9
|
`#@native.isId`
|
8
10
|
end
|
9
11
|
|
12
|
+
# @!attribute [r] name
|
13
|
+
# @return [String] the name of the attribute
|
10
14
|
def name
|
11
15
|
`#@native.name`
|
12
16
|
end
|
13
17
|
|
18
|
+
# @!attribute [r] value
|
19
|
+
# @return [String] the value of the attribute
|
14
20
|
def value
|
15
21
|
`#@native.value`
|
16
22
|
end
|
data/opal/browser/dom/builder.rb
CHANGED
@@ -9,10 +9,6 @@ class Paggio::HTML::Element < BasicObject
|
|
9
9
|
def on(*args, &block)
|
10
10
|
(@on ||= []) << [args, block]
|
11
11
|
end
|
12
|
-
|
13
|
-
def style(*args, &block)
|
14
|
-
@style = [args, block]
|
15
|
-
end
|
16
12
|
end
|
17
13
|
|
18
14
|
module Browser; module DOM
|
@@ -79,10 +75,6 @@ Builder.for Paggio::HTML::Element do |b, item|
|
|
79
75
|
}
|
80
76
|
end
|
81
77
|
|
82
|
-
if style = `item.style || nil`
|
83
|
-
dom.style(*style[0], &style[1])
|
84
|
-
end
|
85
|
-
|
86
78
|
if inner = `item.inner_html || nil`
|
87
79
|
dom.inner_html = inner
|
88
80
|
else
|
@@ -94,4 +86,8 @@ Builder.for Paggio::HTML::Element do |b, item|
|
|
94
86
|
dom
|
95
87
|
end
|
96
88
|
|
89
|
+
Builder.for DOM::Node do |b, item|
|
90
|
+
item
|
91
|
+
end
|
92
|
+
|
97
93
|
end; end
|
@@ -1,34 +1,70 @@
|
|
1
1
|
module Browser; module DOM
|
2
2
|
|
3
3
|
class CharacterData < Node
|
4
|
+
# Append data to the node.
|
5
|
+
#
|
6
|
+
# @param string [String] the data to add
|
7
|
+
#
|
8
|
+
# @return [self]
|
9
|
+
def append(string)
|
10
|
+
`#@native.appendData(string)`
|
11
|
+
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
# @!attribute [r] data
|
16
|
+
# @return [String] the data of the node
|
4
17
|
def data
|
5
18
|
`#@native.data`
|
6
19
|
end
|
7
20
|
|
8
|
-
|
9
|
-
|
21
|
+
# Delete data from the node.
|
22
|
+
#
|
23
|
+
# @param count [Integer] how much data to delete
|
24
|
+
# @param offset [Integer] the offset to start at
|
25
|
+
#
|
26
|
+
# @return [self]
|
27
|
+
def delete(count, offset = 0)
|
28
|
+
`#@native.deleteData(offset, count)`
|
10
29
|
|
11
30
|
self
|
12
31
|
end
|
13
32
|
|
33
|
+
# Insert data in the node.
|
34
|
+
#
|
35
|
+
# @param string [String] the data to insert
|
36
|
+
# @param offset [Integer] the offset to start at
|
37
|
+
#
|
38
|
+
# @return [self]
|
14
39
|
def insert(string, offset = 0)
|
15
40
|
`#@native.insertData(offset, string)`
|
16
41
|
|
17
42
|
self
|
18
43
|
end
|
19
44
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
self
|
24
|
-
end
|
45
|
+
# @!attribute [r] length
|
46
|
+
# @return [Integer] the length of the node
|
47
|
+
alias_native :length
|
25
48
|
|
49
|
+
# Replace data in the node.
|
50
|
+
#
|
51
|
+
# @param string [String] the data to replace with
|
52
|
+
# @param offset [Integer] the offset to start at
|
53
|
+
# @param count [Integer] how much data to replace
|
54
|
+
#
|
55
|
+
# @return [self]
|
26
56
|
def replace(string, offset = 0, count = `#@native.length`)
|
27
57
|
`#@native.replaceData(offset, count, string)`
|
28
58
|
|
29
59
|
self
|
30
60
|
end
|
31
61
|
|
62
|
+
# Get a substring of the data.
|
63
|
+
#
|
64
|
+
# @param count [Integer] how much data to lice
|
65
|
+
# @param offset [Integer] the offset to start at
|
66
|
+
#
|
67
|
+
# @return [String] the substring
|
32
68
|
def substring(count, offset = 0)
|
33
69
|
`#@native.substringData(offset, count)`
|
34
70
|
end
|