diff --git a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb index ffbffbf25e..3d0657e873 100644 --- a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb +++ b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb @@ -6,6 +6,7 @@ module ActionView include ActionView::Helpers::TagHelper include ActionView::Helpers::TextHelper include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::FormHelper def content_tag(*, &block) block_called_from_erb?(block) ? safe_concat(super) : super @@ -15,6 +16,22 @@ module ActionView block_called_from_erb?(block) ? safe_concat(super) : super end + def form_for(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def form_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def fields_for(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def field_set_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' if RUBY_VERSION < '1.9.0' diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 742e873a49..48df26efaa 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -92,6 +92,10 @@ module ActionView # link:classes/ActionView/Helpers/DateHelper.html, and # link:classes/ActionView/Helpers/ActiveRecordHelper.html module FormHelper + extend ActiveSupport::Concern + + include FormTagHelper + # Creates a form and a scope around a specific model object that is used # as a base for questioning about values for the fields. # @@ -309,9 +313,9 @@ module ActionView options[:html][:remote] = true if options.delete(:remote) - safe_concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {})) - fields_for(object_name, *(args << options), &proc) - safe_concat('') + output = form_tag(options.delete(:url) || {}, options.delete(:html) || {}) + output << fields_for(object_name, *(args << options), &proc) + output.safe_concat('') end def apply_form_for_options!(object_or_array, options) #:nodoc: @@ -528,7 +532,10 @@ module ActionView end builder = options[:builder] || ActionView::Base.default_form_builder - yield builder.new(object_name, object, self, options, block) + + with_output_buffer do + yield builder.new(object_name, object, self, options, block) + end end # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object @@ -1183,9 +1190,11 @@ module ActionView if association.is_a?(Array) explicit_child_index = options[:child_index] - association.map do |child| - fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block) - end.join + output = ActiveSupport::SafeBuffer.new + association.each do |child| + output << fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block) + end + output elsif association fields_for_nested_model(name, association, options, block) end diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 7f74be27cb..7039ecd233 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -97,7 +97,9 @@ module ActionView # # module FormOptionsHelper + # ERB::Util can mask some helpers like textilize. Make sure to include them. include ERB::Util + include TextHelper # Create a select tag and a series of contained option tags for the provided object and method. # The option currently held by the object will be selected, provided that the object is available. diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 7dcaee7e34..573733ffea 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -10,6 +10,11 @@ module ActionView # NOTE: The HTML options disabled, readonly, and multiple can all be treated as booleans. So specifying # :disabled => true will give disabled="disabled". module FormTagHelper + extend ActiveSupport::Concern + + include UrlHelper + include TextHelper + # Starts a form tag that points the action to an url configured with url_for_options just like # ActionController::Base#url_for. The method for the form defaults to POST. # @@ -441,10 +446,10 @@ module ActionView # # =>
def field_set_tag(legend = nil, options = nil, &block) content = capture(&block) - safe_concat(tag(:fieldset, options, true)) - safe_concat(content_tag(:legend, legend)) unless legend.blank? - concat(content) - safe_concat("") + output = tag(:fieldset, options, true) + output.safe_concat(content_tag(:legend, legend)) unless legend.blank? + output.concat(content) + output.safe_concat("") end private @@ -477,9 +482,10 @@ module ActionView def form_tag_in_block(html_options, &block) content = capture(&block) - safe_concat(form_tag_html(html_options)) - concat(content) - safe_concat("") + output = ActiveSupport::SafeBuffer.new + output.safe_concat(form_tag_html(html_options)) + output << content + output.safe_concat("") end def token_tag diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 3fcae167ff..937694ce8e 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -28,10 +28,18 @@ module ActionView @buffer.to_s end + def to_str + @buffer.to_str + end + def empty? @buffer.empty? end + def html_safe? + @buffer.html_safe? + end + if "".respond_to?(:force_encoding) def force_encoding(encoding) @buffer.force_encoding(encoding) diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index 9a2d490854..da2477b6f8 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -1250,7 +1250,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.date_select(:written_on) end @@ -1266,7 +1266,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) id = 27 - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.date_select(:written_on) end @@ -1282,7 +1282,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) id = nil - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.date_select(:written_on) end @@ -1478,7 +1478,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.date_select(:written_on, {}, :class => 'selector') end @@ -1642,7 +1642,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.time_select(:written_on, {}, :class => 'selector') end @@ -1816,7 +1816,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.datetime_select(:updated_at, {}, :class => 'selector') end @@ -2052,7 +2052,7 @@ class DateHelperTest < ActionView::TestCase @post.updated_at = Time.local(2004, 6, 15, 16, 35) id = 456 - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.datetime_select(:updated_at) end diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb index d9ca828b43..b91539ef0b 100644 --- a/actionpack/test/template/erb/tag_helper_test.rb +++ b/actionpack/test/template/erb/tag_helper_test.rb @@ -1,6 +1,28 @@ require "abstract_unit" module ERBTest + class ViewContext + mock_controller = Class.new do + include SharedTestRoutes.url_helpers + end + + include ActionView::Helpers::TagHelper + include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::FormHelper + + attr_accessor :output_buffer + + def protect_against_forgery?() false end + + define_method(:controller) do + mock_controller.new + end + end + + class DeprecatedViewContext < ViewContext + include ActionView::Helpers::DeprecatedBlockHelpers + end + module SharedTagHelpers extend ActiveSupport::Testing::Declarative @@ -22,16 +44,21 @@ module ERBTest expected_output = "" assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')") end + + test "percent equals works with form tags" do + expected_output = "" + assert_equal expected_output, render_content("form_tag('foo')", "<%= 'hello' %>") + end + + test "percent equals works with fieldset tags" do + expected_output = "" + assert_equal expected_output, render_content("field_set_tag('foo')", "<%= 'hello' %>") + end end class TagHelperTest < ActiveSupport::TestCase def context - Class.new do - include ActionView::Helpers::TagHelper - include ActionView::Helpers::JavaScriptHelper - - attr_accessor :output_buffer - end + ViewContext end def block_helper(str, rest) @@ -43,12 +70,7 @@ module ERBTest class DeprecatedTagHelperTest < ActiveSupport::TestCase def context - Class.new do - include ActionView::Helpers::TagHelper - include ActionView::Helpers::JavaScriptHelper - include ActionView::Helpers::DeprecatedBlockHelpers - attr_accessor :output_buffer - end + DeprecatedViewContext end def block_helper(str, rest) diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index d143c39c9c..7c5ccfd6ed 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -4,6 +4,10 @@ require 'controller/fake_models' class FormHelperTest < ActionView::TestCase tests ActionView::Helpers::FormHelper + def form_for(*) + @output_buffer = super + end + def setup super @@ -590,9 +594,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for form_for(:post, @post) do |f| - f.fields_for(:comment, @post) do |c| + concat f.fields_for(:comment, @post) { |c| concat c.text_field(:title) - end + } end expected = "