actionview 4.2.10 → 5.1.0
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 +141 -272
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/action_view/base.rb +33 -21
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +1 -1
- data/lib/action_view/dependency_tracker.rb +52 -20
- data/lib/action_view/digestor.rb +86 -83
- data/lib/action_view/flows.rb +9 -11
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/active_model_helper.rb +8 -8
- data/lib/action_view/helpers/asset_tag_helper.rb +74 -38
- data/lib/action_view/helpers/asset_url_helper.rb +160 -59
- data/lib/action_view/helpers/atom_feed_helper.rb +16 -16
- data/lib/action_view/helpers/cache_helper.rb +90 -35
- data/lib/action_view/helpers/capture_helper.rb +7 -6
- data/lib/action_view/helpers/controller_helper.rb +3 -2
- data/lib/action_view/helpers/csrf_helper.rb +3 -3
- data/lib/action_view/helpers/date_helper.rb +156 -108
- data/lib/action_view/helpers/debug_helper.rb +3 -4
- data/lib/action_view/helpers/form_helper.rb +475 -94
- data/lib/action_view/helpers/form_options_helper.rb +87 -47
- data/lib/action_view/helpers/form_tag_helper.rb +88 -57
- data/lib/action_view/helpers/javascript_helper.rb +10 -10
- data/lib/action_view/helpers/number_helper.rb +76 -59
- data/lib/action_view/helpers/output_safety_helper.rb +34 -4
- data/lib/action_view/helpers/record_tag_helper.rb +12 -99
- data/lib/action_view/helpers/rendering_helper.rb +3 -3
- data/lib/action_view/helpers/sanitize_helper.rb +17 -14
- data/lib/action_view/helpers/tag_helper.rb +198 -73
- data/lib/action_view/helpers/tags/base.rb +132 -97
- data/lib/action_view/helpers/tags/check_box.rb +17 -17
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +9 -33
- data/lib/action_view/helpers/tags/collection_helpers.rb +68 -36
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -11
- data/lib/action_view/helpers/tags/collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/date_select.rb +36 -36
- data/lib/action_view/helpers/tags/datetime_field.rb +1 -1
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
- data/lib/action_view/helpers/tags/label.rb +5 -1
- data/lib/action_view/helpers/tags/password_field.rb +1 -1
- data/lib/action_view/helpers/tags/placeholderable.rb +1 -1
- data/lib/action_view/helpers/tags/radio_button.rb +4 -4
- data/lib/action_view/helpers/tags/search_field.rb +12 -9
- data/lib/action_view/helpers/tags/select.rb +9 -9
- data/lib/action_view/helpers/tags/text_area.rb +1 -1
- data/lib/action_view/helpers/tags/text_field.rb +5 -6
- data/lib/action_view/helpers/tags/translator.rb +15 -13
- data/lib/action_view/helpers/text_helper.rb +47 -30
- data/lib/action_view/helpers/translation_helper.rb +60 -30
- data/lib/action_view/helpers/url_helper.rb +132 -104
- data/lib/action_view/helpers.rb +1 -1
- data/lib/action_view/layouts.rb +59 -54
- data/lib/action_view/log_subscriber.rb +56 -7
- data/lib/action_view/lookup_context.rb +76 -61
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +28 -19
- data/lib/action_view/railtie.rb +30 -6
- data/lib/action_view/record_identifier.rb +51 -25
- data/lib/action_view/renderer/abstract_renderer.rb +19 -15
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +55 -0
- data/lib/action_view/renderer/partial_renderer.rb +208 -206
- data/lib/action_view/renderer/renderer.rb +2 -6
- data/lib/action_view/renderer/streaming_template_renderer.rb +46 -48
- data/lib/action_view/renderer/template_renderer.rb +65 -66
- data/lib/action_view/rendering.rb +16 -9
- data/lib/action_view/routing_url_for.rb +25 -17
- data/lib/action_view/tasks/cache_digests.rake +23 -0
- data/lib/action_view/template/error.rb +14 -13
- data/lib/action_view/template/handlers/builder.rb +7 -7
- data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +9 -0
- data/lib/action_view/template/handlers/erb/erubi.rb +81 -0
- data/lib/action_view/template/handlers/erb/erubis.rb +81 -0
- data/lib/action_view/template/handlers/erb.rb +9 -76
- data/lib/action_view/template/handlers/html.rb +9 -0
- data/lib/action_view/template/handlers/raw.rb +1 -3
- data/lib/action_view/template/handlers.rb +8 -6
- data/lib/action_view/template/html.rb +2 -4
- data/lib/action_view/template/resolver.rb +133 -109
- data/lib/action_view/template/text.rb +5 -8
- data/lib/action_view/template/types.rb +15 -17
- data/lib/action_view/template.rb +51 -28
- data/lib/action_view/test_case.rb +32 -27
- data/lib/action_view/testing/resolvers.rb +29 -31
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +26 -32
- data/lib/action_view.rb +5 -5
- data/lib/assets/compiled/rails-ujs.js +685 -0
- metadata +23 -23
- data/lib/action_view/tasks/dependencies.rake +0 -23
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require "action_view/helpers/tag_helper"
|
2
2
|
|
3
3
|
module ActionView
|
4
4
|
module Helpers
|
5
5
|
module JavaScriptHelper
|
6
6
|
JS_ESCAPE_MAP = {
|
7
7
|
'\\' => '\\\\',
|
8
|
-
|
8
|
+
"</" => '<\/',
|
9
9
|
"\r\n" => '\n',
|
10
10
|
"\n" => '\n',
|
11
11
|
"\r" => '\n',
|
@@ -13,21 +13,21 @@ module ActionView
|
|
13
13
|
"'" => "\\'"
|
14
14
|
}
|
15
15
|
|
16
|
-
JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] =
|
17
|
-
JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] =
|
16
|
+
JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = "
"
|
17
|
+
JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = "
"
|
18
18
|
|
19
19
|
# Escapes carriage returns and single and double quotes for JavaScript segments.
|
20
20
|
#
|
21
21
|
# Also available through the alias j(). This is particularly helpful in JavaScript
|
22
22
|
# responses, like:
|
23
23
|
#
|
24
|
-
# $('some_element').replaceWith('<%=j render 'some/element_template' %>');
|
24
|
+
# $('some_element').replaceWith('<%= j render 'some/element_template' %>');
|
25
25
|
def escape_javascript(javascript)
|
26
26
|
if javascript
|
27
|
-
result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }
|
27
|
+
result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) { |match| JS_ESCAPE_MAP[match] }
|
28
28
|
javascript.html_safe? ? result.html_safe : result
|
29
29
|
else
|
30
|
-
|
30
|
+
""
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -47,8 +47,8 @@ module ActionView
|
|
47
47
|
# tag.
|
48
48
|
#
|
49
49
|
# javascript_tag "alert('All is good')", defer: 'defer'
|
50
|
-
#
|
51
|
-
# Returns:
|
50
|
+
#
|
51
|
+
# Returns:
|
52
52
|
# <script defer="defer">
|
53
53
|
# //<![CDATA[
|
54
54
|
# alert('All is good')
|
@@ -70,7 +70,7 @@ module ActionView
|
|
70
70
|
content_or_options_with_block
|
71
71
|
end
|
72
72
|
|
73
|
-
content_tag(
|
73
|
+
content_tag("script".freeze, javascript_cdata_section(content), html_options)
|
74
74
|
end
|
75
75
|
|
76
76
|
def javascript_cdata_section(content) #:nodoc:
|
@@ -1,13 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require 'active_support/core_ext/string/output_safety'
|
5
|
-
require 'active_support/number_helper'
|
1
|
+
require "active_support/core_ext/hash/keys"
|
2
|
+
require "active_support/core_ext/string/output_safety"
|
3
|
+
require "active_support/number_helper"
|
6
4
|
|
7
5
|
module ActionView
|
8
6
|
# = Action View Number Helpers
|
9
7
|
module Helpers #:nodoc:
|
10
|
-
|
11
8
|
# Provides methods for converting numbers into formatted strings.
|
12
9
|
# Methods are provided for phone numbers, currency, percentage,
|
13
10
|
# precision, positional notation, file size and pretty printing.
|
@@ -15,7 +12,6 @@ module ActionView
|
|
15
12
|
# Most methods expect a +number+ argument, and will return it
|
16
13
|
# unchanged if can't be converted into a valid number.
|
17
14
|
module NumberHelper
|
18
|
-
|
19
15
|
# Raised when argument +number+ param given to the helpers is invalid and
|
20
16
|
# the option :raise is set to +true+.
|
21
17
|
class InvalidNumberError < StandardError
|
@@ -25,7 +21,7 @@ module ActionView
|
|
25
21
|
end
|
26
22
|
end
|
27
23
|
|
28
|
-
# Formats a +number+ into a
|
24
|
+
# Formats a +number+ into a phone number (US by default e.g., (555)
|
29
25
|
# 123-9876). You can customize the format in the +options+ hash.
|
30
26
|
#
|
31
27
|
# ==== Options
|
@@ -37,6 +33,8 @@ module ActionView
|
|
37
33
|
# end of the generated number.
|
38
34
|
# * <tt>:country_code</tt> - Sets the country code for the phone
|
39
35
|
# number.
|
36
|
+
# * <tt>:pattern</tt> - Specifies how the number is divided into three
|
37
|
+
# groups with the custom regexp to override the default format.
|
40
38
|
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
|
41
39
|
# the argument is invalid.
|
42
40
|
#
|
@@ -54,6 +52,11 @@ module ActionView
|
|
54
52
|
#
|
55
53
|
# number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: ".")
|
56
54
|
# # => +1.123.555.1234 x 1343
|
55
|
+
#
|
56
|
+
# number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
|
57
|
+
# # => "(755) 6123-4567"
|
58
|
+
# number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/))
|
59
|
+
# # => "133-1234-5678"
|
57
60
|
def number_to_phone(number, options = {})
|
58
61
|
return unless number
|
59
62
|
options = options.symbolize_keys
|
@@ -65,6 +68,14 @@ module ActionView
|
|
65
68
|
# Formats a +number+ into a currency string (e.g., $13.65). You
|
66
69
|
# can customize the format in the +options+ hash.
|
67
70
|
#
|
71
|
+
# The currency unit and number formatting of the current locale will be used
|
72
|
+
# unless otherwise specified in the provided options. No currency conversion
|
73
|
+
# is performed. If the user is given a way to change their locale, they will
|
74
|
+
# also be able to change the relative value of the currency displayed with
|
75
|
+
# this helper. If your application will ever support multiple locales, you
|
76
|
+
# may want to specify a constant <tt>:locale</tt> option or consider
|
77
|
+
# using a library capable of currency conversion.
|
78
|
+
#
|
68
79
|
# ==== Options
|
69
80
|
#
|
70
81
|
# * <tt>:locale</tt> - Sets the locale to be used for formatting
|
@@ -81,7 +92,7 @@ module ActionView
|
|
81
92
|
# (defaults to "%u%n"). Fields are <tt>%u</tt> for the
|
82
93
|
# currency, and <tt>%n</tt> for the number.
|
83
94
|
# * <tt>:negative_format</tt> - Sets the format for negative
|
84
|
-
# numbers (defaults to prepending
|
95
|
+
# numbers (defaults to prepending a hyphen to the formatted
|
85
96
|
# number given by <tt>:format</tt>). Accepts the same fields
|
86
97
|
# than <tt>:format</tt>, except <tt>%n</tt> is here the
|
87
98
|
# absolute value of the number.
|
@@ -117,8 +128,8 @@ module ActionView
|
|
117
128
|
# (defaults to current locale).
|
118
129
|
# * <tt>:precision</tt> - Sets the precision of the number
|
119
130
|
# (defaults to 3).
|
120
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
121
|
-
# of significant_digits. If +false+, the
|
131
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
132
|
+
# of significant_digits. If +false+, the number of fractional
|
122
133
|
# digits (defaults to +false+).
|
123
134
|
# * <tt>:separator</tt> - Sets the separator between the
|
124
135
|
# fractional and integer digits (defaults to ".").
|
@@ -141,7 +152,7 @@ module ActionView
|
|
141
152
|
# number_to_percentage(302.24398923423, precision: 5) # => 302.24399%
|
142
153
|
# number_to_percentage(1000, locale: :fr) # => 1 000,000%
|
143
154
|
# number_to_percentage("98a") # => 98a%
|
144
|
-
# number_to_percentage(100, format: "%n %") # => 100 %
|
155
|
+
# number_to_percentage(100, format: "%n %") # => 100.000 %
|
145
156
|
#
|
146
157
|
# number_to_percentage("98a", raise: true) # => InvalidNumberError
|
147
158
|
def number_to_percentage(number, options = {})
|
@@ -160,6 +171,9 @@ module ActionView
|
|
160
171
|
# to ",").
|
161
172
|
# * <tt>:separator</tt> - Sets the separator between the
|
162
173
|
# fractional and integer digits (defaults to ".").
|
174
|
+
# * <tt>:delimiter_pattern</tt> - Sets a custom regular expression used for
|
175
|
+
# deriving the placement of delimiter. Helpful when using currency formats
|
176
|
+
# like INR.
|
163
177
|
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
|
164
178
|
# the argument is invalid.
|
165
179
|
#
|
@@ -176,6 +190,9 @@ module ActionView
|
|
176
190
|
# number_with_delimiter(98765432.98, delimiter: " ", separator: ",")
|
177
191
|
# # => 98 765 432,98
|
178
192
|
#
|
193
|
+
# number_with_delimiter("123456.78",
|
194
|
+
# delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/) # => "1,23,456.78"
|
195
|
+
#
|
179
196
|
# number_with_delimiter("112a", raise: true) # => raise InvalidNumberError
|
180
197
|
def number_with_delimiter(number, options = {})
|
181
198
|
delegate_number_helper_method(:number_to_delimited, number, options)
|
@@ -192,8 +209,8 @@ module ActionView
|
|
192
209
|
# (defaults to current locale).
|
193
210
|
# * <tt>:precision</tt> - Sets the precision of the number
|
194
211
|
# (defaults to 3).
|
195
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
196
|
-
# of significant_digits. If +false+, the
|
212
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
213
|
+
# of significant_digits. If +false+, the number of fractional
|
197
214
|
# digits (defaults to +false+).
|
198
215
|
# * <tt>:separator</tt> - Sets the separator between the
|
199
216
|
# fractional and integer digits (defaults to ".").
|
@@ -240,8 +257,8 @@ module ActionView
|
|
240
257
|
# (defaults to current locale).
|
241
258
|
# * <tt>:precision</tt> - Sets the precision of the number
|
242
259
|
# (defaults to 3).
|
243
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
244
|
-
# of significant_digits. If +false+, the
|
260
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
261
|
+
# of significant_digits. If +false+, the number of fractional
|
245
262
|
# digits (defaults to +true+)
|
246
263
|
# * <tt>:separator</tt> - Sets the separator between the
|
247
264
|
# fractional and integer digits (defaults to ".").
|
@@ -250,8 +267,6 @@ module ActionView
|
|
250
267
|
# * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
|
251
268
|
# insignificant zeros after the decimal separator (defaults to
|
252
269
|
# +true+)
|
253
|
-
# * <tt>:prefix</tt> - If +:si+ formats the number using the SI
|
254
|
-
# prefix (defaults to :binary)
|
255
270
|
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
|
256
271
|
# the argument is invalid.
|
257
272
|
#
|
@@ -263,6 +278,8 @@ module ActionView
|
|
263
278
|
# number_to_human_size(1234567) # => 1.18 MB
|
264
279
|
# number_to_human_size(1234567890) # => 1.15 GB
|
265
280
|
# number_to_human_size(1234567890123) # => 1.12 TB
|
281
|
+
# number_to_human_size(1234567890123456) # => 1.1 PB
|
282
|
+
# number_to_human_size(1234567890123456789) # => 1.07 EB
|
266
283
|
# number_to_human_size(1234567, precision: 2) # => 1.2 MB
|
267
284
|
# number_to_human_size(483989, precision: 2) # => 470 KB
|
268
285
|
# number_to_human_size(1234567, precision: 2, separator: ',') # => 1,2 MB
|
@@ -280,7 +297,7 @@ module ActionView
|
|
280
297
|
# See <tt>number_to_human_size</tt> if you want to print a file
|
281
298
|
# size.
|
282
299
|
#
|
283
|
-
# You can also define
|
300
|
+
# You can also define your own unit-quantifier names if you want
|
284
301
|
# to use other decimal units (eg.: 1500 becomes "1.5
|
285
302
|
# kilometers", 0.150 becomes "150 milliliters", etc). You may
|
286
303
|
# define a wide range of unit quantifiers, even fractional ones
|
@@ -292,8 +309,8 @@ module ActionView
|
|
292
309
|
# (defaults to current locale).
|
293
310
|
# * <tt>:precision</tt> - Sets the precision of the number
|
294
311
|
# (defaults to 3).
|
295
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
296
|
-
# of significant_digits. If +false+, the
|
312
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
313
|
+
# of significant_digits. If +false+, the number of fractional
|
297
314
|
# digits (defaults to +true+)
|
298
315
|
# * <tt>:separator</tt> - Sets the separator between the
|
299
316
|
# fractional and integer digits (defaults to ".").
|
@@ -380,53 +397,53 @@ module ActionView
|
|
380
397
|
|
381
398
|
private
|
382
399
|
|
383
|
-
|
384
|
-
|
385
|
-
|
400
|
+
def delegate_number_helper_method(method, number, options)
|
401
|
+
return unless number
|
402
|
+
options = escape_unsafe_options(options.symbolize_keys)
|
386
403
|
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
404
|
+
wrap_with_output_safety_handling(number, options.delete(:raise)) {
|
405
|
+
ActiveSupport::NumberHelper.public_send(method, number, options)
|
406
|
+
}
|
407
|
+
end
|
391
408
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
409
|
+
def escape_unsafe_options(options)
|
410
|
+
options[:format] = ERB::Util.html_escape(options[:format]) if options[:format]
|
411
|
+
options[:negative_format] = ERB::Util.html_escape(options[:negative_format]) if options[:negative_format]
|
412
|
+
options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator]
|
413
|
+
options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter]
|
414
|
+
options[:unit] = ERB::Util.html_escape(options[:unit]) if options[:unit] && !options[:unit].html_safe?
|
415
|
+
options[:units] = escape_units(options[:units]) if options[:units] && Hash === options[:units]
|
416
|
+
options
|
417
|
+
end
|
401
418
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
419
|
+
def escape_units(units)
|
420
|
+
Hash[units.map do |k, v|
|
421
|
+
[k, ERB::Util.html_escape(v)]
|
422
|
+
end]
|
423
|
+
end
|
407
424
|
|
408
|
-
|
409
|
-
|
410
|
-
|
425
|
+
def wrap_with_output_safety_handling(number, raise_on_invalid, &block)
|
426
|
+
valid_float = valid_float?(number)
|
427
|
+
raise InvalidNumberError, number if raise_on_invalid && !valid_float
|
411
428
|
|
412
|
-
|
429
|
+
formatted_number = yield
|
413
430
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
431
|
+
if valid_float || number.html_safe?
|
432
|
+
formatted_number.html_safe
|
433
|
+
else
|
434
|
+
formatted_number
|
435
|
+
end
|
418
436
|
end
|
419
|
-
end
|
420
437
|
|
421
|
-
|
422
|
-
|
423
|
-
|
438
|
+
def valid_float?(number)
|
439
|
+
!parse_float(number, false).nil?
|
440
|
+
end
|
424
441
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
442
|
+
def parse_float(number, raise_error)
|
443
|
+
Float(number)
|
444
|
+
rescue ArgumentError, TypeError
|
445
|
+
raise InvalidNumberError, number if raise_error
|
446
|
+
end
|
430
447
|
end
|
431
448
|
end
|
432
449
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/core_ext/string/output_safety"
|
2
2
|
|
3
3
|
module ActionView #:nodoc:
|
4
4
|
# = Action View Raw Output Helper
|
@@ -22,17 +22,47 @@ module ActionView #:nodoc:
|
|
22
22
|
# the supplied separator, are HTML escaped unless they are HTML
|
23
23
|
# safe, and the returned string is marked as HTML safe.
|
24
24
|
#
|
25
|
-
# safe_join(["<p>foo</p>"
|
25
|
+
# safe_join([raw("<p>foo</p>"), "<p>bar</p>"], "<br />")
|
26
26
|
# # => "<p>foo</p><br /><p>bar</p>"
|
27
27
|
#
|
28
|
-
# safe_join(["<p>foo</p>"
|
28
|
+
# safe_join([raw("<p>foo</p>"), raw("<p>bar</p>")], raw("<br />"))
|
29
29
|
# # => "<p>foo</p><br /><p>bar</p>"
|
30
30
|
#
|
31
|
-
def safe_join(array, sep
|
31
|
+
def safe_join(array, sep = $,)
|
32
32
|
sep = ERB::Util.unwrapped_html_escape(sep)
|
33
33
|
|
34
34
|
array.flatten.map! { |i| ERB::Util.unwrapped_html_escape(i) }.join(sep).html_safe
|
35
35
|
end
|
36
|
+
|
37
|
+
# Converts the array to a comma-separated sentence where the last element is
|
38
|
+
# joined by the connector word. This is the html_safe-aware version of
|
39
|
+
# ActiveSupport's {Array#to_sentence}[http://api.rubyonrails.org/classes/Array.html#method-i-to_sentence].
|
40
|
+
#
|
41
|
+
def to_sentence(array, options = {})
|
42
|
+
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
|
43
|
+
|
44
|
+
default_connectors = {
|
45
|
+
words_connector: ", ",
|
46
|
+
two_words_connector: " and ",
|
47
|
+
last_word_connector: ", and "
|
48
|
+
}
|
49
|
+
if defined?(I18n)
|
50
|
+
i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
|
51
|
+
default_connectors.merge!(i18n_connectors)
|
52
|
+
end
|
53
|
+
options = default_connectors.merge!(options)
|
54
|
+
|
55
|
+
case array.length
|
56
|
+
when 0
|
57
|
+
"".html_safe
|
58
|
+
when 1
|
59
|
+
ERB::Util.html_escape(array[0])
|
60
|
+
when 2
|
61
|
+
safe_join([array[0], array[1]], options[:two_words_connector])
|
62
|
+
else
|
63
|
+
safe_join([safe_join(array[0...-1], options[:words_connector]), options[:last_word_connector], array[-1]], nil)
|
64
|
+
end
|
65
|
+
end
|
36
66
|
end
|
37
67
|
end
|
38
68
|
end
|
@@ -1,108 +1,21 @@
|
|
1
|
-
require 'action_view/record_identifier'
|
2
|
-
|
3
1
|
module ActionView
|
4
|
-
# = Action View Record Tag Helpers
|
5
2
|
module Helpers
|
6
3
|
module RecordTagHelper
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# <%= @person.name %>
|
14
|
-
# <% end %>
|
15
|
-
#
|
16
|
-
# produces:
|
17
|
-
#
|
18
|
-
# <div id="person_123" class="person foo"> Joe Bloggs </div>
|
19
|
-
#
|
20
|
-
# You can also pass an array of Active Record objects, which will then
|
21
|
-
# get iterated over and yield each record as an argument for the block.
|
22
|
-
# For example:
|
23
|
-
#
|
24
|
-
# <%= div_for(@people, class: "foo") do |person| %>
|
25
|
-
# <%= person.name %>
|
26
|
-
# <% end %>
|
27
|
-
#
|
28
|
-
# produces:
|
29
|
-
#
|
30
|
-
# <div id="person_123" class="person foo"> Joe Bloggs </div>
|
31
|
-
# <div id="person_124" class="person foo"> Jane Bloggs </div>
|
32
|
-
#
|
33
|
-
def div_for(record, *args, &block)
|
34
|
-
content_tag_for(:div, record, *args, &block)
|
4
|
+
def div_for(*)
|
5
|
+
raise NoMethodError, "The `div_for` method has been removed from " \
|
6
|
+
"Rails. To continue using it, add the `record_tag_helper` gem to " \
|
7
|
+
"your Gemfile:\n" \
|
8
|
+
" gem 'record_tag_helper', '~> 1.0'\n" \
|
9
|
+
"Consult the Rails upgrade guide for details."
|
35
10
|
end
|
36
11
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
# <% end %>
|
44
|
-
#
|
45
|
-
# would produce the following HTML (assuming @person is an instance of
|
46
|
-
# a Person object, with an id value of 123):
|
47
|
-
#
|
48
|
-
# <tr id="person_123" class="person">....</tr>
|
49
|
-
#
|
50
|
-
# If you require the HTML id attribute to have a prefix, you can specify it:
|
51
|
-
#
|
52
|
-
# <%= content_tag_for(:tr, @person, :foo) do %> ...
|
53
|
-
#
|
54
|
-
# produces:
|
55
|
-
#
|
56
|
-
# <tr id="foo_person_123" class="person">...
|
57
|
-
#
|
58
|
-
# You can also pass an array of objects which this method will loop through
|
59
|
-
# and yield the current object to the supplied block, reducing the need for
|
60
|
-
# having to iterate through the object (using <tt>each</tt>) beforehand.
|
61
|
-
# For example (assuming @people is an array of Person objects):
|
62
|
-
#
|
63
|
-
# <%= content_tag_for(:tr, @people) do |person| %>
|
64
|
-
# <td><%= person.first_name %></td>
|
65
|
-
# <td><%= person.last_name %></td>
|
66
|
-
# <% end %>
|
67
|
-
#
|
68
|
-
# produces:
|
69
|
-
#
|
70
|
-
# <tr id="person_123" class="person">...</tr>
|
71
|
-
# <tr id="person_124" class="person">...</tr>
|
72
|
-
#
|
73
|
-
# content_tag_for also accepts a hash of options, which will be converted to
|
74
|
-
# additional HTML attributes. If you specify a <tt>:class</tt> value, it will be combined
|
75
|
-
# with the default class name for your object. For example:
|
76
|
-
#
|
77
|
-
# <%= content_tag_for(:li, @person, class: "bar") %>...
|
78
|
-
#
|
79
|
-
# produces:
|
80
|
-
#
|
81
|
-
# <li id="person_123" class="person bar">...
|
82
|
-
#
|
83
|
-
def content_tag_for(tag_name, single_or_multiple_records, prefix = nil, options = nil, &block)
|
84
|
-
options, prefix = prefix, nil if prefix.is_a?(Hash)
|
85
|
-
|
86
|
-
Array(single_or_multiple_records).map do |single_record|
|
87
|
-
content_tag_for_single_record(tag_name, single_record, prefix, options, &block)
|
88
|
-
end.join("\n").html_safe
|
12
|
+
def content_tag_for(*)
|
13
|
+
raise NoMethodError, "The `content_tag_for` method has been removed from " \
|
14
|
+
"Rails. To continue using it, add the `record_tag_helper` gem to " \
|
15
|
+
"your Gemfile:\n" \
|
16
|
+
" gem 'record_tag_helper', '~> 1.0'\n" \
|
17
|
+
"Consult the Rails upgrade guide for details."
|
89
18
|
end
|
90
|
-
|
91
|
-
private
|
92
|
-
|
93
|
-
# Called by <tt>content_tag_for</tt> internally to render a content tag
|
94
|
-
# for each record.
|
95
|
-
def content_tag_for_single_record(tag_name, record, prefix, options, &block)
|
96
|
-
options = options ? options.dup : {}
|
97
|
-
options[:class] = [ dom_class(record, prefix), options[:class] ].compact
|
98
|
-
options[:id] = dom_id(record, prefix)
|
99
|
-
|
100
|
-
if block_given?
|
101
|
-
content_tag(tag_name, capture(record, &block), options)
|
102
|
-
else
|
103
|
-
content_tag(tag_name, "", options)
|
104
|
-
end
|
105
|
-
end
|
106
19
|
end
|
107
20
|
end
|
108
21
|
end
|
@@ -18,7 +18,7 @@ module ActionView
|
|
18
18
|
# performs HTML escape on the string first. Setting the content type as
|
19
19
|
# <tt>text/html</tt>.
|
20
20
|
# * <tt>:body</tt> - Renders the text passed in, and inherits the content
|
21
|
-
# type of <tt>text/
|
21
|
+
# type of <tt>text/plain</tt> from <tt>ActionDispatch::Response</tt>
|
22
22
|
# object.
|
23
23
|
#
|
24
24
|
# If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
|
@@ -27,12 +27,12 @@ module ActionView
|
|
27
27
|
case options
|
28
28
|
when Hash
|
29
29
|
if block_given?
|
30
|
-
view_renderer.render_partial(self, options.merge(:
|
30
|
+
view_renderer.render_partial(self, options.merge(partial: options[:layout]), &block)
|
31
31
|
else
|
32
32
|
view_renderer.render(self, options)
|
33
33
|
end
|
34
34
|
else
|
35
|
-
view_renderer.render_partial(self, :
|
35
|
+
view_renderer.render_partial(self, partial: options, locals: locals, &block)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -1,6 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'rails-html-sanitizer'
|
1
|
+
require "active_support/core_ext/object/try"
|
2
|
+
require "rails-html-sanitizer"
|
4
3
|
|
5
4
|
module ActionView
|
6
5
|
# = Action View Sanitize Helpers
|
@@ -14,6 +13,7 @@ module ActionView
|
|
14
13
|
# It also strips href/src attributes with unsafe protocols like
|
15
14
|
# <tt>javascript:</tt>, while also protecting against attempts to use Unicode,
|
16
15
|
# ASCII, and hex character references to work around these protocol filters.
|
16
|
+
# All special characters will be escaped.
|
17
17
|
#
|
18
18
|
# The default sanitizer is Rails::Html::WhiteListSanitizer. See {Rails HTML
|
19
19
|
# Sanitizers}[https://github.com/rails/rails-html-sanitizer] for more information.
|
@@ -21,8 +21,7 @@ module ActionView
|
|
21
21
|
# Custom sanitization rules can also be provided.
|
22
22
|
#
|
23
23
|
# Please note that sanitizing user-provided text does not guarantee that the
|
24
|
-
# resulting markup is valid or even well-formed.
|
25
|
-
# contain unescaped characters like <tt><</tt>, <tt>></tt>, or <tt>&</tt>.
|
24
|
+
# resulting markup is valid or even well-formed.
|
26
25
|
#
|
27
26
|
# ==== Options
|
28
27
|
#
|
@@ -46,17 +45,15 @@ module ActionView
|
|
46
45
|
# Providing a custom Rails::Html scrubber:
|
47
46
|
#
|
48
47
|
# class CommentScrubber < Rails::Html::PermitScrubber
|
49
|
-
# def
|
50
|
-
#
|
48
|
+
# def initialize
|
49
|
+
# super
|
50
|
+
# self.tags = %w( form script comment blockquote )
|
51
|
+
# self.attributes = %w( style )
|
51
52
|
# end
|
52
53
|
#
|
53
54
|
# def skip_node?(node)
|
54
55
|
# node.text?
|
55
56
|
# end
|
56
|
-
#
|
57
|
-
# def scrub_attribute?(name)
|
58
|
-
# name == 'style'
|
59
|
-
# end
|
60
57
|
# end
|
61
58
|
#
|
62
59
|
# <%= sanitize @comment.body, scrubber: CommentScrubber.new %>
|
@@ -89,7 +86,7 @@ module ActionView
|
|
89
86
|
self.class.white_list_sanitizer.sanitize_css(style)
|
90
87
|
end
|
91
88
|
|
92
|
-
# Strips all HTML tags from +html+, including comments.
|
89
|
+
# Strips all HTML tags from +html+, including comments and special characters.
|
93
90
|
#
|
94
91
|
# strip_tags("Strip <i>these</i> tags!")
|
95
92
|
# # => Strip these tags!
|
@@ -99,8 +96,11 @@ module ActionView
|
|
99
96
|
#
|
100
97
|
# strip_tags("<div id='top-bar'>Welcome to my website!</div>")
|
101
98
|
# # => Welcome to my website!
|
99
|
+
#
|
100
|
+
# strip_tags("> A quote from Smith & Wesson")
|
101
|
+
# # => > A quote from Smith & Wesson
|
102
102
|
def strip_tags(html)
|
103
|
-
self.class.full_sanitizer.sanitize(html
|
103
|
+
self.class.full_sanitizer.sanitize(html)
|
104
104
|
end
|
105
105
|
|
106
106
|
# Strips all link tags from +html+ leaving just the link text.
|
@@ -113,6 +113,9 @@ module ActionView
|
|
113
113
|
#
|
114
114
|
# strip_links('Blog: <a href="http://www.myblog.com/" class="nav" target=\"_blank\">Visit</a>.')
|
115
115
|
# # => Blog: Visit.
|
116
|
+
#
|
117
|
+
# strip_links('<<a href="https://example.org">malformed & link</a>')
|
118
|
+
# # => <malformed & link
|
116
119
|
def strip_links(html)
|
117
120
|
self.class.link_sanitizer.sanitize(html)
|
118
121
|
end
|
@@ -121,7 +124,7 @@ module ActionView
|
|
121
124
|
attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer
|
122
125
|
|
123
126
|
# Vendors the full, link and white list sanitizers.
|
124
|
-
# Provided strictly for
|
127
|
+
# Provided strictly for compatibility and can be removed in Rails 5.1.
|
125
128
|
def sanitizer_vendor
|
126
129
|
Rails::Html::Sanitizer
|
127
130
|
end
|