phlex 1.5.1 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of phlex might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/phlex/context.rb +22 -0
- data/lib/phlex/element_clobbering_guard.rb +3 -3
- data/lib/phlex/elements.rb +23 -22
- data/lib/phlex/html.rb +1 -1
- data/lib/phlex/sgml.rb +49 -46
- data/lib/phlex/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ada5b83ea9c2fbd305a249ffa81a43c9e9da26a7c87860dac62e594a43341001
|
4
|
+
data.tar.gz: e728f6c83cae97671bf4092f7bd384c93611d51158f613a75518d1109a669942
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f8b512d89247318f657482d3eeb1ba9fd0c1de73edcf4f3c5d0b6ff843bbd0bbca6d47d9a957780a1831e70b67ec8c2d1d1beba10a00bc9546a8966f67d545d
|
7
|
+
data.tar.gz: a5a780a277bc36e8fa028af0ccdd3b985189ae6c49241d737b9d86e4f37fa43bbbfc8e4cb1736914735a35821a741c8fcc964f45c8b82b96c5389053c72b2684
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Phlex::Context
|
4
|
+
def initialize
|
5
|
+
@target = +""
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_accessor :target
|
9
|
+
|
10
|
+
def with_target(new_target)
|
11
|
+
original_target = @target
|
12
|
+
|
13
|
+
begin
|
14
|
+
@target = new_target
|
15
|
+
yield
|
16
|
+
ensure
|
17
|
+
@target = original_target
|
18
|
+
end
|
19
|
+
|
20
|
+
new_target
|
21
|
+
end
|
22
|
+
end
|
@@ -3,11 +3,11 @@
|
|
3
3
|
module Phlex
|
4
4
|
module ElementClobberingGuard
|
5
5
|
def method_added(method_name)
|
6
|
-
if method_name[0] == "_" &&
|
6
|
+
if method_name[0] == "_" && element_method?(method_name[1..].to_sym)
|
7
7
|
raise NameError, "👋 Redefining the method `#{name}##{method_name}` is not a good idea."
|
8
|
+
else
|
9
|
+
super
|
8
10
|
end
|
9
|
-
|
10
|
-
super
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
data/lib/phlex/elements.rb
CHANGED
@@ -5,45 +5,44 @@ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.0")
|
|
5
5
|
end
|
6
6
|
|
7
7
|
module Phlex::Elements
|
8
|
-
|
9
|
-
|
10
|
-
.lazy
|
11
|
-
.map(&:to_s)
|
12
|
-
.select { |m| m.start_with?("__phlex_") }
|
13
|
-
.map { |m| m[8...-2].to_sym }
|
8
|
+
def registered_elements
|
9
|
+
@registered_elements ||= Concurrent::Map.new
|
14
10
|
end
|
15
11
|
|
16
12
|
def register_element(element, tag: element.name.tr("_", "-"))
|
17
13
|
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
18
14
|
# frozen_string_literal: true
|
19
15
|
|
20
|
-
|
16
|
+
|
17
|
+
def #{element}(**attributes, &block)
|
18
|
+
target = @_context.target
|
19
|
+
|
21
20
|
if attributes.length > 0 # with attributes
|
22
21
|
if block_given? # with content block
|
23
|
-
|
22
|
+
target << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[respond_to?(:process_attributes) ? (attributes.hash + self.class.hash) : attributes.hash] || __attributes__(**attributes)) << ">"
|
24
23
|
yield_content(&block)
|
25
|
-
|
24
|
+
target << "</#{tag}>"
|
26
25
|
else # without content block
|
27
|
-
|
26
|
+
target << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[respond_to?(:process_attributes) ? (attributes.hash + self.class.hash) : attributes.hash] || __attributes__(**attributes)) << "></#{tag}>"
|
28
27
|
end
|
29
28
|
else # without attributes
|
30
29
|
if block_given? # with content block
|
31
|
-
|
30
|
+
target << "<#{tag}>"
|
32
31
|
yield_content(&block)
|
33
|
-
|
32
|
+
target << "</#{tag}>"
|
34
33
|
else # without content block
|
35
|
-
|
34
|
+
target << "<#{tag}></#{tag}>"
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
38
|
nil
|
40
39
|
end
|
41
40
|
|
42
|
-
alias_method :_#{element},
|
43
|
-
alias_method :#{element}, :__phlex_#{element}__
|
44
|
-
private :__phlex_#{element}__
|
41
|
+
alias_method :_#{element}, :#{element}
|
45
42
|
RUBY
|
46
43
|
|
44
|
+
registered_elements[element] = tag
|
45
|
+
|
47
46
|
element
|
48
47
|
end
|
49
48
|
|
@@ -51,21 +50,23 @@ module Phlex::Elements
|
|
51
50
|
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
52
51
|
# frozen_string_literal: true
|
53
52
|
|
54
|
-
def
|
53
|
+
def #{element}(**attributes)
|
54
|
+
target = @_context.target
|
55
|
+
|
55
56
|
if attributes.length > 0 # with attributes
|
56
|
-
|
57
|
+
target << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[respond_to?(:process_attributes) ? (attributes.hash + self.class.hash) : attributes.hash] || __attributes__(**attributes)) << ">"
|
57
58
|
else # without attributes
|
58
|
-
|
59
|
+
target << "<#{tag}>"
|
59
60
|
end
|
60
61
|
|
61
62
|
nil
|
62
63
|
end
|
63
64
|
|
64
|
-
alias_method :_#{element},
|
65
|
-
alias_method :#{element}, :__phlex_#{element}__
|
66
|
-
private :__phlex_#{element}__
|
65
|
+
alias_method :_#{element}, :#{element}
|
67
66
|
RUBY
|
68
67
|
|
68
|
+
registered_elements[element] = tag
|
69
|
+
|
69
70
|
element
|
70
71
|
end
|
71
72
|
end
|
data/lib/phlex/html.rb
CHANGED
data/lib/phlex/sgml.rb
CHANGED
@@ -12,8 +12,6 @@ module Phlex
|
|
12
12
|
new(...).call
|
13
13
|
end
|
14
14
|
|
15
|
-
alias_method :render, :call
|
16
|
-
|
17
15
|
# Create a new instance of the component.
|
18
16
|
# @note The block will not be delegated to the initializer. Instead, it will be provided to `template` when rendering.
|
19
17
|
def new(*args, **kwargs, &block)
|
@@ -31,28 +29,39 @@ module Phlex
|
|
31
29
|
alias_method :__attributes__, :__final_attributes__
|
32
30
|
alias_method :call, :__final_call__
|
33
31
|
end
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
def element_method?(method_name)
|
35
|
+
return false unless instance_methods.include?(method_name)
|
36
|
+
|
37
|
+
owner = instance_method(method_name).owner
|
38
|
+
|
39
|
+
return true if owner.is_a?(Phlex::Elements) && owner.registered_elements[method_name]
|
40
|
+
|
41
|
+
false
|
42
|
+
end
|
34
43
|
end
|
35
44
|
|
36
45
|
# Renders the view and returns the buffer. The default buffer is a mutable String.
|
37
|
-
def call(buffer = nil,
|
38
|
-
__final_call__(buffer,
|
46
|
+
def call(buffer = nil, context: Phlex::Context.new, view_context: nil, parent: nil, &block)
|
47
|
+
__final_call__(buffer, context: context, view_context: view_context, parent: parent, &block).tap do
|
39
48
|
self.class.rendered_at_least_once!
|
40
49
|
end
|
41
50
|
end
|
42
51
|
|
43
52
|
# @api private
|
44
|
-
def __final_call__(buffer = nil,
|
45
|
-
@
|
53
|
+
def __final_call__(buffer = nil, context: Phlex::Context.new, view_context: nil, parent: nil, &block)
|
54
|
+
@_context = context
|
46
55
|
@_view_context = view_context
|
47
56
|
@_parent = parent
|
48
57
|
|
49
58
|
block ||= @_content_block
|
50
59
|
|
51
|
-
return buffer || target unless render?
|
60
|
+
return buffer || context.target unless render?
|
52
61
|
|
53
62
|
around_template do
|
54
63
|
if block
|
55
|
-
if DeferredRender
|
64
|
+
if is_a?(DeferredRender)
|
56
65
|
__vanish__(self, &block)
|
57
66
|
template
|
58
67
|
else
|
@@ -69,7 +78,7 @@ module Phlex
|
|
69
78
|
end
|
70
79
|
end
|
71
80
|
|
72
|
-
buffer ? (buffer << target) : target
|
81
|
+
buffer ? (buffer << context.target) : context.target
|
73
82
|
end
|
74
83
|
|
75
84
|
# Render another view
|
@@ -78,11 +87,15 @@ module Phlex
|
|
78
87
|
def render(renderable, &block)
|
79
88
|
case renderable
|
80
89
|
when Phlex::SGML
|
81
|
-
renderable.call(
|
90
|
+
renderable.call(context: @_context, view_context: @_view_context, parent: self, &block)
|
82
91
|
when Class
|
83
92
|
if renderable < Phlex::SGML
|
84
|
-
renderable.new.call(
|
93
|
+
renderable.new.call(context: @_context, view_context: @_view_context, parent: self, &block)
|
85
94
|
end
|
95
|
+
when Enumerable
|
96
|
+
renderable.each { |r| render(r, &block) }
|
97
|
+
when Proc
|
98
|
+
yield_content(&renderable)
|
86
99
|
else
|
87
100
|
raise ArgumentError, "You can't render a #{renderable}."
|
88
101
|
end
|
@@ -95,16 +108,16 @@ module Phlex
|
|
95
108
|
def plain(content)
|
96
109
|
case content
|
97
110
|
when String
|
98
|
-
@
|
111
|
+
@_context.target << ERB::Escape.html_escape(content)
|
99
112
|
when Symbol
|
100
|
-
@
|
113
|
+
@_context.target << ERB::Escape.html_escape(content.name)
|
101
114
|
when Integer
|
102
|
-
@
|
115
|
+
@_context.target << ERB::Escape.html_escape(content.to_s)
|
103
116
|
when nil
|
104
117
|
nil
|
105
118
|
else
|
106
119
|
if (formatted_object = format_object(content))
|
107
|
-
@
|
120
|
+
@_context.target << ERB::Escape.html_escape(formatted_object)
|
108
121
|
end
|
109
122
|
end
|
110
123
|
|
@@ -114,11 +127,13 @@ module Phlex
|
|
114
127
|
# Output a whitespace character. This is useful for getting inline elements to wrap. If you pass a block, a whitespace will be output before and after yielding the block.
|
115
128
|
# @return [nil]
|
116
129
|
def whitespace
|
117
|
-
|
130
|
+
target = @_context.target
|
131
|
+
|
132
|
+
target << " "
|
118
133
|
|
119
134
|
if block_given?
|
120
135
|
yield
|
121
|
-
|
136
|
+
target << " "
|
122
137
|
end
|
123
138
|
|
124
139
|
nil
|
@@ -127,9 +142,11 @@ module Phlex
|
|
127
142
|
# Output an HTML comment.
|
128
143
|
# @return [nil]
|
129
144
|
def comment(&block)
|
130
|
-
|
145
|
+
target = @_context.target
|
146
|
+
|
147
|
+
target << "<!-- "
|
131
148
|
yield_content(&block)
|
132
|
-
|
149
|
+
target << " -->"
|
133
150
|
|
134
151
|
nil
|
135
152
|
end
|
@@ -140,27 +157,17 @@ module Phlex
|
|
140
157
|
def unsafe_raw(content = nil)
|
141
158
|
return nil unless content
|
142
159
|
|
143
|
-
@
|
160
|
+
@_context.target << content
|
144
161
|
nil
|
145
162
|
end
|
146
163
|
|
147
164
|
# Capture a block of output as a String.
|
165
|
+
# @note This only works if the block's receiver is the current component or the block returns a String.
|
148
166
|
# @return [String]
|
149
167
|
def capture(&block)
|
150
|
-
return "" unless
|
168
|
+
return "" unless block
|
151
169
|
|
152
|
-
|
153
|
-
@_target.clear
|
154
|
-
|
155
|
-
begin
|
156
|
-
yield_content(&block)
|
157
|
-
new_buffer_content = @_target.dup
|
158
|
-
ensure
|
159
|
-
@_target.clear
|
160
|
-
@_target << original_buffer_content
|
161
|
-
end
|
162
|
-
|
163
|
-
new_buffer_content.is_a?(String) ? new_buffer_content : ""
|
170
|
+
@_context.with_target(+"") { yield_content(&block) }
|
164
171
|
end
|
165
172
|
|
166
173
|
# Like `capture` but the output is vanished into a BlackHole buffer.
|
@@ -169,14 +176,7 @@ module Phlex
|
|
169
176
|
private def __vanish__(*args)
|
170
177
|
return unless block_given?
|
171
178
|
|
172
|
-
|
173
|
-
|
174
|
-
begin
|
175
|
-
@_target = BlackHole
|
176
|
-
yield(*args)
|
177
|
-
ensure
|
178
|
-
@_target = original_buffer
|
179
|
-
end
|
179
|
+
@_context.with_target(BlackHole) { yield(*args) }
|
180
180
|
|
181
181
|
nil
|
182
182
|
end
|
@@ -223,10 +223,11 @@ module Phlex
|
|
223
223
|
private def yield_content
|
224
224
|
return unless block_given?
|
225
225
|
|
226
|
-
|
227
|
-
content = yield(self)
|
226
|
+
target = @_context.target
|
228
227
|
|
229
|
-
|
228
|
+
original_length = target.length
|
229
|
+
content = yield(self)
|
230
|
+
plain(content) if original_length == target.length
|
230
231
|
|
231
232
|
nil
|
232
233
|
end
|
@@ -236,9 +237,11 @@ module Phlex
|
|
236
237
|
private def yield_content_with_args(*args)
|
237
238
|
return unless block_given?
|
238
239
|
|
239
|
-
|
240
|
+
target = @_context.target
|
241
|
+
|
242
|
+
original_length = target.length
|
240
243
|
content = yield(*args)
|
241
|
-
plain(content) if original_length ==
|
244
|
+
plain(content) if original_length == target.length
|
242
245
|
|
243
246
|
nil
|
244
247
|
end
|
data/lib/phlex/version.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: 1.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03-
|
11
|
+
date: 2023-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/phlex.rb
|
77
77
|
- lib/phlex/black_hole.rb
|
78
78
|
- lib/phlex/callable.rb
|
79
|
+
- lib/phlex/context.rb
|
79
80
|
- lib/phlex/deferred_render.rb
|
80
81
|
- lib/phlex/element_clobbering_guard.rb
|
81
82
|
- lib/phlex/elements.rb
|