barefoot_js 0.18.0
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 +7 -0
- data/lib/barefoot_js/backend/erb.rb +123 -0
- data/lib/barefoot_js/dev_reload.rb +159 -0
- data/lib/barefoot_js/evaluator.rb +714 -0
- data/lib/barefoot_js/search_params.rb +63 -0
- data/lib/barefoot_js.rb +1155 -0
- metadata +51 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BarefootJS
|
|
4
|
+
# Request-scoped SSR view of the query string behind the reactive
|
|
5
|
+
# `searchParams()` environment signal (router v0.5, #1922). The framework
|
|
6
|
+
# integration builds one per request from the request URL and threads it
|
|
7
|
+
# into the template scope as `v[:searchParams]` (the camelCase JS name the
|
|
8
|
+
# adapters keep, like every other signal/prop var); the compiled ERB
|
|
9
|
+
# template reads it via `v[:searchParams].get('key')`.
|
|
10
|
+
#
|
|
11
|
+
# This runtime is template-engine- and framework-agnostic (Ruby stdlib
|
|
12
|
+
# only), matching the rest of BarefootJS, so it can ship standalone.
|
|
13
|
+
#
|
|
14
|
+
# Semantics mirror the browser's URLSearchParams#get exactly under the
|
|
15
|
+
# adapters' `?? -> ||=`-style lowering: get() returns the first value for a
|
|
16
|
+
# key, or `nil` when the key is absent. A present-but-empty value
|
|
17
|
+
# (`?sort=`) keeps the empty string -- the same distinction JS `??` draws
|
|
18
|
+
# between `null` and `''`.
|
|
19
|
+
class SearchParams
|
|
20
|
+
# Parse a raw query string into the reader. A leading '?' is tolerated,
|
|
21
|
+
# '+' decodes to a space, and %XX escapes are decoded -- mirroring
|
|
22
|
+
# URLSearchParams's application/x-www-form-urlencoded parsing. A
|
|
23
|
+
# malformed pair never raises; it simply contributes nothing, matching
|
|
24
|
+
# the browser's lenient parsing.
|
|
25
|
+
def initialize(query = '')
|
|
26
|
+
query ||= ''
|
|
27
|
+
query = query.sub(/\A\?/, '')
|
|
28
|
+
@values = Hash.new { |h, k| h[k] = [] }
|
|
29
|
+
query.split(/[&;]/).each do |pair|
|
|
30
|
+
next if pair.empty?
|
|
31
|
+
|
|
32
|
+
key, val = pair.split('=', 2)
|
|
33
|
+
key = decode(key)
|
|
34
|
+
val = val.nil? ? '' : decode(val)
|
|
35
|
+
@values[key] << val
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# First value for `key`, or `nil` when the key is absent (see the class
|
|
40
|
+
# docstring for why `nil` -- not '' -- is the right "missing" sentinel).
|
|
41
|
+
# A present-but-empty value returns ''.
|
|
42
|
+
def get(key)
|
|
43
|
+
vals = @values[key]
|
|
44
|
+
return nil if vals.nil? || vals.empty?
|
|
45
|
+
|
|
46
|
+
vals.first
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def decode(s)
|
|
52
|
+
s = (s || '').dup
|
|
53
|
+
s.tr!('+', ' ')
|
|
54
|
+
# %XX -> raw octet, then interpret the octet stream as UTF-8 (what
|
|
55
|
+
# URLSearchParams does). A byte run that isn't valid UTF-8 is
|
|
56
|
+
# replaced rather than raising (lenient parsing, mirrors the Perl
|
|
57
|
+
# port's leave-as-is policy as closely as Ruby's String#encode allows).
|
|
58
|
+
bytes = s.gsub(/%([0-9A-Fa-f]{2})/) { [Regexp.last_match(1)].pack('H2') }
|
|
59
|
+
bytes.force_encoding('UTF-8')
|
|
60
|
+
bytes.valid_encoding? ? bytes : bytes.force_encoding('ASCII-8BIT').encode('UTF-8', invalid: :replace, undef: :replace)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|