diff options
-rw-r--r-- | actionpack/lib/action_view/flows.rb | 9 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/capture_helper.rb | 8 | ||||
-rw-r--r-- | actionpack/test/fixtures/layouts/streaming.erb | 4 | ||||
-rw-r--r-- | actionpack/test/fixtures/test/nested_streaming.erb | 3 | ||||
-rw-r--r-- | actionpack/test/fixtures/test/streaming.erb | 3 | ||||
-rw-r--r-- | actionpack/test/fixtures/test/streaming_buster.erb | 3 | ||||
-rw-r--r-- | actionpack/test/template/capture_helper_test.rb | 11 | ||||
-rw-r--r-- | actionpack/test/template/streaming_render_test.rb | 12 |
8 files changed, 43 insertions, 10 deletions
diff --git a/actionpack/lib/action_view/flows.rb b/actionpack/lib/action_view/flows.rb index b5e2c5d37d..995a0b51e4 100644 --- a/actionpack/lib/action_view/flows.rb +++ b/actionpack/lib/action_view/flows.rb @@ -19,6 +19,10 @@ module ActionView def append(key, value) @content[key] << value end + + def append!(key, value) + @content[key] << value + end end class StreamingFlow < OutputFlow @@ -58,6 +62,11 @@ module ActionView # by provides and resumes back to the fiber if it is # the key it is waiting for. def set(key, value) + @content[key] = (ActiveSupport::SafeBuffer.new << value) + end + + # Append but also resume the fiber if it provided the right key. + def append!(key, value) super @fiber.resume if @waiting_for == key end diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 148d814ac7..0139714240 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -142,12 +142,12 @@ module ActionView # The same as +content_for+ but when used with streaming flushes # straight back to the layout. In other words, if you want to # concatenate several times to the same buffer when rendering a given - # template, you should use +content_for+, if not, use +provide+ as it - # has better streaming support. + # template, you should use +content_for+, if not, use +provide+ to tell + # the layout to stop looking for more contents. def provide(name, content = nil, &block) content = capture(&block) if block_given? - @_view_flow.set(name, content) if content - content + result = @_view_flow.append!(name, content) if content + result unless content end # content_for? simply checks whether any content has been captured yet using content_for diff --git a/actionpack/test/fixtures/layouts/streaming.erb b/actionpack/test/fixtures/layouts/streaming.erb new file mode 100644 index 0000000000..d3f896a6ca --- /dev/null +++ b/actionpack/test/fixtures/layouts/streaming.erb @@ -0,0 +1,4 @@ +<%= yield :header -%> +<%= yield -%> +<%= yield :footer -%> +<%= yield(:unknown).presence || "." -%>
\ No newline at end of file diff --git a/actionpack/test/fixtures/test/nested_streaming.erb b/actionpack/test/fixtures/test/nested_streaming.erb new file mode 100644 index 0000000000..55525e0c92 --- /dev/null +++ b/actionpack/test/fixtures/test/nested_streaming.erb @@ -0,0 +1,3 @@ +<%- content_for :header do -%>?<%- end -%> +<%= render :template => "test/streaming" %> +?
\ No newline at end of file diff --git a/actionpack/test/fixtures/test/streaming.erb b/actionpack/test/fixtures/test/streaming.erb new file mode 100644 index 0000000000..fb9b8b1ade --- /dev/null +++ b/actionpack/test/fixtures/test/streaming.erb @@ -0,0 +1,3 @@ +<%- provide :header do -%>Yes, <%- end -%> +this works +<%- content_for :footer, " like a charm" -%> diff --git a/actionpack/test/fixtures/test/streaming_buster.erb b/actionpack/test/fixtures/test/streaming_buster.erb new file mode 100644 index 0000000000..4221d56dcc --- /dev/null +++ b/actionpack/test/fixtures/test/streaming_buster.erb @@ -0,0 +1,3 @@ +<%= yield :foo -%> +This won't look +<% provide :unknown, " good." -%> diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb index c2f0825375..a9a36e6e6b 100644 --- a/actionpack/test/template/capture_helper_test.rb +++ b/actionpack/test/template/capture_helper_test.rb @@ -47,13 +47,16 @@ class CaptureHelperTest < ActionView::TestCase def test_provide assert !content_for?(:title) - provide :title, "title" + provide :title, "hi" assert content_for?(:title) - assert_equal "title", @_view_flow.get(:title) + assert_equal "hi", @_view_flow.get(:title) provide :title, "<p>title</p>" - assert_equal "<p>title</p>", @_view_flow.get(:title) + assert_equal "hi<p>title</p>", @_view_flow.get(:title) + + @_view_flow = ActionView::OutputFlow.new + provide :title, "hi" provide :title, "<p>title</p>".html_safe - assert_equal "<p>title</p>", @_view_flow.get(:title) + assert_equal "hi<p>title</p>", @_view_flow.get(:title) end def test_with_output_buffer_swaps_the_output_buffer_given_no_argument diff --git a/actionpack/test/template/streaming_render_test.rb b/actionpack/test/template/streaming_render_test.rb index 754ede9701..4d69081570 100644 --- a/actionpack/test/template/streaming_render_test.rb +++ b/actionpack/test/template/streaming_render_test.rb @@ -88,10 +88,18 @@ class FiberedTest < ActiveSupport::TestCase end def test_render_with_streaming_multiple_yields_provide_and_content_for - assert_equal "Yes, \nthis works\n like a charm.", buffered_render(:template => "test/streaming", :layout => "layouts/streaming") + assert_equal "Yes, \nthis works\n like a charm.", + buffered_render(:template => "test/streaming", :layout => "layouts/streaming") end def test_render_with_streaming_with_fake_yields_and_streaming_buster - assert_equal "This won't look\n good.", buffered_render(:template => "test/streaming_buster", :layout => "layouts/streaming") + assert_equal "This won't look\n good.", + buffered_render(:template => "test/streaming_buster", :layout => "layouts/streaming") end + + def test_render_with_nested_streaming_multiple_yields_provide_and_content_for + assert_equal "?Yes, \n\nthis works\n\n? like a charm.", + buffered_render(:template => "test/nested_streaming", :layout => "layouts/streaming") + end + end if defined?(Fiber)
\ No newline at end of file |