Skip to content

Commit e7e4e48

Browse files
authored
Merge pull request #226 from phlex-ruby/unbuffered-bug
Fix unbuffered bug
2 parents 6c1e183 + 645b1bd commit e7e4e48

File tree

8 files changed

+66
-56
lines changed

8 files changed

+66
-56
lines changed

lib/phlex/rails/sgml.rb

+8-21
Original file line numberDiff line numberDiff line change
@@ -55,33 +55,20 @@ def render(*args, **kwargs, &block)
5555
nil
5656
end
5757

58-
def render_in(view_context, &block)
58+
def render_in(view_context, &erb)
5959
fragments = if view_context.request && (fragment_header = view_context.request.headers["X-Fragment"])
6060
fragment_header.split
6161
end
6262

63-
if block_given?
64-
call(view_context:, fragments:) do |*args|
65-
original_length = @_context.target.bytesize
66-
67-
if args.length == 1 && Phlex::SGML === args[0] && !block.source_location&.[](0)&.end_with?(".rb")
68-
output = view_context.capture(
69-
Phlex::Rails::Unbuffered.new(args[0]),
70-
&block
71-
)
63+
if erb
64+
call(view_context:, fragments:) { |*args|
65+
if args.length == 1 && Phlex::SGML === args[0] && !erb.source_location&.[](0)&.end_with?(".rb")
66+
unbuffered = Phlex::Rails::Unbuffered.new(args[0])
67+
raw(helpers.capture(unbuffered, &erb))
7268
else
73-
output = view_context.capture(*args, &block)
74-
end
75-
76-
unchanged = (original_length == @_context.target.bytesize)
77-
78-
if unchanged
79-
case output
80-
when ActiveSupport::SafeBuffer
81-
@_context.target << output
82-
end
69+
raw(helpers.capture(*args, &erb))
8370
end
84-
end.html_safe
71+
}.html_safe
8572
else
8673
call(view_context:, fragments:).html_safe
8774
end

lib/phlex/rails/testing.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# frozen_string_literal: true
12

23
require "phlex/rails"
34
require "phlex/testing"
@@ -13,5 +14,5 @@ def controller
1314
end
1415

1516
Phlex::Testing::SGML.include(
16-
Phlex::Testing::RailsContext
17+
Phlex::Testing::RailsContext,
1718
)

lib/phlex/rails/unbuffered.rb

+26-34
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,51 @@
11
# frozen_string_literal: true
22

33
# @api private
4-
class Phlex::Rails::Unbuffered < BasicObject
5-
def initialize(object)
6-
@object = object
4+
class Phlex::Rails::Unbuffered
5+
def initialize(component)
6+
@component = component
77
end
88

9-
def inspect
10-
"Unbuffered(#{@object.class.name})[object: #{@object.inspect}]"
11-
end
12-
13-
define_method :__class__,
14-
::Object.instance_method(:class)
15-
169
def respond_to_missing?(...)
17-
@object.respond_to?(...)
10+
@component.respond_to?(...)
1811
end
1912

20-
def method_missing(name, ...)
21-
if @object.respond_to?(name)
22-
__class__.define_method(name) do |*a, **k, &b|
23-
@object.capture do
24-
if b
25-
@object.public_send(name, *a, **k) do |*aa|
26-
if aa.length == 1 && ::Phlex::SGML === aa[0]
27-
@object.helpers.capture(
28-
::Phlex::Rails::Unbuffered.new(aa[0]),
29-
&b
30-
)
31-
else
32-
@object.helpers.capture(*aa, &b)
33-
end
34-
end
35-
else
36-
@object.public_send(name, *a, **k)
13+
def method_missing(method_name, *, &erb)
14+
if @component.respond_to?(method_name)
15+
output = @component.capture do
16+
if erb
17+
@component.public_send(method_name, *) do
18+
@component.raw(
19+
@component.helpers.capture(
20+
&erb
21+
),
22+
)
3723
end
24+
else # no erb block
25+
@component.public_send(
26+
method_name,
27+
*,
28+
)
3829
end
3930
end
40-
41-
__send__(name, ...)
4231
else
4332
super
4433
end
4534
end
4635

47-
# Forward some methods to the original underlying object
36+
def inspect
37+
"Unbuffered(#{@component.inspect})"
38+
end
39+
4840
def call(...)
49-
@object.call(...)
41+
@component.call(...)
5042
end
5143

5244
def send(...)
53-
@object.__send__(...)
45+
@component.__send__(...)
5446
end
5547

5648
def public_send(...)
57-
@object.public_send(...)
49+
@component.public_send(...)
5850
end
5951
end

test/dummy/app/controllers/rendering_controller.rb

+3
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ def partial_from_phlex
88
def view_component_from_phlex
99
render Rendering::ViewComponentFromPhlex.new
1010
end
11+
12+
def phlex_component_from_erb
13+
end
1114
end
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
3+
class Card < ApplicationComponent
4+
def view_template(&)
5+
article(class: "card", &)
6+
end
7+
8+
def title(&)
9+
h1(class: "title", &)
10+
end
11+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<div class="outside">
2+
<%= render Card.new do |t| %>
3+
<div class="inside">
4+
<%= t.title do %>
5+
<strong class="inside-slot">Hi</strong>
6+
<% end %>
7+
</div>
8+
<% end %>
9+
</div>

test/dummy/config/routes.rb

+1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@
2020

2121
get "/rendering/partial_from_phlex", to: "rendering#partial_from_phlex"
2222
get "/rendering/view_component_from_phlex", to: "rendering#view_component_from_phlex"
23+
get "/rendering/phlex_component_from_erb", to: "rendering#phlex_component_from_erb"
2324
end

test/phlex/render_test.rb

+6
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,10 @@ class RenderTest < ActionDispatch::IntegrationTest
1414
assert_response :success
1515
assert_select "#phlex", "Rendered from Phlex"
1616
end
17+
18+
test "rendering Phlex component from ERB view" do
19+
get "/rendering/phlex_component_from_erb"
20+
assert_response :success
21+
assert_select ".outside .card .inside .title .inside-slot", "Hi"
22+
end
1723
end

0 commit comments

Comments
 (0)