actionview 6.1.0 → 6.1.7.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66b9ba4747ae5973f8f784343f64e7201d2bbf8299cb9b9dc2ed7869db55cbc6
4
- data.tar.gz: da671bc8666ecd9386fa75a7639c837492df9b0d5b81c9f2a66114a522d6dec9
3
+ metadata.gz: f91caf0c3c900f6272f88a204aa46f4af927c8cf1547aea4162f166252b75c37
4
+ data.tar.gz: e306577e5bf3bb4ee01f6c467f2c2aac6bfe547fbf982051fb8b0c0fb2eb314a
5
5
  SHA512:
6
- metadata.gz: 409ff7a86026884f20e3fbf1eb0560fc990328369c15e90500f27dc8336020edc59acfb3b8da61806c7eac62ae501c1c5f176c4dc7da641f3da338bcfb2cc6f5
7
- data.tar.gz: 961932d31d4e46c9674a9ea3229db468dfd922c1b79c9f23403b928763f1a8798848dae25554f09255965968109e7557953b4c3a7d6573e142061a3fc3e360c7
6
+ metadata.gz: 7fed80a845b3909ee328404415c2b50b783b129dfefa84912841b56ebfadec701594433bcb20b8911ae8e51ce13fc1a30a92e991f1220a59a1bf7a0dba0607ba
7
+ data.tar.gz: fd5db5a70516983533d56e65033588c9db897e8b59df818f05f9c25d01f15e16b5f916a8547bdf780dd4e2566133c079fceb2ad8e1ab32a788d48b3183039e7a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,159 @@
1
+ ## Rails 6.1.7.1 (January 17, 2023) ##
2
+
3
+ * No changes.
4
+
5
+
6
+ ## Rails 6.1.7 (September 09, 2022) ##
7
+
8
+ * No changes.
9
+
10
+
11
+ ## Rails 6.1.6.1 (July 12, 2022) ##
12
+
13
+ * No changes.
14
+
15
+
16
+ ## Rails 6.1.6 (May 09, 2022) ##
17
+
18
+ * No changes.
19
+
20
+
21
+ ## Rails 6.1.5.1 (April 26, 2022) ##
22
+
23
+ * Fix and add protections for XSS in `ActionView::Helpers` and `ERB::Util`.
24
+
25
+ Escape dangerous characters in names of tags and names of attributes in the
26
+ tag helpers, following the XML specification. Rename the option
27
+ `:escape_attributes` to `:escape`, to simplify by applying the option to the
28
+ whole tag.
29
+
30
+ *Álvaro Martín Fraguas*
31
+
32
+ ## Rails 6.1.5 (March 09, 2022) ##
33
+
34
+ * `preload_link_tag` properly inserts `as` attributes for files with `image` MIME
35
+ types, such as JPG or SVG.
36
+
37
+ *Nate Berkopec*
38
+
39
+ * Add `autocomplete="off"` to all generated hidden fields.
40
+
41
+ Fixes #42610.
42
+
43
+ *Ryan Baumann*
44
+
45
+ * Fix `current_page?` when URL has trailing slash.
46
+
47
+ This fixes the `current_page?` helper when the given URL has a trailing slash,
48
+ and is an absolute URL or also has query params.
49
+
50
+ Fixes #33956.
51
+
52
+ *Jonathan Hefner*
53
+
54
+
55
+ ## Rails 6.1.4.7 (March 08, 2022) ##
56
+
57
+ * No changes.
58
+
59
+
60
+ ## Rails 6.1.4.6 (February 11, 2022) ##
61
+
62
+ * No changes.
63
+
64
+
65
+ ## Rails 6.1.4.5 (February 11, 2022) ##
66
+
67
+ * No changes.
68
+
69
+
70
+ ## Rails 6.1.4.4 (December 15, 2021) ##
71
+
72
+ * No changes.
73
+
74
+
75
+ ## Rails 6.1.4.3 (December 14, 2021) ##
76
+
77
+ * No changes.
78
+
79
+
80
+ ## Rails 6.1.4.2 (December 14, 2021) ##
81
+
82
+ * No changes.
83
+
84
+
85
+ ## Rails 6.1.4.1 (August 19, 2021) ##
86
+
87
+ * No changes.
88
+
89
+
90
+ ## Rails 6.1.4 (June 24, 2021) ##
91
+
92
+ * The `translate` helper now passes `default` values that aren't
93
+ translation keys through `I18n.translate` for interpolation.
94
+
95
+ *Jonathan Hefner*
96
+
97
+ * Don't attach UJS form submission handlers to Turbo forms.
98
+
99
+ *David Heinemeier Hansson*
100
+
101
+ * Allow both `current_page?(url_hash)` and `current_page?(**url_hash)` on Ruby 2.7.
102
+
103
+ *Ryuta Kamizono*
104
+
105
+
106
+ ## Rails 6.1.3.2 (May 05, 2021) ##
107
+
108
+ * No changes.
109
+
110
+
111
+ ## Rails 6.1.3.1 (March 26, 2021) ##
112
+
113
+ * No changes.
114
+
115
+
116
+ ## Rails 6.1.3 (February 17, 2021) ##
117
+
118
+ * No changes.
119
+
120
+
121
+ ## Rails 6.1.2.1 (February 10, 2021) ##
122
+
123
+ * No changes.
124
+
125
+
126
+ ## Rails 6.1.2 (February 09, 2021) ##
127
+
128
+ * No changes.
129
+
130
+
131
+ ## Rails 6.1.1 (January 07, 2021) ##
132
+
133
+ * Fix lazy translation in partial with block.
134
+
135
+ *Marek Kasztelnik*
136
+
137
+ * Avoid extra `SELECT COUNT` queries when rendering Active Record collections.
138
+
139
+ *aar0nr*
140
+
141
+ * Link preloading keep integrity hashes in the header.
142
+
143
+ *Étienne Barrié*
144
+
145
+ * Add `config.action_view.preload_links_header` to allow disabling of
146
+ the `Link` header being added by default when using `stylesheet_link_tag`
147
+ and `javascript_include_tag`.
148
+
149
+ *Andrew White*
150
+
151
+ * The `translate` helper now resolves `default` values when a `nil` key is
152
+ specified, instead of always returning `nil`.
153
+
154
+ *Jonathan Hefner*
155
+
156
+
1
157
  ## Rails 6.1.0 (December 09, 2020) ##
