From 2c2b0beaf46c997773b9adc8ef9ff57547a770a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Sat, 26 May 2012 14:11:28 -0300 Subject: [PATCH] Add `:escape` option for `truncate` This options can be used to not escape the result by default. --- actionpack/CHANGELOG.md | 5 +++++ .../lib/action_view/helpers/text_helper.rb | 7 +++++-- actionpack/test/template/text_helper_test.rb | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index db5e40b07c..ba66b525bc 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,10 @@ ## Rails 4.0.0 (unreleased) ## +* `truncate` now always returns an escaped HTMl-safe string. The option `:escape` can be used as + false to not escape the result. + + *Li Ellis Gallardo + Rafael Mendonça França* + * `truncate` now accepts a block to show extra content when the text is truncated. *Li Ellis Gallardo* * Add `week_field`, `week_field_tag`, `month_field`, `month_field_tag`, `datetime_local_field`, diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 72f9dd2cef..0cc0d069ea 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -64,7 +64,9 @@ def safe_concat(string) # # Pass a block if you want to show extra content when the text is truncated. # - # The result is marked as HTML-safe, but the it is escaped first. + # The result is marked as HTML-safe, but it is escaped by default, unless :escape is + # +false+. Care should be taken if +text+ contains HTML tags or entities, because truncation + # may produce invalid HTML (such as unbalanced or incomplete tags). # # truncate("Once upon a time in a world far far away") # # => "Once upon a time in a world..." @@ -87,7 +89,8 @@ def truncate(text, options = {}, &block) if text length = options.fetch(:length, 30) - content = ERB::Util.html_escape(text.truncate(length, options)) + content = text.truncate(length, options) + content = options[:escape] == false ? content.html_safe : ERB::Util.html_escape(content) content << capture(&block) if block_given? && text.length > length content end diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb index 4b1c1ef78b..a3ab091c6c 100644 --- a/actionpack/test/template/text_helper_test.rb +++ b/actionpack/test/template/text_helper_test.rb @@ -119,6 +119,15 @@ def test_truncate_should_escape_the_input assert_equal "Hello <sc...", truncate("Hello World!!", :length => 12) end + def test_truncate_should_not_escape_the_input_with_escape_false + assert_equal "Hello code!World!!", :length => 12, :escape => false) + end + + def test_truncate_with_escape_false_should_be_html_safe + truncated = truncate("Hello World!!", :length => 12, :escape => false) + assert truncated.html_safe? + end + def test_truncate_with_block_should_be_html_safe truncated = truncate("Here's a long test and I need a continue to read link", :length => 27) { link_to 'Continue', '#' } assert truncated.html_safe? @@ -129,6 +138,16 @@ def test_truncate_with_block_should_escape_the_input truncate("Here's a long test and I need a continue to read link", :length => 27) { link_to 'Continue', '#' } end + def test_truncate_with_block_should_not_escape_the_input_with_escape_false + assert_equal "He...Continue", + truncate("Here's a long test and I need a continue to read link", :length => 27, :escape => false) { link_to 'Continue', '#' } + end + + def test_truncate_with_block_with_escape_false_should_be_html_safe + truncated = truncate("Here's a long test and I need a continue to read link", :length => 27, :escape => false) { link_to 'Continue', '#' } + assert truncated.html_safe? + end + def test_truncate_with_block_should_escape_the_block assert_equal "Here's a long test and I...<script>alert('foo');</script>", truncate("Here's a long test and I need a continue to read link", :length => 27) { "" } -- GitLab