opal-vite 0.2.5 → 0.2.7
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/compiler.rb +229 -11
- data/lib/opal/vite/version.rb +1 -1
- data/opal/opal_vite/concerns/vue_helpers.rb +249 -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: d647a605d1362c318322a04e13412cb9bb298fff93d9d2892b96afdc7170fc6b
|
|
4
|
+
data.tar.gz: 0a72ac91f6973d02587de1b63ec63052fce19519138ece126e7f9edd40af8c56
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 508a5e5f69a85c218c2ccf2f451140080860885a00d041909a5da09c9a7d755ba369ba6ecc10f2c4ed84c31a4491103495ec0afa022f9abfb6d2d8d349c16f7b
|
|
7
|
+
data.tar.gz: 4b84a15c0db47b794d0bb50a1eba4e6b78df5683f0fbf281d5e05f7f14ab2fb016ad59591b37b846b62125cc7035541e31772140a8c41e91285c628531e810ed
|
data/lib/opal/vite/compiler.rb
CHANGED
|
@@ -146,7 +146,7 @@ module Opal
|
|
|
146
146
|
return nil unless builder.respond_to?(:source_map) && builder.source_map
|
|
147
147
|
|
|
148
148
|
source_map = builder.source_map
|
|
149
|
-
map_hash = source_map.to_h
|
|
149
|
+
map_hash = deep_stringify_keys(source_map.to_h)
|
|
150
150
|
return nil unless map_hash
|
|
151
151
|
|
|
152
152
|
# If it's an index format with sections, merge all sections
|
|
@@ -156,16 +156,35 @@ module Opal
|
|
|
156
156
|
|
|
157
157
|
return nil unless map_hash
|
|
158
158
|
|
|
159
|
+
# Add sourceRoot for proper browser debugging
|
|
160
|
+
# This helps DevTools organize source files in a logical tree
|
|
161
|
+
map_hash['sourceRoot'] = ''
|
|
162
|
+
|
|
159
163
|
# Normalize source paths for browser debugging
|
|
164
|
+
# Prefix with /opal-sources/ so they appear in a dedicated folder in DevTools
|
|
160
165
|
if map_hash['sources']
|
|
161
166
|
map_hash['sources'] = map_hash['sources'].map do |source|
|
|
162
|
-
|
|
167
|
+
normalize_source_path_for_devtools(source, file_path)
|
|
163
168
|
end
|
|
164
169
|
end
|
|
165
170
|
|
|
166
171
|
map_hash.to_json
|
|
167
172
|
end
|
|
168
173
|
|
|
174
|
+
# Recursively convert all hash keys to strings
|
|
175
|
+
def deep_stringify_keys(obj)
|
|
176
|
+
case obj
|
|
177
|
+
when Hash
|
|
178
|
+
obj.each_with_object({}) do |(key, value), result|
|
|
179
|
+
result[key.to_s] = deep_stringify_keys(value)
|
|
180
|
+
end
|
|
181
|
+
when Array
|
|
182
|
+
obj.map { |item| deep_stringify_keys(item) }
|
|
183
|
+
else
|
|
184
|
+
obj
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
169
188
|
def merge_all_sections(index_map, file_path)
|
|
170
189
|
sections = index_map['sections']
|
|
171
190
|
return nil if sections.nil? || sections.empty?
|
|
@@ -186,6 +205,13 @@ module Opal
|
|
|
186
205
|
'mappings' => ''
|
|
187
206
|
}
|
|
188
207
|
|
|
208
|
+
# Track cumulative state for VLQ relative encoding
|
|
209
|
+
# These track the "previous" values across all sections
|
|
210
|
+
prev_source = 0
|
|
211
|
+
prev_orig_line = 0
|
|
212
|
+
prev_orig_col = 0
|
|
213
|
+
prev_name = 0
|
|
214
|
+
|
|
189
215
|
current_line = 0
|
|
190
216
|
|
|
191
217
|
sections.each_with_index do |section, idx|
|
|
@@ -202,7 +228,7 @@ module Opal
|
|
|
202
228
|
current_line = section_start_line
|
|
203
229
|
end
|
|
204
230
|
|
|
205
|
-
# Track source index
|
|
231
|
+
# Track source and name index offsets for this section
|
|
206
232
|
source_offset = merged['sources'].length
|
|
207
233
|
name_offset = merged['names'].length
|
|
208
234
|
|
|
@@ -223,25 +249,184 @@ module Opal
|
|
|
223
249
|
merged['names'].concat(section_map['names'])
|
|
224
250
|
end
|
|
225
251
|
|
|
226
|
-
#
|
|
252
|
+
# Process mappings from this section with index adjustment
|
|
227
253
|
if section_map['mappings'] && !section_map['mappings'].empty?
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
254
|
+
adjusted_mappings, prev_source, prev_orig_line, prev_orig_col, prev_name =
|
|
255
|
+
adjust_section_mappings(
|
|
256
|
+
section_map['mappings'],
|
|
257
|
+
source_offset,
|
|
258
|
+
name_offset,
|
|
259
|
+
prev_source,
|
|
260
|
+
prev_orig_line,
|
|
261
|
+
prev_orig_col,
|
|
262
|
+
prev_name
|
|
263
|
+
)
|
|
264
|
+
|
|
231
265
|
if idx > 0 && !merged['mappings'].empty? && !merged['mappings'].end_with?(';')
|
|
232
266
|
merged['mappings'] += ';'
|
|
233
267
|
end
|
|
234
|
-
merged['mappings'] +=
|
|
268
|
+
merged['mappings'] += adjusted_mappings
|
|
235
269
|
|
|
236
|
-
#
|
|
237
|
-
|
|
238
|
-
current_line
|
|
270
|
+
# Update current_line to the last line we wrote to
|
|
271
|
+
# section_start_line + number of semicolons in this section's mappings
|
|
272
|
+
current_line = section_start_line + section_map['mappings'].count(';')
|
|
239
273
|
end
|
|
240
274
|
end
|
|
241
275
|
|
|
242
276
|
merged
|
|
243
277
|
end
|
|
244
278
|
|
|
279
|
+
# Adjust mappings from a section by adding offsets to source/name indices
|
|
280
|
+
# VLQ mappings use relative deltas. When merging sections:
|
|
281
|
+
# - First section: no adjustment, just track final absolute state
|
|
282
|
+
# - Later sections: adjust first segment's source/name delta to bridge from previous section's end state
|
|
283
|
+
#
|
|
284
|
+
# Returns: [adjusted_mappings, new_prev_source, new_prev_orig_line, new_prev_orig_col, new_prev_name]
|
|
285
|
+
def adjust_section_mappings(mappings, source_offset, name_offset, prev_source, prev_orig_line, prev_orig_col, prev_name)
|
|
286
|
+
return ['', prev_source, prev_orig_line, prev_orig_col, prev_name] if mappings.nil? || mappings.empty?
|
|
287
|
+
|
|
288
|
+
result_lines = []
|
|
289
|
+
lines = mappings.split(';', -1)
|
|
290
|
+
|
|
291
|
+
# Track absolute state within this section (section-local, starting from 0)
|
|
292
|
+
section_abs_source = 0
|
|
293
|
+
section_abs_orig_line = 0
|
|
294
|
+
section_abs_orig_col = 0
|
|
295
|
+
section_abs_name = 0
|
|
296
|
+
|
|
297
|
+
first_segment_processed = false
|
|
298
|
+
|
|
299
|
+
lines.each do |line|
|
|
300
|
+
if line.empty?
|
|
301
|
+
result_lines << ''
|
|
302
|
+
next
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
result_segments = []
|
|
306
|
+
segments = line.split(',')
|
|
307
|
+
|
|
308
|
+
segments.each do |segment|
|
|
309
|
+
values = decode_vlq(segment)
|
|
310
|
+
next if values.empty?
|
|
311
|
+
|
|
312
|
+
# values[0] = generated column delta (always present, relative within line)
|
|
313
|
+
# values[1] = source index delta
|
|
314
|
+
# values[2] = original line delta
|
|
315
|
+
# values[3] = original column delta
|
|
316
|
+
# values[4] = name index delta
|
|
317
|
+
|
|
318
|
+
gen_col_delta = values[0]
|
|
319
|
+
|
|
320
|
+
if values.length > 1
|
|
321
|
+
# Update section-local absolute positions
|
|
322
|
+
section_abs_source += values[1]
|
|
323
|
+
section_abs_orig_line += values[2] if values.length > 2
|
|
324
|
+
section_abs_orig_col += values[3] if values.length > 3
|
|
325
|
+
section_abs_name += values[4] if values.length > 4
|
|
326
|
+
|
|
327
|
+
# Calculate global absolute positions (with offset)
|
|
328
|
+
global_abs_source = section_abs_source + source_offset
|
|
329
|
+
global_abs_name = section_abs_name + name_offset
|
|
330
|
+
|
|
331
|
+
if !first_segment_processed
|
|
332
|
+
# First segment: calculate delta from previous section's end state to this segment's global position
|
|
333
|
+
new_source_delta = global_abs_source - prev_source
|
|
334
|
+
new_orig_line_delta = section_abs_orig_line - prev_orig_line
|
|
335
|
+
new_orig_col_delta = section_abs_orig_col - prev_orig_col
|
|
336
|
+
new_name_delta = global_abs_name - prev_name
|
|
337
|
+
|
|
338
|
+
new_values = [gen_col_delta, new_source_delta, new_orig_line_delta, new_orig_col_delta]
|
|
339
|
+
new_values << new_name_delta if values.length > 4
|
|
340
|
+
|
|
341
|
+
first_segment_processed = true
|
|
342
|
+
else
|
|
343
|
+
# Subsequent segments: deltas are already correct (relative within section = relative within merged)
|
|
344
|
+
new_values = values.dup
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
result_segments << encode_vlq(new_values)
|
|
348
|
+
|
|
349
|
+
# Update tracking for next section
|
|
350
|
+
prev_source = global_abs_source
|
|
351
|
+
prev_orig_line = section_abs_orig_line
|
|
352
|
+
prev_orig_col = section_abs_orig_col
|
|
353
|
+
prev_name = global_abs_name if values.length > 4
|
|
354
|
+
else
|
|
355
|
+
# Only generated column, no source mapping
|
|
356
|
+
result_segments << encode_vlq([gen_col_delta])
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
result_lines << result_segments.join(',')
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
[result_lines.join(';'), prev_source, prev_orig_line, prev_orig_col, prev_name]
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
# VLQ Base64 character set
|
|
367
|
+
VLQ_BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.freeze
|
|
368
|
+
VLQ_BASE64_VALUES = VLQ_BASE64_CHARS.each_char.with_index.to_h.freeze
|
|
369
|
+
VLQ_BASE_SHIFT = 5
|
|
370
|
+
VLQ_BASE = 1 << VLQ_BASE_SHIFT # 32
|
|
371
|
+
VLQ_BASE_MASK = VLQ_BASE - 1 # 31
|
|
372
|
+
VLQ_CONTINUATION_BIT = VLQ_BASE # 32
|
|
373
|
+
|
|
374
|
+
# Decode a VLQ-encoded segment into an array of integers
|
|
375
|
+
def decode_vlq(segment)
|
|
376
|
+
return [] if segment.nil? || segment.empty?
|
|
377
|
+
|
|
378
|
+
values = []
|
|
379
|
+
shift = 0
|
|
380
|
+
value = 0
|
|
381
|
+
|
|
382
|
+
segment.each_char do |char|
|
|
383
|
+
digit = VLQ_BASE64_VALUES[char]
|
|
384
|
+
return values if digit.nil? # Invalid character
|
|
385
|
+
|
|
386
|
+
continuation = (digit & VLQ_CONTINUATION_BIT) != 0
|
|
387
|
+
digit &= VLQ_BASE_MASK
|
|
388
|
+
value += digit << shift
|
|
389
|
+
|
|
390
|
+
if continuation
|
|
391
|
+
shift += VLQ_BASE_SHIFT
|
|
392
|
+
else
|
|
393
|
+
# Convert from VLQ signed representation
|
|
394
|
+
negative = (value & 1) == 1
|
|
395
|
+
value >>= 1
|
|
396
|
+
value = -value if negative
|
|
397
|
+
values << value
|
|
398
|
+
|
|
399
|
+
# Reset for next value
|
|
400
|
+
value = 0
|
|
401
|
+
shift = 0
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
values
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# Encode an array of integers into a VLQ-encoded string
|
|
409
|
+
def encode_vlq(values)
|
|
410
|
+
return '' if values.nil? || values.empty?
|
|
411
|
+
|
|
412
|
+
result = ''
|
|
413
|
+
|
|
414
|
+
values.each do |value|
|
|
415
|
+
# Convert to VLQ signed representation
|
|
416
|
+
vlq = value < 0 ? ((-value) << 1) + 1 : value << 1
|
|
417
|
+
|
|
418
|
+
loop do
|
|
419
|
+
digit = vlq & VLQ_BASE_MASK
|
|
420
|
+
vlq >>= VLQ_BASE_SHIFT
|
|
421
|
+
digit |= VLQ_CONTINUATION_BIT if vlq > 0
|
|
422
|
+
result += VLQ_BASE64_CHARS[digit]
|
|
423
|
+
break if vlq == 0
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
result
|
|
428
|
+
end
|
|
429
|
+
|
|
245
430
|
def normalize_source_path(source, file_path)
|
|
246
431
|
# Convert absolute paths to relative for better browser debugging
|
|
247
432
|
return source if source.nil? || source.empty?
|
|
@@ -257,6 +442,39 @@ module Opal
|
|
|
257
442
|
source
|
|
258
443
|
end
|
|
259
444
|
end
|
|
445
|
+
|
|
446
|
+
def normalize_source_path_for_devtools(source, file_path)
|
|
447
|
+
# Format source paths so they appear properly in browser DevTools
|
|
448
|
+
# Chrome DevTools uses the source path to build the file tree
|
|
449
|
+
return source if source.nil? || source.empty?
|
|
450
|
+
|
|
451
|
+
# Remove any leading ./ for consistency
|
|
452
|
+
source = source.sub(/^\.\//, '')
|
|
453
|
+
|
|
454
|
+
# Handle absolute paths - make them relative to show properly
|
|
455
|
+
if source.start_with?('/')
|
|
456
|
+
# Extract just the relevant path (last few components)
|
|
457
|
+
parts = source.split('/')
|
|
458
|
+
# Keep last 3 path components for context (e.g., app/opal/controllers/...)
|
|
459
|
+
source = parts.last(3).join('/')
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
# Prefix paths for user code (controllers, services, etc.) to group them
|
|
463
|
+
# This ensures they appear under a dedicated folder in DevTools
|
|
464
|
+
if source.include?('controllers/') || source.include?('services/')
|
|
465
|
+
# Already has recognizable path, prefix with opal-sources for visibility
|
|
466
|
+
"/opal-sources/#{source}"
|
|
467
|
+
elsif source.start_with?('corelib/') || source.start_with?('opal/')
|
|
468
|
+
# Opal core library files - put under opal-core
|
|
469
|
+
"/opal-core/#{source}"
|
|
470
|
+
elsif source.include?('opal_stimulus/') || source.include?('opal_vite/')
|
|
471
|
+
# Opal library files
|
|
472
|
+
"/opal-libs/#{source}"
|
|
473
|
+
else
|
|
474
|
+
# Other files (native.rb, js/proxy.rb, etc.)
|
|
475
|
+
"/opal-other/#{source}"
|
|
476
|
+
end
|
|
477
|
+
end
|
|
260
478
|
end
|
|
261
479
|
end
|
|
262
480
|
end
|
data/lib/opal/vite/version.rb
CHANGED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# backtick_javascript: true
|
|
2
|
+
|
|
3
|
+
# VueHelpers - DSL helpers for Vue.js 3 applications with Opal
|
|
4
|
+
# Reduces backtick JavaScript usage in Vue components
|
|
5
|
+
module VueHelpers
|
|
6
|
+
extend self # Makes all methods available as module methods
|
|
7
|
+
# ===================
|
|
8
|
+
# Vue Access
|
|
9
|
+
# ===================
|
|
10
|
+
|
|
11
|
+
# Get Vue from window
|
|
12
|
+
def vue
|
|
13
|
+
`window.Vue`
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Create a Vue application
|
|
17
|
+
# @param options [Hash] Vue component options (data, methods, computed, template, etc.)
|
|
18
|
+
# @return [Native] Vue app instance
|
|
19
|
+
def create_app(options = {})
|
|
20
|
+
Native(`window.Vue.createApp(#{options.to_n})`)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Create a reactive ref
|
|
24
|
+
# @param initial_value [Object] Initial value
|
|
25
|
+
# @return [Native] Vue ref
|
|
26
|
+
def vue_ref(initial_value)
|
|
27
|
+
Native(`window.Vue.ref(#{initial_value})`)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Create a reactive object
|
|
31
|
+
# @param object [Hash] Object to make reactive
|
|
32
|
+
# @return [Native] Vue reactive object
|
|
33
|
+
def vue_reactive(object)
|
|
34
|
+
Native(`window.Vue.reactive(#{object.to_n})`)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Create a computed property
|
|
38
|
+
# @param getter [Proc] Getter function
|
|
39
|
+
# @return [Native] Vue computed ref
|
|
40
|
+
def vue_computed(&getter)
|
|
41
|
+
Native(`window.Vue.computed(#{getter})`)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Watch a reactive source
|
|
45
|
+
# @param source [Native] Reactive source to watch
|
|
46
|
+
# @param callback [Proc] Callback function
|
|
47
|
+
def vue_watch(source, &callback)
|
|
48
|
+
`window.Vue.watch(#{source}, #{callback})`
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# ===================
|
|
52
|
+
# Component Definition Helpers
|
|
53
|
+
# ===================
|
|
54
|
+
|
|
55
|
+
# Define component data as a function
|
|
56
|
+
# @param data_hash [Hash] Initial data
|
|
57
|
+
# @return [Proc] Data function for Vue component
|
|
58
|
+
def data_fn(data_hash)
|
|
59
|
+
-> { data_hash.to_n }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Define methods hash for Vue component
|
|
63
|
+
# @param methods_hash [Hash] Methods with name => proc
|
|
64
|
+
# @return [Hash] Methods object for Vue component
|
|
65
|
+
def methods_obj(methods_hash)
|
|
66
|
+
result = {}
|
|
67
|
+
methods_hash.each do |name, proc|
|
|
68
|
+
result[name] = proc
|
|
69
|
+
end
|
|
70
|
+
result.to_n
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Define computed properties hash
|
|
74
|
+
# @param computed_hash [Hash] Computed properties with name => proc
|
|
75
|
+
# @return [Hash] Computed object for Vue component
|
|
76
|
+
def computed_obj(computed_hash)
|
|
77
|
+
result = {}
|
|
78
|
+
computed_hash.each do |name, proc|
|
|
79
|
+
result[name] = proc
|
|
80
|
+
end
|
|
81
|
+
result.to_n
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# ===================
|
|
85
|
+
# Lifecycle Hooks
|
|
86
|
+
# ===================
|
|
87
|
+
|
|
88
|
+
# onMounted hook
|
|
89
|
+
def on_mounted(&block)
|
|
90
|
+
`window.Vue.onMounted(#{block})`
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# onUnmounted hook
|
|
94
|
+
def on_unmounted(&block)
|
|
95
|
+
`window.Vue.onUnmounted(#{block})`
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# onUpdated hook
|
|
99
|
+
def on_updated(&block)
|
|
100
|
+
`window.Vue.onUpdated(#{block})`
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# onBeforeMount hook
|
|
104
|
+
def on_before_mount(&block)
|
|
105
|
+
`window.Vue.onBeforeMount(#{block})`
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# onBeforeUnmount hook
|
|
109
|
+
def on_before_unmount(&block)
|
|
110
|
+
`window.Vue.onBeforeUnmount(#{block})`
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# ===================
|
|
114
|
+
# Window/Global Access
|
|
115
|
+
# ===================
|
|
116
|
+
|
|
117
|
+
# Get a property from window
|
|
118
|
+
def window_get(key)
|
|
119
|
+
`window[#{key}]`
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Set a property on window
|
|
123
|
+
def window_set(key, value)
|
|
124
|
+
`window[#{key}] = #{value}`
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# ===================
|
|
128
|
+
# Console
|
|
129
|
+
# ===================
|
|
130
|
+
|
|
131
|
+
# Console log
|
|
132
|
+
def console_log(*args)
|
|
133
|
+
`console.log(...#{args})`
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Console warn
|
|
137
|
+
def console_warn(*args)
|
|
138
|
+
`console.warn(...#{args})`
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Console error
|
|
142
|
+
def console_error(*args)
|
|
143
|
+
`console.error(...#{args})`
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# ===================
|
|
147
|
+
# DOM Events
|
|
148
|
+
# ===================
|
|
149
|
+
|
|
150
|
+
# Execute block when DOM is ready
|
|
151
|
+
def on_dom_ready(&block)
|
|
152
|
+
`document.addEventListener('DOMContentLoaded', #{block})`
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# ===================
|
|
156
|
+
# DOM Query
|
|
157
|
+
# ===================
|
|
158
|
+
|
|
159
|
+
# Query single element
|
|
160
|
+
def query(selector)
|
|
161
|
+
`document.querySelector(#{selector})`
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Query all elements
|
|
165
|
+
def query_all(selector)
|
|
166
|
+
`Array.from(document.querySelectorAll(#{selector}))`
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Get element by ID
|
|
170
|
+
def get_element_by_id(id)
|
|
171
|
+
`document.getElementById(#{id})`
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# ===================
|
|
175
|
+
# Timing
|
|
176
|
+
# ===================
|
|
177
|
+
|
|
178
|
+
# Set timeout
|
|
179
|
+
def set_timeout(delay_ms, &block)
|
|
180
|
+
`setTimeout(#{block}, #{delay_ms})`
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Set interval
|
|
184
|
+
def set_interval(interval_ms, &block)
|
|
185
|
+
`setInterval(#{block}, #{interval_ms})`
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Clear timeout
|
|
189
|
+
def clear_timeout(timeout_id)
|
|
190
|
+
`clearTimeout(#{timeout_id})`
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Clear interval
|
|
194
|
+
def clear_interval(interval_id)
|
|
195
|
+
`clearInterval(#{interval_id})`
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# ===================
|
|
199
|
+
# LocalStorage
|
|
200
|
+
# ===================
|
|
201
|
+
|
|
202
|
+
# Get from localStorage
|
|
203
|
+
def storage_get(key)
|
|
204
|
+
`localStorage.getItem(#{key})`
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Set to localStorage
|
|
208
|
+
def storage_set(key, value)
|
|
209
|
+
`localStorage.setItem(#{key}, #{value})`
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Remove from localStorage
|
|
213
|
+
def storage_remove(key)
|
|
214
|
+
`localStorage.removeItem(#{key})`
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# ===================
|
|
218
|
+
# JSON
|
|
219
|
+
# ===================
|
|
220
|
+
|
|
221
|
+
# Parse JSON string
|
|
222
|
+
def parse_json(json_string)
|
|
223
|
+
`JSON.parse(#{json_string})`
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Stringify to JSON
|
|
227
|
+
def to_json_string(object)
|
|
228
|
+
`JSON.stringify(#{object})`
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# ===================
|
|
232
|
+
# Type Conversion
|
|
233
|
+
# ===================
|
|
234
|
+
|
|
235
|
+
# Parse string to integer
|
|
236
|
+
def parse_int(value, radix = 10)
|
|
237
|
+
`parseInt(#{value}, #{radix})`
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Parse string to float
|
|
241
|
+
def parse_float(value)
|
|
242
|
+
`parseFloat(#{value})`
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Check if value is NaN
|
|
246
|
+
def is_nan?(value)
|
|
247
|
+
`Number.isNaN(#{value})`
|
|
248
|
+
end
|
|
249
|
+
end
|
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.2.
|
|
4
|
+
version: 0.2.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- stofu1234
|
|
@@ -119,6 +119,7 @@ files:
|
|
|
119
119
|
- opal/opal_vite/concerns/stimulus_helpers.rb
|
|
120
120
|
- opal/opal_vite/concerns/storable.rb
|
|
121
121
|
- opal/opal_vite/concerns/toastable.rb
|
|
122
|
+
- opal/opal_vite/concerns/vue_helpers.rb
|
|
122
123
|
homepage: https://github.com/stofu1234/opal-vite
|
|
123
124
|
licenses:
|
|
124
125
|
- MIT
|