2
158
 
3
159
  * SanitizeHelper.sanitized_allowed_attributes and SanitizeHelper.sanitized_allowed_tags
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2020 David Heinemeier Hansson
1
+ Copyright (c) 2004-2022 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -18,4 +18,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
-
data/README.rdoc CHANGED
@@ -15,7 +15,7 @@ The latest version of Action View can be installed with RubyGems:
15
15
 
16
16
  Source code can be downloaded as part of the Rails project on GitHub:
17
17
 
18
- * https://github.com/rails/rails/tree/master/actionview
18
+ * https://github.com/rails/rails/tree/main/actionview
19
19
 
20
20
 
21
21
  == License
@@ -241,12 +241,12 @@ module ActionView #:nodoc:
241
241
  end
242
242
 
243
243
  def _run(method, template, locals, buffer, add_to_stack: true, &block)
244
- _old_output_buffer, _old_template = @output_buffer, @current_template
244
+ _old_output_buffer, _old_virtual_path, _old_template = @output_buffer, @virtual_path, @current_template
245
245
  @current_template = template if add_to_stack
246
246
  @output_buffer = buffer
247
247
  public_send(method, locals, buffer, &block)
248
248
  ensure
249
- @output_buffer, @current_template = _old_output_buffer, _old_template
249
+ @output_buffer, @virtual_path, @current_template = _old_output_buffer, _old_virtual_path, _old_template
250
250
  end
251
251
 
252
252
  def compiled_method_container
@@ -18,6 +18,7 @@ module ActionView
18
18
  def _prepare_context
19
19
  @view_flow = OutputFlow.new
20
20
  @output_buffer = nil
21
+ @virtual_path = nil
21
22
  end
22
23
 
23
24
  # Encapsulates the interaction with the view flow so it
@@ -9,8 +9,8 @@ module ActionView
9
9
  module VERSION
10
10
  MAJOR = 6
11
11
  MINOR = 1
12
- TINY = 0
13
- PRE = nil
12
+ TINY = 7
13
+ PRE = "1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -23,6 +23,8 @@ module ActionView
23
23
  include AssetUrlHelper
24
24
  include TagHelper
25
25
 
26
+ mattr_accessor :preload_links_header
27
+
26
28
  # Returns an HTML script tag for each of the +sources+ provided.
27
29
  #
28
30
  # Sources may be paths to JavaScript files. Relative paths are assumed to be relative
@@ -90,12 +92,14 @@ module ActionView
90
92
  nopush = options["nopush"].nil? ? true : options.delete("nopush")
91
93
  crossorigin = options.delete("crossorigin")
92
94
  crossorigin = "anonymous" if crossorigin == true
95
+ integrity = options["integrity"]
93
96
 
