actionview 6.1.7.2 → 7.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +268 -254
- data/MIT-LICENSE +1 -0
- data/README.rdoc +2 -2
- data/lib/action_view/base.rb +4 -7
- 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 +5 -5
- data/lib/action_view/helpers/active_model_helper.rb +2 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +95 -39
- data/lib/action_view/helpers/asset_url_helper.rb +16 -16
- data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
- data/lib/action_view/helpers/cache_helper.rb +52 -3
- data/lib/action_view/helpers/capture_helper.rb +4 -4
- 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 +2 -2
- data/lib/action_view/helpers/date_helper.rb +111 -43
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +211 -85
- data/lib/action_view/helpers/form_options_helper.rb +70 -33
- data/lib/action_view/helpers/form_tag_helper.rb +150 -53
- data/lib/action_view/helpers/javascript_helper.rb +3 -5
- data/lib/action_view/helpers/number_helper.rb +17 -16
- data/lib/action_view/helpers/output_safety_helper.rb +4 -4
- data/lib/action_view/helpers/rendering_helper.rb +5 -6
- data/lib/action_view/helpers/sanitize_helper.rb +3 -3
- data/lib/action_view/helpers/tag_helper.rb +37 -8
- data/lib/action_view/helpers/tags/base.rb +5 -25
- 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/file_field.rb +16 -0
- data/lib/action_view/helpers/tags/select.rb +1 -1
- data/lib/action_view/helpers/tags/time_field.rb +10 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +28 -0
- data/lib/action_view/helpers/tags.rb +3 -2
- data/lib/action_view/helpers/text_helper.rb +25 -14
- data/lib/action_view/helpers/translation_helper.rb +12 -43
- data/lib/action_view/helpers/url_helper.rb +194 -123
- data/lib/action_view/helpers.rb +25 -25
- data/lib/action_view/layouts.rb +7 -4
- data/lib/action_view/lookup_context.rb +33 -52
- data/lib/action_view/model_naming.rb +2 -2
- data/lib/action_view/path_set.rb +16 -22
- data/lib/action_view/railtie.rb +19 -7
- data/lib/action_view/record_identifier.rb +1 -1
- 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 +1 -35
- 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 +3 -3
- data/lib/action_view/ripper_ast_parser.rb +198 -0
- data/lib/action_view/routing_url_for.rb +8 -5
- 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 +89 -314
- data/lib/action_view/template/text.rb +3 -3
- data/lib/action_view/template/types.rb +14 -12
- data/lib/action_view/template.rb +18 -2
- 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 +7 -3
- data/lib/action_view/testing/resolvers.rb +11 -12
- data/lib/action_view/unbound_template.rb +33 -7
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +4 -4
- data/lib/action_view.rb +2 -3
- data/lib/assets/compiled/rails-ujs.js +36 -5
- metadata +23 -16
@@ -1,15 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/enumerable"
|
3
4
|
require "active_support/core_ext/string/output_safety"
|
4
5
|
require "set"
|
6
|
+
require "action_view/helpers/capture_helper"
|
7
|
+
require "action_view/helpers/output_safety_helper"
|
5
8
|
|
6
9
|
module ActionView
|
7
10
|
# = Action View Tag Helpers
|
8
|
-
module Helpers
|
11
|
+
module Helpers # :nodoc:
|
9
12
|
# Provides methods to generate HTML tags programmatically both as a modern
|
10
13
|
# HTML5 compliant builder style and legacy XHTML compliant tags.
|
11
14
|
module TagHelper
|
12
|
-
extend ActiveSupport::Concern
|
13
15
|
include CaptureHelper
|
14
16
|
include OutputSafetyHelper
|
15
17
|
|
@@ -39,16 +41,26 @@ module ActionView
|
|
39
41
|
PRE_CONTENT_STRINGS[:textarea] = "\n"
|
40
42
|
PRE_CONTENT_STRINGS["textarea"] = "\n"
|
41
43
|
|
42
|
-
class TagBuilder
|
44
|
+
class TagBuilder # :nodoc:
|
43
45
|
include CaptureHelper
|
44
46
|
include OutputSafetyHelper
|
45
47
|
|
46
|
-
|
48
|
+
HTML_VOID_ELEMENTS = %i(area base br col embed hr img input keygen link meta param source track wbr).to_set
|
49
|
+
SVG_SELF_CLOSING_ELEMENTS = %i(animate animateMotion animateTransform circle ellipse line path polygon polyline rect set stop use view).to_set
|
47
50
|
|
48
51
|
def initialize(view_context)
|
49
52
|
@view_context = view_context
|
50
53
|
end
|
51
54
|
|
55
|
+
# Transforms a Hash into HTML Attributes, ready to be interpolated into
|
56
|
+
# ERB.
|
57
|
+
#
|
58
|
+
# <input <%= tag.attributes(type: :text, aria: { label: "Search" }) %> >
|
59
|
+
# # => <input type="text" aria-label="Search">
|
60
|
+
def attributes(attributes)
|
61
|
+
tag_options(attributes.to_h).to_s.strip.html_safe
|
62
|
+
end
|
63
|
+
|
52
64
|
def p(*arguments, **options, &block)
|
53
65
|
tag_string(:p, *arguments, **options, &block)
|
54
66
|
end
|
@@ -57,8 +69,9 @@ module ActionView
|
|
57
69
|
escape = handle_deprecated_escape_options(options)
|
58
70
|
|
59
71
|
content = @view_context.capture(self, &block) if block_given?
|
60
|
-
|
61
|
-
|
72
|
+
self_closing = SVG_SELF_CLOSING_ELEMENTS.include?(name)
|
73
|
+
if (HTML_VOID_ELEMENTS.include?(name) || self_closing) && content.nil?
|
74
|
+
"<#{name.to_s.dasherize}#{tag_options(options, escape)}#{self_closing ? " />" : ">"}".html_safe
|
62
75
|
else
|
63
76
|
content_tag_string(name.to_s.dasherize, content || "", options, escape)
|
64
77
|
end
|
@@ -128,6 +141,8 @@ module ActionView
|
|
128
141
|
when Array, Hash
|
129
142
|
value = TagHelper.build_tag_values(value) if key.to_s == "class"
|
130
143
|
value = escape ? safe_join(value, " ") : value.join(" ")
|
144
|
+
when Regexp
|
145
|
+
value = escape ? ERB::Util.unwrapped_html_escape(value.source) : value.source
|
131
146
|
else
|
132
147
|
value = escape ? ERB::Util.unwrapped_html_escape(value) : value.to_s
|
133
148
|
end
|
@@ -225,7 +240,7 @@ module ActionView
|
|
225
240
|
#
|
226
241
|
# Thus <tt>data-user-id</tt> can be accessed as <tt>dataset.userId</tt>.
|
227
242
|
#
|
228
|
-
# Data attribute values are encoded to JSON, with the exception of strings, symbols and
|
243
|
+
# Data attribute values are encoded to JSON, with the exception of strings, symbols, and
|
229
244
|
# BigDecimals.
|
230
245
|
# This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
|
231
246
|
# from 1.4.3.
|
@@ -252,6 +267,20 @@ module ActionView
|
|
252
267
|
# # A void element:
|
253
268
|
# tag.br # => <br>
|
254
269
|
#
|
270
|
+
# === Building HTML attributes
|
271
|
+
#
|
272
|
+
# Transforms a Hash into HTML attributes, ready to be interpolated into
|
273
|
+
# ERB. Includes or omits boolean attributes based on their truthiness.
|
274
|
+
# Transforms keys nested within
|
275
|
+
# <tt>aria:</tt> or <tt>data:</tt> objects into <tt>aria-</tt> and <tt>data-</tt>
|
276
|
+
# prefixed attributes:
|
277
|
+
#
|
278
|
+
# <input <%= tag.attributes(type: :text, aria: { label: "Search" }) %>>
|
279
|
+
# # => <input type="text" aria-label="Search">
|
280
|
+
#
|
281
|
+
# <button <%= tag.attributes id: "call-to-action", disabled: false, aria: { expanded: false } %> class="primary">Get Started!</button>
|
282
|
+
# # => <button id="call-to-action" aria-expanded="false" class="primary">Get Started!</button>
|
283
|
+
#
|
255
284
|
# === Legacy syntax
|
256
285
|
#
|
257
286
|
# The following format is for legacy syntax support. It will be deprecated in future versions of Rails.
|
@@ -377,7 +406,7 @@ module ActionView
|
|
377
406
|
# cdata_section("hello]]>world")
|
378
407
|
# # => <![CDATA[hello]]]]><![CDATA[>world]]>
|
379
408
|
def cdata_section(content)
|
380
|
-
splitted = content.to_s.gsub(/\]\]
|
409
|
+
splitted = content.to_s.gsub(/\]\]>/, "]]]]><![CDATA[>")
|
381
410
|
"<![CDATA[#{splitted}]]>".html_safe
|
382
411
|
end
|
383
412
|
|
@@ -97,7 +97,7 @@ module ActionView
|
|
97
97
|
options["name"] = options.fetch("name") { tag_name(options["multiple"], index) }
|
98
98
|
|
99
99
|
if generate_ids?
|
100
|
-
options["id"] = options.fetch("id") { tag_id(index) }
|
100
|
+
options["id"] = options.fetch("id") { tag_id(index, options.delete("namespace")) }
|
101
101
|
if namespace = options.delete("namespace")
|
102
102
|
options["id"] = options["id"] ? "#{namespace}_#{options['id']}" : namespace
|
103
103
|
end
|
@@ -105,31 +105,11 @@ module ActionView
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def tag_name(multiple = false, index = nil)
|
108
|
-
|
109
|
-
case
|
110
|
-
when @object_name.empty?
|
111
|
-
"#{sanitized_method_name}#{multiple ? "[]" : ""}"
|
112
|
-
when index
|
113
|
-
"#{@object_name}[#{index}][#{sanitized_method_name}]#{multiple ? "[]" : ""}"
|
114
|
-
else
|
115
|
-
"#{@object_name}[#{sanitized_method_name}]#{multiple ? "[]" : ""}"
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def tag_id(index = nil)
|
120
|
-
# a little duplication to construct fewer strings
|
121
|
-
case
|
122
|
-
when @object_name.empty?
|
123
|
-
sanitized_method_name.dup
|
124
|
-
when index
|
125
|
-
"#{sanitized_object_name}_#{index}_#{sanitized_method_name}"
|
126
|
-
else
|
127
|
-
"#{sanitized_object_name}_#{sanitized_method_name}"
|
128
|
-
end
|
108
|
+
@template_object.field_name(@object_name, sanitized_method_name, multiple: multiple, index: index)
|
129
109
|
end
|
130
110
|
|
131
|
-
def
|
132
|
-
@
|
111
|
+
def tag_id(index = nil, namespace = nil)
|
112
|
+
@template_object.field_id(@object_name, @method_name, index: index, namespace: namespace)
|
133
113
|
end
|
134
114
|
|
135
115
|
def sanitized_method_name
|
@@ -137,7 +117,7 @@ module ActionView
|
|
137
117
|
end
|
138
118
|
|
139
119
|
def sanitized_value(value)
|
140
|
-
value.to_s.gsub(/[\s
|
120
|
+
value.to_s.gsub(/[\s.]/, "_").gsub(/[^-[[:word:]]]/, "").downcase
|
141
121
|
end
|
142
122
|
|
143
123
|
def select_content_tag(option_tags, options, html_options)
|
@@ -5,7 +5,7 @@ require "action_view/helpers/tags/checkable"
|
|
5
5
|
module ActionView
|
6
6
|
module Helpers
|
7
7
|
module Tags # :nodoc:
|
8
|
-
class CheckBox < Base
|
8
|
+
class CheckBox < Base # :nodoc:
|
9
9
|
include Checkable
|
10
10
|
|
11
11
|
def initialize(object_name, method_name, template_object, checked_value, unchecked_value, options)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module ActionView
|
4
4
|
module Helpers
|
5
5
|
module Tags # :nodoc:
|
6
|
-
class CollectionSelect < Base
|
6
|
+
class CollectionSelect < Base # :nodoc:
|
7
7
|
def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options)
|
8
8
|
@collection = collection
|
9
9
|
@value_method = value_method
|
@@ -4,6 +4,22 @@ module ActionView
|
|
4
4
|
module Helpers
|
5
5
|
module Tags # :nodoc:
|
6
6
|
class FileField < TextField # :nodoc:
|
7
|
+
def render
|
8
|
+
include_hidden = @options.delete(:include_hidden)
|
9
|
+
options = @options.stringify_keys
|
10
|
+
add_default_name_and_id(options)
|
11
|
+
|
12
|
+
if options["multiple"] && include_hidden
|
13
|
+
hidden_field_for_multiple_file(options) + super
|
14
|
+
else
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def hidden_field_for_multiple_file(options)
|
21
|
+
tag("input", "name" => options["name"], "type" => "hidden", "value" => "", "autocomplete" => "off")
|
22
|
+
end
|
7
23
|
end
|
8
24
|
end
|
9
25
|
end
|
@@ -34,7 +34,7 @@ module ActionView
|
|
34
34
|
# [nil, []]
|
35
35
|
# { nil => [] }
|
36
36
|
def grouped_choices?
|
37
|
-
!@choices.blank? && @choices.first.respond_to?(:
|
37
|
+
!@choices.blank? && @choices.first.respond_to?(:second) && Array === @choices.first.second
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -4,9 +4,18 @@ module ActionView
|
|
4
4
|
module Helpers
|
5
5
|
module Tags # :nodoc:
|
6
6
|
class TimeField < DatetimeField # :nodoc:
|
7
|
+
def initialize(object_name, method_name, template_object, options = {})
|
8
|
+
@include_seconds = options.delete(:include_seconds) { true }
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
7
12
|
private
|
8
13
|
def format_date(value)
|
9
|
-
|
14
|
+
if @include_seconds
|
15
|
+
value&.strftime("%T.%L")
|
16
|
+
else
|
17
|
+
value&.strftime("%H:%M")
|
18
|
+
end
|
10
19
|
end
|
11
20
|
end
|
12
21
|
end
|
@@ -0,0 +1,28 @@
|
|
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
|
+
beginning_of_week: @options.fetch(:beginning_of_week, Date.beginning_of_week)
|
20
|
+
),
|
21
|
+
@options,
|
22
|
+
@html_options
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
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)
|
@@ -264,7 +268,7 @@ module ActionView
|
|
264
268
|
end
|
265
269
|
|
266
270
|
# Returns +text+ transformed into HTML using simple formatting rules.
|
267
|
-
# Two or more consecutive newlines(<tt>\n\n</tt> or <tt>\r\n\r\n</tt>) are
|
271
|
+
# Two or more consecutive newlines (<tt>\n\n</tt> or <tt>\r\n\r\n</tt>) are
|
268
272
|
# considered a paragraph and wrapped in <tt><p></tt> tags. One newline
|
269
273
|
# (<tt>\n</tt> or <tt>\r\n</tt>) is considered a linebreak and a
|
270
274
|
# <tt><br /></tt> tag is appended. This method does not remove the
|
@@ -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,16 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "action_view/helpers/tag_helper"
|
4
|
-
require "active_support/
|
4
|
+
require "active_support/html_safe_translation"
|
5
5
|
|
6
6
|
module ActionView
|
7
7
|
# = Action View Translation Helpers
|
8
|
-
module Helpers
|
8
|
+
module Helpers # :nodoc:
|
9
9
|
module TranslationHelper
|
10
10
|
extend ActiveSupport::Concern
|
11
11
|
|
12
12
|
include TagHelper
|
13
13
|
|
14
|
+
# Specify whether an error should be raised for missing translations
|
15
|
+
singleton_class.attr_accessor :raise_on_missing_translations
|
16
|
+
|
14
17
|
included do
|
15
18
|
mattr_accessor :debug_missing_translation, default: true
|
16
19
|
end
|
@@ -37,7 +40,7 @@ module ActionView
|
|
37
40
|
#
|
38
41
|
# If you would prefer missing translations to raise an error, you can
|
39
42
|
# opt out of span-wrapping behavior globally by setting
|
40
|
-
# <tt>
|
43
|
+
# <tt>config.i18n.raise_on_missing_translations = true</tt> or
|
41
44
|
# individually by passing <tt>raise: true</tt> as an option to
|
42
45
|
# <tt>translate</tt>.
|
43
46
|
#
|
@@ -75,7 +78,7 @@ module ActionView
|
|
75
78
|
options[:default].is_a?(Array) ? options.delete(:default).compact : [options.delete(:default)]
|
76
79
|
end
|
77
80
|
|
78
|
-
options[:raise] = true if options[:raise].nil? &&
|
81
|
+
options[:raise] = true if options[:raise].nil? && TranslationHelper.raise_on_missing_translations
|
79
82
|
default = MISSING_TRANSLATION
|
80
83
|
|
81
84
|
translation = while key || alternatives.present?
|
@@ -85,14 +88,9 @@ module ActionView
|
|
85
88
|
|
86
89
|
key = scope_key_by_partial(key)
|
87
90
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
break html_safe_translation(translated) unless translated.equal?(MISSING_TRANSLATION)
|
92
|
-
else
|
93
|
-
translated = I18n.translate(key, **options, default: default)
|
94
|
-
break translated unless translated.equal?(MISSING_TRANSLATION)
|
95
|
-
end
|
91
|
+
translated = ActiveSupport::HtmlSafeTranslation.translate(key, **options, default: default)
|
92
|
+
|
93
|
+
break translated unless translated == MISSING_TRANSLATION
|
96
94
|
|
97
95
|
if alternatives.present? && !alternatives.first.is_a?(Symbol)
|
98
96
|
break alternatives.first && I18n.translate(**options, default: alternatives)
|
@@ -113,7 +111,7 @@ module ActionView
|
|
113
111
|
|
114
112
|
# Delegates to <tt>I18n.localize</tt> with no additional functionality.
|
115
113
|
#
|
116
|
-
# See https://www.rubydoc.info/
|
114
|
+
# See https://www.rubydoc.info/gems/i18n/I18n/Backend/Base:localize
|
117
115
|
# for more information.
|
118
116
|
def localize(object, **options)
|
119
117
|
I18n.localize(object, **options)
|
@@ -121,16 +119,12 @@ module ActionView
|
|
121
119
|
alias :l :localize
|
122
120
|
|
123
121
|
private
|
124
|
-
MISSING_TRANSLATION =
|
122
|
+
MISSING_TRANSLATION = -(2**60)
|
125
123
|
private_constant :MISSING_TRANSLATION
|
126
124
|
|
127
125
|
NO_DEFAULT = [].freeze
|
128
126
|
private_constant :NO_DEFAULT
|
129
127
|
|
130
|
-
def self.i18n_option?(name)
|
131
|
-
(@i18n_option_names ||= I18n::RESERVED_KEYS.to_set).include?(name)
|
132
|
-
end
|
133
|
-
|
134
128
|
def scope_key_by_partial(key)
|
135
129
|
if key&.start_with?(".")
|
136
130
|
if @virtual_path
|
@@ -145,31 +139,6 @@ module ActionView
|
|
145
139
|
end
|
146
140
|
end
|
147
141
|
|
148
|
-
def html_escape_translation_options(options)
|
149
|
-
return options if options.empty?
|
150
|
-
html_safe_options = options.dup
|
151
|
-
|
152
|
-
options.each do |name, value|
|
153
|
-
unless TranslationHelper.i18n_option?(name) || (name == :count && value.is_a?(Numeric))
|
154
|
-
html_safe_options[name] = ERB::Util.html_escape(value.to_s)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
html_safe_options
|
159
|
-
end
|
160
|
-
|
161
|
-
def html_safe_translation_key?(key)
|
162
|
-
/(?:_|\b)html\z/.match?(key)
|
163
|
-
end
|
164
|
-
|
165
|
-
def html_safe_translation(translation)
|
166
|
-
if translation.respond_to?(:map)
|
167
|
-
translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
|
168
|
-
else
|
169
|
-
translation.respond_to?(:html_safe) ? translation.html_safe : translation
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
142
|
def missing_translation(key, options)
|
174
143
|
keys = I18n.normalize_keys(options[:locale] || I18n.locale, key, options[:scope])
|
175
144
|
|