actionview 6.1.4.6 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +92 -306
- data/MIT-LICENSE +1 -1
- data/lib/action_view/base.rb +3 -3
- data/lib/action_view/buffers.rb +2 -2
- data/lib/action_view/cache_expiry.rb +46 -32
- data/lib/action_view/dependency_tracker/erb_tracker.rb +154 -0
- data/lib/action_view/dependency_tracker/ripper_tracker.rb +59 -0
- data/lib/action_view/dependency_tracker.rb +6 -147
- data/lib/action_view/digestor.rb +7 -4
- data/lib/action_view/flows.rb +4 -4
- data/lib/action_view/gem_version.rb +4 -4
- data/lib/action_view/helpers/active_model_helper.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +84 -29
- data/lib/action_view/helpers/asset_url_helper.rb +7 -7
- data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
- data/lib/action_view/helpers/cache_helper.rb +51 -3
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/controller_helper.rb +2 -2
- data/lib/action_view/helpers/csp_helper.rb +1 -1
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +5 -5
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +72 -12
- data/lib/action_view/helpers/form_options_helper.rb +65 -33
- data/lib/action_view/helpers/form_tag_helper.rb +73 -30
- data/lib/action_view/helpers/javascript_helper.rb +3 -5
- data/lib/action_view/helpers/number_helper.rb +3 -4
- data/lib/action_view/helpers/output_safety_helper.rb +2 -2
- data/lib/action_view/helpers/rendering_helper.rb +1 -1
- data/lib/action_view/helpers/sanitize_helper.rb +2 -2
- data/lib/action_view/helpers/tag_helper.rb +17 -4
- data/lib/action_view/helpers/tags/base.rb +2 -14
- data/lib/action_view/helpers/tags/check_box.rb +1 -1
- data/lib/action_view/helpers/tags/collection_select.rb +1 -1
- data/lib/action_view/helpers/tags/time_field.rb +10 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +27 -0
- data/lib/action_view/helpers/tags.rb +3 -2
- data/lib/action_view/helpers/text_helper.rb +24 -13
- data/lib/action_view/helpers/translation_helper.rb +1 -2
- data/lib/action_view/helpers/url_helper.rb +110 -81
- data/lib/action_view/helpers.rb +25 -25
- data/lib/action_view/lookup_context.rb +33 -52
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +16 -22
- data/lib/action_view/railtie.rb +15 -2
- data/lib/action_view/render_parser.rb +188 -0
- data/lib/action_view/renderer/abstract_renderer.rb +2 -2
- data/lib/action_view/renderer/partial_renderer.rb +0 -34
- data/lib/action_view/renderer/renderer.rb +4 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +3 -3
- data/lib/action_view/renderer/template_renderer.rb +6 -2
- data/lib/action_view/rendering.rb +2 -2
- data/lib/action_view/ripper_ast_parser.rb +198 -0
- data/lib/action_view/routing_url_for.rb +1 -1
- data/lib/action_view/template/error.rb +108 -13
- data/lib/action_view/template/handlers/erb.rb +6 -0
- data/lib/action_view/template/handlers.rb +3 -3
- data/lib/action_view/template/html.rb +3 -3
- data/lib/action_view/template/inline.rb +3 -3
- data/lib/action_view/template/raw_file.rb +3 -3
- data/lib/action_view/template/resolver.rb +84 -311
- data/lib/action_view/template/text.rb +3 -3
- data/lib/action_view/template/types.rb +14 -12
- data/lib/action_view/template.rb +10 -1
- data/lib/action_view/template_details.rb +66 -0
- data/lib/action_view/template_path.rb +64 -0
- data/lib/action_view/test_case.rb +6 -2
- data/lib/action_view/testing/resolvers.rb +11 -12
- data/lib/action_view/unbound_template.rb +33 -7
- data/lib/action_view.rb +3 -4
- metadata +25 -18
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionView
|
4
|
+
module Helpers
|
5
|
+
module Tags # :nodoc:
|
6
|
+
class WeekdaySelect < Base # :nodoc:
|
7
|
+
def initialize(object_name, method_name, template_object, options, html_options)
|
8
|
+
@html_options = html_options
|
9
|
+
|
10
|
+
super(object_name, method_name, template_object, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def render
|
14
|
+
select_content_tag(
|
15
|
+
weekday_options_for_select(
|
16
|
+
value || @options[:selected],
|
17
|
+
index_as_value: @options.fetch(:index_as_value, false),
|
18
|
+
day_format: @options.fetch(:day_format, :day_names)
|
19
|
+
),
|
20
|
+
@options,
|
21
|
+
@html_options
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionView
|
4
|
-
module Helpers
|
5
|
-
module Tags
|
4
|
+
module Helpers # :nodoc:
|
5
|
+
module Tags # :nodoc:
|
6
6
|
extend ActiveSupport::Autoload
|
7
7
|
|
8
8
|
eager_autoload do
|
@@ -38,6 +38,7 @@ module ActionView
|
|
38
38
|
autoload :TimeZoneSelect
|
39
39
|
autoload :UrlField
|
40
40
|
autoload :WeekField
|
41
|
+
autoload :WeekdaySelect
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
@@ -1,11 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/string/filters"
|
4
|
+
require "active_support/core_ext/string/access"
|
4
5
|
require "active_support/core_ext/array/extract_options"
|
6
|
+
require "action_view/helpers/sanitize_helper"
|
7
|
+
require "action_view/helpers/tag_helper"
|
8
|
+
require "action_view/helpers/output_safety_helper"
|
5
9
|
|
6
10
|
module ActionView
|
7
11
|
# = Action View Text Helpers
|
8
|
-
module Helpers
|
12
|
+
module Helpers # :nodoc:
|
9
13
|
# The TextHelper module provides a set of methods for filtering, formatting
|
10
14
|
# and transforming strings, which can reduce the amount of inline Ruby code in
|
11
15
|
# your views. These helper methods extend Action View making them callable
|
@@ -129,7 +133,7 @@ module ActionView
|
|
129
133
|
#
|
130
134
|
# highlight('<a href="javascript:alert(\'no!\')">ruby</a> on rails', 'rails', sanitize: false)
|
131
135
|
# # => <a href="javascript:alert('no!')">ruby</a> on <mark>rails</mark>
|
132
|
-
def highlight(text, phrases, options = {})
|
136
|
+
def highlight(text, phrases, options = {}, &block)
|
133
137
|
text = sanitize(text) if options.fetch(:sanitize, true)
|
134
138
|
|
135
139
|
if text.blank? || phrases.blank?
|
@@ -140,7 +144,7 @@ module ActionView
|
|
140
144
|
end.join("|")
|
141
145
|
|
142
146
|
if block_given?
|
143
|
-
text.gsub(/(#{match})(?![^<]*?>)/i)
|
147
|
+
text.gsub(/(#{match})(?![^<]*?>)/i, &block)
|
144
148
|
else
|
145
149
|
highlighter = options.fetch(:highlighter, '<mark>\1</mark>')
|
146
150
|
text.gsub(/(#{match})(?![^<]*?>)/i, highlighter)
|
@@ -403,7 +407,7 @@ module ActionView
|
|
403
407
|
cycle.reset if cycle
|
404
408
|
end
|
405
409
|
|
406
|
-
class Cycle
|
410
|
+
class Cycle # :nodoc:
|
407
411
|
attr_reader :values
|
408
412
|
|
409
413
|
def initialize(first_value, *values)
|
@@ -467,18 +471,25 @@ module ActionView
|
|
467
471
|
radius = options.fetch(:radius, 100)
|
468
472
|
omission = options.fetch(:omission, "...")
|
469
473
|
|
470
|
-
|
471
|
-
|
472
|
-
|
474
|
+
if separator != ""
|
475
|
+
part = part.split(separator)
|
476
|
+
part.delete("")
|
477
|
+
end
|
473
478
|
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
+
affix = part.length > radius ? omission : ""
|
480
|
+
|
481
|
+
part =
|
482
|
+
if part_position == :first
|
483
|
+
part.last(radius)
|
484
|
+
else
|
485
|
+
part.first(radius)
|
486
|
+
end
|
487
|
+
|
488
|
+
if separator != ""
|
489
|
+
part = part.join(separator)
|
479
490
|
end
|
480
491
|
|
481
|
-
return affix, part
|
492
|
+
return affix, part
|
482
493
|
end
|
483
494
|
end
|
484
495
|
end
|
@@ -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
|
7
|
+
module Helpers # :nodoc:
|
9
8
|
module TranslationHelper
|
10
9
|
extend ActiveSupport::Concern
|
11
10
|
|
@@ -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
|
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
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
222
|
-
#
|
223
|
-
#
|
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
|
-
#
|
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
|
-
# # <
|
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
|
-
# # <
|
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
|
-
# # <
|
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
|
-
# # <
|
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
|
-
# # <
|
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
|
-
# # <
|
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",
|
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">
|
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
|
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,16 +576,14 @@ 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!("/")
|
565
|
-
end
|
566
|
-
|
567
579
|
if %r{^\w+://}.match?(url_string)
|
568
|
-
|
569
|
-
else
|
570
|
-
url_string == request_uri
|
580
|
+
request_uri = +"#{request.protocol}#{request.host_with_port}#{request_uri}"
|
571
581
|
end
|
582
|
+
|
583
|
+
remove_trailing_slash!(url_string)
|
584
|
+
remove_trailing_slash!(request_uri)
|
585
|
+
|
586
|
+
url_string == request_uri
|
572
587
|
end
|
573
588
|
|
574
589
|
if RUBY_VERSION.start_with?("2.7")
|
@@ -584,29 +599,37 @@ module ActionView
|
|
584
599
|
end
|
585
600
|
end
|
586
601
|
|
587
|
-
# Creates an SMS anchor link tag to the specified +phone_number
|
588
|
-
#
|
589
|
-
#
|
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+.
|
590
606
|
#
|
591
|
-
#
|
592
|
-
#
|
607
|
+
# If +name+ is not specified, +phone_number+ will be used as the name of
|
608
|
+
# the link.
|
593
609
|
#
|
594
|
-
# +
|
595
|
-
#
|
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+.
|
596
616
|
#
|
597
617
|
# ==== Options
|
618
|
+
# * <tt>:country_code</tt> - Prepend the country code to the phone number.
|
598
619
|
# * <tt>:body</tt> - Preset the body of the message.
|
599
620
|
#
|
600
621
|
# ==== Examples
|
601
622
|
# sms_to "5155555785"
|
602
623
|
# # => <a href="sms:5155555785;">5155555785</a>
|
603
624
|
#
|
625
|
+
# sms_to "5155555785", country_code: "01"
|
626
|
+
# # => <a href="sms:+015155555785;">5155555785</a>
|
627
|
+
#
|
604
628
|
# sms_to "5155555785", "Text me"
|
605
629
|
# # => <a href="sms:5155555785;">Text me</a>
|
606
630
|
#
|
607
|
-
# sms_to "5155555785", "
|
608
|
-
#
|
609
|
-
# # => <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>
|
610
633
|
#
|
611
634
|
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
612
635
|
#
|
@@ -617,46 +640,47 @@ module ActionView
|
|
617
640
|
# <strong>Text me:</strong>
|
618
641
|
# </a>
|
619
642
|
def sms_to(phone_number, name = nil, html_options = {}, &block)
|
620
|
-
html_options, name = name, nil if
|
643
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
621
644
|
html_options = (html_options || {}).stringify_keys
|
622
645
|
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
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)}" : ""
|
628
651
|
|
629
652
|
encoded_phone_number = ERB::Util.url_encode(phone_number)
|
630
|
-
html_options["href"] = "sms:#{encoded_phone_number};#{
|
653
|
+
html_options["href"] = "sms:#{country_code}#{encoded_phone_number};#{body}"
|
631
654
|
|
632
655
|
content_tag("a", name || phone_number, html_options, &block)
|
633
656
|
end
|
634
657
|
|
635
|
-
# Creates a TEL anchor link tag to the specified +phone_number
|
636
|
-
#
|
637
|
-
#
|
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.
|
638
664
|
#
|
639
|
-
#
|
640
|
-
#
|
641
|
-
#
|
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.
|
642
669
|
#
|
643
|
-
#
|
644
|
-
# code as well as the + sign in the phone numer that gets prepopulated,
|
645
|
-
# for example if +country_code: "01"+ +\+01+ will be prepended to the
|
646
|
-
# phone numer, by passing special keys to +html_options+.
|
670
|
+
# Additional HTML attributes for the link can be passed via +html_options+.
|
647
671
|
#
|
648
672
|
# ==== Options
|
649
|
-
# * <tt>:country_code</tt> - Prepends the country code to the number
|
673
|
+
# * <tt>:country_code</tt> - Prepends the country code to the phone number
|
650
674
|
#
|
651
675
|
# ==== Examples
|
652
676
|
# phone_to "1234567890"
|
653
677
|
# # => <a href="tel:1234567890">1234567890</a>
|
654
678
|
#
|
655
679
|
# phone_to "1234567890", "Phone me"
|
656
|
-
# # => <a href="tel:
|
680
|
+
# # => <a href="tel:1234567890">Phone me</a>
|
657
681
|
#
|
658
|
-
# phone_to "1234567890",
|
659
|
-
# # => <a href="tel:+
|
682
|
+
# phone_to "1234567890", country_code: "01"
|
683
|
+
# # => <a href="tel:+011234567890">1234567890</a>
|
660
684
|
#
|
661
685
|
# You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
|
662
686
|
#
|
@@ -667,7 +691,7 @@ module ActionView
|
|
667
691
|
# <strong>Phone me:</strong>
|
668
692
|
# </a>
|
669
693
|
def phone_to(phone_number, name = nil, html_options = {}, &block)
|
670
|
-
html_options, name = name, nil if
|
694
|
+
html_options, name = name, nil if name.is_a?(Hash)
|
671
695
|
html_options = (html_options || {}).stringify_keys
|
672
696
|
|
673
697
|
country_code = html_options.delete("country_code").presence
|
@@ -779,6 +803,11 @@ module ActionView
|
|
779
803
|
|
780
804
|
params.sort_by { |pair| pair[:name] }
|
781
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
|
782
811
|
end
|
783
812
|
end
|
784
813
|
end
|
data/lib/action_view/helpers.rb
CHANGED
@@ -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
|
6
|
-
module Helpers
|
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!
|