94
97
  sources_tags = sources.uniq.map { |source|
95
98
  href = path_to_javascript(source, path_options)
96
- unless options["defer"]
99
+ if preload_links_header && !options["defer"]
97
100
  preload_link = "<#{href}>; rel=preload; as=script"
98
101
  preload_link += "; crossorigin=#{crossorigin}" unless crossorigin.nil?
102
+ preload_link += "; integrity=#{integrity}" unless integrity.nil?
99
103
  preload_link += "; nopush" if nopush
100
104
  preload_links << preload_link
101
105
  end
@@ -109,7 +113,9 @@ module ActionView
109
113
  content_tag("script", "", tag_options)
110
114
  }.join("\n").html_safe
111
115
 
112
- send_preload_links_header(preload_links)
116
+ if preload_links_header
117
+ send_preload_links_header(preload_links)
118
+ end
113
119
 
114
120
  sources_tags
115
121
  end
@@ -149,13 +155,17 @@ module ActionView
149
155
  crossorigin = options.delete("crossorigin")
150
156
  crossorigin = "anonymous" if crossorigin == true
151
157
  nopush = options["nopush"].nil? ? true : options.delete("nopush")
158
+ integrity = options["integrity"]
152
159
 
153
160
  sources_tags = sources.uniq.map { |source|
154
161
  href = path_to_stylesheet(source, path_options)
155
- preload_link = "<#{href}>; rel=preload; as=style"
156
- preload_link += "; crossorigin=#{crossorigin}" unless crossorigin.nil?
157
- preload_link += "; nopush" if nopush
158
- preload_links << preload_link
162
+ if preload_links_header
163
+ preload_link = "<#{href}>; rel=preload; as=style"
164
+ preload_link += "; crossorigin=#{crossorigin}" unless crossorigin.nil?
165
+ preload_link += "; integrity=#{integrity}" unless integrity.nil?
166
+ preload_link += "; nopush" if nopush
167
+ preload_links << preload_link
168
+ end
159
169
  tag_options = {
160
170
  "rel" => "stylesheet",
161
171
  "media" => "screen",
@@ -165,7 +175,9 @@ module ActionView
165
175
  tag(:link, tag_options)
166
176
  }.join("\n").html_safe
167
177
 
168
- send_preload_links_header(preload_links)
178
+ if preload_links_header
179
+ send_preload_links_header(preload_links)
180
+ end
169
181
 
170
182
  sources_tags
171
183
  end
@@ -256,6 +268,7 @@ module ActionView
256
268
  # * <tt>:as</tt> - Override the auto-generated value for as attribute, calculated using +source+ extension and mime type.
257
269
  # * <tt>:crossorigin</tt> - Specify the crossorigin attribute, required to load cross-origin resources.
258
270
  # * <tt>:nopush</tt> - Specify if the use of server push is not desired for the resource. Defaults to +false+.
271
+ # * <tt>:integrity</tt> - Specify the integrity attribute.
259
272
  #
260
273
  # ==== Examples
261
274
  #
@@ -281,12 +294,13 @@ module ActionView
281
294
  # # => <link rel="preload" href="/media/audio.ogg" as="audio" type="audio/ogg" />
282
295
  #
283
296
  def preload_link_tag(source, options = {})
284
- href = asset_path(source, skip_pipeline: options.delete(:skip_pipeline))
297
+ href = path_to_asset(source, skip_pipeline: options.delete(:skip_pipeline))
285
298
  extname = File.extname(source).downcase.delete(".")
286
299
  mime_type = options.delete(:type) || Template::Types[extname]&.to_s
287
300
  as_type = options.delete(:as) || resolve_link_as(extname, mime_type)
288
301
  crossorigin = options.delete(:crossorigin)
289
302
  crossorigin = "anonymous" if crossorigin == true || (crossorigin.blank? && as_type == "font")
303
+ integrity = options[:integrity]
290
304
  nopush = options.delete(:nopush) || false
291
305
 
292
306
  link_tag = tag.link(**{
@@ -300,6 +314,7 @@ module ActionView
300
314
  preload_link = "<#{href}>; rel=preload; as=#{as_type}"
301
315
  preload_link += "; type=#{mime_type}" if mime_type
302
316
  preload_link += "; crossorigin=#{crossorigin}" if crossorigin
317
+ preload_link += "; integrity=#{integrity}" if integrity
303
318
  preload_link += "; nopush" if nopush
304
319
 
305
320
  send_preload_links_header([preload_link])
@@ -494,7 +509,7 @@ module ActionView
494
509
  "style"
495
510
  elsif extname == "vtt"
496
511
  "track"
497
- elsif (type = mime_type.to_s.split("/")[0]) && type.in?(%w(audio video font))
512
+ elsif (type = mime_type.to_s.split("/")[0]) && type.in?(%w(audio video font image))
498
513
  type
499
514
  end
500
515
  end
@@ -98,7 +98,7 @@ module ActionView
98
98
  # have SSL certificates for each of the asset hosts this technique allows you
99
99
  # to avoid warnings in the client about mixed media.
100
100
  # Note that the +request+ parameter might not be supplied, e.g. when the assets
101
- # are precompiled with the command `bin/rails assets:precompile`. Make sure to use a
101
+ # are precompiled with the command <tt>bin/rails assets:precompile</tt>. Make sure to use a
102
102
  # +Proc+ instead of a lambda, since a +Proc+ allows missing parameters and sets them
103
103
  # to +nil+.
104
104
  #
@@ -1101,7 +1101,8 @@ module ActionView
1101
1101
  type: "hidden",
1102
1102
  id: input_id_from_type(type),
1103
1103
  name: input_name_from_type(type),
1104
- value: value
1104
+ value: value,
1105
+ autocomplete: "off"
1105
1106
  }.merge!(@html_options.slice(:disabled))
1106
1107
  select_options[:disabled] = "disabled" if @options[:disabled]
1107
1108
 
@@ -186,8 +186,7 @@ module ActionView
186
186
  # get the authenticity token from the <tt>meta</tt> tag, so embedding is
187
187
  # unnecessary unless you support browsers without JavaScript.
188
188
  # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive
189
- # JavaScript drivers to control the submit behavior. By default this
190
- # behavior is an ajax submit.
189
+ # JavaScript drivers to control the submit behavior.
191
190
  # * <tt>:enforce_utf8</tt> - If set to false, a hidden input with name
192
191
  # utf8 is not output.
193
192
  # * <tt>:html</tt> - Optional HTML attributes for the form tag.
@@ -323,10 +322,8 @@ module ActionView
323
322
  # remote: true
324
323
  #
325
324
  # in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its
326
- # behavior. The expected default behavior is an XMLHttpRequest in the background instead of the regular
327
- # POST arrangement, but ultimately the behavior is the choice of the JavaScript driver implementor.
328
- # Even though it's using JavaScript to serialize the form elements, the form submission will work just like
329
- # a regular submission as viewed by the receiving side (all elements available in <tt>params</tt>).
325
+ # behavior. The form submission will work just like a regular submission as viewed by the receiving
326
+ # side (all elements available in <tt>params</tt>).
330
327
  #
331
328
  # Example:
332
329
  #
@@ -536,11 +533,6 @@ module ActionView
536
533
  # accessible as <tt>params[:title]</tt> and <tt>params[:post][:title]</tt>
537
534
  # respectively.
538
535
  #
539
- # By default +form_with+ attaches the <tt>data-remote</tt> attribute
540
- # submitting the form via an XMLHTTPRequest in the background if an
541
- # Unobtrusive JavaScript driver, like rails-ujs, is used. See the
542
- # <tt>:local</tt> option for more.
543
- #
544
536
  # For ease of comparison the examples above left out the submit button,
545
537
  # as well as the auto generated hidden fields that enable UTF-8 support
546
538
  # and adds an authenticity token needed for cross site request forgery
@@ -612,8 +604,10 @@ module ActionView
612
604
  # This is helpful when fragment-caching the form. Remote forms
613
605
  # get the authenticity token from the <tt>meta</tt> tag, so embedding is
614
606
  # unnecessary unless you support browsers without JavaScript.
615
- # * <tt>:local</tt> - By default form submits are remote and unobtrusive XHRs.
616
- # Disable remote submits with <tt>local: true</tt>.
607
+ # * <tt>:local</tt> - By default form submits via typical HTTP requests.
608
+ # Enable remote and unobtrusive XHRs submits with <tt>local: false</tt>.
609
+ # Remote forms may be enabled by default by setting
610
+ # <tt>config.action_view.form_with_generates_remote_forms = true</tt>.
617
611
  # * <tt>:skip_enforcing_utf8</tt> - If set to true, a hidden input with name
618
612
  # utf8 is not output.
619
613
  # * <tt>:builder</tt> - Override the object used to build the form.
@@ -241,7 +241,7 @@ module ActionView
241
241
  # # => <input id="collected_input" name="collected_input" onchange="alert('Input collected!')"
242
242
  # # type="hidden" value="" />
243
243
  def hidden_field_tag(name, value = nil, options = {})
244
- text_field_tag(name, value, options.merge(type: :hidden))
244
+ text_field_tag(name, value, options.merge(type: :hidden, autocomplete: "off"))
245
245
  end
246
246
 
247
247
  # Creates a file upload field. If you are using file uploads then you will also need
@@ -823,7 +823,7 @@ module ActionView
823
823
  # Use raw HTML to ensure the value is written as an HTML entity; it
824
824
  # needs to be the right character regardless of which encoding the
825
825
  # browser infers.
826
- '<input name="utf8" type="hidden" value="&#x2713;" />'.html_safe
826
+ '<input name="utf8" type="hidden" value="&#x2713;" autocomplete="off" />'.html_safe
827
827
  end
828
828
 
829
829
  private
@@ -24,7 +24,7 @@ module ActionView
24
24
  #
25
25
  # If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
26
26
  #
27
- # If an object responding to `render_in` is passed, `render_in` is called on the object,
27
+ # If an object responding to +render_in+ is passed, +render_in+ is called on the object,
28
28
  # passing in the current view context.
29
29
  #
30
30
  # Otherwise, a partial is rendered using the second parameter as the locals hash.
@@ -53,18 +53,25 @@ module ActionView
53
53
  tag_string(:p, *arguments, **options, &block)
54
54
  end
55
55
 
56
- def tag_string(name, content = nil, escape_attributes: true, **options, &block)
56
+ def tag_string(name, content = nil, **options, &block)
57
+ escape = handle_deprecated_escape_options(options)
58
+
57
59
  content = @view_context.capture(self, &block) if block_given?
58
60
  if VOID_ELEMENTS.include?(name) && content.nil?
59
- "<#{name.to_s.dasherize}#{tag_options(options, escape_attributes)}>".html_safe
61
+ "<#{name.to_s.dasherize}#{tag_options(options, escape)}>".html_safe
60
62
  else
61
- content_tag_string(name.to_s.dasherize, content || "", options, escape_attributes)
63
+ content_tag_string(name.to_s.dasherize, content || "", options, escape)
62
64
  end
63
65
  end
64
66
 
65
67
  def content_tag_string(name, content, options, escape = true)
66
68
  tag_options = tag_options(options, escape) if options
67
- content = ERB::Util.unwrapped_html_escape(content) if escape
69
+
70
+ if escape
71
+ name = ERB::Util.xml_name_escape(name)
72
+ content = ERB::Util.unwrapped_html_escape(content)
73
+ end
74
+
68
75
  "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name]}#{content}</#{name}>".html_safe
69
76
  end
70
77
 
@@ -115,6 +122,8 @@ module ActionView
115
122
  end
116
123
 
117
124
  def tag_option(key, value, escape)
125
+ key = ERB::Util.xml_name_escape(key) if escape
126
+
118
127
  case value
119
128
  when Array, Hash
120
129
  value = TagHelper.build_tag_values(value) if key.to_s == "class"
@@ -123,6 +132,7 @@ module ActionView
123
132
  value = escape ? ERB::Util.unwrapped_html_escape(value) : value.to_s
124
133
  end
125
134
  value = value.gsub('"', "&quot;") if value.include?('"')
135
+
126
136
  %(#{key}="#{value}")
127
137
  end
128
138
 
@@ -139,6 +149,27 @@ module ActionView
139
149
  true
140
150
  end
141
151
 
152
+ def handle_deprecated_escape_options(options)
153
+ # The option :escape_attributes has been merged into the options hash to be
154
+ # able to warn when it is used, so we need to handle default values here.
155
+ escape_option_provided = options.has_key?(:escape)
156
+ escape_attributes_option_provided = options.has_key?(:escape_attributes)
157
+
158
+ if escape_attributes_option_provided
159
+ ActiveSupport::Deprecation.warn(<<~MSG)
160
+ Use of the option :escape_attributes is deprecated. It currently \
161
+ escapes both names and values of tags and attributes and it is \
162
+ equivalent to :escape. If any of them are enabled, the escaping \
163
+ is fully enabled.
164
+ MSG
165
+ end
166
+
167
+ return true unless escape_option_provided || escape_attributes_option_provided
168
+ escape_option = options.delete(:escape)
169
+ escape_attributes_option = options.delete(:escape_attributes)
170
+ escape_option || escape_attributes_option
171
+ end
172
+
142
173
  def method_missing(called, *args, **options, &block)
143
174
  tag_string(called, *args, **options, &block)
144
175
  end
@@ -202,13 +233,13 @@ module ActionView
202
233
  # tag.div data: { city_state: %w( Chicago IL ) }
203
234
  # # => <div data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]"></div>
204
235
  #
205
- # The generated attributes are escaped by default. This can be disabled using
206
- # +escape_attributes+.
236
+ # The generated tag names and attributes are escaped by default. This can be disabled using
237
+ # +escape+.
207
238
  #
208
239
  # tag.img src: 'open & shut.png'
209
240
  # # => <img src="open &amp; shut.png">
210
241
  #
211
- # tag.img src: 'open & shut.png', escape_attributes: false
242
+ # tag.img src: 'open & shut.png', escape: false
212
243
  # # => <img src="open & shut.png">
213
244
  #
214
245
  # The tag builder respects
@@ -272,6 +303,7 @@ module ActionView
272
303
  if name.nil?
273
304
  tag_builder
274
305
  else
306
+ name = ERB::Util.xml_name_escape(name) if escape
275
307
  "<#{name}#{tag_builder.tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
276
308
  end
277
309
  end
@@ -280,7 +312,7 @@ module ActionView
280
312
  # HTML attributes by passing an attributes hash to +options+.
281
313
  # Instead of passing the content as an argument, you can also use a block
282
314
  # in which case, you pass your +options+ as the second parameter.
283
- # Set escape to false to disable attribute value escaping.
315
+ # Set escape to false to disable escaping.
284
316
  # Note: this is legacy syntax, see +tag+ method description for details.
285
317
  #
286
318
  # ==== Options
@@ -153,7 +153,7 @@ module ActionView
153
153
  select = content_tag("select", add_options(option_tags, options, value), html_options)
154
154
 
155
155
  if html_options["multiple"] && options.fetch(:include_hidden, true)
156
- tag("input", disabled: html_options["disabled"], name: html_options["name"], type: "hidden", value: "") + select
156
+ tag("input", disabled: html_options["disabled"], name: html_options["name"], type: "hidden", value: "", autocomplete: "off") + select
157
157
  else
158
158
  select
159
159
  end
@@ -57,7 +57,7 @@ module ActionView
57
57
  end
58
58
 
59
59
  def hidden_field_for_checkbox(options)
60
- @unchecked_value ? tag("input", options.slice("name", "disabled", "form").merge!("type" => "hidden", "value" => @unchecked_value)) : "".html_safe
60
+ @unchecked_value ? tag("input", options.slice("name", "disabled", "form").merge!("type" => "hidden", "value" => @unchecked_value, "autocomplete" => "off")) : "".html_safe
61
61
  end
62
62
  end
63
63
  end
@@ -4,6 +4,10 @@ module ActionView
4
4
  module Helpers
5
5
  module Tags # :nodoc:
6
6
  class HiddenField < TextField # :nodoc:
7
+ def render
8
+ @options[:autocomplete] = "off"
9
+ super
10
+ end
7
11
  end
8
12
  end
9
13
  end
@@ -105,7 +105,7 @@ module ActionView
105
105
  # Highlights one or more +phrases+ everywhere in +text+ by inserting it into
106
106
  # a <tt>:highlighter</tt> string. The highlighter can be specialized by passing <tt>:highlighter</tt>
107
107
  # as a single-quoted string with <tt>\1</tt> where the phrase is to be inserted (defaults to
108
- # '<mark>\1</mark>') or passing a block that receives each matched term. By default +text+
108
+ # <tt><mark>\1</mark></tt>) or passing a block that receives each matched term. By default +text+
109
109
  # is sanitized to prevent possible XSS attacks. If the input is trustworthy, passing false
110
110
  # for <tt>:sanitize</tt> will turn sanitizing off.
111
111
  #
@@ -69,7 +69,7 @@ module ActionView
69
69
  #
70
70
  def translate(key, **options)
71
71
  return key.map { |k| translate(k, **options) } if key.is_a?(Array)
72
- key = key.to_s unless key.is_a?(Symbol)
72
+ key = key&.to_s unless key.is_a?(Symbol)
73
73
 
74
74
  alternatives = if options.key?(:default)
75
75
  options[:default].is_a?(Array) ? options.delete(:default).compact : [options.delete(:default)]
@@ -78,13 +78,12 @@ module ActionView
78
78
  options[:raise] = true if options[:raise].nil? && ActionView::Base.raise_on_missing_translations
79
79
  default = MISSING_TRANSLATION
80
80
 
81
- translation = while key
81
+ translation = while key || alternatives.present?
82
82
  if alternatives.blank? && !options[:raise].nil?
83
83
  default = NO_DEFAULT # let I18n handle missing translation
84
84
  end
85
85
 
86
86
  key = scope_key_by_partial(key)
87
- first_key ||= key
88
87
 
89
88
  if html_safe_translation_key?(key)
90
89
  html_safe_options ||= html_escape_translation_options(options)
@@ -95,12 +94,15 @@ module ActionView
95
94
  break translated unless translated.equal?(MISSING_TRANSLATION)
96
95
  end
97
96
 
98
- break alternatives.first if alternatives.present? && !alternatives.first.is_a?(Symbol)
97
+ if alternatives.present? && !alternatives.first.is_a?(Symbol)
98
+ break alternatives.first && I18n.translate(**options, default: alternatives)
99
+ end
99
100
 
101
+ first_key ||= key
100
102
  key = alternatives&.shift
101
103
  end
102
104
 
103
- if key.nil?
105
+ if key.nil? && !first_key.nil?
104
106
  translation = missing_translation(first_key, options)
105
107
  key = first_key
106
108
  end
@@ -130,11 +132,11 @@ module ActionView
130
132
  end
131
133
 
132
134
  def scope_key_by_partial(key)
133
- if key.start_with?(".")
134
- if @current_template&.virtual_path
135
+ if key&.start_with?(".")
136
+ if @virtual_path
135
137
  @_scope_key_by_partial_cache ||= {}
136
- @_scope_key_by_partial_cache[@current_template.virtual_path] ||= @current_template.virtual_path.gsub(%r{/_?}, ".")
137
- "#{@_scope_key_by_partial_cache[@current_template.virtual_path]}#{key}"
138
+ @_scope_key_by_partial_cache[@virtual_path] ||= @virtual_path.gsub(%r{/_?}, ".")
139
+ "#{@_scope_key_by_partial_cache[@virtual_path]}#{key}"
138
140
  else
139
141
  raise "Cannot use t(#{key.inspect}) shortcut because path is not available"
140
142
  end
@@ -337,7 +337,8 @@ module ActionView
337
337
  inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
338
338
  if params
339
339
  to_form_params(params).each do |param|
340
- inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value])
340
+ inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value],
341
+ autocomplete: "off")
341
342
  end
