actionview 6.1.3.1 → 7.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionview might be problematic. Click here for more details.

Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -261
  3. data/MIT-LICENSE +1 -1
  4. data/lib/action_view/base.rb +3 -3
  5. data/lib/action_view/buffers.rb +2 -2
  6. data/lib/action_view/cache_expiry.rb +46 -32
  7. data/lib/action_view/dependency_tracker/erb_tracker.rb +154 -0
  8. data/lib/action_view/dependency_tracker/ripper_tracker.rb +59 -0
  9. data/lib/action_view/dependency_tracker.rb +6 -147
  10. data/lib/action_view/digestor.rb +7 -4
  11. data/lib/action_view/flows.rb +4 -4
  12. data/lib/action_view/gem_version.rb +4 -4
  13. data/lib/action_view/helpers/active_model_helper.rb +1 -1
  14. data/lib/action_view/helpers/asset_tag_helper.rb +85 -30
  15. data/lib/action_view/helpers/asset_url_helper.rb +7 -7
  16. data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
  17. data/lib/action_view/helpers/cache_helper.rb +51 -3
  18. data/lib/action_view/helpers/capture_helper.rb +2 -2
  19. data/lib/action_view/helpers/controller_helper.rb +2 -2
  20. data/lib/action_view/helpers/csp_helper.rb +1 -1
  21. data/lib/action_view/helpers/csrf_helper.rb +1 -1
  22. data/lib/action_view/helpers/date_helper.rb +5 -5
  23. data/lib/action_view/helpers/debug_helper.rb +3 -1
  24. data/lib/action_view/helpers/form_helper.rb +72 -12
  25. data/lib/action_view/helpers/form_options_helper.rb +65 -33
  26. data/lib/action_view/helpers/form_tag_helper.rb +73 -30
  27. data/lib/action_view/helpers/javascript_helper.rb +3 -5
  28. data/lib/action_view/helpers/number_helper.rb +3 -4
  29. data/lib/action_view/helpers/output_safety_helper.rb +2 -2
  30. data/lib/action_view/helpers/rendering_helper.rb +1 -1
  31. data/lib/action_view/helpers/sanitize_helper.rb +2 -2
  32. data/lib/action_view/helpers/tag_helper.rb +17 -4
  33. data/lib/action_view/helpers/tags/base.rb +2 -14
  34. data/lib/action_view/helpers/tags/check_box.rb +1 -1
  35. data/lib/action_view/helpers/tags/collection_select.rb +1 -1
  36. data/lib/action_view/helpers/tags/time_field.rb +10 -1
  37. data/lib/action_view/helpers/tags/weekday_select.rb +27 -0
  38. data/lib/action_view/helpers/tags.rb +3 -2
  39. data/lib/action_view/helpers/text_helper.rb +24 -13
  40. data/lib/action_view/helpers/translation_helper.rb +4 -3
  41. data/lib/action_view/helpers/url_helper.rb +122 -80
  42. data/lib/action_view/helpers.rb +25 -25
  43. data/lib/action_view/lookup_context.rb +33 -52
  44. data/lib/action_view/model_naming.rb +1 -1
  45. data/lib/action_view/path_set.rb +16 -22
  46. data/lib/action_view/railtie.rb +15 -2
  47. data/lib/action_view/render_parser.rb +188 -0
  48. data/lib/action_view/renderer/abstract_renderer.rb +2 -2
  49. data/lib/action_view/renderer/partial_renderer.rb +0 -34
  50. data/lib/action_view/renderer/renderer.rb +4 -4
  51. data/lib/action_view/renderer/streaming_template_renderer.rb +3 -3
  52. data/lib/action_view/renderer/template_renderer.rb +6 -2
  53. data/lib/action_view/rendering.rb +2 -2
  54. data/lib/action_view/ripper_ast_parser.rb +198 -0
  55. data/lib/action_view/routing_url_for.rb +1 -1
  56. data/lib/action_view/template/error.rb +108 -13
  57. data/lib/action_view/template/handlers/erb.rb +6 -0
  58. data/lib/action_view/template/handlers.rb +3 -3
  59. data/lib/action_view/template/html.rb +3 -3
  60. data/lib/action_view/template/inline.rb +3 -3
  61. data/lib/action_view/template/raw_file.rb +3 -3
  62. data/lib/action_view/template/resolver.rb +84 -311
  63. data/lib/action_view/template/text.rb +3 -3
  64. data/lib/action_view/template/types.rb +14 -12
  65. data/lib/action_view/template.rb +10 -1
  66. data/lib/action_view/template_details.rb +66 -0
  67. data/lib/action_view/template_path.rb +64 -0
  68. data/lib/action_view/test_case.rb +6 -2
  69. data/lib/action_view/testing/resolvers.rb +11 -12
  70. data/lib/action_view/unbound_template.rb +33 -7
  71. data/lib/action_view.rb +3 -4
  72. data/lib/assets/compiled/rails-ujs.js +2 -2
  73. metadata +22 -15
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "action_view/helpers/tag_helper"
4
- require "active_support/core_ext/symbol/starts_ends_with"
5
4
 
