diff options
Diffstat (limited to 'actionview')
-rw-r--r-- | actionview/CHANGELOG.md | 5 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/url_helper.rb | 48 | ||||
-rw-r--r-- | actionview/lib/action_view/template/error.rb | 20 | ||||
-rw-r--r-- | actionview/lib/action_view/unbound_template.rb | 6 | ||||
-rw-r--r-- | actionview/test/template/template_error_test.rb | 16 | ||||
-rw-r--r-- | actionview/test/template/url_helper_test.rb | 62 |
6 files changed, 142 insertions, 15 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index f2f57e6a36..504b1d3e98 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,8 @@ +* annotated_source_code returns an empty array so TemplateErrors without a + template in the backtrace are surfaced properly by DebugExceptions. + + *Guilherme Mansur*, *Kasper Timm Hansen* + * Add autoload for SyntaxErrorInTemplate so syntax errors are correctly raised by DebugExceptions. *Guilherme Mansur*, *Gannon McGibbon* diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 4b3a258287..3df2eaf079 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -571,6 +571,54 @@ module ActionView end end + # Creates an SMS anchor link tag to the specified +phone_number+, which is + # also used as the name of the link unless +name+ is specified. Additional + # HTML attributes for the link can be passed in +html_options+. + # + # When clicked, an SMS message is prepopulated with the passed phone number + # and optional +body+ value. + # + # +sms_to+ has a +body+ option for customizing the SMS message itself by + # passing special keys to +html_options+. + # + # ==== Options + # * <tt>:body</tt> - Preset the body of the message. + # + # ==== Examples + # sms_to "5155555785" + # # => <a href="sms:5155555785;">5155555785</a> + # + # sms_to "5155555785", "Text me" + # # => <a href="sms:5155555785;">Text me</a> + # + # sms_to "5155555785", "Text me", + # body: "Hello Jim I have a question about your product." + # # => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a> + # + # You can use a block as well if your link target is hard to fit into the name parameter. ERB example: + # + # <%= sms_to "5155555785" do %> + # <strong>Text me:</strong> + # <% end %> + # # => <a href="sms:5155555785;"> + # <strong>Text me:</strong> + # </a> + def sms_to(phone_number, name = nil, html_options = {}, &block) + html_options, name = name, nil if block_given? + html_options = (html_options || {}).stringify_keys + + extras = %w{ body }.map! { |item| + option = html_options.delete(item).presence || next + "#{item.dasherize}=#{ERB::Util.url_encode(option)}" + }.compact + extras = extras.empty? ? "" : "?&" + extras.join("&") + + encoded_phone_number = ERB::Util.url_encode(phone_number) + html_options["href"] = "sms:#{encoded_phone_number};#{extras}" + + content_tag("a", name || phone_number, html_options, &block) + end + private def convert_options_to_data_attributes(options, html_options) if html_options diff --git a/actionview/lib/action_view/template/error.rb b/actionview/lib/action_view/template/error.rb index feceef15f9..7fc74a5502 100644 --- a/actionview/lib/action_view/template/error.rb +++ b/actionview/lib/action_view/template/error.rb @@ -81,8 +81,8 @@ module ActionView end end - def source_extract(indentation = 0, output = :console) - return unless num = line_number + def source_extract(indentation = 0) + return [] unless num = line_number num = num.to_i source_code = @template.source.split("\n") @@ -91,9 +91,9 @@ module ActionView end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min indent = end_on_line.to_s.size + indentation - return unless source_code = source_code[start_on_line..end_on_line] + return [] unless source_code = source_code[start_on_line..end_on_line] - formatted_code_for(source_code, start_on_line, indent, output) + formatted_code_for(source_code, start_on_line, indent) end def sub_template_of(template_path) @@ -122,15 +122,11 @@ module ActionView end + file_name end - def formatted_code_for(source_code, line_counter, indent, output) - start_value = (output == :html) ? {} : [] - source_code.inject(start_value) do |result, line| + def formatted_code_for(source_code, line_counter, indent) + indent_template = "%#{indent}s: %s" + source_code.map do |line| line_counter += 1 - if output == :html - result.update(line_counter.to_s => "%#{indent}s %s\n" % ["", line]) - else - result << "%#{indent}s: %s" % [line_counter, line] - end + indent_template % [line_counter, line] end end end diff --git a/actionview/lib/action_view/unbound_template.rb b/actionview/lib/action_view/unbound_template.rb index d28bab91b6..3d4434b2e9 100644 --- a/actionview/lib/action_view/unbound_template.rb +++ b/actionview/lib/action_view/unbound_template.rb @@ -4,9 +4,9 @@ require "concurrent/map" module ActionView class UnboundTemplate - def initialize(source, identifer, handler, options) + def initialize(source, identifier, handler, options) @source = source - @identifer = identifer + @identifier = identifier @handler = handler @options = options @@ -22,7 +22,7 @@ module ActionView options = @options.merge(locals: locals) Template.new( @source, - @identifer, + @identifier, @handler, options ) diff --git a/actionview/test/template/template_error_test.rb b/actionview/test/template/template_error_test.rb index c4dc88e4aa..643c29602b 100644 --- a/actionview/test/template/template_error_test.rb +++ b/actionview/test/template/template_error_test.rb @@ -34,4 +34,20 @@ class TemplateErrorTest < ActiveSupport::TestCase assert_equal "#<ActionView::Template::Error: original>", error.inspect end + + def test_annotated_source_code_returns_empty_array_if_source_cant_be_found + template = Class.new do + def identifier + "something" + end + end.new + + error = begin + raise + rescue + raise ActionView::Template::Error.new(template) rescue $! + end + + assert_equal [], error.annotated_source_code + end end diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb index 632b32f09f..bce6e7f370 100644 --- a/actionview/test/template/url_helper_test.rb +++ b/actionview/test/template/url_helper_test.rb @@ -708,6 +708,68 @@ class UrlHelperTest < ActiveSupport::TestCase assert_equal({ class: "special" }, options) end + def test_sms_to + assert_dom_equal %{<a href="sms:15155555785;">15155555785</a>}, sms_to("15155555785") + assert_dom_equal %{<a href="sms:15155555785;">Jim Jones</a>}, sms_to("15155555785", "Jim Jones") + assert_dom_equal( + %{<a class="admin" href="sms:15155555785;">Jim Jones</a>}, + sms_to("15155555785", "Jim Jones", "class" => "admin") + ) + assert_equal sms_to("15155555785", "Jim Jones", "class" => "admin"), + sms_to("15155555785", "Jim Jones", class: "admin") + end + + def test_sms_to_with_options + assert_dom_equal( + %{<a class="simple-class" href="sms:15155555785;?&body=Hello%20from%20Jim">Text me</a>}, + sms_to("15155555785", "Text me", class: "simple-class", body: "Hello from Jim") + ) + + assert_dom_equal( + %{<a href="sms:15155555785;?&body=This%20is%20the%20body%20of%20the%20message.">Text me</a>}, + sms_to("15155555785", "Text me", body: "This is the body of the message.") + ) + end + + def test_sms_with_img + assert_dom_equal %{<a href="sms:15155555785;"><img src="/feedback.png" /></a>}, + sms_to("15155555785", raw('<img src="/feedback.png" />')) + end + + def test_sms_with_html_safe_string + assert_dom_equal( + %{<a href="sms:1%2B5155555785;">1+5155555785</a>}, + sms_to(raw("1+5155555785")) + ) + end + + def test_sms_with_nil + assert_dom_equal( + %{<a href="sms:;"></a>}, + sms_to(nil) + ) + end + + def test_sms_returns_html_safe_string + assert_predicate sms_to("15155555785"), :html_safe? + end + + def test_sms_with_block + assert_dom_equal %{<a href="sms:15155555785;"><span>Text me</span></a>}, + sms_to("15155555785") { content_tag(:span, "Text me") } + end + + def test_sms_with_block_and_options + assert_dom_equal %{<a class="special" href="sms:15155555785;?&body=Hello%20from%20Jim"><span>Text me</span></a>}, + sms_to("15155555785", body: "Hello from Jim", class: "special") { content_tag(:span, "Text me") } + end + + def test_sms_does_not_modify_html_options_hash + options = { class: "special" } + sms_to "15155555785", "ME!", options + assert_equal({ class: "special" }, options) + end + def protect_against_forgery? request_forgery end |