342
343
  end
343
344
  content_tag("form", inner_tags, form_options)
@@ -539,7 +540,7 @@ module ActionView
539
540
  #
540
541
  # We can also pass in the symbol arguments instead of strings.
541
542
  #
542
- def current_page?(options, check_parameters: false)
543
+ def current_page?(options = nil, check_parameters: false, **options_as_kwargs)
543
544
  unless request
544
545
  raise "You cannot use helpers that need to determine the current " \
545
546
  "page unless your view context provides a Request object " \
@@ -548,6 +549,7 @@ module ActionView
548
549
 
549
550
  return false unless request.get? || request.head?
550
551
 
552
+ options ||= options_as_kwargs
551
553
  check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
552
554
  url_string = URI::DEFAULT_PARSER.unescape(url_for(options)).force_encoding(Encoding::BINARY)
553
555
 
@@ -558,15 +560,26 @@ module ActionView
558
560
  request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
559
561
  request_uri = URI::DEFAULT_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY)
560
562
 
561
- if url_string.start_with?("/") && url_string != "/"
562
- url_string.chomp!("/")
563
- request_uri.chomp!("/")
563
+ if %r{^\w+://}.match?(url_string)
564
+ request_uri = +"#{request.protocol}#{request.host_with_port}#{request_uri}"
564
565
  end
565
566
 
566
- if %r{^\w+://}.match?(url_string)
567
- url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
568
- else
569
- url_string == request_uri
567
+ remove_trailing_slash!(url_string)
568
+ remove_trailing_slash!(request_uri)
569
+
570
+ url_string == request_uri
571
+ end
572
+
573
+ if RUBY_VERSION.start_with?("2.7")
574
+ using Module.new {
575
+ refine UrlHelper do
576
+ alias :_current_page? :current_page?
577
+ end
578
+ }
579
+
580
+ def current_page?(*args) # :nodoc:
581
+ options = args.pop
582
+ options.is_a?(Hash) ? _current_page?(*args, **options) : _current_page?(*args, options)
570
583
  end
571
584
  end
572
585
 
@@ -714,14 +727,14 @@ module ActionView
714
727
  def token_tag(token = nil, form_options: {})
715
728
  if token != false && defined?(protect_against_forgery?) && protect_against_forgery?
716
729
  token ||= form_authenticity_token(form_options: form_options)
717
- tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token)
730
+ tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token, autocomplete: "off")
718
731
  else