6
5
  module ActionView
7
6
  # = Action View Translation Helpers
8
- module Helpers #:nodoc:
7
+ module Helpers # :nodoc:
9
8
  module TranslationHelper
10
9
  extend ActiveSupport::Concern
11
10
 
@@ -94,7 +93,9 @@ module ActionView
94
93
  break translated unless translated.equal?(MISSING_TRANSLATION)
95
94
  end
96
95
 
97
- break alternatives.first if alternatives.present? && !alternatives.first.is_a?(Symbol)
96
+ if alternatives.present? && !alternatives.first.is_a?(Symbol)
97
+ break alternatives.first && I18n.translate(**options, default: alternatives)
98
+ end
98
99
 
99
100
  first_key ||= key
100
101
  key = alternatives&.shift
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "action_view/helpers/javascript_helper"
4
3
  require "active_support/core_ext/array/access"
5
4
  require "active_support/core_ext/hash/keys"
6
5
  require "active_support/core_ext/string/output_safety"
6
+ require "action_view/helpers/tag_helper"
7
7
 
8
8
  module ActionView
9
9
  # = Action View URL Helpers
10
- module Helpers #:nodoc:
10
+ module Helpers # :nodoc:
11
11
  # Provides a set of methods for making links and getting URLs that
12
12
  # depend on the routing subsystem (see ActionDispatch::Routing).
13
13
  # This allows you to use the same format for links in views
@@ -29,6 +29,8 @@ module ActionView
29
29
  end
30
30
  end
31
31
 
32
+ mattr_accessor :button_to_generates_button_tag, default: false
33
+
32
34
  # Basic implementation of url_for to allow use helpers without routes existence
33
35
  def url_for(options = nil) # :nodoc:
34
36
  case options
@@ -101,17 +103,8 @@ module ActionView
101
103
  # completion of the Ajax request and performing JavaScript operations once
102
104
  # they're complete
103
105
  #
104
- # ==== Data attributes
105
- #
106
- # * <tt>confirm: 'question?'</tt> - This will allow the unobtrusive JavaScript
107
- # driver to prompt with the question specified (in this case, the
108
- # resulting text would be <tt>question?</tt>. If the user accepts, the
109
- # link is processed normally, otherwise no action is taken.
110
- # * <tt>:disable_with</tt> - Value of this parameter will be used as the
111
- # name for a disabled version of the link. This feature is provided by
112
- # the unobtrusive JavaScript driver.
113
- #
114
106
  # ==== Examples
107
+ #
115
108
  # Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
116
109
  # and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
117
110
  # your application on resources and use
@@ -184,15 +177,27 @@ module ActionView
184
177
  # link_to("Destroy", "http://www.example.com", method: :delete)
185
178
  # # => <a href='http://www.example.com' rel="nofollow" data-method="delete">Destroy</a>
186
179
  #
187
- # You can also use custom data attributes using the <tt>:data</tt> option:
188
- #
189
- # link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
190
- # # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
191
- #
192
180
  # Also you can set any link attributes such as <tt>target</tt>, <tt>rel</tt>, <tt>type</tt>:
193
181
  #
194
182
  # link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow"
195
183
  # # => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
