phlex 2.1.0 → 2.1.2
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/phlex/csv.rb +9 -3
- data/lib/phlex/sgml/state.rb +12 -15
- data/lib/phlex/sgml.rb +53 -11
- data/lib/phlex/version.rb +1 -1
- data/lib/phlex.rb +0 -1
- metadata +2 -3
- data/lib/phlex/vanish.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bec8e4750b58937139e2cd64d5890a406f537b925995588c23d336340e998f46
|
4
|
+
data.tar.gz: 722c0d77adc2cf4d3110bc2653a7e5dced17554f8d0b102acb8e178a873b5d1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2a6ea6722f8576a413d60f4918c7505069c24a5f1c26a0ff2514d5a1b03206b64688d8ba41b7457f51070ac710dfe0dabe7f5818e139c0cfffde1e513da1244
|
7
|
+
data.tar.gz: 52f9f64241f7d957b7e25dabb8598a4bd1c2a343a3c2a0dd2264bc23dc6d057c272d2b1bae772b80d9dbe071af3cc46f21b1480dabf414c154f17789dbda368d
|
data/lib/phlex/csv.rb
CHANGED
@@ -168,7 +168,9 @@ class Phlex::CSV
|
|
168
168
|
value = value.strip
|
169
169
|
|
170
170
|
if escape_csv_injection
|
171
|
-
if
|
171
|
+
if value.empty?
|
172
|
+
buffer << value
|
173
|
+
elsif FORMULA_PREFIXES_MAP[value.getbyte(0)]
|
172
174
|
value.gsub!('"', '""')
|
173
175
|
buffer << '"\'' << value << '"'
|
174
176
|
elsif value.match?(escape_regex)
|
@@ -184,7 +186,9 @@ class Phlex::CSV
|
|
184
186
|
if escape_csv_injection
|
185
187
|
first_byte = value.getbyte(0)
|
186
188
|
|
187
|
-
if
|
189
|
+
if value.empty?
|
190
|
+
buffer << '""'
|
191
|
+
elsif FORMULA_PREFIXES_MAP[first_byte]
|
188
192
|
buffer << '"\'' << value.gsub('"', '""') << '"'
|
189
193
|
elsif value.match?(escape_regex)
|
190
194
|
buffer << '"' << value.gsub('"', '""') << '"'
|
@@ -192,7 +196,9 @@ class Phlex::CSV
|
|
192
196
|
buffer << value
|
193
197
|
end
|
194
198
|
else # not escaping CSV injection
|
195
|
-
if value.
|
199
|
+
if value.empty?
|
200
|
+
buffer << '""'
|
201
|
+
elsif value.match?(escape_regex)
|
196
202
|
buffer << '"' << value.gsub('"', '""') << '"'
|
197
203
|
else
|
198
204
|
buffer << value
|
data/lib/phlex/sgml/state.rb
CHANGED
@@ -14,16 +14,7 @@ class Phlex::SGML::State
|
|
14
14
|
|
15
15
|
attr_accessor :capturing, :user_context
|
16
16
|
|
17
|
-
attr_reader :fragments, :fragment_depth, :output_buffer
|
18
|
-
|
19
|
-
def buffer
|
20
|
-
case @buffer
|
21
|
-
when Proc
|
22
|
-
@buffer.call
|
23
|
-
else
|
24
|
-
@buffer
|
25
|
-
end
|
26
|
-
end
|
17
|
+
attr_reader :fragments, :fragment_depth, :output_buffer, :buffer
|
27
18
|
|
28
19
|
def around_render(component)
|
29
20
|
stack = @stack
|
@@ -85,17 +76,23 @@ class Phlex::SGML::State
|
|
85
76
|
end
|
86
77
|
|
87
78
|
def caching(&)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
79
|
+
result = nil
|
80
|
+
|
81
|
+
capture do
|
82
|
+
@cache_stack.push([buffer, {}].freeze)
|
83
|
+
yield
|
84
|
+
result = @cache_stack.pop
|
85
|
+
end
|
86
|
+
|
87
|
+
result
|
92
88
|
end
|
93
89
|
|
94
90
|
def caching?
|
95
91
|
@cache_stack.length > 0
|
96
92
|
end
|
97
93
|
|
98
|
-
def
|
94
|
+
def capture
|
95
|
+
new_buffer = +""
|
99
96
|
original_buffer = @buffer
|
100
97
|
original_capturing = @capturing
|
101
98
|
original_fragments = @fragments
|
data/lib/phlex/sgml.rb
CHANGED
@@ -5,6 +5,17 @@ class Phlex::SGML
|
|
5
5
|
UNSAFE_ATTRIBUTES = Set.new(%w[srcdoc sandbox http-equiv]).freeze
|
6
6
|
REF_ATTRIBUTES = Set.new(%w[href src action formaction lowsrc dynsrc background ping]).freeze
|
7
7
|
|
8
|
+
ERBCompiler = ERB::Compiler.new("<>").tap do |compiler|
|
9
|
+
compiler.pre_cmd = [""]
|
10
|
+
compiler.put_cmd = "@_state.buffer.<<"
|
11
|
+
compiler.insert_cmd = "__implicit_output__"
|
12
|
+
compiler.post_cmd = ["nil"]
|
13
|
+
|
14
|
+
def compiler.add_insert_cmd(out, content)
|
15
|
+
out.push("#{@insert_cmd}((#{content}))")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
8
19
|
autoload :Elements, "phlex/sgml/elements"
|
9
20
|
autoload :SafeObject, "phlex/sgml/safe_object"
|
10
21
|
autoload :SafeValue, "phlex/sgml/safe_value"
|
@@ -29,6 +40,40 @@ class Phlex::SGML
|
|
29
40
|
super
|
30
41
|
end
|
31
42
|
end
|
43
|
+
|
44
|
+
def erb(method_name, erb = nil, locals: nil, &block)
|
45
|
+
loc = caller_locations(1, 1)[0]
|
46
|
+
path = loc.path.delete_suffix(".rb")
|
47
|
+
file = loc.path
|
48
|
+
line = loc.lineno - 1
|
49
|
+
|
50
|
+
unless erb
|
51
|
+
method_path = "#{path}/#{method_name}.html.erb"
|
52
|
+
sidecar_path = "#{path}.html.erb"
|
53
|
+
|
54
|
+
if File.exist?(method_path)
|
55
|
+
erb = File.read(method_path)
|
56
|
+
file = method_path
|
57
|
+
line = 1
|
58
|
+
elsif method_name == :view_template && File.exist?(sidecar_path)
|
59
|
+
erb = File.read(sidecar_path)
|
60
|
+
file = sidecar_path
|
61
|
+
line = 1
|
62
|
+
else
|
63
|
+
raise Phlex::RuntimeError.new(<<~MESSAGE)
|
64
|
+
No ERB template found for #{method_name}
|
65
|
+
MESSAGE
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
code, _enc = ERBCompiler.compile(erb)
|
70
|
+
|
71
|
+
class_eval(<<~RUBY, file, line)
|
72
|
+
def #{method_name} #{locals}
|
73
|
+
#{code}
|
74
|
+
end
|
75
|
+
RUBY
|
76
|
+
end
|
32
77
|
end
|
33
78
|
|
34
79
|
def view_template
|
@@ -172,9 +217,9 @@ class Phlex::SGML
|
|
172
217
|
return "" unless block
|
173
218
|
|
174
219
|
if args.length > 0
|
175
|
-
@_state.
|
220
|
+
@_state.capture { __yield_content_with_args__(*args, &block) }
|
176
221
|
else
|
177
|
-
@_state.
|
222
|
+
@_state.capture { __yield_content__(&block) }
|
178
223
|
end
|
179
224
|
end
|
180
225
|
|
@@ -253,6 +298,8 @@ class Phlex::SGML
|
|
253
298
|
].freeze
|
254
299
|
|
255
300
|
low_level_cache(full_key, **, &content)
|
301
|
+
|
302
|
+
nil
|
256
303
|
end
|
257
304
|
|
258
305
|
# Cache a block of content where you control the entire cache key.
|
@@ -286,6 +333,8 @@ class Phlex::SGML
|
|
286
333
|
end
|
287
334
|
end
|
288
335
|
end
|
336
|
+
|
337
|
+
nil
|
289
338
|
end
|
290
339
|
|
291
340
|
def json_escape(string)
|
@@ -308,15 +357,8 @@ class Phlex::SGML
|
|
308
357
|
false
|
309
358
|
end
|
310
359
|
|
311
|
-
def vanish(
|
312
|
-
|
313
|
-
|
314
|
-
if args.length > 0
|
315
|
-
@_state.capturing_into(Phlex::Vanish) { yield(*args) }
|
316
|
-
else
|
317
|
-
@_state.capturing_into(Phlex::Vanish) { yield(self) }
|
318
|
-
end
|
319
|
-
|
360
|
+
def vanish(...)
|
361
|
+
capture(...)
|
320
362
|
nil
|
321
363
|
end
|
322
364
|
|
data/lib/phlex/version.rb
CHANGED
data/lib/phlex.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phlex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
8
8
|
- Will Cosgrove
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Build HTML, SVG and CSV views with Ruby classes.
|
14
14
|
email:
|
@@ -40,7 +40,6 @@ files:
|
|
40
40
|
- lib/phlex/sgml/state.rb
|
41
41
|
- lib/phlex/svg.rb
|
42
42
|
- lib/phlex/svg/standard_elements.rb
|
43
|
-
- lib/phlex/vanish.rb
|
44
43
|
- lib/phlex/version.rb
|
45
44
|
homepage: https://www.phlex.fun
|
46
45
|
licenses:
|
data/lib/phlex/vanish.rb
DELETED