719
732
  ""
720
733
  end
721
734
  end
722
735
 
723
736
  def method_tag(method)
724
- tag("input", type: "hidden", name: "_method", value: method.to_s)
737
+ tag("input", type: "hidden", name: "_method", value: method.to_s, autocomplete: "off")
725
738
  end
726
739
 
727
740
  # Returns an array of hashes each containing :name and :value keys
@@ -765,6 +778,11 @@ module ActionView
765
778
 
766
779
  params.sort_by { |pair| pair[:name] }
767
780
  end
781
+
782
+ def remove_trailing_slash!(url_string)
783
+ trailing_index = (url_string.index("?") || 0) - 1
784
+ url_string[trailing_index] = "" if url_string[trailing_index] == "/"
785
+ end
768
786
  end
769
787
  end
770
788
  end
@@ -37,12 +37,16 @@ module ActionView
37
37
  end
38
38
  end
39
39
 
40
+ config.after_initialize do |app|
41
+ ActionView::Helpers::AssetTagHelper.preload_links_header = app.config.action_view.delete(:preload_links_header)
42
+ end
43
+
40
44
  config.after_initialize do |app|
41
45
  ActiveSupport.on_load(:action_view) do
42
46
  app.config.action_view.each do |k, v|
43
47
  if k == :raise_on_missing_translations
