Fix for Rails 3.2.3 textarea helpers

Textarea helpers on 3.2.3 emit a newline after the opening textarea tag,
which caused Haml to mess up indenting and add an encoded newline to the
textarea content. This fixes the issue by replacing the first newline
with <haml:newline/> in the Haml buffer, and then changing it to a true
newline at render time.
This commit is contained in:
Norman Clarke 2012-04-17 12:52:40 -03:00
parent 984c2d7ac8
commit 173626f341
4 changed files with 75 additions and 8 deletions

View File

@ -8,6 +8,9 @@
* Respect Rails' `html_safe` flag when escaping attribute values
(thanks to [Gerad Suyderhoud](https://github.com/gerad)).
* Fix for Rails 3.2.3 textarea helpers
(thanks to [James Coleman](https://github.com/jcoleman) and others).
## 3.1.4
* Fix the use of `FormBuilder#block` with a label in Haml.

View File

@ -256,3 +256,5 @@ module ActionView
end
end
end
require "haml/helpers/rails_323_textarea_fix" if Haml::Util.ap_geq?("3.2.3")

View File

@ -0,0 +1,49 @@
# Rails 3.2.3's form helpers add a newline after opening textareas, which can
# cause problems with newlines being considered content rather than markup.
# These changes fix the issue by making the helpers emit "<haml:newline/>"
# rather than the leading newline. The tag is then replaced by a newline after
# rendering.
#
# This should be considered nothing more than an emergency hotfix to ensure
# compatibility with the latest version of Rails, made at a moment when the Haml
# project is transitioning to a new maintainer.
module AbstractController
module Rendering
def render_to_body_with_haml(options = {})
if rendered = render_to_body_without_haml(options)
rendered.gsub('<haml:newline/>', "\n").html_safe
end
end
alias_method_chain :render_to_body, :haml
end
end
module ActionView
class Renderer
def render_template_with_haml(context, options)
if rendered = render_template_without_haml(context, options)
rendered.gsub('<haml:newline/>', "\n").html_safe
end
end
alias_method_chain :render_template, :haml
end
module Helpers
module TagHelper
private
def content_tag_string_with_haml(name, content, options, escape = true)
if name.to_sym == :textarea
tag_options = tag_options(options, escape) if options
content = ERB::Util.h(content) if escape
"<#{name}#{tag_options}><haml:newline/>#{content}</#{name}>".html_safe
else
content_tag_string_without_haml(name, content, options, escape)
end
end
alias_method_chain :content_tag_string, :haml
end
end
end

View File

@ -133,17 +133,30 @@ HTML
HAML
end
def test_text_area
assert_equal(%(<textarea id="body" name="body">Foo&#x000A;Bar&#x000A; Baz&#x000A; Boom</textarea>\n),
render('= text_area_tag "body", "Foo\nBar\n Baz\n Boom"', :action_view))
if Haml::Util.ap_geq?("3.2.3")
def test_text_area
assert_equal(%(<textarea id="body" name="body">\nFoo&#x000A;Bar&#x000A; Baz&#x000A; Boom</textarea>\n),
render('= text_area_tag "body", "Foo\nBar\n Baz\n Boom"', :action_view))
assert_equal(%(<textarea cols="40" id="post_body" name="post[body]" rows="20">Foo bar&#x000A;baz</textarea>\n),
render('= text_area :post, :body', :action_view))
assert_equal(%(<textarea cols="40" id="post_body" name="post[body]" rows="20">\nFoo bar&#x000A;baz</textarea>\n),
render('= text_area :post, :body', :action_view))
assert_equal(%(<pre>Foo bar&#x000A; baz</pre>\n),
render('= content_tag "pre", "Foo bar\n baz"', :action_view))
assert_equal(%(<pre>Foo bar&#x000A; baz</pre>\n),
render('= content_tag "pre", "Foo bar\n baz"', :action_view))
end
else
def test_text_area
assert_equal(%(<textarea id="body" name="body">Foo&#x000A;Bar&#x000A; Baz&#x000A; Boom</textarea>\n),
render('= text_area_tag "body", "Foo\nBar\n Baz\n Boom"', :action_view))
assert_equal(%(<textarea cols="40" id="post_body" name="post[body]" rows="20">Foo bar&#x000A;baz</textarea>\n),
render('= text_area :post, :body', :action_view))
assert_equal(%(<pre>Foo bar&#x000A; baz</pre>\n),
render('= content_tag "pre", "Foo bar\n baz"', :action_view))
end
end
def test_capture_haml
assert_equal(<<HTML, render(<<HAML))
"<p>13</p>\\n"