opal-vite 0.3.12 → 0.3.14
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/lib/opal/vite/version.rb +1 -1
- data/opal/opal_vite/concerns/v1/action_cable_helpers.rb +1 -1
- data/opal/opal_vite/concerns/v1/base64_helpers.rb +10 -8
- data/opal/opal_vite/concerns/v1/component.rb +112 -0
- data/opal/opal_vite/concerns/v1/react_helpers.rb +4 -1
- data/opal/opal_vite/concerns/v1/storable.rb +1 -1
- data/opal/opal_vite/concerns/v1/turbo_helpers.rb +7 -1
- data/opal/opal_vite/concerns/v1/uri_helpers.rb +4 -4
- data/opal/opal_vite/concerns/v1/vue_helpers.rb +4 -1
- data/opal/opal_vite/concerns/v1.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 70f625bc74c24b95f12fb5fbfddd5f5aee028c1f1953affb73d9bfab639deedf
|
|
4
|
+
data.tar.gz: 416c5805372e4ff28a55005ec0d0fc0cb23e2d2d76cfe81db04e1da5131ac4d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 97ecab260b4b8284f5a07a5bdbb9ede917e5708193348d40c77b2d953be852b3f6b97a5a7405082ce2aec62c3abae0561c9a04960f599d622af8ea1ce801edc0
|
|
7
|
+
data.tar.gz: d51d3a7602afbbc9e3d5cc3898f31f95a9f0c731635074e3d9fe88ae731aadf676f6a9d8e39f5ece06cedca44998fac708983311068fcb38c8c5f2f2a11dc679
|
data/lib/opal/vite/version.rb
CHANGED
|
@@ -29,7 +29,7 @@ module OpalVite
|
|
|
29
29
|
# @return [String] Base64 encoded string
|
|
30
30
|
def base64_encode(str)
|
|
31
31
|
`btoa(#{str})`
|
|
32
|
-
rescue
|
|
32
|
+
rescue Exception
|
|
33
33
|
nil
|
|
34
34
|
end
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ module OpalVite
|
|
|
38
38
|
# @return [String] Decoded string
|
|
39
39
|
def base64_decode(str)
|
|
40
40
|
`atob(#{str})`
|
|
41
|
-
rescue
|
|
41
|
+
rescue Exception
|
|
42
42
|
nil
|
|
43
43
|
end
|
|
44
44
|
|
|
@@ -81,7 +81,7 @@ module OpalVite
|
|
|
81
81
|
def base64_encode_unicode(str)
|
|
82
82
|
# Convert to UTF-8 bytes, then encode
|
|
83
83
|
`btoa(unescape(encodeURIComponent(#{str})))`
|
|
84
|
-
rescue
|
|
84
|
+
rescue Exception
|
|
85
85
|
nil
|
|
86
86
|
end
|
|
87
87
|
|
|
@@ -90,7 +90,7 @@ module OpalVite
|
|
|
90
90
|
# @return [String] Decoded Unicode string
|
|
91
91
|
def base64_decode_unicode(str)
|
|
92
92
|
`decodeURIComponent(escape(atob(#{str})))`
|
|
93
|
-
rescue
|
|
93
|
+
rescue Exception
|
|
94
94
|
nil
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -108,7 +108,7 @@ module OpalVite
|
|
|
108
108
|
}
|
|
109
109
|
return btoa(binary);
|
|
110
110
|
`
|
|
111
|
-
rescue
|
|
111
|
+
rescue Exception
|
|
112
112
|
nil
|
|
113
113
|
end
|
|
114
114
|
|
|
@@ -124,7 +124,7 @@ module OpalVite
|
|
|
124
124
|
}
|
|
125
125
|
return bytes;
|
|
126
126
|
`
|
|
127
|
-
rescue
|
|
127
|
+
rescue Exception
|
|
128
128
|
nil
|
|
129
129
|
end
|
|
130
130
|
|
|
@@ -202,7 +202,7 @@ module OpalVite
|
|
|
202
202
|
return nil unless payload_json
|
|
203
203
|
|
|
204
204
|
`JSON.parse(#{payload_json})`
|
|
205
|
-
rescue
|
|
205
|
+
rescue Exception
|
|
206
206
|
nil
|
|
207
207
|
end
|
|
208
208
|
|
|
@@ -264,7 +264,9 @@ module OpalVite
|
|
|
264
264
|
|
|
265
265
|
len = str.length
|
|
266
266
|
padding = str.end_with?('==') ? 2 : (str.end_with?('=') ? 1 : 0)
|
|
267
|
-
|
|
267
|
+
# Use integer division: in Opal `len * 3 / 4` is JS float division, so
|
|
268
|
+
# unpadded/URL-safe input (len % 4 == 2 or 3) would yield e.g. 16.5.
|
|
269
|
+
((len * 3) / 4).floor - padding
|
|
268
270
|
end
|
|
269
271
|
end
|
|
270
272
|
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# backtick_javascript: true
|
|
2
|
+
|
|
3
|
+
module OpalVite
|
|
4
|
+
module Concerns
|
|
5
|
+
module V1
|
|
6
|
+
# Component - a lightweight, framework-agnostic UI component base class.
|
|
7
|
+
#
|
|
8
|
+
# opal-rails users coming from hand-written opal-jquery DOM code (or
|
|
9
|
+
# Hyperstack) usually just want "a base class that holds state and
|
|
10
|
+
# re-renders". This provides exactly that, with no React/Vue dependency,
|
|
11
|
+
# using only the native DOM. Because it is Sprockets-independent it runs
|
|
12
|
+
# unchanged under Vite.
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# class Counter < OpalComponent
|
|
16
|
+
# def initial_state
|
|
17
|
+
# { count: 0 }
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# def render
|
|
21
|
+
# "<button>count: #{state[:count]}</button>"
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# def after_render
|
|
25
|
+
# on('button', 'click') { set_state(count: state[:count] + 1) }
|
|
26
|
+
# end
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# Counter.new.mount('#app')
|
|
30
|
+
class Component
|
|
31
|
+
attr_reader :state, :props, :el
|
|
32
|
+
|
|
33
|
+
# @param props [Hash] immutable inputs passed from the parent/caller
|
|
34
|
+
def initialize(props = {})
|
|
35
|
+
@props = props
|
|
36
|
+
@state = initial_state
|
|
37
|
+
@el = nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Override to provide the initial state hash. Defaults to empty.
|
|
41
|
+
def initial_state
|
|
42
|
+
{}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Override to return the component's HTML as a String.
|
|
46
|
+
def render
|
|
47
|
+
''
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Optional hook run after every render. Attach event listeners here
|
|
51
|
+
# (the DOM produced by #render only exists after rendering).
|
|
52
|
+
def after_render; end
|
|
53
|
+
|
|
54
|
+
# Mount the component into a DOM element.
|
|
55
|
+
# @param target [String, Native] a CSS selector or a native element
|
|
56
|
+
# @return [self]
|
|
57
|
+
def mount(target)
|
|
58
|
+
@el = resolve_el(target)
|
|
59
|
+
raise "OpalComponent#mount: target not found: #{target}" if `#{@el} == null`
|
|
60
|
+
|
|
61
|
+
do_render
|
|
62
|
+
self
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Merge +partial+ into the current state and re-render (if mounted).
|
|
66
|
+
# @param partial [Hash]
|
|
67
|
+
# @return [Hash] the new state
|
|
68
|
+
def set_state(partial)
|
|
69
|
+
unless partial.is_a?(Hash)
|
|
70
|
+
raise ArgumentError, "OpalComponent#set_state expects a Hash, got #{partial.class}"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
@state = @state.merge(partial)
|
|
74
|
+
do_render if @el
|
|
75
|
+
@state
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# querySelector scoped to this component's element.
|
|
79
|
+
def query(selector)
|
|
80
|
+
`#{@el}.querySelector(#{selector})`
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Attach an event listener to a descendant matched by +selector+.
|
|
84
|
+
# The block receives the native DOM event.
|
|
85
|
+
def on(selector, event, &block)
|
|
86
|
+
node = query(selector)
|
|
87
|
+
return if `#{node} == null`
|
|
88
|
+
|
|
89
|
+
`#{node}.addEventListener(#{event}, #{block})`
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def do_render
|
|
95
|
+
`#{@el}.innerHTML = #{render}`
|
|
96
|
+
after_render
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def resolve_el(target)
|
|
100
|
+
if target.is_a?(String)
|
|
101
|
+
`document.querySelector(#{target})`
|
|
102
|
+
else
|
|
103
|
+
target
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Friendly top-level alias (the base class users subclass).
|
|
112
|
+
OpalComponent = OpalVite::Concerns::V1::Component
|
|
@@ -275,7 +275,10 @@ module OpalVite
|
|
|
275
275
|
|
|
276
276
|
# Stringify to JSON
|
|
277
277
|
def to_json(object)
|
|
278
|
-
|
|
278
|
+
# Convert Ruby Hash/Array to a native JS value first; passing a raw
|
|
279
|
+
# Opal Hash to JSON.stringify serializes to "{}" (silent data loss).
|
|
280
|
+
native = object.respond_to?(:to_n) ? object.to_n : object
|
|
281
|
+
`JSON.stringify(#{native})`
|
|
279
282
|
end
|
|
280
283
|
|
|
281
284
|
# ===================
|
|
@@ -356,7 +356,13 @@ module OpalVite
|
|
|
356
356
|
# source = turbo_stream_from("/notifications/stream")
|
|
357
357
|
# # Turbo will automatically process incoming streams
|
|
358
358
|
def turbo_stream_from(url)
|
|
359
|
-
|
|
359
|
+
# Keep a reference to the EventSource and return it: connectStreamSource
|
|
360
|
+
# returns undefined, so returning its result would make the documented
|
|
361
|
+
# `turbo_stream_disconnect(source)` call `undefined.close()` and leak
|
|
362
|
+
# the SSE connection.
|
|
363
|
+
source = `new EventSource(#{url})`
|
|
364
|
+
`window.Turbo.connectStreamSource(#{source})`
|
|
365
|
+
source
|
|
360
366
|
end
|
|
361
367
|
|
|
362
368
|
# Disconnect a Turbo Stream SSE source
|
|
@@ -27,7 +27,7 @@ module OpalVite
|
|
|
27
27
|
# @return [Native] JavaScript URL object
|
|
28
28
|
def parse_url(url_string)
|
|
29
29
|
`new URL(#{url_string})`
|
|
30
|
-
rescue
|
|
30
|
+
rescue Exception
|
|
31
31
|
nil
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -37,7 +37,7 @@ module OpalVite
|
|
|
37
37
|
# @return [Native] JavaScript URL object
|
|
38
38
|
def parse_url_with_base(url_string, base)
|
|
39
39
|
`new URL(#{url_string}, #{base})`
|
|
40
|
-
rescue
|
|
40
|
+
rescue Exception
|
|
41
41
|
nil
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -225,7 +225,7 @@ module OpalVite
|
|
|
225
225
|
# @return [String] Decoded string
|
|
226
226
|
def decode_uri_component(str)
|
|
227
227
|
`decodeURIComponent(#{str})`
|
|
228
|
-
rescue
|
|
228
|
+
rescue Exception
|
|
229
229
|
str
|
|
230
230
|
end
|
|
231
231
|
|
|
@@ -241,7 +241,7 @@ module OpalVite
|
|
|
241
241
|
# @return [String] Decoded URI
|
|
242
242
|
def decode_uri(str)
|
|
243
243
|
`decodeURI(#{str})`
|
|
244
|
-
rescue
|
|
244
|
+
rescue Exception
|
|
245
245
|
str
|
|
246
246
|
end
|
|
247
247
|
|
|
@@ -315,7 +315,10 @@ module OpalVite
|
|
|
315
315
|
|
|
316
316
|
# Stringify to JSON
|
|
317
317
|
def to_json_string(object)
|
|
318
|
-
|
|
318
|
+
# Convert Ruby Hash/Array to a native JS value first; passing a raw
|
|
319
|
+
# Opal Hash to JSON.stringify serializes to "{}" (silent data loss).
|
|
320
|
+
native = object.respond_to?(:to_n) ? object.to_n : object
|
|
321
|
+
`JSON.stringify(#{native})`
|
|
319
322
|
end
|
|
320
323
|
|
|
321
324
|
# ===================
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: opal-vite
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.14
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- stofu1234
|
|
@@ -122,6 +122,7 @@ files:
|
|
|
122
122
|
- opal/opal_vite/concerns/v1.rb
|
|
123
123
|
- opal/opal_vite/concerns/v1/action_cable_helpers.rb
|
|
124
124
|
- opal/opal_vite/concerns/v1/base64_helpers.rb
|
|
125
|
+
- opal/opal_vite/concerns/v1/component.rb
|
|
125
126
|
- opal/opal_vite/concerns/v1/debug_helpers.rb
|
|
126
127
|
- opal/opal_vite/concerns/v1/dom_helpers.rb
|
|
127
128
|
- opal/opal_vite/concerns/v1/functional_component.rb
|