44
48
  ActiveSupport::Deprecation.warn \
45
- "action_view.raise_on_missing_translations is deprecated and will be removed in Rails 6.2. " \
49
+ "action_view.raise_on_missing_translations is deprecated and will be removed in Rails 7.0. " \
46
50
  "Set i18n.raise_on_missing_translations instead. " \
47
51
  "Note that this new setting also affects how missing translations are handled in controllers."
48
52
  end
@@ -47,6 +47,10 @@ module ActionView
47
47
  def size
48
48
  @collection.size
49
49
  end
50
+
51
+ def length
52
+ @collection.respond_to?(:length) ? @collection.length : size
53
+ end
50
54
  end
51
55
 
52
56
  class SameCollectionIterator < CollectionIterator # :nodoc:
@@ -144,7 +148,7 @@ module ActionView
144
148
  "render_collection.action_view",
145
149
  identifier: identifier,
146
150
  layout: layout && layout.virtual_path,
147
- count: collection.size
151
+ count: collection.length
148
152
  ) do |payload|
149
153
  spacer = if @options.key?(:spacer_template)
150
154
  spacer_template = find_template(@options[:spacer_template], @locals.keys)
data/lib/action_view.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2004-2020 David Heinemeier Hansson
4
+ # Copyright (c) 2004-2022 David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  Unobtrusive JavaScript
3
- https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts
3
+ https://github.com/rails/rails/blob/main/actionview/app/assets/javascripts
4
4
  Released under the MIT license