184
+ #
185
+ # ==== Deprecated: Rails UJS attributes
186
+ #
187
+ # Prior to Rails 7, Rails shipped with a JavaScript library called @rails/ujs on by default. Following Rails 7,
188
+ # this library is no longer on by default. This library integrated with the following options:
189
+ #
190
+ # * <tt>confirm: 'question?'</tt> - This will allow the unobtrusive JavaScript
191
+ # driver to prompt with the question specified (in this case, the
192
+ # resulting text would be <tt>question?</tt>. If the user accepts, the
193
+ # link is processed normally, otherwise no action is taken.
194
+ # * <tt>:disable_with</tt> - Value of this parameter will be used as the
195
+ # name for a disabled version of the link. This feature is provided by
196
+ # the unobtrusive JavaScript driver.
197
+ #
198
+ # link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
199
+ # # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
200
+ #
196
201
  def link_to(name = nil, options = nil, html_options = nil, &block)
197
202
  html_options, options, name = options, name, block if block_given?
198
203
  options ||= {}
@@ -212,20 +217,24 @@ module ActionView
212
217
  # using the +link_to+ method with the <tt>:method</tt> modifier as described in
213
218
  # the +link_to+ documentation.
214
219
  #
215
- # By default, the generated form element has a class name of <tt>button_to</tt>
216
- # to allow styling of the form itself and its children. This can be changed
217
- # using the <tt>:form_class</tt> modifier within +html_options+. You can control
218
- # the form submission and input element behavior using +html_options+.
219
- # This method accepts the <tt>:method</tt> modifier described in the +link_to+ documentation.
220
- # If no <tt>:method</tt> modifier is given, it will default to performing a POST operation.
221
- # You can also disable the button by passing <tt>disabled: true</tt> in +html_options+.
222
- # If you are using RESTful routes, you can pass the <tt>:method</tt>
223
- # to change the HTTP verb used to submit the form.
220
+ # You can control the form and button behavior with +html_options+. Most
221
+ # values in +html_options+ are passed through to the button element. For
222
+ # example, passing a +:class+ option within +html_options+ will set the
223
+ # class attribute of the button element.
224
+ #
225
+ # The class attribute of the form element can be set by passing a
226
+ # +:form_class+ option within +html_options+. It defaults to
227
+ # <tt>"button_to"</tt> to allow styling of the form and its children.
228
+ #
229
+ # The form submits a POST request by default. You can specify a different
230
+ # HTTP verb via the +:method+ option within +html_options+.
224
231
  #
225
232
  # ==== Options
226
233
  # The +options+ hash accepts the same options as +url_for+.
227
234
  #
228
- # There are a few special +html_options+:
235
+ # Most values in +html_options+ are passed through to the button element,
236
+ # but there are a few special options:
237
+ #
229
238
  # * <tt>:method</tt> - \Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
230
239
  # <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
231
240
  # * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
@@ -250,12 +259,21 @@ module ActionView
250
259
  # ==== Examples
251
260
  # <%= button_to "New", action: "new" %>
252
261
  # # => "<form method="post" action="/controller/new" class="button_to">
253
- # # <input value="New" type="submit" />
262
+ # # <button type="submit">New</button>
263
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
254
264
  # # </form>"
255
265
  #
256
266
  # <%= button_to "New", new_article_path %>
257
267
  # # => "<form method="post" action="/articles/new" class="button_to">
258
- # # <input value="New" type="submit" />
268
+ # # <button type="submit">New</button>
269
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
270
+ # # </form>"
271
+ #
272
+ # <%= button_to "New", new_article_path, params: { time: Time.now } %>
273
+ # # => "<form method="post" action="/articles/new" class="button_to">
274
+ # # <button type="submit">New</button>
275
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
276
+ # # <input type="hidden" name="time" value="2021-04-08 14:06:09 -0500">
259
277
  # # </form>"
260
278
  #
261
279
  # <%= button_to [:make_happy, @user] do %>
@@ -265,35 +283,34 @@ module ActionView
265
283
  # # <button type="submit">
266
284
  # # Make happy <strong><%= @user.name %></strong>
267
285
  # # </button>
286
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
268
287
  # # </form>"
269
288
  #
270
289
  # <%= button_to "New", { action: "new" }, form_class: "new-thing" %>
271
290
  # # => "<form method="post" action="/controller/new" class="new-thing">
272
- # # <input value="New" type="submit" />
291
+ # # <button type="submit">New</button>
292
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
273
293
  # # </form>"
274
294
  #
275
- #
276
295
  # <%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
277
296
  # # => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
278
- # # <input value="Create" type="submit" />
297
+ # # <button type="submit">Create</button>
279
298
  # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
280
299
  # # </form>"
