phlex 2.0.0.rc2 → 2.0.1
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/README.md +7 -23
- data/lib/phlex/errors/runtime_error.rb +5 -0
- data/lib/phlex/fifo_cache_store.rb +3 -1
- data/lib/phlex/html/standard_elements.rb +517 -828
- data/lib/phlex/html/void_elements.rb +47 -80
- data/lib/phlex/html.rb +71 -9
- data/lib/phlex/kit.rb +11 -2
- data/lib/phlex/sgml/elements.rb +8 -8
- data/lib/phlex/sgml/state.rb +2 -3
- data/lib/phlex/sgml.rb +24 -18
- data/lib/phlex/svg.rb +39 -0
- data/lib/phlex/version.rb +1 -1
- data/lib/phlex.rb +45 -12
- metadata +7 -11
- data/lib/phlex/null_cache_store.rb +0 -9
- data/lib/phlex/testing/capybara.rb +0 -28
- data/lib/phlex/testing/nokogiri.rb +0 -19
- data/lib/phlex/testing/nokolexbor.rb +0 -19
- data/lib/phlex/testing/sgml.rb +0 -9
- data/lib/phlex/testing.rb +0 -10
@@ -5,95 +5,62 @@ module Phlex::HTML::VoidElements
|
|
5
5
|
extend Phlex::SGML::Elements
|
6
6
|
|
7
7
|
# Outputs an `<area>` tag.
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
**attributes
|
13
|
-
) = nil
|
8
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/area)
|
9
|
+
# [Spec](https://html.spec.whatwg.org/#the-area-element)
|
10
|
+
__register_void_element__ def area(**attributes) = nil
|
11
|
+
|
14
12
|
# Outputs a `<base>` tag.
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
id: nil,
|
20
|
-
target: nil,
|
21
|
-
**attributes
|
22
|
-
) = nil
|
13
|
+
# [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)
|
14
|
+
# [Spec](https://html.spec.whatwg.org/#the-base-element)
|
15
|
+
__register_void_element__ def base(**attributes) = nil
|
16
|
+
|
23
17
|
# Outputs a `<br>` tag.
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
**attributes
|
29
|
-
) = nil
|
18
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/br)
|
19
|
+
# [Spec](https://html.spec.whatwg.org/#the-br-element)
|
20
|
+
__register_void_element__ def br(**attributes) = nil
|
21
|
+
|
30
22
|
# Outputs a `<col>` tag.
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
**attributes
|
36
|
-
) = nil
|
23
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/col)
|
24
|
+
# [Spec](https://html.spec.whatwg.org/#the-col-element)
|
25
|
+
__register_void_element__ def col(**attributes) = nil
|
26
|
+
|
37
27
|
# Outputs an `<embed>` tag.
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
**attributes
|
43
|
-
) = nil
|
28
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/embed)
|
29
|
+
# [Spec](https://html.spec.whatwg.org/#the-embed-element)
|
30
|
+
__register_void_element__ def embed(**attributes) = nil
|
31
|
+
|
44
32
|
# Outputs an `<hr>` tag.
|
45
|
-
#
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
**attributes
|
50
|
-
) = nil
|
33
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/hr)
|
34
|
+
# [Spec](https://html.spec.whatwg.org/#the-hr-element)
|
35
|
+
__register_void_element__ def hr(**attributes) = nil
|
36
|
+
|
51
37
|
# Outputs an `<img>` tag.
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
id: nil,
|
57
|
-
src: nil,
|
58
|
-
**attributes
|
59
|
-
) = nil
|
38
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/img)
|
39
|
+
# [Spec](https://html.spec.whatwg.org/#the-img-element)
|
40
|
+
__register_void_element__ def img(**attributes) = nil
|
41
|
+
|
60
42
|
# Outputs an `<input>` tag.
|
61
|
-
#
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
name: nil,
|
66
|
-
type: nil,
|
67
|
-
**attributes
|
68
|
-
) = nil
|
43
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/input)
|
44
|
+
# [Spec](https://html.spec.whatwg.org/#the-input-element)
|
45
|
+
__register_void_element__ def input(**attributes) = nil
|
46
|
+
|
69
47
|
# Outputs a `<link>` tag.
|
70
|
-
#
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
**attributes
|
75
|
-
) = nil
|
48
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/link)
|
49
|
+
# [Spec](https://html.spec.whatwg.org/#the-link-element)
|
50
|
+
__register_void_element__ def link(**attributes) = nil
|
51
|
+
|
76
52
|
# Outputs a `<meta>` tag.
|
77
|
-
#
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
id: nil,
|
82
|
-
name: nil,
|
83
|
-
**attributes
|
84
|
-
) = nil
|
53
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/meta)
|
54
|
+
# [Spec](https://html.spec.whatwg.org/#the-meta-element)
|
55
|
+
__register_void_element__ def meta(**attributes) = nil
|
56
|
+
|
85
57
|
# Outputs a `<source>` tag.
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
**attributes
|
91
|
-
) = nil
|
58
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/source)
|
59
|
+
# [Spec](https://html.spec.whatwg.org/#the-source-element)
|
60
|
+
__register_void_element__ def source(**attributes) = nil
|
61
|
+
|
92
62
|
# Outputs a `<track>` tag.
|
93
|
-
#
|
94
|
-
|
95
|
-
|
96
|
-
id: nil,
|
97
|
-
**attributes
|
98
|
-
) = nil
|
63
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/HTML/Element/track)
|
64
|
+
# [Spec](https://html.spec.whatwg.org/#the-track-element)
|
65
|
+
__register_void_element__ def track(**attributes) = nil
|
99
66
|
end
|
data/lib/phlex/html.rb
CHANGED
@@ -16,26 +16,88 @@ class Phlex::HTML < Phlex::SGML
|
|
16
16
|
nil
|
17
17
|
end
|
18
18
|
|
19
|
-
# Outputs an `<svg>` tag
|
20
|
-
#
|
21
|
-
#
|
22
|
-
|
19
|
+
# Outputs an `<svg>` tag.
|
20
|
+
#
|
21
|
+
# [MDN Docs](https://developer.mozilla.org/docs/Web/SVG/Element/svg)
|
22
|
+
# [Spec](https://html.spec.whatwg.org/#the-svg-element)
|
23
|
+
def svg(*, **, &)
|
23
24
|
if block_given?
|
24
|
-
super
|
25
|
-
render Phlex::SVG.new do |svg|
|
26
|
-
yield(svg)
|
27
|
-
end
|
28
|
-
end
|
25
|
+
super { render Phlex::SVG.new(&) }
|
29
26
|
else
|
30
27
|
super
|
31
28
|
end
|
32
29
|
end
|
33
30
|
|
31
|
+
# Override to provide a filename for the HTML file
|
34
32
|
def filename
|
35
33
|
nil
|
36
34
|
end
|
37
35
|
|
36
|
+
# Returns the string "text/html"
|
38
37
|
def content_type
|
39
38
|
"text/html"
|
40
39
|
end
|
40
|
+
|
41
|
+
# Output an HTML tag dynamically, e.g:
|
42
|
+
#
|
43
|
+
# ```ruby
|
44
|
+
# @tag_name = :h1
|
45
|
+
# tag(@tag_name, class: "title")
|
46
|
+
# ```
|
47
|
+
def tag(name, **attributes, &)
|
48
|
+
state = @_state
|
49
|
+
block_given = block_given?
|
50
|
+
buffer = state.buffer
|
51
|
+
|
52
|
+
unless state.should_render?
|
53
|
+
yield(self) if block_given
|
54
|
+
return nil
|
55
|
+
end
|
56
|
+
|
57
|
+
unless Symbol === name
|
58
|
+
raise Phlex::ArgumentError.new("Expected the tag name to be a Symbol.")
|
59
|
+
end
|
60
|
+
|
61
|
+
if (tag = StandardElements.__registered_elements__[name]) || (tag = name.name.tr("_", "-")).include?("-")
|
62
|
+
if attributes.length > 0 # with attributes
|
63
|
+
if block_given # with content block
|
64
|
+
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
|
65
|
+
if tag == "svg"
|
66
|
+
render Phlex::SVG.new(&)
|
67
|
+
else
|
68
|
+
__yield_content__(&)
|
69
|
+
end
|
70
|
+
buffer << "</#{tag}>"
|
71
|
+
else # without content
|
72
|
+
buffer << "<#{tag}" << (::Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << "></#{tag}>"
|
73
|
+
end
|
74
|
+
else # without attributes
|
75
|
+
if block_given # with content block
|
76
|
+
buffer << ("<#{tag}>")
|
77
|
+
if tag == "svg"
|
78
|
+
render Phlex::SVG.new(&)
|
79
|
+
else
|
80
|
+
__yield_content__(&)
|
81
|
+
end
|
82
|
+
buffer << "</#{tag}>"
|
83
|
+
else # without content
|
84
|
+
buffer << "<#{tag}></#{tag}>"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
elsif (tag = VoidElements.__registered_elements__[name])
|
88
|
+
if block_given
|
89
|
+
raise Phlex::ArgumentError.new("Void elements cannot have content blocks.")
|
90
|
+
end
|
91
|
+
|
92
|
+
if attributes.length > 0 # with attributes
|
93
|
+
buffer << "<#{tag}" << (::Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
|
94
|
+
else # without attributes
|
95
|
+
buffer << "<#{tag}>"
|
96
|
+
end
|
97
|
+
|
98
|
+
nil
|
99
|
+
else
|
100
|
+
raise Phlex::ArgumentError.new("Invalid HTML tag: #{name}")
|
101
|
+
end
|
102
|
+
end
|
41
103
|
end
|
data/lib/phlex/kit.rb
CHANGED
@@ -24,7 +24,16 @@ module Phlex::Kit
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.extended(mod)
|
27
|
-
mod
|
27
|
+
case mod
|
28
|
+
when Class
|
29
|
+
raise Phlex::ArgumentError.new(<<~MESSAGE)
|
30
|
+
`Phlex::Kit` was extended into #{mod.name}.
|
31
|
+
|
32
|
+
You should only extend modules with `Phlex::Kit` as it is not compatible with classes.
|
33
|
+
MESSAGE
|
34
|
+
else
|
35
|
+
mod.include(LazyLoader)
|
36
|
+
end
|
28
37
|
end
|
29
38
|
|
30
39
|
def method_missing(name, ...)
|
@@ -52,7 +61,7 @@ module Phlex::Kit
|
|
52
61
|
case constant
|
53
62
|
when Class
|
54
63
|
if constant < Phlex::SGML
|
55
|
-
constant.include(
|
64
|
+
constant.include(me)
|
56
65
|
|
57
66
|
constant = nil
|
58
67
|
|
data/lib/phlex/sgml/elements.rb
CHANGED
@@ -27,14 +27,14 @@ module Phlex::SGML::Elements
|
|
27
27
|
content = yield(self)
|
28
28
|
if original_length == buffer.bytesize
|
29
29
|
case content
|
30
|
-
when
|
31
|
-
|
30
|
+
when ::Phlex::SGML::SafeObject
|
31
|
+
buffer << content.to_s
|
32
32
|
when String
|
33
33
|
buffer << ::Phlex::Escape.html_escape(content)
|
34
34
|
when Symbol
|
35
35
|
buffer << ::Phlex::Escape.html_escape(content.name)
|
36
|
-
when
|
37
|
-
|
36
|
+
when nil
|
37
|
+
nil
|
38
38
|
else
|
39
39
|
if (formatted_object = format_object(content))
|
40
40
|
buffer << ::Phlex::Escape.html_escape(formatted_object)
|
@@ -54,14 +54,14 @@ module Phlex::SGML::Elements
|
|
54
54
|
content = yield(self)
|
55
55
|
if original_length == buffer.bytesize
|
56
56
|
case content
|
57
|
-
when
|
58
|
-
|
57
|
+
when ::Phlex::SGML::SafeObject
|
58
|
+
buffer << content.to_s
|
59
59
|
when String
|
60
60
|
buffer << ::Phlex::Escape.html_escape(content)
|
61
61
|
when Symbol
|
62
62
|
buffer << ::Phlex::Escape.html_escape(content.name)
|
63
|
-
when
|
64
|
-
|
63
|
+
when nil
|
64
|
+
nil
|
65
65
|
else
|
66
66
|
if (formatted_object = format_object(content))
|
67
67
|
buffer << ::Phlex::Escape.html_escape(formatted_object)
|
data/lib/phlex/sgml/state.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Phlex::SGML::State
|
4
|
-
def initialize(user_context: {},
|
4
|
+
def initialize(user_context: {}, output_buffer:, fragments:)
|
5
5
|
@buffer = +""
|
6
6
|
@capturing = false
|
7
7
|
@user_context = user_context
|
@@ -9,13 +9,12 @@ class Phlex::SGML::State
|
|
9
9
|
@fragment_depth = 0
|
10
10
|
@cache_stack = []
|
11
11
|
@halt_signal = nil
|
12
|
-
@view_context = view_context
|
13
12
|
@output_buffer = output_buffer
|
14
13
|
end
|
15
14
|
|
16
15
|
attr_accessor :buffer, :capturing, :user_context
|
17
16
|
|
18
|
-
attr_reader :fragments, :fragment_depth, :
|
17
|
+
attr_reader :fragments, :fragment_depth, :output_buffer
|
19
18
|
|
20
19
|
def around_render(component)
|
21
20
|
stack = @stack
|
data/lib/phlex/sgml.rb
CHANGED
@@ -43,10 +43,9 @@ class Phlex::SGML
|
|
43
43
|
proc { |c| c.render(self) }
|
44
44
|
end
|
45
45
|
|
46
|
-
def call(buffer = +"", context: {},
|
46
|
+
def call(buffer = +"", context: {}, fragments: nil, &)
|
47
47
|
state = Phlex::SGML::State.new(
|
48
48
|
user_context: context,
|
49
|
-
view_context:,
|
50
49
|
output_buffer: buffer,
|
51
50
|
fragments: fragments&.to_set,
|
52
51
|
)
|
@@ -57,8 +56,6 @@ class Phlex::SGML
|
|
57
56
|
end
|
58
57
|
|
59
58
|
def internal_call(parent: nil, state: nil, &block)
|
60
|
-
return "" unless render?
|
61
|
-
|
62
59
|
if @_state
|
63
60
|
raise Phlex::DoubleRenderError.new(
|
64
61
|
"You can't render a #{self.class.name} more than once."
|
@@ -67,6 +64,8 @@ class Phlex::SGML
|
|
67
64
|
|
68
65
|
@_state = state
|
69
66
|
|
67
|
+
return "" unless render?
|
68
|
+
|
70
69
|
block ||= @_content_block
|
71
70
|
|
72
71
|
Thread.current[:__phlex_component__] = [self, Fiber.current.object_id].freeze
|
@@ -188,6 +187,7 @@ class Phlex::SGML
|
|
188
187
|
|
189
188
|
alias_method :🦺, :safe
|
190
189
|
|
190
|
+
# Flush the current state to the output buffer.
|
191
191
|
def flush
|
192
192
|
@_state.flush
|
193
193
|
end
|
@@ -195,9 +195,7 @@ class Phlex::SGML
|
|
195
195
|
def render(renderable = nil, &)
|
196
196
|
case renderable
|
197
197
|
when Phlex::SGML
|
198
|
-
Thread.current[:__phlex_component__] = [renderable, Fiber.current.object_id].freeze
|
199
198
|
renderable.internal_call(state: @_state, parent: self, &)
|
200
|
-
Thread.current[:__phlex_component__] = [self, Fiber.current.object_id].freeze
|
201
199
|
when Class
|
202
200
|
if renderable < Phlex::SGML
|
203
201
|
render(renderable.new, &)
|
@@ -206,7 +204,7 @@ class Phlex::SGML
|
|
206
204
|
renderable.each { |r| render(r, &) }
|
207
205
|
when Proc, Method
|
208
206
|
if renderable.arity == 0
|
209
|
-
|
207
|
+
__yield_content_with_no_yield_args__(&renderable)
|
210
208
|
else
|
211
209
|
__yield_content__(&renderable)
|
212
210
|
end
|
@@ -234,11 +232,12 @@ class Phlex::SGML
|
|
234
232
|
location = caller_locations(1, 1)[0]
|
235
233
|
|
236
234
|
full_key = [
|
237
|
-
|
238
|
-
self.class.name,
|
239
|
-
|
240
|
-
location.
|
241
|
-
|
235
|
+
app_version_key, # invalidates the key when deploying new code in case of changes
|
236
|
+
self.class.name, # prevents collisions between classes
|
237
|
+
(self.class.object_id if enable_cache_reloading?), # enables reloading
|
238
|
+
location.base_label, # prevents collisions between different methods
|
239
|
+
location.lineno, # prevents collisions between different lines
|
240
|
+
cache_key, # allows for custom cache keys
|
242
241
|
].freeze
|
243
242
|
|
244
243
|
low_level_cache(full_key, **, &content)
|
@@ -277,14 +276,21 @@ class Phlex::SGML
|
|
277
276
|
end
|
278
277
|
end
|
279
278
|
|
280
|
-
|
281
|
-
|
279
|
+
private
|
280
|
+
|
281
|
+
# Override this method to use a different deployment key.
|
282
|
+
def app_version_key
|
283
|
+
Phlex::DEPLOYED_AT
|
284
|
+
end
|
285
|
+
|
282
286
|
# Override this method to use a different cache store.
|
283
287
|
def cache_store
|
284
|
-
|
288
|
+
raise "Cache store not implemented."
|
285
289
|
end
|
286
290
|
|
287
|
-
|
291
|
+
def enable_cache_reloading?
|
292
|
+
false
|
293
|
+
end
|
288
294
|
|
289
295
|
def vanish(*args)
|
290
296
|
return unless block_given?
|
@@ -334,13 +340,13 @@ class Phlex::SGML
|
|
334
340
|
nil
|
335
341
|
end
|
336
342
|
|
337
|
-
def
|
343
|
+
def __yield_content_with_no_yield_args__
|
338
344
|
return unless block_given?
|
339
345
|
|
340
346
|
buffer = @_state.buffer
|
341
347
|
|
342
348
|
original_length = buffer.bytesize
|
343
|
-
content = yield
|
349
|
+
content = yield # <-- doesn’t yield self 😉
|
344
350
|
__implicit_output__(content) if original_length == buffer.bytesize
|
345
351
|
|
346
352
|
nil
|
data/lib/phlex/svg.rb
CHANGED
@@ -5,11 +5,50 @@ class Phlex::SVG < Phlex::SGML
|
|
5
5
|
|
6
6
|
include StandardElements
|
7
7
|
|
8
|
+
# Returns the string "image/svg+xml"
|
8
9
|
def content_type
|
9
10
|
"image/svg+xml"
|
10
11
|
end
|
11
12
|
|
13
|
+
# Override to provide a filename for the SVG file
|
12
14
|
def filename
|
13
15
|
nil
|
14
16
|
end
|
17
|
+
|
18
|
+
def tag(name, **attributes, &)
|
19
|
+
state = @_state
|
20
|
+
block_given = block_given?
|
21
|
+
buffer = state.buffer
|
22
|
+
|
23
|
+
unless state.should_render?
|
24
|
+
yield(self) if block_given
|
25
|
+
return nil
|
26
|
+
end
|
27
|
+
|
28
|
+
unless Symbol === name
|
29
|
+
raise Phlex::ArgumentError.new("Expected the tag name to be a Symbol.")
|
30
|
+
end
|
31
|
+
|
32
|
+
if (tag = StandardElements.__registered_elements__[name]) || (tag = name.name.tr("_", "-")).include?("-")
|
33
|
+
if attributes.length > 0 # with attributes
|
34
|
+
if block_given # with content block
|
35
|
+
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
|
36
|
+
__yield_content__(&)
|
37
|
+
buffer << "</#{tag}>"
|
38
|
+
else # without content
|
39
|
+
buffer << "<#{tag}" << (::Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << "></#{tag}>"
|
40
|
+
end
|
41
|
+
else # without attributes
|
42
|
+
if block_given # with content block
|
43
|
+
buffer << ("<#{tag}>")
|
44
|
+
__yield_content__(&)
|
45
|
+
buffer << "</#{tag}>"
|
46
|
+
else # without content
|
47
|
+
buffer << "<#{tag}></#{tag}>"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
else
|
51
|
+
raise Phlex::ArgumentError.new("Invalid SVG tag: #{name}")
|
52
|
+
end
|
53
|
+
end
|
15
54
|
end
|
data/lib/phlex/version.rb
CHANGED
data/lib/phlex.rb
CHANGED
@@ -4,25 +4,26 @@ require "erb"
|
|
4
4
|
require "set"
|
5
5
|
|
6
6
|
module Phlex
|
7
|
-
autoload :
|
8
|
-
autoload :CSV, "phlex/csv"
|
9
|
-
autoload :DoubleRenderError, "phlex/errors/double_render_error"
|
10
|
-
autoload :Error, "phlex/error"
|
7
|
+
autoload :Kit, "phlex/kit"
|
11
8
|
autoload :FIFO, "phlex/fifo"
|
9
|
+
autoload :Vanish, "phlex/vanish"
|
10
|
+
autoload :Helpers, "phlex/helpers"
|
12
11
|
autoload :FIFOCacheStore, "phlex/fifo_cache_store"
|
12
|
+
|
13
|
+
autoload :CSV, "phlex/csv"
|
14
|
+
autoload :SVG, "phlex/svg"
|
13
15
|
autoload :HTML, "phlex/html"
|
14
|
-
autoload :Helpers, "phlex/helpers"
|
15
|
-
autoload :Kit, "phlex/kit"
|
16
|
-
autoload :NameError, "phlex/errors/name_error"
|
17
|
-
autoload :NullCacheStore, "phlex/null_cache_store"
|
18
16
|
autoload :SGML, "phlex/sgml"
|
19
|
-
|
20
|
-
autoload :
|
17
|
+
|
18
|
+
autoload :Error, "phlex/error"
|
19
|
+
autoload :NameError, "phlex/errors/name_error"
|
20
|
+
autoload :RuntimeError, "phlex/errors/runtime_error"
|
21
|
+
autoload :ArgumentError, "phlex/errors/argument_error"
|
22
|
+
autoload :DoubleRenderError, "phlex/errors/double_render_error"
|
21
23
|
|
22
24
|
Escape = ERB::Escape
|
23
|
-
Null = Object.new.freeze
|
24
25
|
|
25
|
-
|
26
|
+
DEPLOYED_AT = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
|
26
27
|
CACHED_FILES = Set.new
|
27
28
|
ATTRIBUTE_CACHE = FIFO.new
|
28
29
|
|
@@ -43,6 +44,38 @@ module Phlex
|
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
47
|
+
|
48
|
+
# Generate an HTML string using Phlex’ HTML DSL
|
49
|
+
def self.html(&block)
|
50
|
+
HTML.call do |component|
|
51
|
+
receiver = block.binding.receiver
|
52
|
+
|
53
|
+
receiver.instance_variables.each do |ivar|
|
54
|
+
next if component.instance_variable_defined?(ivar)
|
55
|
+
|
56
|
+
value = receiver.instance_variable_get(ivar)
|
57
|
+
component.instance_variable_set(ivar, value)
|
58
|
+
end
|
59
|
+
|
60
|
+
component.instance_exec(receiver, &block)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Generate an SVG string using Phlex’ SVG DSL
|
65
|
+
def self.svg(&block)
|
66
|
+
SVG.call do |component|
|
67
|
+
receiver = block.binding.receiver
|
68
|
+
|
69
|
+
receiver.instance_variables.each do |ivar|
|
70
|
+
next if component.instance_variable_defined?(ivar)
|
71
|
+
|
72
|
+
value = receiver.instance_variable_get(ivar)
|
73
|
+
component.instance_variable_set(ivar, value)
|
74
|
+
end
|
75
|
+
|
76
|
+
component.instance_exec(receiver, &block)
|
77
|
+
end
|
78
|
+
end
|
46
79
|
end
|
47
80
|
|
48
81
|
def 💪
|
metadata
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phlex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Drapper
|
8
|
+
- Will Cosgrove
|
8
9
|
bindir: bin
|
9
10
|
cert_chain: []
|
10
|
-
date: 2025-02-
|
11
|
+
date: 2025-02-15 00:00:00.000000000 Z
|
11
12
|
dependencies: []
|
12
|
-
description:
|
13
|
+
description: Build HTML & SVG view components with Ruby classes.
|
13
14
|
email:
|
14
15
|
- joel@drapper.me
|
15
16
|
executables: []
|
@@ -24,6 +25,7 @@ files:
|
|
24
25
|
- lib/phlex/errors/argument_error.rb
|
25
26
|
- lib/phlex/errors/double_render_error.rb
|
26
27
|
- lib/phlex/errors/name_error.rb
|
28
|
+
- lib/phlex/errors/runtime_error.rb
|
27
29
|
- lib/phlex/fifo.rb
|
28
30
|
- lib/phlex/fifo_cache_store.rb
|
29
31
|
- lib/phlex/helpers.rb
|
@@ -31,7 +33,6 @@ files:
|
|
31
33
|
- lib/phlex/html/standard_elements.rb
|
32
34
|
- lib/phlex/html/void_elements.rb
|
33
35
|
- lib/phlex/kit.rb
|
34
|
-
- lib/phlex/null_cache_store.rb
|
35
36
|
- lib/phlex/sgml.rb
|
36
37
|
- lib/phlex/sgml/elements.rb
|
37
38
|
- lib/phlex/sgml/safe_object.rb
|
@@ -39,11 +40,6 @@ files:
|
|
39
40
|
- lib/phlex/sgml/state.rb
|
40
41
|
- lib/phlex/svg.rb
|
41
42
|
- lib/phlex/svg/standard_elements.rb
|
42
|
-
- lib/phlex/testing.rb
|
43
|
-
- lib/phlex/testing/capybara.rb
|
44
|
-
- lib/phlex/testing/nokogiri.rb
|
45
|
-
- lib/phlex/testing/nokolexbor.rb
|
46
|
-
- lib/phlex/testing/sgml.rb
|
47
43
|
- lib/phlex/vanish.rb
|
48
44
|
- lib/phlex/version.rb
|
49
45
|
homepage: https://www.phlex.fun
|
@@ -52,7 +48,7 @@ licenses:
|
|
52
48
|
metadata:
|
53
49
|
homepage_uri: https://www.phlex.fun
|
54
50
|
source_code_uri: https://github.com/phlex-ruby/phlex
|
55
|
-
changelog_uri: https://github.com/phlex-ruby/phlex/
|
51
|
+
changelog_uri: https://github.com/phlex-ruby/phlex/releases
|
56
52
|
funding_uri: https://github.com/sponsors/joeldrapper
|
57
53
|
rubygems_mfa_required: 'true'
|
58
54
|
rdoc_options: []
|
@@ -71,5 +67,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
67
|
requirements: []
|
72
68
|
rubygems_version: 3.6.2
|
73
69
|
specification_version: 4
|
74
|
-
summary:
|
70
|
+
summary: Object-oriented views in Ruby.
|
75
71
|
test_files: []
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "capybara"
|
4
|
-
|
5
|
-
module Phlex::Testing::Capybara
|
6
|
-
include Phlex::Testing::SGML
|
7
|
-
|
8
|
-
def self.included(mod)
|
9
|
-
if defined?(Minitest::Test) && Minitest::Test > mod
|
10
|
-
require "capybara/minitest"
|
11
|
-
mod.include Capybara::Minitest::Assertions
|
12
|
-
end
|
13
|
-
|
14
|
-
if defined?(RSpec::Core::ExampleGroup) && RSpec::Core::ExampleGroup > mod
|
15
|
-
require "capybara/rspec"
|
16
|
-
mod.include Capybara::RSpecMatchers
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
attr_reader :page
|
21
|
-
alias_method :component, :page
|
22
|
-
|
23
|
-
def render(...)
|
24
|
-
@page = ::Capybara::Node::Simple.new(
|
25
|
-
render_to_string(...),
|
26
|
-
)
|
27
|
-
end
|
28
|
-
end
|