5
5
  */;
6
6
 
@@ -16,8 +16,8 @@ Released under the MIT license
16
16
  exclude: 'form button'
17
17
  },
18
18
  inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
19
- formSubmitSelector: 'form',
20
- formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
19
+ formSubmitSelector: 'form:not([data-turbo=true])',
20
+ formInputClickSelector: 'form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
21
21
  formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
22
22
  formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
23
23
  fileInputSelector: 'input[name][type=file]:not([disabled])',
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionview
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.0
4
+ version: 6.1.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-09 00:00:00.000000000 Z
11
+ date: 2023-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 6.1.0
19
+ version: 6.1.7.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 6.1.0
26
+ version: 6.1.7.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: builder
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -92,28 +92,28 @@ dependencies:
92
92
  requirements:
93
93
  - - '='
94
94
  - !ruby/object:Gem::Version
95
- version: 6.1.0
95
+ version: 6.1.7.1
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - '='
101
101
  - !ruby/object:Gem::Version
102
- version: 6.1.0
102
+ version: 6.1.7.1
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: activemodel
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - '='
108
108
  - !ruby/object:Gem::Version
109
- version: 6.1.0
109
+ version: 6.1.7.1
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - '='
115
115
  - !ruby/object:Gem::Version
116
- version: 6.1.0
116
+ version: 6.1.7.1
117
117
  description: Simple, battle-tested conventions and helpers for building web pages.
