aboutsummaryrefslogtreecommitdiffstats
path: root/actionview
diff options
context:
space:
mode:
Diffstat (limited to 'actionview')
-rw-r--r--actionview/CHANGELOG.md5
-rw-r--r--actionview/lib/action_view/helpers/url_helper.rb48
-rw-r--r--actionview/lib/action_view/template/error.rb20
-rw-r--r--actionview/lib/action_view/unbound_template.rb6
-rw-r--r--actionview/test/template/template_error_test.rb16
-rw-r--r--actionview/test/template/url_helper_test.rb62
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