281
300
  #
282
- #
283
301
  # <%= button_to "Delete Image", { action: "delete", id: @image.id },
284
302
  # method: :delete, data: { confirm: "Are you sure?" } %>
285
303
  # # => "<form method="post" action="/images/delete/1" class="button_to">
286
304
  # # <input type="hidden" name="_method" value="delete" />
287
- # # <input data-confirm='Are you sure?' value="Delete Image" type="submit" />
305
+ # # <button data-confirm='Are you sure?' type="submit">Delete Image</button>
288
306
  # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
289
307
  # # </form>"
290
308
  #
291
- #
292
309
  # <%= button_to('Destroy', 'http://www.example.com',
293
310
  # method: :delete, remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
294
311
  # # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
295
312
  # # <input name='_method' value='delete' type='hidden' />
296
- # # <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
313
+ # # <button type='submit' data-disable-with='loading...' data-confirm='Are you sure?'>Destroy</button>
297
314
  # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
298
315
  # # </form>"
299
316
  # #
@@ -327,8 +344,8 @@ module ActionView
327
344
  html_options = convert_options_to_data_attributes(options, html_options)
328
345
  html_options["type"] = "submit"
329
346
 
330
- button = if block_given?
331
- content_tag("button", html_options, &block)
347
+ button = if block_given? || button_to_generates_button_tag
348
+ content_tag("button", name || url, html_options, &block)
332
349
  else
333
350
  html_options["value"] = name || url
334
351
  tag("input", html_options)
@@ -466,9 +483,9 @@ module ActionView
466
483
  # mail_to "me@domain.com", "My email"
467
484
  # # => <a href="mailto:me@domain.com">My email</a>
468
485
  #
469
- # mail_to "me@domain.com", "My email", cc: "ccaddress@domain.com",
486
+ # mail_to "me@domain.com", cc: "ccaddress@domain.com",
470
487
  # subject: "This is an example email"
471
- # # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">My email</a>
488
+ # # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">me@domain.com</a>
472
489
  #
473
490
  # You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
474
491
  #
@@ -479,7 +496,7 @@ module ActionView
479
496
  # <strong>Email me:</strong> <span>me@domain.com</span>
480
497
  # </a>
481
498
  def mail_to(email_address, name = nil, html_options = {}, &block)
482
- html_options, name = name, nil if block_given?
499
+ html_options, name = name, nil if name.is_a?(Hash)
483
500
  html_options = (html_options || {}).stringify_keys
484
501
 
485
502
  extras = %w{ cc bcc body subject reply_to }.map! { |item|
@@ -559,41 +576,60 @@ module ActionView
559
576
  request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
560
577
  request_uri = URI::DEFAULT_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY)
561
578
 