118
118
  email: david@loudthinking.com
119
119
  executables: []
@@ -239,11 +239,12 @@ licenses:
239
239
  - MIT
240
240
  metadata:
241
241
  bug_tracker_uri: https://github.com/rails/rails/issues
242
- changelog_uri: https://github.com/rails/rails/blob/v6.1.0/actionview/CHANGELOG.md
243
- documentation_uri: https://api.rubyonrails.org/v6.1.0/
242
+ changelog_uri: https://github.com/rails/rails/blob/v6.1.7.1/actionview/CHANGELOG.md
243
+ documentation_uri: https://api.rubyonrails.org/v6.1.7.1/
244
244
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
245
- source_code_uri: https://github.com/rails/rails/tree/v6.1.0/actionview
246
- post_install_message:
245
+ source_code_uri: https://github.com/rails/rails/tree/v6.1.7.1/actionview
246
+ rubygems_mfa_required: 'true'
247
+ post_install_message:
247
248
  rdoc_options: []
248
249
  require_paths:
249
250
  - lib
@@ -259,8 +260,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
259
260
  version: '0'
260
261
  requirements:
261
262
  - none
262
- rubygems_version: 3.1.4
263
- signing_key:
263
+ rubygems_version: 3.4.3
264
+ signing_key:
264
265
  specification_version: 4
265
266
  summary: Rendering framework putting the V in MVC (part of Rails).
266
267
  test_files: []