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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8db189359fc8003771075a598fbeed0c2205ca52604fd829d77afe3c0b3a467
4
- data.tar.gz: e5446344e9a83c982fdfa94d4d31abd4b7511858704cc2e9f9d285ad9740b9c3
3
+ metadata.gz: bec8e4750b58937139e2cd64d5890a406f537b925995588c23d336340e998f46
4
+ data.tar.gz: 722c0d77adc2cf4d3110bc2653a7e5dced17554f8d0b102acb8e178a873b5d1d
5
5
  SHA512:
6
- metadata.gz: db1c7e4b591440cea077fb99285552f443301564b293f2a0cf0098750d514af3ac48684d820398ac588570ba71f6f1c1284b72c3b32d6f54f48d20c457a476eb
7
- data.tar.gz: fb9ff7728339e8edbcae2b9031c41f77ae2d28e68963b8c27368575d44a20935ff6393730d180579bb29d9a3786e43c1c6388223d0115b17c6d35b31245b64ff
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 FORMULA_PREFIXES_MAP[value.getbyte(0)]
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 FORMULA_PREFIXES_MAP[first_byte]
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.match?(escape_regex)
199
+ if value.empty?
200
+ buffer << '""'
201
+ elsif value.match?(escape_regex)
196
202
  buffer << '"' << value.gsub('"', '""') << '"'
197
203
  else
198
204
  buffer << value
@@ -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
- buffer = +""
89
- @cache_stack.push([buffer, {}].freeze)
90
- capturing_into(buffer, &)
91
- @cache_stack.pop
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 capturing_into(new_buffer)
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.capturing_into(+"") { __yield_content_with_args__(*args, &block) }
220
+ @_state.capture { __yield_content_with_args__(*args, &block) }
176
221
  else
177
- @_state.capturing_into(+"") { __yield_content__(&block) }
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(*args)
312
- return unless block_given?
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Phlex
4
- VERSION = "2.1.0"
4
+ VERSION = "2.1.2"
5
5
  end
data/lib/phlex.rb CHANGED
@@ -8,7 +8,6 @@ module Phlex
8
8
 
9
9
  autoload :Kit, "phlex/kit"
10
10
  autoload :FIFO, "phlex/fifo"
11
- autoload :Vanish, "phlex/vanish"
12
11
  autoload :Helpers, "phlex/helpers"
13
12
  autoload :FIFOCacheStore, "phlex/fifo_cache_store"
14
13
 
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.0
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-05 00:00:00.000000000 Z
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
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # @api private
4
- module Phlex::Vanish
5
- extend self
6
-
7
- def <<(anything)
8
- self
9
- end
10
-
11
- def bytesize
12
- 0
13
- end
14
-
15
- def dup
16
- self
17
- end
18
-
19
- def clear
20
- self
21
- end
22
- end