actionview 5.1.4 → 6.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionview might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +199 -168
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -5
- data/lib/action_view.rb +10 -4
- data/lib/action_view/base.rb +87 -23
- data/lib/action_view/buffers.rb +17 -0
- data/lib/action_view/cache_expiry.rb +52 -0
- data/lib/action_view/context.rb +7 -11
- data/lib/action_view/dependency_tracker.rb +12 -4
- data/lib/action_view/digestor.rb +24 -23
- data/lib/action_view/flows.rb +2 -1
- data/lib/action_view/gem_version.rb +4 -2
- data/lib/action_view/helpers.rb +4 -2
- data/lib/action_view/helpers/active_model_helper.rb +9 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +220 -57
- data/lib/action_view/helpers/asset_url_helper.rb +28 -23
- data/lib/action_view/helpers/atom_feed_helper.rb +5 -2
- data/lib/action_view/helpers/cache_helper.rb +39 -28
- data/lib/action_view/helpers/capture_helper.rb +13 -7
- data/lib/action_view/helpers/controller_helper.rb +3 -1
- data/lib/action_view/helpers/csp_helper.rb +26 -0
- data/lib/action_view/helpers/csrf_helper.rb +5 -3
- data/lib/action_view/helpers/date_helper.rb +78 -33
- data/lib/action_view/helpers/debug_helper.rb +4 -2
- data/lib/action_view/helpers/form_helper.rb +357 -106
- data/lib/action_view/helpers/form_options_helper.rb +45 -39
- data/lib/action_view/helpers/form_tag_helper.rb +42 -27
- data/lib/action_view/helpers/javascript_helper.rb +28 -12
- data/lib/action_view/helpers/number_helper.rb +16 -8
- data/lib/action_view/helpers/output_safety_helper.rb +3 -1
- data/lib/action_view/helpers/rendering_helper.rb +20 -9
- data/lib/action_view/helpers/sanitize_helper.rb +15 -19
- data/lib/action_view/helpers/tag_helper.rb +100 -24
- data/lib/action_view/helpers/tags.rb +3 -1
- data/lib/action_view/helpers/tags/base.rb +30 -21
- data/lib/action_view/helpers/tags/check_box.rb +3 -2
- data/lib/action_view/helpers/tags/checkable.rb +4 -2
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +2 -1
- data/lib/action_view/helpers/tags/collection_helpers.rb +2 -1
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +2 -1
- data/lib/action_view/helpers/tags/collection_select.rb +3 -1
- data/lib/action_view/helpers/tags/color_field.rb +4 -3
- data/lib/action_view/helpers/tags/date_field.rb +3 -2
- data/lib/action_view/helpers/tags/date_select.rb +5 -4
- data/lib/action_view/helpers/tags/datetime_field.rb +3 -2
- data/lib/action_view/helpers/tags/datetime_local_field.rb +3 -2
- data/lib/action_view/helpers/tags/datetime_select.rb +2 -0
- data/lib/action_view/helpers/tags/email_field.rb +2 -0
- data/lib/action_view/helpers/tags/file_field.rb +2 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +3 -1
- data/lib/action_view/helpers/tags/hidden_field.rb +2 -0
- data/lib/action_view/helpers/tags/label.rb +6 -5
- data/lib/action_view/helpers/tags/month_field.rb +3 -2
- data/lib/action_view/helpers/tags/number_field.rb +2 -0
- data/lib/action_view/helpers/tags/password_field.rb +2 -0
- data/lib/action_view/helpers/tags/placeholderable.rb +2 -0
- data/lib/action_view/helpers/tags/radio_button.rb +3 -2
- data/lib/action_view/helpers/tags/range_field.rb +2 -0
- data/lib/action_view/helpers/tags/search_field.rb +2 -0
- data/lib/action_view/helpers/tags/select.rb +4 -3
- data/lib/action_view/helpers/tags/tel_field.rb +2 -0
- data/lib/action_view/helpers/tags/text_area.rb +3 -1
- data/lib/action_view/helpers/tags/text_field.rb +3 -2
- data/lib/action_view/helpers/tags/time_field.rb +3 -2
- data/lib/action_view/helpers/tags/time_select.rb +2 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +3 -1
- data/lib/action_view/helpers/tags/translator.rb +3 -6
- data/lib/action_view/helpers/tags/url_field.rb +2 -0
- data/lib/action_view/helpers/tags/week_field.rb +3 -2
- data/lib/action_view/helpers/text_helper.rb +11 -10
- data/lib/action_view/helpers/translation_helper.rb +102 -52
- data/lib/action_view/helpers/url_helper.rb +150 -32
- data/lib/action_view/layouts.rb +15 -15
- data/lib/action_view/log_subscriber.rb +32 -15
- data/lib/action_view/lookup_context.rb +67 -39
- data/lib/action_view/model_naming.rb +2 -0
- data/lib/action_view/path_set.rb +5 -12
- data/lib/action_view/railtie.rb +46 -21
- data/lib/action_view/record_identifier.rb +4 -3
- data/lib/action_view/renderer/abstract_renderer.rb +144 -11
- data/lib/action_view/renderer/collection_renderer.rb +196 -0
- data/lib/action_view/renderer/object_renderer.rb +34 -0
- data/lib/action_view/renderer/partial_renderer.rb +33 -283
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +64 -17
- data/lib/action_view/renderer/renderer.rb +61 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +14 -8
- data/lib/action_view/renderer/template_renderer.rb +36 -26
- data/lib/action_view/rendering.rb +57 -38
- data/lib/action_view/routing_url_for.rb +15 -12
- data/lib/action_view/tasks/cache_digests.rake +2 -0
- data/lib/action_view/template.rb +69 -76
- data/lib/action_view/template/error.rb +32 -18
- data/lib/action_view/template/handlers.rb +4 -2
- data/lib/action_view/template/handlers/builder.rb +5 -6
- data/lib/action_view/template/handlers/erb.rb +20 -19
- data/lib/action_view/template/handlers/erb/erubi.rb +17 -9
- data/lib/action_view/template/handlers/html.rb +3 -1
- data/lib/action_view/template/handlers/raw.rb +4 -2
- data/lib/action_view/template/html.rb +8 -7
- data/lib/action_view/template/inline.rb +22 -0
- data/lib/action_view/template/raw_file.rb +25 -0
- data/lib/action_view/template/renderable.rb +24 -0
- data/lib/action_view/template/resolver.rb +194 -152
- data/lib/action_view/template/sources.rb +13 -0
- data/lib/action_view/template/sources/file.rb +17 -0
- data/lib/action_view/template/text.rb +5 -4
- data/lib/action_view/template/types.rb +3 -1
- data/lib/action_view/test_case.rb +38 -30
- data/lib/action_view/testing/resolvers.rb +20 -27
- data/lib/action_view/unbound_template.rb +31 -0
- data/lib/action_view/version.rb +2 -0
- data/lib/action_view/view_paths.rb +61 -40
- data/lib/assets/compiled/rails-ujs.js +84 -23
- metadata +34 -23
- data/lib/action_view/helpers/record_tag_helper.rb +0 -21
- data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +0 -9
- data/lib/action_view/template/handlers/erb/erubis.rb +0 -81
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "zlib"
|
2
4
|
|
3
5
|
module ActionView
|
4
6
|
# = Action View Asset URL Helpers
|
5
|
-
module Helpers
|
7
|
+
module Helpers #:nodoc:
|
6
8
|
# This module provides methods for generating asset paths and
|
7
|
-
#
|
9
|
+
# URLs.
|
8
10
|
#
|
9
11
|
# image_path("rails.png")
|
10
12
|
# # => "/assets/rails.png"
|
@@ -27,7 +29,7 @@ module ActionView
|
|
27
29
|
# Helpers take that into account:
|
28
30
|
#
|
29
31
|
# image_tag("rails.png")
|
30
|
-
# # => <img
|
32
|
+
# # => <img src="http://assets.example.com/assets/rails.png" />
|
31
33
|
# stylesheet_link_tag("application")
|
32
34
|
# # => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" />
|
33
35
|
#
|
@@ -40,7 +42,7 @@ module ActionView
|
|
40
42
|
# "assets0.example.com", ..., "assets3.example.com".
|
41
43
|
#
|
42
44
|
# image_tag("rails.png")
|
43
|
-
# # => <img
|
45
|
+
# # => <img src="http://assets0.example.com/assets/rails.png" />
|
44
46
|
# stylesheet_link_tag("application")
|
45
47
|
# # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
|
46
48
|
#
|
@@ -50,13 +52,13 @@ module ActionView
|
|
50
52
|
# solution being slower. You should be sure to measure your actual
|
51
53
|
# performance across targeted browsers both before and after this change.
|
52
54
|
#
|
53
|
-
# To implement the corresponding hosts you can either
|
55
|
+
# To implement the corresponding hosts you can either set up four actual
|
54
56
|
# hosts or use wildcard DNS to CNAME the wildcard to a single asset host.
|
55
57
|
# You can read more about setting up your DNS CNAME records from your ISP.
|
56
58
|
#
|
57
59
|
# Note: This is purely a browser performance optimization and is not meant
|
58
|
-
# for server load balancing. See
|
59
|
-
# for background and
|
60
|
+
# for server load balancing. See https://www.die.net/musings/page_load_time/
|
61
|
+
# for background and https://www.browserscope.org/?category=network for
|
60
62
|
# connection limit data.
|
61
63
|
#
|
62
64
|
# Alternatively, you can exert more control over the asset host by setting
|
@@ -66,7 +68,7 @@ module ActionView
|
|
66
68
|
# "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
|
67
69
|
# }
|
68
70
|
# image_tag("rails.png")
|
69
|
-
# # => <img
|
71
|
+
# # => <img src="http://assets1.example.com/assets/rails.png" />
|
70
72
|
# stylesheet_link_tag("application")
|
71
73
|
# # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
|
72
74
|
#
|
@@ -78,14 +80,14 @@ module ActionView
|
|
78
80
|
# absolute path of the asset, for example "/assets/rails.png".
|
79
81
|
#
|
80
82
|
# ActionController::Base.asset_host = Proc.new { |source|
|
81
|
-
# if source.
|
83
|
+
# if source.end_with?('.css')
|
82
84
|
# "http://stylesheets.example.com"
|
83
85
|
# else
|
84
86
|
# "http://assets.example.com"
|
85
87
|
# end
|
86
88
|
# }
|
87
89
|
# image_tag("rails.png")
|
88
|
-
# # => <img
|
90
|
+
# # => <img src="http://assets.example.com/assets/rails.png" />
|
89
91
|
# stylesheet_link_tag("application")
|
90
92
|
# # => <link href="http://stylesheets.example.com/assets/application.css" media="screen" rel="stylesheet" />
|
91
93
|
#
|
@@ -95,9 +97,10 @@ module ActionView
|
|
95
97
|
# still sending assets for plain HTTP requests from asset hosts. If you don't
|
96
98
|
# have SSL certificates for each of the asset hosts this technique allows you
|
97
99
|
# to avoid warnings in the client about mixed media.
|
98
|
-
# Note that the request parameter might not be supplied, e.g. when the assets
|
99
|
-
# are precompiled
|
100
|
-
# since a +Proc+ allows missing parameters and sets them
|
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
|
102
|
+
# +Proc+ instead of a lambda, since a +Proc+ allows missing parameters and sets them
|
103
|
+
# to +nil+.
|
101
104
|
#
|
102
105
|
# config.action_controller.asset_host = Proc.new { |source, request|
|
103
106
|
# if request && request.ssl?
|
@@ -130,6 +133,8 @@ module ActionView
|
|
130
133
|
# which is implemented by sprockets-rails.
|
131
134
|
#
|
132
135
|
# asset_path("application.js") # => "/assets/application-60aa4fdc5cea14baf5400fba1abf4f2a46a5166bad4772b1effe341570f07de9.js"
|
136
|
+
# asset_path('application.js', host: 'example.com') # => "//example.com/assets/application.js"
|
137
|
+
# asset_path("application.js", host: 'example.com', protocol: 'https') # => "https://example.com/assets/application.js"
|
133
138
|
#
|
134
139
|
# === Without the asset pipeline (<tt>skip_pipeline: true</tt>)
|
135
140
|
#
|
@@ -147,13 +152,13 @@ module ActionView
|
|
147
152
|
# Below lists scenarios that apply to +asset_path+ whether or not you're
|
148
153
|
# using the asset pipeline.
|
149
154
|
#
|
150
|
-
# - All fully qualified
|
155
|
+
# - All fully qualified URLs are returned immediately. This bypasses the
|
151
156
|
# asset pipeline and all other behavior described.
|
152
157
|
#
|
153
158
|
# asset_path("http://www.example.com/js/xmlhr.js") # => "http://www.example.com/js/xmlhr.js"
|
154
159
|
#
|
155
160
|
# - All assets that begin with a forward slash are assumed to be full
|
156
|
-
#
|
161
|
+
# URLs and will not be expanded. This will bypass the asset pipeline.
|
157
162
|
#
|
158
163
|
# asset_path("/foo.png") # => "/foo.png"
|
159
164
|
#
|
@@ -185,7 +190,7 @@ module ActionView
|
|
185
190
|
return "" if source.blank?
|
186
191
|
return source if URI_REGEXP.match?(source)
|
187
192
|
|
188
|
-
tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, ""
|
193
|
+
tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, "")
|
189
194
|
|
190
195
|
if extname = compute_asset_extname(source, options)
|
191
196
|
source = "#{source}#{extname}"
|
@@ -201,7 +206,7 @@ module ActionView
|
|
201
206
|
|
202
207
|
relative_url_root = defined?(config.relative_url_root) && config.relative_url_root
|
203
208
|
if relative_url_root
|
204
|
-
source = File.join(relative_url_root, source) unless source.
|
209
|
+
source = File.join(relative_url_root, source) unless source.start_with?("#{relative_url_root}/")
|
205
210
|
end
|
206
211
|
|
207
212
|
if host = compute_asset_host(source, options)
|
@@ -322,7 +327,7 @@ module ActionView
|
|
322
327
|
# Since +javascript_url+ is based on +asset_url+ method you can set :host options. If :host
|
323
328
|
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
|
324
329
|
#
|
325
|
-
# javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/
|
330
|
+
# javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/js/xmlhr.js
|
326
331
|
#
|
327
332
|
def javascript_url(source, options = {})
|
328
333
|
url_to_asset(source, { type: :javascript }.merge!(options))
|
@@ -349,7 +354,7 @@ module ActionView
|
|
349
354
|
# Since +stylesheet_url+ is based on +asset_url+ method you can set :host options. If :host
|
350
355
|
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
|
351
356
|
#
|
352
|
-
# stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/css/style.css
|
357
|
+
# stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/assets/css/style.css
|
353
358
|
#
|
354
359
|
def stylesheet_url(source, options = {})
|
355
360
|
url_to_asset(source, { type: :stylesheet }.merge!(options))
|
@@ -379,7 +384,7 @@ module ActionView
|
|
379
384
|
# Since +image_url+ is based on +asset_url+ method you can set :host options. If :host
|
380
385
|
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
|
381
386
|
#
|
382
|
-
# image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/edit.png
|
387
|
+
# image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/assets/edit.png
|
383
388
|
#
|
384
389
|
def image_url(source, options = {})
|
385
390
|
url_to_asset(source, { type: :image }.merge!(options))
|
@@ -405,7 +410,7 @@ module ActionView
|
|
405
410
|
# Since +video_url+ is based on +asset_url+ method you can set :host options. If :host
|
406
411
|
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
|
407
412
|
#
|
408
|
-
# video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/hd.avi
|
413
|
+
# video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/videos/hd.avi
|
409
414
|
#
|
410
415
|
def video_url(source, options = {})
|
411
416
|
url_to_asset(source, { type: :video }.merge!(options))
|
@@ -431,7 +436,7 @@ module ActionView
|
|
431
436
|
# Since +audio_url+ is based on +asset_url+ method you can set :host options. If :host
|
432
437
|
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
|
433
438
|
#
|
434
|
-
# audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/horse.wav
|
439
|
+
# audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/audios/horse.wav
|
435
440
|
#
|
436
441
|
def audio_url(source, options = {})
|
437
442
|
url_to_asset(source, { type: :audio }.merge!(options))
|
@@ -456,7 +461,7 @@ module ActionView
|
|
456
461
|
# Since +font_url+ is based on +asset_url+ method you can set :host options. If :host
|
457
462
|
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
|
458
463
|
#
|
459
|
-
# font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/font.ttf
|
464
|
+
# font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/fonts/font.ttf
|
460
465
|
#
|
461
466
|
def font_url(source, options = {})
|
462
467
|
url_to_asset(source, { type: :font }.merge!(options))
|
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "set"
|
4
|
+
require "active_support/core_ext/symbol/starts_ends_with"
|
2
5
|
|
3
6
|
module ActionView
|
4
7
|
# = Action View Atom Feed Helpers
|
5
|
-
module Helpers
|
8
|
+
module Helpers #:nodoc:
|
6
9
|
module AtomFeedHelper
|
7
10
|
# Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERB or any other
|
8
11
|
# template languages).
|
@@ -113,7 +116,7 @@ module ActionView
|
|
113
116
|
end
|
114
117
|
|
115
118
|
feed_opts = { "xml:lang" => options[:language] || "en-US", "xmlns" => "http://www.w3.org/2005/Atom" }
|
116
|
-
feed_opts.merge!(options).
|
119
|
+
feed_opts.merge!(options).select! { |k, _| k.start_with?("xml") }
|
117
120
|
|
118
121
|
xml.feed(feed_opts) do
|
119
122
|
xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}")
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionView
|
2
4
|
# = Action View Cache Helper
|
3
|
-
module Helpers
|
5
|
+
module Helpers #:nodoc:
|
4
6
|
module CacheHelper
|
5
7
|
# This helper exposes a method for caching fragments of a view
|
6
8
|
# rather than an entire action or page. This technique is useful
|
@@ -8,10 +10,9 @@ module ActionView
|
|
8
10
|
# fragments, and so on. This method takes a block that contains
|
9
11
|
# the content you wish to cache.
|
10
12
|
#
|
11
|
-
# The best way to use this is by doing key-based cache expiration
|
12
|
-
# on top of a cache store like Memcached that'll automatically
|
13
|
-
# kick out old entries.
|
14
|
-
# http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works
|
13
|
+
# The best way to use this is by doing recyclable key-based cache expiration
|
14
|
+
# on top of a cache store like Memcached or Redis that'll automatically
|
15
|
+
# kick out old entries.
|
15
16
|
#
|
16
17
|
# When using this method, you list the cache dependency as the name of the cache, like so:
|
17
18
|
#
|
@@ -23,10 +24,14 @@ module ActionView
|
|
23
24
|
# This approach will assume that when a new topic is added, you'll touch
|
24
25
|
# the project. The cache key generated from this call will be something like:
|
25
26
|
#
|
26
|
-
# views/projects/123
|
27
|
-
# ^
|
27
|
+
# views/template/action:7a1156131a6928cb0026877f8b749ac9/projects/123
|
28
|
+
# ^template path ^template tree digest ^class ^id
|
28
29
|
#
|
29
|
-
#
|
30
|
+
# This cache key is stable, but it's combined with a cache version derived from the project
|
31
|
+
# record. When the project updated_at is touched, the #cache_version changes, even
|
32
|
+
# if the key stays stable. This means that unlike a traditional key-based cache expiration
|
33
|
+
# approach, you won't be generating cache trash, unused keys, simply because the dependent
|
34
|
+
# record is updated.
|
30
35
|
#
|
31
36
|
# If your template cache depends on multiple sources (try to avoid this to keep things simple),
|
32
37
|
# you can name all these dependencies as part of an array:
|
@@ -106,9 +111,9 @@ module ActionView
|
|
106
111
|
# <%= render_categorizable_events @person.events %>
|
107
112
|
#
|
108
113
|
# This marks every template in the directory as a dependency. To find those
|
109
|
-
# templates, the wildcard path must be absolutely defined from app/views or paths
|
114
|
+
# templates, the wildcard path must be absolutely defined from <tt>app/views</tt> or paths
|
110
115
|
# otherwise added with +prepend_view_path+ or +append_view_path+.
|
111
|
-
# This way the wildcard for
|
116
|
+
# This way the wildcard for <tt>app/views/recordings/events</tt> would be <tt>recordings/events/*</tt> etc.
|
112
117
|
#
|
113
118
|
# The pattern used to match explicit dependencies is <tt>/# Template Dependency: (\S+)/</tt>,
|
114
119
|
# so it's important that you type it out just so.
|
@@ -128,14 +133,14 @@ module ActionView
|
|
128
133
|
#
|
129
134
|
# === Collection Caching
|
130
135
|
#
|
131
|
-
# When rendering a collection of objects that each use the same partial, a
|
136
|
+
# When rendering a collection of objects that each use the same partial, a <tt>:cached</tt>
|
132
137
|
# option can be passed.
|
133
138
|
#
|
134
139
|
# For collections rendered such:
|
135
140
|
#
|
136
141
|
# <%= render partial: 'projects/project', collection: @projects, cached: true %>
|
137
142
|
#
|
138
|
-
# The
|
143
|
+
# The <tt>cached: true</tt> will make Action View's rendering read several templates
|
139
144
|
# from cache at once instead of one call per template.
|
140
145
|
#
|
141
146
|
# Templates in the collection not already cached are written to cache.
|
@@ -160,8 +165,8 @@ module ActionView
|
|
160
165
|
# expire the cache.
|
161
166
|
def cache(name = {}, options = {}, &block)
|
162
167
|
if controller.respond_to?(:perform_caching) && controller.perform_caching
|
163
|
-
name_options = options.slice(:skip_digest
|
164
|
-
safe_concat(fragment_for(cache_fragment_name(name, name_options), options, &block))
|
168
|
+
name_options = options.slice(:skip_digest)
|
169
|
+
safe_concat(fragment_for(cache_fragment_name(name, **name_options), options, &block))
|
165
170
|
else
|
166
171
|
yield
|
167
172
|
end
|
@@ -196,29 +201,35 @@ module ActionView
|
|
196
201
|
end
|
197
202
|
|
198
203
|
# This helper returns the name of a cache key for a given fragment cache
|
199
|
-
# call. By supplying
|
204
|
+
# call. By supplying <tt>skip_digest: true</tt> to cache, the digestion of cache
|
200
205
|
# fragments can be manually bypassed. This is useful when cache fragments
|
201
206
|
# cannot be manually expired unless you know the exact key which is the
|
202
207
|
# case when using memcached.
|
203
|
-
|
204
|
-
# The digest will be generated using +virtual_path:+ if it is provided.
|
205
|
-
#
|
206
|
-
def cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil)
|
208
|
+
def cache_fragment_name(name = {}, skip_digest: nil, digest_path: nil)
|
207
209
|
if skip_digest
|
208
210
|
name
|
209
211
|
else
|
210
|
-
fragment_name_with_digest(name,
|
212
|
+
fragment_name_with_digest(name, digest_path)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def digest_path_from_template(template) # :nodoc:
|
217
|
+
digest = Digestor.digest(name: template.virtual_path, format: template.format, finder: lookup_context, dependencies: view_cache_dependencies)
|
218
|
+
|
219
|
+
if digest.present?
|
220
|
+
"#{template.virtual_path}:#{digest}"
|
221
|
+
else
|
222
|
+
template.virtual_path
|
211
223
|
end
|
212
224
|
end
|
213
225
|
|
214
226
|
private
|
227
|
+
def fragment_name_with_digest(name, digest_path)
|
228
|
+
name = controller.url_for(name).split("://").last if name.is_a?(Hash)
|
215
229
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
name = controller.url_for(name).split("://").last if name.is_a?(Hash)
|
220
|
-
digest = Digestor.digest name: virtual_path, finder: lookup_context, dependencies: view_cache_dependencies
|
221
|
-
[ name, digest ]
|
230
|
+
if @current_template&.virtual_path || digest_path
|
231
|
+
digest_path ||= digest_path_from_template(@current_template)
|
232
|
+
[ digest_path, name ]
|
222
233
|
else
|
223
234
|
name
|
224
235
|
end
|
@@ -226,10 +237,10 @@ module ActionView
|
|
226
237
|
|
227
238
|
def fragment_for(name = {}, options = nil, &block)
|
228
239
|
if content = read_fragment_for(name, options)
|
229
|
-
@view_renderer.cache_hits[@virtual_path] = :hit if defined?(@view_renderer)
|
240
|
+
@view_renderer.cache_hits[@current_template&.virtual_path] = :hit if defined?(@view_renderer)
|
230
241
|
content
|
231
242
|
else
|
232
|
-
@view_renderer.cache_hits[@virtual_path] = :miss if defined?(@view_renderer)
|
243
|
+
@view_renderer.cache_hits[@current_template&.virtual_path] = :miss if defined?(@view_renderer)
|
233
244
|
write_fragment_for(name, options, &block)
|
234
245
|
end
|
235
246
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/string/output_safety"
|
2
4
|
|
3
5
|
module ActionView
|
4
6
|
# = Action View Capture Helper
|
5
|
-
module Helpers
|
7
|
+
module Helpers #:nodoc:
|
6
8
|
# CaptureHelper exposes methods to let you extract generated markup which
|
7
9
|
# can be used in other parts of a template or layout file.
|
8
10
|
#
|
9
11
|
# It provides a method to capture blocks into variables through capture and
|
10
|
-
# a way to capture a block of markup for use in a layout through content_for.
|
12
|
+
# a way to capture a block of markup for use in a layout through {content_for}[rdoc-ref:ActionView::Helpers::CaptureHelper#content_for].
|
11
13
|
module CaptureHelper
|
12
14
|
# The capture method extracts part of a template as a String object.
|
13
15
|
# You can then use this object anywhere in your templates, layout, or helpers.
|
@@ -34,6 +36,10 @@ module ActionView
|
|
34
36
|
# </body>
|
35
37
|
# </html>
|
36
38
|
#
|
39
|
+
# The return of capture is the string generated by the block. For Example:
|
40
|
+
#
|
41
|
+
# @greeting # => "Welcome to my shiny new web page! The date and time is 2018-09-06 11:09:16 -0500"
|
42
|
+
#
|
37
43
|
def capture(*args)
|
38
44
|
value = nil
|
39
45
|
buffer = with_output_buffer { value = yield(*args) }
|
@@ -42,7 +48,7 @@ module ActionView
|
|
42
48
|
end
|
43
49
|
end
|
44
50
|
|
45
|
-
# Calling content_for stores a block of markup in an identifier for later use.
|
51
|
+
# Calling <tt>content_for</tt> stores a block of markup in an identifier for later use.
|
46
52
|
# In order to access this stored content in other templates, helper modules
|
47
53
|
# or the layout, you would pass the identifier as an argument to <tt>content_for</tt>.
|
48
54
|
#
|
@@ -108,7 +114,7 @@ module ActionView
|
|
108
114
|
# That will place +script+ tags for your default set of JavaScript files on the page;
|
109
115
|
# this technique is useful if you'll only be using these scripts in a few views.
|
110
116
|
#
|
111
|
-
# Note that content_for concatenates (default) the blocks it is given for a particular
|
117
|
+
# Note that <tt>content_for</tt> concatenates (default) the blocks it is given for a particular
|
112
118
|
# identifier in order. For example:
|
113
119
|
#
|
114
120
|
# <% content_for :navigation do %>
|
@@ -125,7 +131,7 @@ module ActionView
|
|
125
131
|
#
|
126
132
|
# <ul><%= content_for :navigation %></ul>
|
127
133
|
#
|
128
|
-
# If the flush parameter is true content_for replaces the blocks it is given. For example:
|
134
|
+
# If the flush parameter is +true+ <tt>content_for</tt> replaces the blocks it is given. For example:
|
129
135
|
#
|
130
136
|
# <% content_for :navigation do %>
|
131
137
|
# <li><%= link_to 'Home', action: 'index' %></li>
|
@@ -145,7 +151,7 @@ module ActionView
|
|
145
151
|
#
|
146
152
|
# <% content_for :script, javascript_include_tag(:defaults) %>
|
147
153
|
#
|
148
|
-
# WARNING: content_for is ignored in caches. So you shouldn't use it for elements that will be fragment cached.
|
154
|
+
# WARNING: <tt>content_for</tt> is ignored in caches. So you shouldn't use it for elements that will be fragment cached.
|
149
155
|
def content_for(name, content = nil, options = {}, &block)
|
150
156
|
if content || block_given?
|
151
157
|
if block_given?
|
@@ -172,7 +178,7 @@ module ActionView
|
|
172
178
|
result unless content
|
173
179
|
end
|
174
180
|
|
175
|
-
# content_for
|
181
|
+
# <tt>content_for?</tt> checks whether any content has been captured yet using <tt>content_for</tt>.
|
176
182
|
# Useful to render parts of your layout differently based on what is in your views.
|
177
183
|
#
|
178
184
|
# <%# This is the layout %>
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/module/attr_internal"
|
2
4
|
|
3
5
|
module ActionView
|
4
|
-
module Helpers
|
6
|
+
module Helpers #:nodoc:
|
5
7
|
# This module keeps all methods and behavior in ActionView
|
6
8
|
# that simply delegates to the controller.
|
7
9
|
module ControllerHelper #:nodoc:
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionView
|
4
|
+
# = Action View CSP Helper
|
5
|
+
module Helpers #:nodoc:
|
6
|
+
module CspHelper
|
7
|
+
# Returns a meta tag "csp-nonce" with the per-session nonce value
|
8
|
+
# for allowing inline <script> tags.
|
9
|
+
#
|
10
|
+
# <head>
|
11
|
+
# <%= csp_meta_tag %>
|
12
|
+
# </head>
|
13
|
+
#
|
14
|
+
# This is used by the Rails UJS helper to create dynamically
|
15
|
+
# loaded inline <script> elements.
|
16
|
+
#
|
17
|
+
def csp_meta_tag(**options)
|
18
|
+
if content_security_policy?
|
19
|
+
options[:name] = "csp-nonce"
|
20
|
+
options[:content] = content_security_policy_nonce
|
21
|
+
tag("meta", options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|