562
- if url_string.start_with?("/") && url_string != "/"
563
- url_string.chomp!("/")
564
- request_uri.chomp!("/")
579
+ if %r{^\w+://}.match?(url_string)
580
+ request_uri = +"#{request.protocol}#{request.host_with_port}#{request_uri}"
565
581
  end
566
582
 
567
- if %r{^\w+://}.match?(url_string)
568
- url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
569
- else
570
- url_string == request_uri
583
+ remove_trailing_slash!(url_string)
584
+ remove_trailing_slash!(request_uri)
585
+
586
+ url_string == request_uri
587
+ end
588
+
589
+ if RUBY_VERSION.start_with?("2.7")
590
+ using Module.new {
591
+ refine UrlHelper do
592
+ alias :_current_page? :current_page?
593
+ end
594
+ }
595
+
596
+ def current_page?(*args) # :nodoc:
597
+ options = args.pop
598
+ options.is_a?(Hash) ? _current_page?(*args, **options) : _current_page?(*args, options)
571
599
  end
572
600
  end
573
601
 
574
- # Creates an SMS anchor link tag to the specified +phone_number+, which is
575
- # also used as the name of the link unless +name+ is specified. Additional
576
- # HTML attributes for the link can be passed in +html_options+.
602
+ # Creates an SMS anchor link tag to the specified +phone_number+. When the
603
+ # link is clicked, the default SMS messaging app is opened ready to send a
604
+ # message to the linked phone number. If the +body+ option is specified,
605
+ # the contents of the message will be preset to +body+.
577
606
  #
578
- # When clicked, an SMS message is prepopulated with the passed phone number
579
- # and optional +body+ value.
607
+ # If +name+ is not specified, +phone_number+ will be used as the name of
608
+ # the link.
580
609
  #
581
- # +sms_to+ has a +body+ option for customizing the SMS message itself by
582
- # passing special keys to +html_options+.
610
+ # A +country_code+ option is supported, which prepends a plus sign and the
611
+ # given country code to the linked phone number. For example,
612
+ # <tt>country_code: "01"</tt> will prepend <tt>+01</tt> to the linked
613
+ # phone number.
614
+ #
615
+ # Additional HTML attributes for the link can be passed via +html_options+.
583
616
  #
584
617
  # ==== Options
618
+ # * <tt>:country_code</tt> - Prepend the country code to the phone number.
585
619
  # * <tt>:body</tt> - Preset the body of the message.
586
620
  #
587
621
  # ==== Examples
588
622
  # sms_to "5155555785"
589
623
  # # => <a href="sms:5155555785;">5155555785</a>
590
624
  #
625
+ # sms_to "5155555785", country_code: "01"
626
+ # # => <a href="sms:+015155555785;">5155555785</a>
627
+ #
591
628
  # sms_to "5155555785", "Text me"
592
629
  # # => <a href="sms:5155555785;">Text me</a>
593
630
  #
594
- # sms_to "5155555785", "Text me",
595
- # body: "Hello Jim I have a question about your product."
596
- # # => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a>
631
+ # sms_to "5155555785", body: "I have a question about your product."
632
+ # # => <a href="sms:5155555785;?body=I%20have%20a%20question%20about%20your%20product">5155555785</a>
597
633
  #
598
634
  # You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
599
635
  #
@@ -604,46 +640,47 @@ module ActionView
604
640
  # <strong>Text me:</strong>
605
641
  # </a>
606
642
  def sms_to(phone_number, name = nil, html_options = {}, &block)
607
- html_options, name = name, nil if block_given?
643
+ html_options, name = name, nil if name.is_a?(Hash)
608
644
  html_options = (html_options || {}).stringify_keys
609
645
 
610
- extras = %w{ body }.map! { |item|
611
- option = html_options.delete(item).presence || next
612
- "#{item.dasherize}=#{ERB::Util.url_encode(option)}"
613
- }.compact
614
- extras = extras.empty? ? "" : "?&" + extras.join("&")
646
+ country_code = html_options.delete("country_code").presence
647
+ country_code = country_code ? "+#{ERB::Util.url_encode(country_code)}" : ""
648
+
649
+ body = html_options.delete("body").presence
650
+ body = body ? "?&body=#{ERB::Util.url_encode(body)}" : ""
615
651
 
616
652
  encoded_phone_number = ERB::Util.url_encode(phone_number)
617
- html_options["href"] = "sms:#{encoded_phone_number};#{extras}"
653
+ html_options["href"] = "sms:#{country_code}#{encoded_phone_number};#{body}"
618
654
 
619
655
  content_tag("a", name || phone_number, html_options, &block)
620
656
  end
621
657
 
622
- # Creates a TEL anchor link tag to the specified +phone_number+, which is
623
- # also used as the name of the link unless +name+ is specified. Additional
624
- # HTML attributes for the link can be passed in +html_options+.
658
+ # Creates a TEL anchor link tag to the specified +phone_number+. When the
659
+ # link is clicked, the default app to make phone calls is opened and
660
+ # prepopulated with the phone number.
661
+ #
662
+ # If +name+ is not specified, +phone_number+ will be used as the name of
663
+ # the link.
625
664
  #
626
- # When clicked, the default app to make calls is opened, and it
627
- # is prepopulated with the passed phone number and optional
628
- # +country_code+ value.
665
+ # A +country_code+ option is supported, which prepends a plus sign and the
666
+ # given country code to the linked phone number. For example,
667
+ # <tt>country_code: "01"</tt> will prepend <tt>+01</tt> to the linked
668
+ # phone number.
629
669
  #
630
- # +phone_to+ has an optional +country_code+ option which automatically adds the country
631
- # code as well as the + sign in the phone numer that gets prepopulated,
632
- # for example if +country_code: "01"+ +\+01+ will be prepended to the
633
- # phone numer, by passing special keys to +html_options+.
670
+ # Additional HTML attributes for the link can be passed via +html_options+.
634
671
  #
635
672
  # ==== Options
636
- # * <tt>:country_code</tt> - Prepends the country code to the number
673
+ # * <tt>:country_code</tt> - Prepends the country code to the phone number
637
674
  #
638
675
  # ==== Examples
639
676
  # phone_to "1234567890"
640
677
  # # => <a href="tel:1234567890">1234567890</a>
641
678
  #
642
679
  # phone_to "1234567890", "Phone me"
643
- # # => <a href="tel:134567890">Phone me</a>
680
+ # # => <a href="tel:1234567890">Phone me</a>
644
681
  #
645
- # phone_to "1234567890", "Phone me", country_code: "01"
646
- # # => <a href="tel:+015155555785">Phone me</a>
682
+ # phone_to "1234567890", country_code: "01"
683
+ # # => <a href="tel:+011234567890">1234567890</a>
647
684
  #
648
685
  # You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
649
686
  #
@@ -654,7 +691,7 @@ module ActionView
654
691
  # <strong>Phone me:</strong>
655
692
  # </a>
656
693
  def phone_to(phone_number, name = nil, html_options = {}, &block)
657
- html_options, name = name, nil if block_given?
694
+ html_options, name = name, nil if name.is_a?(Hash)
658
695
  html_options = (html_options || {}).stringify_keys
659
696
 
660
697
  country_code = html_options.delete("country_code").presence
@@ -766,6 +803,11 @@ module ActionView
766
803
 
767
804
  params.sort_by { |pair| pair[:name] }
768
805
  end
806
+
807
+ def remove_trailing_slash!(url_string)
808
+ trailing_index = (url_string.index("?") || 0) - 1
809
+ url_string[trailing_index] = "" if url_string[trailing_index] == "/"
810
+ end
769
811
  end
770
812
  end
771
813
  end
@@ -1,34 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/benchmarkable"
4
+ require "action_view/helpers/capture_helper"
5
+ require "action_view/helpers/output_safety_helper"
6
+ require "action_view/helpers/tag_helper"
7
+ require "action_view/helpers/url_helper"
8
+ require "action_view/helpers/sanitize_helper"
9
+ require "action_view/helpers/text_helper"
10
+ require "action_view/helpers/active_model_helper"
11
+ require "action_view/helpers/asset_tag_helper"
12
+ require "action_view/helpers/asset_url_helper"
13
+ require "action_view/helpers/atom_feed_helper"
14
+ require "action_view/helpers/cache_helper"
15
+ require "action_view/helpers/controller_helper"
16
+ require "action_view/helpers/csp_helper"
17
+ require "action_view/helpers/csrf_helper"
18
+ require "action_view/helpers/date_helper"
19
+ require "action_view/helpers/debug_helper"
20
+ require "action_view/helpers/form_tag_helper"
21
+ require "action_view/helpers/form_helper"
22
+ require "action_view/helpers/form_options_helper"
23
+ require "action_view/helpers/javascript_helper"
24
+ require "action_view/helpers/number_helper"
25
+ require "action_view/helpers/rendering_helper"
26
+ require "action_view/helpers/translation_helper"
4
27
 
5
- module ActionView #:nodoc:
6
- module Helpers #:nodoc:
28
+ module ActionView # :nodoc:
29
+ module Helpers # :nodoc:
7
30
  extend ActiveSupport::Autoload
8
31
 
9
- autoload :ActiveModelHelper
10
- autoload :AssetTagHelper
11
- autoload :AssetUrlHelper
12
- autoload :AtomFeedHelper
13
- autoload :CacheHelper
14
- autoload :CaptureHelper
15
- autoload :ControllerHelper
16
- autoload :CspHelper
17
- autoload :CsrfHelper
18
- autoload :DateHelper
19
- autoload :DebugHelper
20
- autoload :FormHelper
21
- autoload :FormOptionsHelper
22
- autoload :FormTagHelper
23
- autoload :JavaScriptHelper, "action_view/helpers/javascript_helper"
24
- autoload :NumberHelper
25
- autoload :OutputSafetyHelper
26
- autoload :RenderingHelper
27
- autoload :SanitizeHelper
28
- autoload :TagHelper
29
- autoload :TextHelper
30
- autoload :TranslationHelper
31
- autoload :UrlHelper
32
32
  autoload :Tags
33
33
 
34
34
  def self.eager_load!