opal-browser 0.2.0 → 0.3.3
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 +5 -5
- data/.github/workflows/build.yml +78 -0
- data/.gitignore +3 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +17 -3
- data/LICENSE +2 -1
- data/README.md +131 -54
- data/Rakefile +29 -1
- data/config.ru +20 -3
- data/docs/polyfills.md +24 -0
- data/examples/2048/Gemfile +6 -0
- data/examples/2048/README.md +13 -0
- data/examples/2048/app/application.rb +169 -0
- data/examples/2048/config.ru +9 -0
- data/examples/canvas/Gemfile +6 -0
- data/examples/canvas/README.md +9 -0
- data/examples/canvas/app/application.rb +55 -0
- data/examples/canvas/config.ru +9 -0
- data/examples/component/Gemfile +6 -0
- data/examples/component/README.md +10 -0
- data/examples/component/app/application.rb +66 -0
- data/examples/component/config.ru +9 -0
- data/examples/integrations/README.md +24 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/Gemfile +6 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/README.md +16 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/app/application.rb +6 -0
- data/examples/integrations/dynamic-rack-opal-sprockets-server/config.ru +9 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/.gitignore +1 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/Gemfile +7 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/README.md +22 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/Rakefile +4 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/app/application.rb +6 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/app.rb +32 -0
- data/examples/integrations/dynamic-roda-roda-sprockets/config.ru +3 -0
- data/examples/integrations/dynamic-roda-tilt/.gitignore +1 -0
- data/examples/integrations/dynamic-roda-tilt/Gemfile +8 -0
- data/examples/integrations/dynamic-roda-tilt/README.md +17 -0
- data/examples/integrations/dynamic-roda-tilt/Rakefile +6 -0
- data/examples/integrations/dynamic-roda-tilt/app/application.rb +6 -0
- data/examples/integrations/dynamic-roda-tilt/app.rb +50 -0
- data/examples/integrations/dynamic-roda-tilt/config.ru +3 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/Gemfile +7 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/README.md +16 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/app/application.rb +6 -0
- data/examples/integrations/dynamic-sinatra-opal-sprockets-server/config.ru +29 -0
- data/examples/integrations/static-bash/.gitignore +2 -0
- data/examples/integrations/static-bash/Gemfile +3 -0
- data/examples/integrations/static-bash/README.md +8 -0
- data/examples/integrations/static-bash/app/application.rb +6 -0
- data/examples/integrations/static-bash/build.sh +4 -0
- data/examples/integrations/static-bash/index.html +10 -0
- data/examples/integrations/static-bash-opal-parser/.gitignore +3 -0
- data/examples/integrations/static-bash-opal-parser/Gemfile +3 -0
- data/examples/integrations/static-bash-opal-parser/README.md +10 -0
- data/examples/integrations/static-bash-opal-parser/build.sh +4 -0
- data/examples/integrations/static-bash-opal-parser/index.html +19 -0
- data/examples/integrations/static-rake/.gitignore +1 -0
- data/examples/integrations/static-rake/Gemfile +4 -0
- data/examples/integrations/static-rake/README.md +7 -0
- data/examples/integrations/static-rake/Rakefile +10 -0
- data/examples/integrations/static-rake/app/application.rb +6 -0
- data/examples/integrations/static-rake/index.html +9 -0
- data/examples/integrations/static-rake-guard/.gitignore +1 -0
- data/examples/integrations/static-rake-guard/Gemfile +6 -0
- data/examples/integrations/static-rake-guard/Guardfile +3 -0
- data/examples/integrations/static-rake-guard/README.md +10 -0
- data/examples/integrations/static-rake-guard/Rakefile +10 -0
- data/examples/integrations/static-rake-guard/app/application.rb +6 -0
- data/examples/integrations/static-rake-guard/index.html +9 -0
- data/examples/svg/.gitignore +1 -0
- data/examples/svg/Gemfile +4 -0
- data/examples/svg/README.md +7 -0
- data/examples/svg/Rakefile +10 -0
- data/examples/svg/app/application.rb +11 -0
- data/examples/svg/index.html +17 -0
- data/examples/svg/index.svg +6 -0
- data/index.html.erb +2 -3
- data/opal/browser/audio/node.rb +121 -0
- data/opal/browser/audio/param_schedule.rb +43 -0
- data/opal/browser/audio.rb +66 -0
- data/opal/browser/blob.rb +94 -0
- data/opal/browser/canvas/data.rb +1 -1
- data/opal/browser/canvas/gradient.rb +1 -1
- data/opal/browser/canvas/style.rb +3 -1
- data/opal/browser/canvas/text.rb +1 -1
- data/opal/browser/canvas.rb +17 -3
- data/opal/browser/console.rb +3 -1
- data/opal/browser/cookies.rb +72 -34
- data/opal/browser/crypto.rb +79 -0
- data/opal/browser/css/declaration.rb +1 -1
- data/opal/browser/css/rule.rb +1 -1
- data/opal/browser/css/style_sheet.rb +2 -2
- data/opal/browser/css.rb +23 -7
- data/opal/browser/database/sql.rb +7 -8
- data/opal/browser/delay.rb +16 -0
- data/opal/browser/dom/attribute.rb +1 -1
- data/opal/browser/dom/builder.rb +29 -10
- data/opal/browser/dom/document.rb +81 -13
- data/opal/browser/dom/document_fragment.rb +18 -0
- data/opal/browser/dom/document_or_shadow_root.rb +19 -0
- data/opal/browser/dom/element/attributes.rb +28 -4
- data/opal/browser/dom/element/button.rb +31 -0
- data/opal/browser/dom/element/custom.rb +177 -0
- data/opal/browser/dom/element/data.rb +17 -2
- data/opal/browser/dom/element/editable.rb +47 -0
- data/opal/browser/dom/element/form.rb +38 -0
- data/opal/browser/dom/element/iframe.rb +37 -0
- data/opal/browser/dom/element/image.rb +2 -0
- data/opal/browser/dom/element/input.rb +36 -0
- data/opal/browser/dom/element/media.rb +17 -0
- data/opal/browser/dom/element/scroll.rb +106 -74
- data/opal/browser/dom/element/select.rb +6 -0
- data/opal/browser/dom/element/size.rb +12 -0
- data/opal/browser/dom/element/template.rb +2 -0
- data/opal/browser/dom/element/textarea.rb +2 -0
- data/opal/browser/dom/element.rb +194 -50
- data/opal/browser/dom/mutation_observer.rb +2 -2
- data/opal/browser/dom/node.rb +53 -13
- data/opal/browser/dom/node_set.rb +13 -2
- data/opal/browser/dom/shadow_root.rb +12 -0
- data/opal/browser/dom/text.rb +2 -2
- data/opal/browser/dom.rb +38 -5
- data/opal/browser/effects.rb +170 -4
- data/opal/browser/event/all.rb +26 -0
- data/opal/browser/event/animation.rb +2 -0
- data/opal/browser/event/audio_processing.rb +2 -0
- data/opal/browser/event/base.rb +35 -4
- data/opal/browser/event/before_unload.rb +2 -0
- data/opal/browser/event/clipboard.rb +9 -0
- data/opal/browser/event/close.rb +2 -0
- data/opal/browser/event/composition.rb +2 -0
- data/opal/browser/event/custom.rb +1 -1
- data/opal/browser/event/data_transfer.rb +95 -0
- data/opal/browser/event/device_light.rb +2 -0
- data/opal/browser/event/device_motion.rb +2 -0
- data/opal/browser/event/device_orientation.rb +2 -0
- data/opal/browser/event/device_proximity.rb +2 -0
- data/opal/browser/event/drag.rb +9 -5
- data/opal/browser/event/focus.rb +2 -0
- data/opal/browser/event/gamepad.rb +3 -1
- data/opal/browser/event/hash_change.rb +2 -0
- data/opal/browser/event/keyboard.rb +14 -1
- data/opal/browser/event/message.rb +2 -0
- data/opal/browser/event/mouse.rb +10 -6
- data/opal/browser/event/page_transition.rb +2 -0
- data/opal/browser/event/pop_state.rb +2 -0
- data/opal/browser/event/progress.rb +2 -0
- data/opal/browser/event/sensor.rb +2 -0
- data/opal/browser/event/storage.rb +2 -0
- data/opal/browser/event/touch.rb +2 -0
- data/opal/browser/event/wheel.rb +2 -0
- data/opal/browser/event.rb +26 -116
- data/opal/browser/event_source.rb +1 -1
- data/opal/browser/form_data.rb +225 -0
- data/opal/browser/history.rb +4 -8
- data/opal/browser/http/request.rb +32 -10
- data/opal/browser/http/response.rb +5 -1
- data/opal/browser/http.rb +0 -2
- data/opal/browser/immediate.rb +0 -2
- data/opal/browser/location.rb +7 -1
- data/opal/browser/navigator.rb +105 -4
- data/opal/browser/polyfill/visual_viewport.rb +216 -0
- data/opal/browser/screen.rb +2 -2
- data/opal/browser/setup/base.rb +6 -0
- data/opal/browser/setup/full.rb +13 -0
- data/opal/browser/setup/large.rb +17 -0
- data/opal/browser/setup/mini.rb +8 -0
- data/opal/browser/setup/traditional.rb +10 -0
- data/opal/browser/socket.rb +3 -3
- data/opal/browser/storage.rb +2 -2
- data/opal/browser/support.rb +46 -22
- data/opal/browser/utils.rb +94 -14
- data/opal/browser/version.rb +1 -1
- data/opal/browser/visual_viewport.rb +39 -0
- data/opal/browser/window/size.rb +14 -0
- data/opal/browser/window/view.rb +15 -0
- data/opal/browser/window.rb +29 -16
- data/opal/browser.rb +1 -11
- data/opal-browser.gemspec +3 -3
- data/spec/database/sql_spec.rb +43 -35
- data/spec/delay_spec.rb +15 -12
- data/spec/dom/document_spec.rb +10 -8
- data/spec/dom/element/custom_spec.rb +106 -0
- data/spec/dom/element/subclass_spec.rb +144 -0
- data/spec/dom/element_spec.rb +42 -0
- data/spec/dom/mutation_observer_spec.rb +12 -8
- data/spec/dom/node_spec.rb +48 -0
- data/spec/dom_spec.rb +8 -0
- data/spec/event_source_spec.rb +15 -12
- data/spec/{dom/event_spec.rb → event_spec.rb} +44 -15
- data/spec/history_spec.rb +23 -19
- data/spec/http_spec.rb +19 -31
- data/spec/immediate_spec.rb +5 -4
- data/spec/interval_spec.rb +18 -9
- data/spec/native_cached_wrapper_spec.rb +46 -0
- data/spec/runner.rb +37 -62
- data/spec/socket_spec.rb +15 -12
- data/spec/spec_helper.rb +2 -1
- data/spec/spec_helper_promise.rb.erb +25 -0
- metadata +120 -16
- data/.travis.yml +0 -74
- data/opal/browser/window/scroll.rb +0 -59
data/opal/browser/canvas.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'promise'
|
|
2
|
-
|
|
3
1
|
require 'browser/canvas/style'
|
|
4
2
|
require 'browser/canvas/text'
|
|
5
3
|
require 'browser/canvas/data'
|
|
@@ -8,7 +6,7 @@ require 'browser/canvas/gradient'
|
|
|
8
6
|
module Browser
|
|
9
7
|
|
|
10
8
|
class Canvas
|
|
11
|
-
include Native
|
|
9
|
+
include Native::Wrapper
|
|
12
10
|
|
|
13
11
|
attr_reader :element, :style, :text
|
|
14
12
|
|
|
@@ -59,6 +57,14 @@ class Canvas
|
|
|
59
57
|
@element[:height].to_i
|
|
60
58
|
end
|
|
61
59
|
|
|
60
|
+
def width=(new_width)
|
|
61
|
+
@element[:width] = new_width.to_i
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def height=(new_height)
|
|
65
|
+
@element[:height] = new_height.to_i
|
|
66
|
+
end
|
|
67
|
+
|
|
62
68
|
def append_to(parent)
|
|
63
69
|
@element.append_to(parent)
|
|
64
70
|
end
|
|
@@ -312,6 +318,14 @@ class Canvas
|
|
|
312
318
|
def to_data(type = undefined)
|
|
313
319
|
`#{@element.to_n}.toDataUrl(type)`
|
|
314
320
|
end
|
|
321
|
+
|
|
322
|
+
def to_dom(*)
|
|
323
|
+
@element
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def on(*args, &block); @element.on(*args, &block); end
|
|
327
|
+
def one(*args, &block); @element.one(*args, &block); end
|
|
328
|
+
def off(*args, &block); @element.off(*args, &block); end
|
|
315
329
|
end
|
|
316
330
|
|
|
317
331
|
Browser::DOM::Builder.for Canvas do |b, item|
|
data/opal/browser/console.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
warn "`console' has been moved to Opal's stdlib, please `require 'console'` instead." if RUBY_ENGINE_VERSION.to_f >= 0.9
|
|
2
|
+
|
|
1
3
|
module Browser
|
|
2
4
|
|
|
3
5
|
# Manipulate the browser console.
|
|
4
6
|
#
|
|
5
7
|
# @see https://developer.mozilla.org/en-US/docs/Web/API/console
|
|
6
8
|
class Console
|
|
7
|
-
include
|
|
9
|
+
include Browser::NativeCachedWrapper
|
|
8
10
|
|
|
9
11
|
# Clear the console.
|
|
10
12
|
def clear
|
data/opal/browser/cookies.rb
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
require 'stringio'
|
|
2
|
-
|
|
3
1
|
module Browser
|
|
4
2
|
|
|
5
3
|
# Allows manipulation of browser cookies.
|
|
6
4
|
#
|
|
7
5
|
# @see https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
#
|
|
9
|
+
# cookies = $document.cookies
|
|
10
|
+
# cookies["my-cookie"] = "monster"
|
|
11
|
+
# cookies.delete("my-cookie")
|
|
12
|
+
#
|
|
13
|
+
# By default, cookies are stored JSON-encoded. You can supply a `raw:` option
|
|
14
|
+
# whenever you need to access/write the cookies in a raw way, eg.
|
|
15
|
+
#
|
|
16
|
+
# cookies["my-other-cookie", raw: true] = 123
|
|
17
|
+
#
|
|
18
|
+
# You can also set this option while referencing $document.cookies, eg.
|
|
19
|
+
#
|
|
20
|
+
# cookies = $document.cookies(raw: true)
|
|
21
|
+
# cookies["my-other-cookie"] = 123
|
|
8
22
|
class Cookies
|
|
9
23
|
# Default cookie options.
|
|
10
24
|
DEFAULT = {
|
|
11
|
-
expires: Time.now +
|
|
25
|
+
expires: Time.now + 60 * 60 * 24,
|
|
12
26
|
secure: false
|
|
13
27
|
}
|
|
14
28
|
|
|
@@ -19,24 +33,34 @@ class Cookies
|
|
|
19
33
|
# Create a new {Cookies} wrapper.
|
|
20
34
|
#
|
|
21
35
|
# @param document [native] the native document object
|
|
22
|
-
|
|
36
|
+
# @param options [Hash] the default cookie options
|
|
37
|
+
def initialize(document, options = {})
|
|
23
38
|
@document = document
|
|
24
|
-
@options = DEFAULT.
|
|
39
|
+
@options = DEFAULT.merge(options)
|
|
25
40
|
end
|
|
26
41
|
|
|
27
42
|
# Access the cookie with the given name.
|
|
28
43
|
#
|
|
29
44
|
# @param name [String] the name of the cookie
|
|
45
|
+
# @param options [Hash] the options for the cookie
|
|
46
|
+
#
|
|
47
|
+
# @option options [Boolean] :raw get a raw cookie value, don't encode it with JSON
|
|
30
48
|
#
|
|
31
49
|
# @return [Object]
|
|
32
|
-
def [](name)
|
|
33
|
-
|
|
50
|
+
def [](name, options = {})
|
|
51
|
+
options = @options.merge(options)
|
|
52
|
+
|
|
53
|
+
matches = `#@document.cookie`.scan(/#{Regexp.escape(FormData.encode(name))}=([^;]*)/)
|
|
34
54
|
|
|
35
55
|
return if matches.empty?
|
|
36
56
|
|
|
37
|
-
result = matches.map
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
result = matches.flatten.map do |value|
|
|
58
|
+
if options[:raw]
|
|
59
|
+
FormData.decode(value)
|
|
60
|
+
else
|
|
61
|
+
JSON.parse(FormData.decode(value))
|
|
62
|
+
end
|
|
63
|
+
end
|
|
40
64
|
|
|
41
65
|
result.length == 1 ? result.first : result
|
|
42
66
|
end
|
|
@@ -47,36 +71,45 @@ class Cookies
|
|
|
47
71
|
# @param value [Object] the data to set
|
|
48
72
|
# @param options [Hash] the options for the cookie
|
|
49
73
|
#
|
|
74
|
+
# @option options [Boolean] :raw don't encode a value with JSON
|
|
50
75
|
# @option options [Integer] :max_age the max age of the cookie in seconds
|
|
51
76
|
# @option options [Time] :expires the expire date
|
|
52
77
|
# @option options [String] :path the path the cookie is valid on
|
|
53
78
|
# @option options [String] :domain the domain the cookie is valid on
|
|
54
79
|
# @option options [Boolean] :secure whether the cookie is secure or not
|
|
55
|
-
def []=(name,
|
|
56
|
-
|
|
80
|
+
def []=(name, options = {}, value)
|
|
81
|
+
options = @options.merge(options)
|
|
82
|
+
if options[:raw]
|
|
83
|
+
string = value.to_s
|
|
84
|
+
else
|
|
85
|
+
string = JSON.dump(value)
|
|
86
|
+
end
|
|
87
|
+
encoded_value = encode(name, string, options)
|
|
88
|
+
`#@document.cookie = #{encoded_value}`
|
|
57
89
|
end
|
|
58
90
|
|
|
59
91
|
# Delete a cookie.
|
|
60
92
|
#
|
|
61
93
|
# @param name [String] the name of the cookie
|
|
62
|
-
def delete(name)
|
|
94
|
+
def delete(name, _options = {})
|
|
63
95
|
`#@document.cookie = #{encode name, '', expires: Time.now}`
|
|
64
96
|
end
|
|
65
97
|
|
|
66
98
|
# @!attribute [r] keys
|
|
67
99
|
# @return [Array<String>] all the cookie names
|
|
68
|
-
def keys
|
|
69
|
-
Array(`#@document.cookie.split(/; /)`).map
|
|
100
|
+
def keys(_options = {})
|
|
101
|
+
Array(`#@document.cookie.split(/; /)`).map do |cookie|
|
|
70
102
|
cookie.split(/\s*=\s*/).first
|
|
71
|
-
|
|
103
|
+
end
|
|
72
104
|
end
|
|
73
105
|
|
|
74
106
|
# @!attribute [r] values
|
|
75
107
|
# @return [Array] all the cookie values
|
|
76
|
-
def values
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
108
|
+
def values(options = {})
|
|
109
|
+
options = @options.merge(options)
|
|
110
|
+
keys.map do |key|
|
|
111
|
+
self[key, options]
|
|
112
|
+
end
|
|
80
113
|
end
|
|
81
114
|
|
|
82
115
|
# Enumerate the cookies.
|
|
@@ -84,13 +117,18 @@ class Cookies
|
|
|
84
117
|
# @yieldparam key [String] the name of the cookie
|
|
85
118
|
# @yieldparam value [String] the value of the cookie
|
|
86
119
|
#
|
|
120
|
+
# @param options [Hash] the options for the cookie
|
|
121
|
+
#
|
|
122
|
+
# @option options [Boolean] :raw don't encode a value with JSON
|
|
123
|
+
#
|
|
87
124
|
# @return [self]
|
|
88
|
-
def each(&block)
|
|
89
|
-
return enum_for :each unless block
|
|
125
|
+
def each(options = {}, &block)
|
|
126
|
+
return enum_for :each, options unless block
|
|
127
|
+
options = @options.merge(options)
|
|
90
128
|
|
|
91
|
-
keys.each
|
|
92
|
-
yield key, self[key]
|
|
93
|
-
|
|
129
|
+
keys.each do |key|
|
|
130
|
+
yield key, self[key, options]
|
|
131
|
+
end
|
|
94
132
|
|
|
95
133
|
self
|
|
96
134
|
end
|
|
@@ -98,35 +136,35 @@ class Cookies
|
|
|
98
136
|
# Delete all the cookies
|
|
99
137
|
#
|
|
100
138
|
# @return [self]
|
|
101
|
-
def clear
|
|
102
|
-
keys.each
|
|
139
|
+
def clear(_options = {})
|
|
140
|
+
keys.each do |key|
|
|
103
141
|
delete key
|
|
104
|
-
|
|
142
|
+
end
|
|
105
143
|
|
|
106
144
|
self
|
|
107
145
|
end
|
|
108
146
|
|
|
109
147
|
protected
|
|
110
148
|
def encode(key, value, options = {})
|
|
111
|
-
io =
|
|
149
|
+
io = []
|
|
112
150
|
|
|
113
|
-
io << key
|
|
151
|
+
io << FormData.encode(key) << ?= << FormData.encode(value) << '; '
|
|
114
152
|
|
|
115
153
|
io << 'max-age=' << options[:max_age] << '; ' if options[:max_age]
|
|
116
|
-
io << 'expires=' << options[:expires].
|
|
154
|
+
io << 'expires=' << options[:expires].utc << '; ' if options[:expires]
|
|
117
155
|
io << 'path=' << options[:path] << '; ' if options[:path]
|
|
118
156
|
io << 'domain=' << options[:domain] << '; ' if options[:domain]
|
|
119
157
|
io << 'secure' if options[:secure]
|
|
120
158
|
|
|
121
|
-
io.
|
|
159
|
+
io.join
|
|
122
160
|
end
|
|
123
161
|
end
|
|
124
162
|
|
|
125
163
|
class DOM::Document < DOM::Element
|
|
126
164
|
# @!attribute [r] cookies
|
|
127
165
|
# @return [Cookies] the cookies for the document
|
|
128
|
-
def cookies
|
|
129
|
-
Cookies.new(@native) if defined?(`#@native.cookie`)
|
|
166
|
+
def cookies(options = {})
|
|
167
|
+
Cookies.new(@native, options) if defined?(`#@native.cookie`)
|
|
130
168
|
end
|
|
131
169
|
end
|
|
132
170
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Browser
|
|
2
|
+
|
|
3
|
+
# Implements (parts of) the web crypto interface
|
|
4
|
+
#
|
|
5
|
+
# https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
|
|
6
|
+
class Crypto
|
|
7
|
+
include NativeCachedWrapper
|
|
8
|
+
|
|
9
|
+
class Digest
|
|
10
|
+
def initialize(buf)
|
|
11
|
+
@buffer = Buffer.new(buf)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attr_reader :buffer
|
|
15
|
+
|
|
16
|
+
# Convert a digest to a hexadecimal string
|
|
17
|
+
def to_hex
|
|
18
|
+
buffer.to_a.map { |i| "%02x" % i }.join
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Convert a digest to a binary string
|
|
22
|
+
def to_s
|
|
23
|
+
buffer.to_a.map { |i| "%c" % i }.join
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Convert a digest to a Base64-encoded string
|
|
27
|
+
#
|
|
28
|
+
# You will need to `require "base64"`
|
|
29
|
+
def to_b64
|
|
30
|
+
Base64.strict_encode64(to_s)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Convert a digest to a urlsafe Base64-encoded string
|
|
34
|
+
#
|
|
35
|
+
# You will need to `require "base64"`
|
|
36
|
+
def to_u64(padding: false)
|
|
37
|
+
Base64.urlsafe_encode64(to_s, padding: padding)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Compute a cryptographic digest of data (a Buffer). If block is given,
|
|
42
|
+
# it will call a block, otherwise it will return a Promise that will
|
|
43
|
+
# return once a digest is computed.
|
|
44
|
+
#
|
|
45
|
+
# Allowed values for algo: SHA-1, SHA-256 (default), SHA-368, SHA-512.
|
|
46
|
+
#
|
|
47
|
+
# The block/promise will be given an argument of type {Digest} which can
|
|
48
|
+
# be used to format a digest.
|
|
49
|
+
#
|
|
50
|
+
# Example:
|
|
51
|
+
# ```
|
|
52
|
+
# Browser::Blob.new(['test']).buffer.then { |b|
|
|
53
|
+
# $window.crypto.digest(b)
|
|
54
|
+
# }.then { |d|
|
|
55
|
+
# puts d.to_hex
|
|
56
|
+
# }
|
|
57
|
+
# ```
|
|
58
|
+
def digest data, algo = 'SHA-256', &block
|
|
59
|
+
promise = nil
|
|
60
|
+
unless block_given?
|
|
61
|
+
promise = Promise.new
|
|
62
|
+
block = proc { |i| promise.resolve(i) }
|
|
63
|
+
end
|
|
64
|
+
resblock = proc { |i| block.call(Digest.new(i)) }
|
|
65
|
+
|
|
66
|
+
`#@native.subtle.digest(algo, #{Native.convert(data)}).then(#{resblock.to_n})`
|
|
67
|
+
promise
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class Window
|
|
72
|
+
# @!attribute [r] crypto
|
|
73
|
+
# @return [Crypto] the crypto interface of this window
|
|
74
|
+
def crypto
|
|
75
|
+
@crypto ||= Crypto.new(`#@native.crypto`)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
data/opal/browser/css/rule.rb
CHANGED
data/opal/browser/css.rb
CHANGED
|
@@ -4,19 +4,35 @@ require 'browser/css/rule'
|
|
|
4
4
|
require 'browser/css/rule/style'
|
|
5
5
|
|
|
6
6
|
module Kernel
|
|
7
|
-
#
|
|
8
|
-
# {Browser::CSS::Builder} DSL.
|
|
7
|
+
# @overload CSS(document = $document, &block)
|
|
9
8
|
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
# Create a `<style>` element from a {Paggio::CSS} DSL.
|
|
10
|
+
#
|
|
11
|
+
# @param document [Browser::DOM::Document] the document instance
|
|
12
|
+
# we intend to use
|
|
13
|
+
#
|
|
14
|
+
# @return [Browser::DOM::Element] the created `<style>` element
|
|
15
|
+
#
|
|
16
|
+
# @overload CSS(string, document = $document)
|
|
17
|
+
#
|
|
18
|
+
# Create a `<style>` element from a string.
|
|
19
|
+
#
|
|
20
|
+
# @param document [Browser::DOM::Document] the document instance
|
|
21
|
+
# we intend to use
|
|
22
|
+
#
|
|
23
|
+
# @return [Browser::DOM::Element] the created `<style>` element
|
|
24
|
+
def CSS(*args, &block)
|
|
25
|
+
document = if args.length > 1 || block_given?
|
|
26
|
+
args.pop
|
|
27
|
+
end || $document
|
|
28
|
+
|
|
29
|
+
style = document.create_element(:style)
|
|
14
30
|
style[:type] = 'text/css'
|
|
15
31
|
|
|
16
32
|
if block
|
|
17
33
|
style.inner_text = Paggio.css(&block)
|
|
18
34
|
else
|
|
19
|
-
style.inner_text =
|
|
35
|
+
style.inner_text = args.join("")
|
|
20
36
|
end
|
|
21
37
|
|
|
22
38
|
style
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'promise'
|
|
2
1
|
require 'ostruct'
|
|
3
2
|
|
|
4
3
|
module Browser; module Database
|
|
@@ -27,7 +26,7 @@ class SQL
|
|
|
27
26
|
Timeout = Class.new(self)
|
|
28
27
|
end
|
|
29
28
|
|
|
30
|
-
include Native
|
|
29
|
+
include Native::Wrapper
|
|
31
30
|
|
|
32
31
|
# @return [String] the name of the database
|
|
33
32
|
attr_reader :name
|
|
@@ -73,7 +72,7 @@ class SQL
|
|
|
73
72
|
return `#@native.version` unless block
|
|
74
73
|
|
|
75
74
|
`#@native.changeVersion(#{from}, #{to},
|
|
76
|
-
#{->
|
|
75
|
+
#{->(t) { block.call(Transaction.new(self, t)) }})`
|
|
77
76
|
end
|
|
78
77
|
|
|
79
78
|
# Start a transaction on the database.
|
|
@@ -82,12 +81,12 @@ class SQL
|
|
|
82
81
|
def transaction(&block)
|
|
83
82
|
raise ArgumentError, 'no block given' unless block
|
|
84
83
|
|
|
85
|
-
`#@native.transaction(#{->
|
|
84
|
+
`#@native.transaction(#{->(t) { block.call(Transaction.new(self, t)) }})`
|
|
86
85
|
end
|
|
87
86
|
|
|
88
87
|
# Allows you to make changes to the database or read data from it.
|
|
89
88
|
class Transaction
|
|
90
|
-
include Native
|
|
89
|
+
include Native::Wrapper
|
|
91
90
|
|
|
92
91
|
# @return [Database] the database the transaction has been created from
|
|
93
92
|
attr_reader :database
|
|
@@ -109,8 +108,8 @@ class SQL
|
|
|
109
108
|
promise = Promise.new
|
|
110
109
|
|
|
111
110
|
`#@native.executeSql(#{query}, #{parameters},
|
|
112
|
-
#{->
|
|
113
|
-
#{->
|
|
111
|
+
#{->(_, r) { promise.resolve(Result.new(self, r)) }},
|
|
112
|
+
#{->(_, e) { promise.reject(Error.new(e)) }})`
|
|
114
113
|
|
|
115
114
|
promise
|
|
116
115
|
end
|
|
@@ -129,7 +128,7 @@ class SQL
|
|
|
129
128
|
end
|
|
130
129
|
|
|
131
130
|
class Result
|
|
132
|
-
include Native
|
|
131
|
+
include Native::Wrapper
|
|
133
132
|
|
|
134
133
|
# @return [Transaction] the transaction the result came from
|
|
135
134
|
attr_reader :transaction
|
data/opal/browser/delay.rb
CHANGED
|
@@ -49,6 +49,17 @@ class Window
|
|
|
49
49
|
def after!(time, &block)
|
|
50
50
|
Delay.new(@native, time, &block)
|
|
51
51
|
end
|
|
52
|
+
|
|
53
|
+
# Returns a promise that will resolve after the given seconds.
|
|
54
|
+
#
|
|
55
|
+
# @param time [Float] the seconds after it gets called
|
|
56
|
+
#
|
|
57
|
+
# @return [Promise] the promise that will resolve after timeout happens
|
|
58
|
+
def resolve_after(time)
|
|
59
|
+
promise = Promise.new
|
|
60
|
+
Delay.new(@native, time) { promise.resolve }.start
|
|
61
|
+
promise
|
|
62
|
+
end
|
|
52
63
|
end
|
|
53
64
|
|
|
54
65
|
end
|
|
@@ -63,6 +74,11 @@ module Kernel
|
|
|
63
74
|
def after!(time, &block)
|
|
64
75
|
$window.after!(time, &block)
|
|
65
76
|
end
|
|
77
|
+
|
|
78
|
+
# (see Browser::Window#resolve_after)
|
|
79
|
+
def resolve_after(time)
|
|
80
|
+
$window.resolve_after(time)
|
|
81
|
+
end
|
|
66
82
|
end
|
|
67
83
|
|
|
68
84
|
class Proc
|
data/opal/browser/dom/builder.rb
CHANGED
|
@@ -38,10 +38,32 @@ class Builder
|
|
|
38
38
|
|
|
39
39
|
attr_reader :document, :element
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
NEW_PAGGIO = (Paggio::HTML.instance_method(:build!) rescue false)
|
|
42
|
+
|
|
43
|
+
def initialize(document, builder=nil, &block)
|
|
42
44
|
@document = document
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
|
|
46
|
+
# Compatibility issue due to an unreleased Paggio gem.
|
|
47
|
+
# Let's try to support both versions. When Paggio is released,
|
|
48
|
+
# we may remove it.
|
|
49
|
+
|
|
50
|
+
if NEW_PAGGIO
|
|
51
|
+
@builder = Paggio::HTML.new(defer: true, &block)
|
|
52
|
+
|
|
53
|
+
build = proc do
|
|
54
|
+
@builder.build!(force_call: !!builder)
|
|
55
|
+
@roots = @builder.each.map { |e| Builder.build(self, e) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if builder
|
|
59
|
+
builder.extend!(@builder, &build)
|
|
60
|
+
else
|
|
61
|
+
build.()
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
@builder = Paggio::HTML.new(&block)
|
|
65
|
+
@roots = @builder.each.map { |e| Builder.build(self, e) }
|
|
66
|
+
end
|
|
45
67
|
end
|
|
46
68
|
|
|
47
69
|
def to_a
|
|
@@ -54,15 +76,12 @@ Builder.for String do |b, item|
|
|
|
54
76
|
end
|
|
55
77
|
|
|
56
78
|
Builder.for Paggio::HTML::Element do |b, item|
|
|
57
|
-
|
|
79
|
+
options = {}
|
|
58
80
|
|
|
59
|
-
if Hash === `item.attributes`
|
|
60
|
-
|
|
61
|
-
end
|
|
81
|
+
options[:attrs] = `item.attributes` if Hash === `item.attributes`
|
|
82
|
+
options[:classes] = `item.class_names`
|
|
62
83
|
|
|
63
|
-
`item.
|
|
64
|
-
dom.add_class value
|
|
65
|
-
}
|
|
84
|
+
dom = b.document.create_element(`item.name`, **options)
|
|
66
85
|
|
|
67
86
|
if on = `item.on || nil`
|
|
68
87
|
on.each {|args, block|
|