aboutsummaryrefslogtreecommitdiffstats
path: root/actionview/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionview/lib')
-rw-r--r--actionview/lib/action_view.rb5
-rw-r--r--actionview/lib/action_view/base.rb18
-rw-r--r--actionview/lib/action_view/buffers.rb2
-rw-r--r--actionview/lib/action_view/context.rb4
-rw-r--r--actionview/lib/action_view/dependency_tracker.rb2
-rw-r--r--actionview/lib/action_view/digestor.rb2
-rw-r--r--actionview/lib/action_view/flows.rb2
-rw-r--r--actionview/lib/action_view/gem_version.rb2
-rw-r--r--actionview/lib/action_view/helpers.rb2
-rw-r--r--actionview/lib/action_view/helpers/active_model_helper.rb12
-rw-r--r--actionview/lib/action_view/helpers/asset_tag_helper.rb101
-rw-r--r--actionview/lib/action_view/helpers/asset_url_helper.rb24
-rw-r--r--actionview/lib/action_view/helpers/atom_feed_helper.rb4
-rw-r--r--actionview/lib/action_view/helpers/cache_helper.rb44
-rw-r--r--actionview/lib/action_view/helpers/capture_helper.rb16
-rw-r--r--actionview/lib/action_view/helpers/controller_helper.rb16
-rw-r--r--actionview/lib/action_view/helpers/csrf_helper.rb6
-rw-r--r--actionview/lib/action_view/helpers/date_helper.rb52
-rw-r--r--actionview/lib/action_view/helpers/debug_helper.rb4
-rw-r--r--actionview/lib/action_view/helpers/form_helper.rb81
-rw-r--r--actionview/lib/action_view/helpers/form_options_helper.rb16
-rw-r--r--actionview/lib/action_view/helpers/form_tag_helper.rb31
-rw-r--r--actionview/lib/action_view/helpers/javascript_helper.rb8
-rw-r--r--actionview/lib/action_view/helpers/number_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/output_safety_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/record_tag_helper.rb8
-rw-r--r--actionview/lib/action_view/helpers/rendering_helper.rb4
-rw-r--r--actionview/lib/action_view/helpers/sanitize_helper.rb4
-rw-r--r--actionview/lib/action_view/helpers/tag_helper.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/base.rb16
-rw-r--r--actionview/lib/action_view/helpers/tags/check_box.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/checkable.rb6
-rw-r--r--actionview/lib/action_view/helpers/tags/collection_check_boxes.rb3
-rw-r--r--actionview/lib/action_view/helpers/tags/collection_helpers.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb3
-rw-r--r--actionview/lib/action_view/helpers/tags/collection_select.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/color_field.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/date_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/date_select.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/datetime_field.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/datetime_local_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/datetime_select.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/email_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/file_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/grouped_collection_select.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/hidden_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/label.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/month_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/number_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/password_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/placeholderable.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/radio_button.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/range_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/search_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/select.rb8
-rw-r--r--actionview/lib/action_view/helpers/tags/tel_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/text_area.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/text_field.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/time_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/time_select.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/time_zone_select.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/translator.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/url_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/week_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/text_helper.rb6
-rw-r--r--actionview/lib/action_view/helpers/translation_helper.rb9
-rw-r--r--actionview/lib/action_view/helpers/url_helper.rb32
-rw-r--r--actionview/lib/action_view/layouts.rb12
-rw-r--r--actionview/lib/action_view/log_subscriber.rb15
-rw-r--r--actionview/lib/action_view/lookup_context.rb8
-rw-r--r--actionview/lib/action_view/model_naming.rb2
-rw-r--r--actionview/lib/action_view/path_set.rb2
-rw-r--r--actionview/lib/action_view/railtie.rb2
-rw-r--r--actionview/lib/action_view/record_identifier.rb2
-rw-r--r--actionview/lib/action_view/renderer/abstract_renderer.rb2
-rw-r--r--actionview/lib/action_view/renderer/partial_renderer.rb26
-rw-r--r--actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb6
-rw-r--r--actionview/lib/action_view/renderer/renderer.rb6
-rw-r--r--actionview/lib/action_view/renderer/streaming_template_renderer.rb4
-rw-r--r--actionview/lib/action_view/renderer/template_renderer.rb2
-rw-r--r--actionview/lib/action_view/rendering.rb8
-rw-r--r--actionview/lib/action_view/routing_url_for.rb2
-rw-r--r--actionview/lib/action_view/tasks/cache_digests.rake2
-rw-r--r--actionview/lib/action_view/template.rb10
-rw-r--r--actionview/lib/action_view/template/error.rb5
-rw-r--r--actionview/lib/action_view/template/handlers.rb4
-rw-r--r--actionview/lib/action_view/template/handlers/builder.rb7
-rw-r--r--actionview/lib/action_view/template/handlers/erb.rb14
-rw-r--r--actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb9
-rw-r--r--actionview/lib/action_view/template/handlers/erb/erubi.rb2
-rw-r--r--actionview/lib/action_view/template/handlers/erb/erubis.rb81
-rw-r--r--actionview/lib/action_view/template/handlers/html.rb2
-rw-r--r--actionview/lib/action_view/template/handlers/raw.rb2
-rw-r--r--actionview/lib/action_view/template/html.rb4
-rw-r--r--actionview/lib/action_view/template/resolver.rb13
-rw-r--r--actionview/lib/action_view/template/text.rb4
-rw-r--r--actionview/lib/action_view/template/types.rb4
-rw-r--r--actionview/lib/action_view/test_case.rb26
-rw-r--r--actionview/lib/action_view/testing/resolvers.rb4
-rw-r--r--actionview/lib/action_view/version.rb2
-rw-r--r--actionview/lib/action_view/view_paths.rb6
102 files changed, 591 insertions, 354 deletions
diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb
index ca586f1d52..9533f8d56c 100644
--- a/actionview/lib/action_view.rb
+++ b/actionview/lib/action_view.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
#--
# Copyright (c) 2004-2017 David Heinemeier Hansson
#
@@ -74,7 +76,6 @@ module ActionView
autoload :MissingTemplate
autoload :ActionViewError
autoload :EncodingError
- autoload :MissingRequestError
autoload :TemplateError
autoload :WrongEncodingError
end
@@ -92,5 +93,5 @@ end
require "active_support/core_ext/string/output_safety"
ActiveSupport.on_load(:i18n) do
- I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
+ I18n.load_path << File.expand_path("action_view/locale/en.yml", __dir__)
end
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb
index 5387174467..d41fe2a608 100644
--- a/actionview/lib/action_view/base.rb
+++ b/actionview/lib/action_view/base.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/module/attr_internal"
require "active_support/core_ext/module/attribute_accessors"
require "active_support/ordered_options"
@@ -140,30 +142,25 @@ module ActionView #:nodoc:
include Helpers, ::ERB::Util, Context
# Specify the proc used to decorate input tags that refer to attributes with errors.
- cattr_accessor :field_error_proc
- @@field_error_proc = Proc.new { |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
+ cattr_accessor :field_error_proc, default: Proc.new { |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
# How to complete the streaming when an exception occurs.
# This is our best guess: first try to close the attribute, then the tag.
- cattr_accessor :streaming_completion_on_exception
- @@streaming_completion_on_exception = %("><script>window.location = "/500.html"</script></html>)
+ cattr_accessor :streaming_completion_on_exception, default: %("><script>window.location = "/500.html"</script></html>)
# Specify whether rendering within namespaced controllers should prefix
# the partial paths for ActiveModel objects with the namespace.
# (e.g., an Admin::PostsController would render @post using /admin/posts/_post.erb)
- cattr_accessor :prefix_partial_path_with_controller_namespace
- @@prefix_partial_path_with_controller_namespace = true
+ cattr_accessor :prefix_partial_path_with_controller_namespace, default: true
# Specify default_formats that can be rendered.
cattr_accessor :default_formats
# Specify whether an error should be raised for missing translations
- cattr_accessor :raise_on_missing_translations
- @@raise_on_missing_translations = false
+ cattr_accessor :raise_on_missing_translations, default: false
# Specify whether submit_tag should automatically disable on click
- cattr_accessor :automatically_disable_submit_tag
- @@automatically_disable_submit_tag = true
+ cattr_accessor :automatically_disable_submit_tag, default: true
class_attribute :_routes
class_attribute :logger
@@ -207,6 +204,7 @@ module ActionView #:nodoc:
@view_renderer = ActionView::Renderer.new(lookup_context)
end
+ @cache_hit = {}
assign(assigns)
assign_controller(controller)
_prepare_context
diff --git a/actionview/lib/action_view/buffers.rb b/actionview/lib/action_view/buffers.rb
index 089daa6d60..2a378fdc3c 100644
--- a/actionview/lib/action_view/buffers.rb
+++ b/actionview/lib/action_view/buffers.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/string/output_safety"
module ActionView
diff --git a/actionview/lib/action_view/context.rb b/actionview/lib/action_view/context.rb
index 31aa73a0cf..665a9e3171 100644
--- a/actionview/lib/action_view/context.rb
+++ b/actionview/lib/action_view/context.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module CompiledTemplates #:nodoc:
# holds compiled template code
@@ -17,7 +19,6 @@ module ActionView
attr_accessor :output_buffer, :view_flow
# Prepares the context by setting the appropriate instance variables.
- # :api: plugin
def _prepare_context
@view_flow = OutputFlow.new
@output_buffer = nil
@@ -27,7 +28,6 @@ module ActionView
# Encapsulates the interaction with the view flow so it
# returns the correct buffer on +yield+. This is usually
# overwritten by helpers to add more behavior.
- # :api: plugin
def _layout_for(name = nil)
name ||= :layout
view_flow.get(name).html_safe
diff --git a/actionview/lib/action_view/dependency_tracker.rb b/actionview/lib/action_view/dependency_tracker.rb
index 451eeec9d6..182f6e2eef 100644
--- a/actionview/lib/action_view/dependency_tracker.rb
+++ b/actionview/lib/action_view/dependency_tracker.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "concurrent/map"
require "action_view/path_set"
diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb
index 5ddf1ceb66..dfd62bdcfd 100644
--- a/actionview/lib/action_view/digestor.rb
+++ b/actionview/lib/action_view/digestor.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "concurrent/map"
require "action_view/dependency_tracker"
require "monitor"
diff --git a/actionview/lib/action_view/flows.rb b/actionview/lib/action_view/flows.rb
index 6d5f57a570..ff44fa6619 100644
--- a/actionview/lib/action_view/flows.rb
+++ b/actionview/lib/action_view/flows.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/string/output_safety"
module ActionView
diff --git a/actionview/lib/action_view/gem_version.rb b/actionview/lib/action_view/gem_version.rb
index 92e21d7a4f..ed92490be7 100644
--- a/actionview/lib/action_view/gem_version.rb
+++ b/actionview/lib/action_view/gem_version.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
# Returns the version of the currently loaded Action View as a <tt>Gem::Version</tt>
def self.gem_version
diff --git a/actionview/lib/action_view/helpers.rb b/actionview/lib/action_view/helpers.rb
index c1b4b4f84b..46f20c4277 100644
--- a/actionview/lib/action_view/helpers.rb
+++ b/actionview/lib/action_view/helpers.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/benchmarkable"
module ActionView #:nodoc:
diff --git a/actionview/lib/action_view/helpers/active_model_helper.rb b/actionview/lib/action_view/helpers/active_model_helper.rb
index 4bb5788a16..e41a95d2ce 100644
--- a/actionview/lib/action_view/helpers/active_model_helper.rb
+++ b/actionview/lib/action_view/helpers/active_model_helper.rb
@@ -1,9 +1,11 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/module/attribute_accessors"
require "active_support/core_ext/enumerable"
module ActionView
# = Active Model Helpers
- module Helpers
+ module Helpers #:nodoc:
module ActiveModelHelper
end
@@ -15,8 +17,8 @@ module ActionView
end
end
- def content_tag(*)
- error_wrapping(super)
+ def content_tag(type, options, *)
+ select_markup_helper?(type) ? super : error_wrapping(super)
end
def tag(type, options, *)
@@ -41,6 +43,10 @@ module ActionView
object.respond_to?(:errors) && object.errors.respond_to?(:[]) && error_message.present?
end
+ def select_markup_helper?(type)
+ ["optgroup", "option"].include?(type)
+ end
+
def tag_generate_errors?(options)
options["type"] != "hidden"
end
diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb
index 750f96f29e..e362f13798 100644
--- a/actionview/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/array/extract_options"
require "active_support/core_ext/hash/keys"
require "action_view/helpers/asset_url_helper"
@@ -11,7 +13,7 @@ module ActionView
# the assets exist before linking to them:
#
# image_tag("rails.png")
- # # => <img alt="Rails" src="/assets/rails.png" />
+ # # => <img src="/assets/rails.png" />
# stylesheet_link_tag("application")
# # => <link href="/assets/application.css?body=1" media="screen" rel="stylesheet" />
module AssetTagHelper
@@ -35,6 +37,9 @@ module ActionView
# When the Asset Pipeline is enabled, you can pass the name of your manifest as
# source, and include other JavaScript or CoffeeScript files inside the manifest.
#
+ # If the server supports Early Hints header links for these assets will be
+ # automatically pushed.
+ #
# ==== Options
#
# When the last parameter is a hash you can add HTML attributes using that
@@ -75,12 +80,20 @@ module ActionView
def javascript_include_tag(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys
- sources.uniq.map { |source|
+ early_hints_links = []
+
+ sources_tags = sources.uniq.map { |source|
+ href = path_to_javascript(source, path_options)
+ early_hints_links << "<#{href}>; rel=preload; as=script"
tag_options = {
- "src" => path_to_javascript(source, path_options)
+ "src" => href
}.merge!(options)
content_tag("script".freeze, "", tag_options)
}.join("\n").html_safe
+
+ request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request)
+
+ sources_tags
end
# Returns a stylesheet link tag for the sources specified as arguments. If
@@ -90,6 +103,9 @@ module ActionView
# to "screen", so you must explicitly set it to "all" for the stylesheet(s) to
# apply to all media types.
#
+ # If the server supports Early Hints header links for these assets will be
+ # automatically pushed.
+ #
# stylesheet_link_tag "style"
# # => <link href="/assets/style.css" media="screen" rel="stylesheet" />
#
@@ -111,20 +127,28 @@ module ActionView
def stylesheet_link_tag(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!("protocol", "host", "skip_pipeline").symbolize_keys
- sources.uniq.map { |source|
+ early_hints_links = []
+
+ sources_tags = sources.uniq.map { |source|
+ href = path_to_stylesheet(source, path_options)
+ early_hints_links << "<#{href}>; rel=preload; as=stylesheet"
tag_options = {
"rel" => "stylesheet",
"media" => "screen",
- "href" => path_to_stylesheet(source, path_options)
+ "href" => href
}.merge!(options)
tag(:link, tag_options)
}.join("\n").html_safe
+
+ request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request)
+
+ sources_tags
end
# Returns a link tag that browsers and feed readers can use to auto-detect
- # an RSS or Atom feed. The +type+ can either be <tt>:rss</tt> (default) or
- # <tt>:atom</tt>. Control the link options in url_for format using the
- # +url_options+. You can modify the LINK tag itself in +tag_options+.
+ # an RSS, Atom, or JSON feed. The +type+ can be <tt>:rss</tt> (default),
+ # <tt>:atom</tt>, or <tt>:json</tt>. Control the link options in url_for format
+ # using the +url_options+. You can modify the LINK tag itself in +tag_options+.
#
# ==== Options
#
@@ -138,6 +162,8 @@ module ActionView
# # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" />
# auto_discovery_link_tag(:atom)
# # => <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.currenthost.com/controller/action" />
+ # auto_discovery_link_tag(:json)
+ # # => <link rel="alternate" type="application/json" title="JSON" href="http://www.currenthost.com/controller/action" />
# auto_discovery_link_tag(:rss, {action: "feed"})
# # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/feed" />
# auto_discovery_link_tag(:rss, {action: "feed"}, {title: "My RSS"})
@@ -147,8 +173,8 @@ module ActionView
# auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "Example RSS"})
# # => <link rel="alternate" type="application/rss+xml" title="Example RSS" href="http://www.example.com/feed.rss" />
def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
- if !(type == :rss || type == :atom) && tag_options[:type].blank?
- raise ArgumentError.new("You should pass :type tag_option key explicitly, because you have passed #{type} type other than :rss or :atom.")
+ if !(type == :rss || type == :atom || type == :json) && tag_options[:type].blank?
+ raise ArgumentError.new("You should pass :type tag_option key explicitly, because you have passed #{type} type other than :rss, :atom, or :json.")
end
tag(
@@ -196,43 +222,62 @@ module ActionView
end
# Returns an HTML image tag for the +source+. The +source+ can be a full
- # path or a file.
+ # path, a file or an Active Storage attachment.
#
# ==== Options
#
# You can add HTML attributes using the +options+. The +options+ supports
- # two additional keys for convenience and conformance:
+ # additional keys for convenience and conformance:
#
- # * <tt>:alt</tt> - If no alt text is given, the file name part of the
- # +source+ is used (capitalized and without the extension)
# * <tt>:size</tt> - Supplied as "{Width}x{Height}" or "{Number}", so "30x45" becomes
# width="30" and height="45", and "50" becomes width="50" and height="50".
# <tt>:size</tt> will be ignored if the value is not in the correct format.
+ # * <tt>:srcset</tt> - If supplied as a hash or array of <tt>[source, descriptor]</tt>
+ # pairs, each image path will be expanded before the list is formatted as a string.
#
# ==== Examples
#
+ # Assets (images that are part of your app):
+ #
# image_tag("icon")
- # # => <img alt="Icon" src="/assets/icon" />
+ # # => <img src="/assets/icon" />
# image_tag("icon.png")
- # # => <img alt="Icon" src="/assets/icon.png" />
+ # # => <img src="/assets/icon.png" />
# image_tag("icon.png", size: "16x10", alt: "Edit Entry")
# # => <img src="/assets/icon.png" width="16" height="10" alt="Edit Entry" />
# image_tag("/icons/icon.gif", size: "16")
- # # => <img src="/icons/icon.gif" width="16" height="16" alt="Icon" />
+ # # => <img src="/icons/icon.gif" width="16" height="16" />
# image_tag("/icons/icon.gif", height: '32', width: '32')
- # # => <img alt="Icon" height="32" src="/icons/icon.gif" width="32" />
+ # # => <img height="32" src="/icons/icon.gif" width="32" />
# image_tag("/icons/icon.gif", class: "menu_icon")
- # # => <img alt="Icon" class="menu_icon" src="/icons/icon.gif" />
+ # # => <img class="menu_icon" src="/icons/icon.gif" />
# image_tag("/icons/icon.gif", data: { title: 'Rails Application' })
# # => <img data-title="Rails Application" src="/icons/icon.gif" />
+ # image_tag("icon.png", srcset: { "icon_2x.png" => "2x", "icon_4x.png" => "4x" })
+ # # => <img src="/assets/icon.png" srcset="/assets/icon_2x.png 2x, /assets/icon_4x.png 4x">
+ # image_tag("pic.jpg", srcset: [["pic_1024.jpg", "1024w"], ["pic_1980.jpg", "1980w"]], sizes: "100vw")
+ # # => <img src="/assets/pic.jpg" srcset="/assets/pic_1024.jpg 1024w, /assets/pic_1980.jpg 1980w" sizes="100vw">
+ #
+ # Active Storage (images that are uploaded by the users of your app):
+ #
+ # image_tag(user.avatar)
+ # # => <img src="/rails/active_storage/blobs/.../tiger.jpg" />
+ # image_tag(user.avatar.variant(resize: "100x100"))
+ # # => <img src="/rails/active_storage/variants/.../tiger.jpg" />
+ # image_tag(user.avatar.variant(resize: "100x100"), size: '100')
+ # # => <img width="100" height="100" src="/rails/active_storage/variants/.../tiger.jpg" />
def image_tag(source, options = {})
options = options.symbolize_keys
check_for_image_tag_errors(options)
+ skip_pipeline = options.delete(:skip_pipeline)
- src = options[:src] = path_to_image(source, skip_pipeline: options.delete(:skip_pipeline))
+ options[:src] = resolve_image_source(source, skip_pipeline)
- unless src.start_with?("cid:") || src.start_with?("data:") || src.blank?
- options[:alt] = options.fetch(:alt) { image_alt(src) }
+ if options[:srcset] && !options[:srcset].is_a?(String)
+ options[:srcset] = options[:srcset].map do |src_path, size|
+ src_path = path_to_image(src_path, skip_pipeline: skip_pipeline)
+ "#{src_path} #{size}"
+ end.join(", ")
end
options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size]
@@ -257,6 +302,8 @@ module ActionView
# image_alt('underscored_file_name.png')
# # => Underscored file name
def image_alt(src)
+ ActiveSupport::Deprecation.warn("image_alt is deprecated and will be removed from Rails 6.0. You must explicitly set alt text on images.")
+
File.basename(src, ".*".freeze).sub(/-[[:xdigit:]]{32,64}\z/, "".freeze).tr("-_".freeze, " ".freeze).capitalize
end
@@ -346,6 +393,16 @@ module ActionView
end
end
+ def resolve_image_source(source, skip_pipeline)
+ if source.is_a?(Symbol) || source.is_a?(String)
+ path_to_image(source, skip_pipeline: skip_pipeline)
+ else
+ polymorphic_url(source)
+ end
+ rescue NoMethodError => e
+ raise ArgumentError, "Can't resolve image into URL: #{e}"
+ end
+
def extract_dimensions(size)
size = size.to_s
if /\A\d+x\d+\z/.match?(size)
diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb
index 03bd1eb008..f7690104ee 100644
--- a/actionview/lib/action_view/helpers/asset_url_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_url_helper.rb
@@ -1,8 +1,10 @@
+# frozen_string_literal: true
+
require "zlib"
module ActionView
# = Action View Asset URL Helpers
- module Helpers
+ module Helpers #:nodoc:
# This module provides methods for generating asset paths and
# urls.
#
@@ -27,7 +29,7 @@ module ActionView
# Helpers take that into account:
#
# image_tag("rails.png")
- # # => <img alt="Rails" src="http://assets.example.com/assets/rails.png" />
+ # # => <img src="http://assets.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
# # => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
@@ -40,7 +42,7 @@ module ActionView
# "assets0.example.com", ..., "assets3.example.com".
#
# image_tag("rails.png")
- # # => <img alt="Rails" src="http://assets0.example.com/assets/rails.png" />
+ # # => <img src="http://assets0.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
# # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
@@ -66,7 +68,7 @@ module ActionView
# "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
# }
# image_tag("rails.png")
- # # => <img alt="Rails" src="http://assets1.example.com/assets/rails.png" />
+ # # => <img src="http://assets1.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
# # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
@@ -85,7 +87,7 @@ module ActionView
# end
# }
# image_tag("rails.png")
- # # => <img alt="Rails" src="http://assets.example.com/assets/rails.png" />
+ # # => <img src="http://assets.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
# # => <link href="http://stylesheets.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
@@ -322,7 +324,7 @@ module ActionView
# Since +javascript_url+ is based on +asset_url+ method you can set :host options. If :host
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
#
- # javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/dir/xmlhr.js
+ # javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/js/xmlhr.js
#
def javascript_url(source, options = {})
url_to_asset(source, { type: :javascript }.merge!(options))
@@ -349,7 +351,7 @@ module ActionView
# Since +stylesheet_url+ is based on +asset_url+ method you can set :host options. If :host
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
#
- # stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/css/style.css
+ # stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/assets/css/style.css
#
def stylesheet_url(source, options = {})
url_to_asset(source, { type: :stylesheet }.merge!(options))
@@ -379,7 +381,7 @@ module ActionView
# Since +image_url+ is based on +asset_url+ method you can set :host options. If :host
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
#
- # image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/edit.png
+ # image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/assets/edit.png
#
def image_url(source, options = {})
url_to_asset(source, { type: :image }.merge!(options))
@@ -405,7 +407,7 @@ module ActionView
# Since +video_url+ is based on +asset_url+ method you can set :host options. If :host
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
#
- # video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/hd.avi
+ # video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/videos/hd.avi
#
def video_url(source, options = {})
url_to_asset(source, { type: :video }.merge!(options))
@@ -431,7 +433,7 @@ module ActionView
# Since +audio_url+ is based on +asset_url+ method you can set :host options. If :host
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
#
- # audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/horse.wav
+ # audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/audios/horse.wav
#
def audio_url(source, options = {})
url_to_asset(source, { type: :audio }.merge!(options))
@@ -456,7 +458,7 @@ module ActionView
# Since +font_url+ is based on +asset_url+ method you can set :host options. If :host
# options is set, it overwrites global +config.action_controller.asset_host+ setting.
#
- # font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/font.ttf
+ # font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/fonts/font.ttf
#
def font_url(source, options = {})
url_to_asset(source, { type: :font }.merge!(options))
diff --git a/actionview/lib/action_view/helpers/atom_feed_helper.rb b/actionview/lib/action_view/helpers/atom_feed_helper.rb
index 3538515aee..e6b9878271 100644
--- a/actionview/lib/action_view/helpers/atom_feed_helper.rb
+++ b/actionview/lib/action_view/helpers/atom_feed_helper.rb
@@ -1,8 +1,10 @@
+# frozen_string_literal: true
+
require "set"
module ActionView
# = Action View Atom Feed Helpers
- module Helpers
+ module Helpers #:nodoc:
module AtomFeedHelper
# Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERB or any other
# template languages).
diff --git a/actionview/lib/action_view/helpers/cache_helper.rb b/actionview/lib/action_view/helpers/cache_helper.rb
index 15ab7e304f..3cbb1ed1a7 100644
--- a/actionview/lib/action_view/helpers/cache_helper.rb
+++ b/actionview/lib/action_view/helpers/cache_helper.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
module ActionView
# = Action View Cache Helper
- module Helpers
+ module Helpers #:nodoc:
module CacheHelper
# This helper exposes a method for caching fragments of a view
# rather than an entire action or page. This technique is useful
@@ -8,10 +10,9 @@ module ActionView
# fragments, and so on. This method takes a block that contains
# the content you wish to cache.
#
- # The best way to use this is by doing key-based cache expiration
- # on top of a cache store like Memcached that'll automatically
- # kick out old entries. For more on key-based expiration, see:
- # http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works
+ # The best way to use this is by doing recyclable key-based cache expiration
+ # on top of a cache store like Memcached or Redis that'll automatically
+ # kick out old entries.
#
# When using this method, you list the cache dependency as the name of the cache, like so:
#
@@ -23,10 +24,14 @@ module ActionView
# This approach will assume that when a new topic is added, you'll touch
# the project. The cache key generated from this call will be something like:
#
- # views/projects/123-20120806214154/7a1156131a6928cb0026877f8b749ac9
- # ^class ^id ^updated_at ^template tree digest
+ # views/template/action.html.erb:7a1156131a6928cb0026877f8b749ac9/projects/123
+ # ^template path ^template tree digest ^class ^id
#
- # The cache is thus automatically bumped whenever the project updated_at is touched.
+ # This cache key is stable, but it's combined with a cache version derived from the project
+ # record. When the project updated_at is touched, the #cache_version changes, even
+ # if the key stays stable. This means that unlike a traditional key-based cache expiration
+ # approach, you won't be generating cache trash, unused keys, simply because the dependent
+ # record is updated.
#
# If your template cache depends on multiple sources (try to avoid this to keep things simple),
# you can name all these dependencies as part of an array:
@@ -106,9 +111,9 @@ module ActionView
# <%= render_categorizable_events @person.events %>
#
# This marks every template in the directory as a dependency. To find those
- # templates, the wildcard path must be absolutely defined from app/views or paths
+ # templates, the wildcard path must be absolutely defined from <tt>app/views</tt> or paths
# otherwise added with +prepend_view_path+ or +append_view_path+.
- # This way the wildcard for `app/views/recordings/events` would be `recordings/events/*` etc.
+ # This way the wildcard for <tt>app/views/recordings/events</tt> would be <tt>recordings/events/*</tt> etc.
#
# The pattern used to match explicit dependencies is <tt>/# Template Dependency: (\S+)/</tt>,
# so it's important that you type it out just so.
@@ -128,14 +133,14 @@ module ActionView
#
# === Collection Caching
#
- # When rendering a collection of objects that each use the same partial, a `cached`
+ # When rendering a collection of objects that each use the same partial, a <tt>:cached</tt>
# option can be passed.
#
# For collections rendered such:
#
# <%= render partial: 'projects/project', collection: @projects, cached: true %>
#
- # The `cached: true` will make Action View's rendering read several templates
+ # The <tt>cached: true</tt> will make Action View's rendering read several templates
# from cache at once instead of one call per template.
#
# Templates in the collection not already cached are written to cache.
@@ -211,16 +216,19 @@ module ActionView
end
end
- attr_reader :cache_hit # :nodoc:
-
private
def fragment_name_with_digest(name, virtual_path)
virtual_path ||= @virtual_path
+
if virtual_path
name = controller.url_for(name).split("://").last if name.is_a?(Hash)
- digest = Digestor.digest name: virtual_path, finder: lookup_context, dependencies: view_cache_dependencies
- [ name, digest ]
+
+ if digest = Digestor.digest(name: virtual_path, finder: lookup_context, dependencies: view_cache_dependencies).presence
+ [ "#{virtual_path}:#{digest}", name ]
+ else
+ [ virtual_path, name ]
+ end
else
name
end
@@ -228,10 +236,10 @@ module ActionView
def fragment_for(name = {}, options = nil, &block)
if content = read_fragment_for(name, options)
- @cache_hit = true
+ @view_renderer.cache_hits[@virtual_path] = :hit if defined?(@view_renderer)
content
else
- @cache_hit = false
+ @view_renderer.cache_hits[@virtual_path] = :miss if defined?(@view_renderer)
write_fragment_for(name, options, &block)
end
end
diff --git a/actionview/lib/action_view/helpers/capture_helper.rb b/actionview/lib/action_view/helpers/capture_helper.rb
index 719592b5c5..92f7ddb70d 100644
--- a/actionview/lib/action_view/helpers/capture_helper.rb
+++ b/actionview/lib/action_view/helpers/capture_helper.rb
@@ -1,13 +1,15 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/string/output_safety"
module ActionView
# = Action View Capture Helper
- module Helpers
+ module Helpers #:nodoc:
# CaptureHelper exposes methods to let you extract generated markup which
# can be used in other parts of a template or layout file.
#
# It provides a method to capture blocks into variables through capture and
- # a way to capture a block of markup for use in a layout through content_for.
+ # a way to capture a block of markup for use in a layout through {content_for}[rdoc-ref:ActionView::Helpers::CaptureHelper#content_for].
module CaptureHelper
# The capture method extracts part of a template as a String object.
# You can then use this object anywhere in your templates, layout, or helpers.
@@ -42,7 +44,7 @@ module ActionView
end
end
- # Calling content_for stores a block of markup in an identifier for later use.
+ # Calling <tt>content_for</tt> stores a block of markup in an identifier for later use.
# In order to access this stored content in other templates, helper modules
# or the layout, you would pass the identifier as an argument to <tt>content_for</tt>.
#
@@ -108,7 +110,7 @@ module ActionView
# That will place +script+ tags for your default set of JavaScript files on the page;
# this technique is useful if you'll only be using these scripts in a few views.
#
- # Note that content_for concatenates (default) the blocks it is given for a particular
+ # Note that <tt>content_for</tt> concatenates (default) the blocks it is given for a particular
# identifier in order. For example:
#
# <% content_for :navigation do %>
@@ -125,7 +127,7 @@ module ActionView
#
# <ul><%= content_for :navigation %></ul>
#
- # If the flush parameter is true content_for replaces the blocks it is given. For example:
+ # If the flush parameter is +true+ <tt>content_for</tt> replaces the blocks it is given. For example:
#
# <% content_for :navigation do %>
# <li><%= link_to 'Home', action: 'index' %></li>
@@ -145,7 +147,7 @@ module ActionView
#
# <% content_for :script, javascript_include_tag(:defaults) %>
#
- # WARNING: content_for is ignored in caches. So you shouldn't use it for elements that will be fragment cached.
+ # WARNING: <tt>content_for</tt> is ignored in caches. So you shouldn't use it for elements that will be fragment cached.
def content_for(name, content = nil, options = {}, &block)
if content || block_given?
if block_given?
@@ -172,7 +174,7 @@ module ActionView
result unless content
end
- # content_for? checks whether any content has been captured yet using `content_for`.
+ # <tt>content_for?</tt> checks whether any content has been captured yet using <tt>content_for</tt>.
# Useful to render parts of your layout differently based on what is in your views.
#
# <%# This is the layout %>
diff --git a/actionview/lib/action_view/helpers/controller_helper.rb b/actionview/lib/action_view/helpers/controller_helper.rb
index e86cdca4e4..79cf86c7d1 100644
--- a/actionview/lib/action_view/helpers/controller_helper.rb
+++ b/actionview/lib/action_view/helpers/controller_helper.rb
@@ -1,14 +1,19 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/module/attr_internal"
module ActionView
- module Helpers
+ module Helpers #:nodoc:
# This module keeps all methods and behavior in ActionView
# that simply delegates to the controller.
module ControllerHelper #:nodoc:
attr_internal :controller, :request
- delegate :request_forgery_protection_token, :params, :session, :cookies, :response, :headers,
- :flash, :action_name, :controller_name, :controller_path, to: :controller
+ CONTROLLER_DELEGATES = [:request_forgery_protection_token, :params,
+ :session, :cookies, :response, :headers, :flash, :action_name,
+ :controller_name, :controller_path]
+
+ delegate(*CONTROLLER_DELEGATES, to: :controller)
def assign_controller(controller)
if @_controller = controller
@@ -21,6 +26,11 @@ module ActionView
def logger
controller.logger if controller.respond_to?(:logger)
end
+
+ def respond_to?(method_name, include_private = false)
+ return controller.respond_to?(method_name) if CONTROLLER_DELEGATES.include?(method_name.to_sym)
+ super
+ end
end
end
end
diff --git a/actionview/lib/action_view/helpers/csrf_helper.rb b/actionview/lib/action_view/helpers/csrf_helper.rb
index 2a15d2aa5a..69c59844a6 100644
--- a/actionview/lib/action_view/helpers/csrf_helper.rb
+++ b/actionview/lib/action_view/helpers/csrf_helper.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
module ActionView
# = Action View CSRF Helper
- module Helpers
+ module Helpers #:nodoc:
module CsrfHelper
# Returns meta tags "csrf-param" and "csrf-token" with the name of the cross-site
# request forgery protection parameter and token, respectively.
@@ -15,7 +17,7 @@ module ActionView
# You don't need to use these tags for regular forms as they generate their own hidden fields.
#
# For AJAX requests other than GETs, extract the "csrf-token" from the meta-tag and send as the
- # "X-CSRF-Token" HTTP header. If you are using jQuery with jquery-rails this happens automatically.
+ # "X-CSRF-Token" HTTP header. If you are using rails-ujs this happens automatically.
#
def csrf_meta_tags
if protect_against_forgery?
diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb
index 09dc6ef6bd..09040ccbc4 100644
--- a/actionview/lib/action_view/helpers/date_helper.rb
+++ b/actionview/lib/action_view/helpers/date_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "date"
require "action_view/helpers/tag_helper"
require "active_support/core_ext/array/extract_options"
@@ -7,7 +9,7 @@ require "active_support/core_ext/object/acts_like"
require "active_support/core_ext/object/with_options"
module ActionView
- module Helpers
+ module Helpers #:nodoc:
# = Action View Date Helpers
#
# The Date Helper primarily creates select/option tags for different kinds of dates and times or date and time
@@ -95,8 +97,8 @@ module ActionView
scope: :'datetime.distance_in_words'
}.merge!(options)
- from_time = from_time.to_time if from_time.respond_to?(:to_time)
- to_time = to_time.to_time if to_time.respond_to?(:to_time)
+ from_time = normalize_distance_of_time_argument_to_time(from_time)
+ to_time = normalize_distance_of_time_argument_to_time(to_time)
from_time, to_time = to_time, from_time if from_time > to_time
distance_in_minutes = ((to_time - from_time) / 60.0).round
distance_in_seconds = (to_time - from_time).round
@@ -130,22 +132,18 @@ module ActionView
# 60 days up to 365 days
when 86400...525600 then locale.t :x_months, count: (distance_in_minutes.to_f / 43200.0).round
else
- if from_time.acts_like?(:time) && to_time.acts_like?(:time)
- fyear = from_time.year
- fyear += 1 if from_time.month >= 3
- tyear = to_time.year
- tyear -= 1 if to_time.month < 3
- leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count { |x| Date.leap?(x) }
- minute_offset_for_leap_year = leap_years * 1440
- # Discount the leap year days when calculating year distance.
- # e.g. if there are 20 leap year days between 2 dates having the same day
- # and month then the based on 365 days calculation
- # the distance in years will come out to over 80 years when in written
- # English it would read better as about 80 years.
- minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
- else
- minutes_with_offset = distance_in_minutes
- end
+ from_year = from_time.year
+ from_year += 1 if from_time.month >= 3
+ to_year = to_time.year
+ to_year -= 1 if to_time.month < 3
+ leap_years = (from_year > to_year) ? 0 : (from_year..to_year).count { |x| Date.leap?(x) }
+ minute_offset_for_leap_year = leap_years * 1440
+ # Discount the leap year days when calculating year distance.
+ # e.g. if there are 20 leap year days between 2 dates having the same day
+ # and month then the based on 365 days calculation
+ # the distance in years will come out to over 80 years when in written
+ # English it would read better as about 80 years.
+ minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
remainder = (minutes_with_offset % MINUTES_IN_YEAR)
distance_in_years = (minutes_with_offset.div MINUTES_IN_YEAR)
if remainder < MINUTES_IN_QUARTER_YEAR
@@ -687,6 +685,18 @@ module ActionView
content_tag("time".freeze, content, options.reverse_merge(datetime: datetime), &block)
end
+
+ private
+
+ def normalize_distance_of_time_argument_to_time(value)
+ if value.is_a?(Numeric)
+ Time.at(value)
+ elsif value.respond_to?(:to_time)
+ value.to_time
+ else
+ raise ArgumentError, "#{value.inspect} can't be converted to a Time value"
+ end
+ end
end
class DateTimeSelector #:nodoc:
@@ -999,7 +1009,7 @@ module ActionView
select_options[:disabled] = "disabled" if @options[:disabled]
select_options[:class] = css_class_attribute(type, select_options[:class], @options[:with_css_classes]) if @options[:with_css_classes]
- select_html = "\n"
+ select_html = "\n".dup
select_html << content_tag("option".freeze, "", value: "") + "\n" if @options[:include_blank]
select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
select_html << select_options_as_html
@@ -1081,7 +1091,7 @@ module ActionView
# Given an ordering of datetime components, create the selection HTML
# and join them with their appropriate separators.
def build_selects_from_types(order)
- select = ""
+ select = "".dup
first_visible = order.find { |type| !@options[:"discard_#{type}"] }
order.reverse_each do |type|
separator = separator(type) unless type == first_visible # don't add before first visible field
diff --git a/actionview/lib/action_view/helpers/debug_helper.rb b/actionview/lib/action_view/helpers/debug_helper.rb
index f61ca2c9c2..52dff1f750 100644
--- a/actionview/lib/action_view/helpers/debug_helper.rb
+++ b/actionview/lib/action_view/helpers/debug_helper.rb
@@ -1,8 +1,10 @@
+# frozen_string_literal: true
+
module ActionView
# = Action View Debug Helper
#
# Provides a set of methods for making it easier to debug Rails objects.
- module Helpers
+ module Helpers #:nodoc:
module DebugHelper
include TagHelper
diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb
index 3eafe0028e..6d2ace8cf8 100644
--- a/actionview/lib/action_view/helpers/form_helper.rb
+++ b/actionview/lib/action_view/helpers/form_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cgi"
require "action_view/helpers/date_helper"
require "action_view/helpers/tag_helper"
@@ -12,7 +14,7 @@ require "active_support/core_ext/string/inflections"
module ActionView
# = Action View Form Helpers
- module Helpers
+ module Helpers #:nodoc:
# Form helpers are designed to make working with resources much easier
# compared to using vanilla HTML.
#
@@ -474,7 +476,7 @@ module ActionView
end
private :apply_form_for_options!
- mattr_accessor(:form_with_generates_remote_forms) { true }
+ mattr_accessor :form_with_generates_remote_forms, default: true
# Creates a form tag based on mixing URLs, scopes, or models.
#
@@ -541,6 +543,36 @@ module ActionView
# and adds an authenticity token needed for cross site request forgery
# protection.
#
+ # === Resource-oriented style
+ #
+ # In many of the examples just shown, the +:model+ passed to +form_with+
+ # is a _resource_. It corresponds to a set of RESTful routes, most likely
+ # defined via +resources+ in <tt>config/routes.rb</tt>.
+ #
+ # So when passing such a model record, Rails infers the URL and method.
+ #
+ # <%= form_with model: @post do |form| %>
+ # ...
+ # <% end %>
+ #
+ # is then equivalent to something like:
+ #
+ # <%= form_with scope: :post, url: post_path(@post), method: :patch do |form| %>
+ # ...
+ # <% end %>
+ #
+ # And for a new record
+ #
+ # <%= form_with model: Post.new do |form| %>
+ # ...
+ # <% end %>
+ #
+ # is equivalent to something like:
+ #
+ # <%= form_with scope: :post, url: posts_path do |form| %>
+ # ...
+ # <% end %>
+ #
# ==== +form_with+ options
#
# * <tt>:url</tt> - The URL the form submits to. Akin to values passed to
@@ -1191,7 +1223,7 @@ module ActionView
# file_field(:attachment, :file, class: 'file_input')
# # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
def file_field(object_name, method, options = {})
- Tags::FileField.new(object_name, method, self, options).render
+ Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render
end
# Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by +method+)
@@ -1567,7 +1599,7 @@ module ActionView
# In the above block, a +FormBuilder+ object is yielded as the
# +person_form+ variable. This allows you to generate the +text_field+
# and +check_box+ fields by specifying their eponymous methods, which
- # modify the underlying template and associates the +@person+ model object
+ # modify the underlying template and associates the <tt>@person</tt> model object
# with the form.
#
# The +FormBuilder+ object can be thought of as serving as a proxy for the
@@ -1606,14 +1638,15 @@ module ActionView
include ModelNaming
# The methods which wrap a form helper call.
- class_attribute :field_helpers
- self.field_helpers = [:fields_for, :fields, :label, :text_field, :password_field,
- :hidden_field, :file_field, :text_area, :check_box,
- :radio_button, :color_field, :search_field,
- :telephone_field, :phone_field, :date_field,
- :time_field, :datetime_field, :datetime_local_field,
- :month_field, :week_field, :url_field, :email_field,
- :number_field, :range_field]
+ class_attribute :field_helpers, default: [
+ :fields_for, :fields, :label, :text_field, :password_field,
+ :hidden_field, :file_field, :text_area, :check_box,
+ :radio_button, :color_field, :search_field,
+ :telephone_field, :phone_field, :date_field,
+ :time_field, :datetime_field, :datetime_local_field,
+ :month_field, :week_field, :url_field, :email_field,
+ :number_field, :range_field
+ ]
attr_accessor :object_name, :object, :options
@@ -2162,11 +2195,11 @@ module ActionView
# <%= f.submit %>
# <% end %>
#
- # In the example above, if @post is a new record, it will use "Create Post" as
- # submit button label, otherwise, it uses "Update Post".
+ # In the example above, if <tt>@post</tt> is a new record, it will use "Create Post" as
+ # submit button label; otherwise, it uses "Update Post".
#
- # Those labels can be customized using I18n, under the helpers.submit key and accept
- # the %{model} as translation interpolation:
+ # Those labels can be customized using I18n under the +helpers.submit+ key and using
+ # <tt>%{model}</tt> for translation interpolation:
#
# en:
# helpers:
@@ -2174,7 +2207,7 @@ module ActionView
# create: "Create a %{model}"
# update: "Confirm changes to %{model}"
#
- # It also searches for a key specific for the given object:
+ # It also searches for a key specific to the given object:
#
# en:
# helpers:
@@ -2195,11 +2228,11 @@ module ActionView
# <%= f.button %>
# <% end %>
#
- # In the example above, if @post is a new record, it will use "Create Post" as
- # button label, otherwise, it uses "Update Post".
+ # In the example above, if <tt>@post</tt> is a new record, it will use "Create Post" as
+ # button label; otherwise, it uses "Update Post".
#
- # Those labels can be customized using I18n, under the helpers.submit key
- # (the same as submit helper) and accept the %{model} as translation interpolation:
+ # Those labels can be customized using I18n under the +helpers.submit+ key
+ # (the same as submit helper) and using <tt>%{model}</tt> for translation interpolation:
#
# en:
# helpers:
@@ -2207,7 +2240,7 @@ module ActionView
# create: "Create a %{model}"
# update: "Confirm changes to %{model}"
#
- # It also searches for a key specific for the given object:
+ # It also searches for a key specific to the given object:
#
# en:
# helpers:
@@ -2317,8 +2350,6 @@ module ActionView
end
ActiveSupport.on_load(:action_view) do
- cattr_accessor(:default_form_builder, instance_writer: false, instance_reader: false) do
- ::ActionView::Helpers::FormBuilder
- end
+ cattr_accessor :default_form_builder, instance_writer: false, instance_reader: false, default: ::ActionView::Helpers::FormBuilder
end
end
diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb
index 07d4310a4e..02a44477c1 100644
--- a/actionview/lib/action_view/helpers/form_options_helper.rb
+++ b/actionview/lib/action_view/helpers/form_options_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cgi"
require "erb"
require "action_view/helpers/form_helper"
@@ -7,7 +9,7 @@ require "active_support/core_ext/array/wrap"
module ActionView
# = Action View Form Option Helpers
- module Helpers
+ module Helpers #:nodoc:
# Provides a number of methods for turning different kinds of containers into a set of option tags.
#
# The <tt>collection_select</tt>, <tt>select</tt> and <tt>time_zone_select</tt> methods take an <tt>options</tt> parameter, a hash:
@@ -277,17 +279,17 @@ module ActionView
# Finally, this method supports a <tt>:default</tt> option, which selects
# a default ActiveSupport::TimeZone if the object's time zone is +nil+.
#
- # time_zone_select( "user", "time_zone", nil, include_blank: true)
+ # time_zone_select("user", "time_zone", nil, include_blank: true)
#
- # time_zone_select( "user", "time_zone", nil, default: "Pacific Time (US & Canada)" )
+ # time_zone_select("user", "time_zone", nil, default: "Pacific Time (US & Canada)")
#
- # time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, default: "Pacific Time (US & Canada)")
+ # time_zone_select("user", 'time_zone', ActiveSupport::TimeZone.us_zones, default: "Pacific Time (US & Canada)")
#
- # time_zone_select( "user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])
+ # time_zone_select("user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])
#
- # time_zone_select( "user", 'time_zone', /Australia/)
+ # time_zone_select("user", 'time_zone', /Australia/)
#
- # time_zone_select( "user", "time_zone", ActiveSupport::TimeZone.all.sort, model: ActiveSupport::TimeZone)
+ # time_zone_select("user", "time_zone", ActiveSupport::TimeZone.all.sort, model: ActiveSupport::TimeZone)
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render
end
diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb
index 9fc08b3837..e86e18dd78 100644
--- a/actionview/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/form_tag_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cgi"
require "action_view/helpers/tag_helper"
require "active_support/core_ext/string/output_safety"
@@ -5,7 +7,7 @@ require "active_support/core_ext/module/attribute_accessors"
module ActionView
# = Action View Form Tag Helpers
- module Helpers
+ module Helpers #:nodoc:
# Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like
# FormHelper does. Instead, you provide the names and values manually.
#
@@ -113,7 +115,7 @@ module ActionView
# # <option>Write</option></select>
#
# select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: true
- # # => <select id="people" name="people"><option value=""></option><option value="1">David</option></select>
+ # # => <select id="people" name="people"><option value="" label=" "></option><option value="1">David</option></select>
#
# select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: "All"
# # => <select id="people" name="people"><option value="">All</option><option value="1">David</option></select>
@@ -272,7 +274,7 @@ module ActionView
# file_field_tag 'file', accept: 'text/html', class: 'upload', value: 'index.html'
# # => <input accept="text/html" class="upload" id="file" name="file" type="file" value="index.html" />
def file_field_tag(name, options = {})
- text_field_tag(name, nil, options.merge(type: :file))
+ text_field_tag(name, nil, convert_direct_upload_option_to_url(options.merge(type: :file)))
end
# Creates a password field, a masked text field that will hide the users input behind a mask character.
@@ -392,7 +394,7 @@ module ActionView
# # => <input checked="checked" id="receive_updates_no" name="receive_updates" type="radio" value="no" />
#
# radio_button_tag 'time_slot', "3:00 p.m.", false, disabled: true
- # # => <input disabled="disabled" id="time_slot_300_pm" name="time_slot" type="radio" value="3:00 p.m." />
+ # # => <input disabled="disabled" id="time_slot_3:00_p.m." name="time_slot" type="radio" value="3:00 p.m." />
#
# radio_button_tag 'color', "green", true, class: "color_input"
# # => <input checked="checked" class="color_input" id="color_green" name="color" type="radio" value="green" />
@@ -454,7 +456,7 @@ module ActionView
# submit tag but it isn't supported in legacy browsers. However,
# the button tag does allow for richer labels such as images and emphasis,
# so this helper will also accept a block. By default, it will create
- # a button tag with type `submit`, if type is not given.
+ # a button tag with type <tt>submit</tt>, if type is not given.
#
# ==== Options
# * <tt>:data</tt> - This option can be used to add custom data attributes.
@@ -532,22 +534,22 @@ module ActionView
#
# ==== Examples
# image_submit_tag("login.png")
- # # => <input alt="Login" src="/assets/login.png" type="image" />
+ # # => <input src="/assets/login.png" type="image" />
#
# image_submit_tag("purchase.png", disabled: true)
- # # => <input alt="Purchase" disabled="disabled" src="/assets/purchase.png" type="image" />
+ # # => <input disabled="disabled" src="/assets/purchase.png" type="image" />
#
# image_submit_tag("search.png", class: 'search_button', alt: 'Find')
- # # => <input alt="Find" class="search_button" src="/assets/search.png" type="image" />
+ # # => <input class="search_button" src="/assets/search.png" type="image" />
#
# image_submit_tag("agree.png", disabled: true, class: "agree_disagree_button")
- # # => <input alt="Agree" class="agree_disagree_button" disabled="disabled" src="/assets/agree.png" type="image" />
+ # # => <input class="agree_disagree_button" disabled="disabled" src="/assets/agree.png" type="image" />
#
# image_submit_tag("save.png", data: { confirm: "Are you sure?" })
- # # => <input alt="Save" src="/assets/save.png" data-confirm="Are you sure?" type="image" />
+ # # => <input src="/assets/save.png" data-confirm="Are you sure?" type="image" />
def image_submit_tag(source, options = {})
options = options.stringify_keys
- tag :input, { "alt" => image_alt(source), "type" => "image", "src" => path_to_image(source) }.update(options)
+ tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options)
end
# Creates a field set for grouping HTML form elements.
@@ -902,6 +904,13 @@ module ActionView
tag_options.delete("data-disable-with")
end
+
+ def convert_direct_upload_option_to_url(options)
+ if options.delete(:direct_upload) && respond_to?(:rails_direct_uploads_url)
+ options["data-direct-upload-url"] = rails_direct_uploads_url
+ end
+ options
+ end
end
end
end
diff --git a/actionview/lib/action_view/helpers/javascript_helper.rb b/actionview/lib/action_view/helpers/javascript_helper.rb
index 22e1e74ad6..dd2cd57ac3 100644
--- a/actionview/lib/action_view/helpers/javascript_helper.rb
+++ b/actionview/lib/action_view/helpers/javascript_helper.rb
@@ -1,7 +1,9 @@
+# frozen_string_literal: true
+
require "action_view/helpers/tag_helper"
module ActionView
- module Helpers
+ module Helpers #:nodoc:
module JavaScriptHelper
JS_ESCAPE_MAP = {
'\\' => '\\\\',
@@ -13,8 +15,8 @@ module ActionView
"'" => "\\'"
}
- JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
- JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"
+ JS_ESCAPE_MAP["\342\200\250".dup.force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
+ JS_ESCAPE_MAP["\342\200\251".dup.force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"
# Escapes carriage returns and single and double quotes for JavaScript segments.
#
diff --git a/actionview/lib/action_view/helpers/number_helper.rb b/actionview/lib/action_view/helpers/number_helper.rb
index b6bc5f4f6f..4b53b8fe6e 100644
--- a/actionview/lib/action_view/helpers/number_helper.rb
+++ b/actionview/lib/action_view/helpers/number_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/hash/keys"
require "active_support/core_ext/string/output_safety"
require "active_support/number_helper"
diff --git a/actionview/lib/action_view/helpers/output_safety_helper.rb b/actionview/lib/action_view/helpers/output_safety_helper.rb
index 25defd1276..279cde5e76 100644
--- a/actionview/lib/action_view/helpers/output_safety_helper.rb
+++ b/actionview/lib/action_view/helpers/output_safety_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/string/output_safety"
module ActionView #:nodoc:
diff --git a/actionview/lib/action_view/helpers/record_tag_helper.rb b/actionview/lib/action_view/helpers/record_tag_helper.rb
index f7ee573035..a6953ee905 100644
--- a/actionview/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/record_tag_helper.rb
@@ -1,7 +1,9 @@
+# frozen_string_literal: true
+
module ActionView
- module Helpers
+ module Helpers #:nodoc:
module RecordTagHelper
- def div_for(*)
+ def div_for(*) # :nodoc:
raise NoMethodError, "The `div_for` method has been removed from " \
"Rails. To continue using it, add the `record_tag_helper` gem to " \
"your Gemfile:\n" \
@@ -9,7 +11,7 @@ module ActionView
"Consult the Rails upgrade guide for details."
end
- def content_tag_for(*)
+ def content_tag_for(*) # :nodoc:
raise NoMethodError, "The `content_tag_for` method has been removed from " \
"Rails. To continue using it, add the `record_tag_helper` gem to " \
"your Gemfile:\n" \
diff --git a/actionview/lib/action_view/helpers/rendering_helper.rb b/actionview/lib/action_view/helpers/rendering_helper.rb
index 7d7f2393ff..8e505ab054 100644
--- a/actionview/lib/action_view/helpers/rendering_helper.rb
+++ b/actionview/lib/action_view/helpers/rendering_helper.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
module ActionView
- module Helpers
+ module Helpers #:nodoc:
# = Action View Rendering
#
# Implements methods that allow rendering from a view context.
diff --git a/actionview/lib/action_view/helpers/sanitize_helper.rb b/actionview/lib/action_view/helpers/sanitize_helper.rb
index 0abd5bc5dc..275a2dffb4 100644
--- a/actionview/lib/action_view/helpers/sanitize_helper.rb
+++ b/actionview/lib/action_view/helpers/sanitize_helper.rb
@@ -1,9 +1,11 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/object/try"
require "rails-html-sanitizer"
module ActionView
# = Action View Sanitize Helpers
- module Helpers
+ module Helpers #:nodoc:
# The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
# These helper methods extend Action View making them callable within your template files.
module SanitizeHelper
diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb
index 306b71c85e..a6cec3f69c 100644
--- a/actionview/lib/action_view/helpers/tag_helper.rb
+++ b/actionview/lib/action_view/helpers/tag_helper.rb
@@ -1,4 +1,4 @@
-# frozen-string-literal: true
+# frozen_string_literal: true
require "active_support/core_ext/string/output_safety"
require "set"
@@ -166,7 +166,7 @@ module ActionView
# This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
# from 1.4.3.
#
- # tag.div data: { city_state: %w( Chigaco IL ) }
+ # tag.div data: { city_state: %w( Chicago IL ) }
# # => <div data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]"></div>
#
# The generated attributes are escaped by default. This can be disabled using
diff --git a/actionview/lib/action_view/helpers/tags.rb b/actionview/lib/action_view/helpers/tags.rb
index a4f6eb0150..566668b958 100644
--- a/actionview/lib/action_view/helpers/tags.rb
+++ b/actionview/lib/action_view/helpers/tags.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
module ActionView
- module Helpers
+ module Helpers #:nodoc:
module Tags #:nodoc:
extend ActiveSupport::Autoload
diff --git a/actionview/lib/action_view/helpers/tags/base.rb b/actionview/lib/action_view/helpers/tags/base.rb
index 0895533a60..8934a9894c 100644
--- a/actionview/lib/action_view/helpers/tags/base.rb
+++ b/actionview/lib/action_view/helpers/tags/base.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
@@ -33,7 +35,7 @@ module ActionView
private
- def value(object)
+ def value
if @allow_method_names_outside_object
object.public_send @method_name if object && object.respond_to?(@method_name)
else
@@ -41,19 +43,19 @@ module ActionView
end
end
- def value_before_type_cast(object)
+ def value_before_type_cast
unless object.nil?
method_before_type_cast = @method_name + "_before_type_cast"
- if value_came_from_user?(object) && object.respond_to?(method_before_type_cast)
+ if value_came_from_user? && object.respond_to?(method_before_type_cast)
object.public_send(method_before_type_cast)
else
- value(object)
+ value
end
end
end
- def value_came_from_user?(object)
+ def value_came_from_user?
method_name = "#{@method_name}_came_from_user?"
!object.respond_to?(method_name) || object.public_send(method_name)
end
@@ -136,7 +138,7 @@ module ActionView
end
def sanitized_value(value)
- value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase
+ value.to_s.gsub(/\s/, "_").gsub(/[^-[[:word:]]]/, "").mb_chars.downcase.to_s
end
def select_content_tag(option_tags, options, html_options)
@@ -148,7 +150,7 @@ module ActionView
options[:include_blank] ||= true unless options[:prompt]
end
- value = options.fetch(:selected) { value(object) }
+ value = options.fetch(:selected) { value() }
select = content_tag("select", add_options(option_tags, options, value), html_options)
if html_options["multiple"] && options.fetch(:include_hidden, true)
diff --git a/actionview/lib/action_view/helpers/tags/check_box.rb b/actionview/lib/action_view/helpers/tags/check_box.rb
index 02f87fc89f..4327e07cae 100644
--- a/actionview/lib/action_view/helpers/tags/check_box.rb
+++ b/actionview/lib/action_view/helpers/tags/check_box.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/helpers/tags/checkable"
module ActionView
@@ -16,7 +18,7 @@ module ActionView
options = @options.stringify_keys
options["type"] = "checkbox"
options["value"] = @checked_value
- options["checked"] = "checked" if input_checked?(object, options)
+ options["checked"] = "checked" if input_checked?(options)
if options["multiple"]
add_default_name_and_id_for_value(@checked_value, options)
diff --git a/actionview/lib/action_view/helpers/tags/checkable.rb b/actionview/lib/action_view/helpers/tags/checkable.rb
index 052e9df662..776fefe778 100644
--- a/actionview/lib/action_view/helpers/tags/checkable.rb
+++ b/actionview/lib/action_view/helpers/tags/checkable.rb
@@ -1,13 +1,15 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
module Checkable # :nodoc:
- def input_checked?(object, options)
+ def input_checked?(options)
if options.has_key?("checked")
checked = options.delete "checked"
checked == true || checked == "checked"
else
- checked?(value(object))
+ checked?(value)
end
end
end
diff --git a/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb b/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb
index 7252d4f2d9..455442178e 100644
--- a/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb
+++ b/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/helpers/tags/collection_helpers"
module ActionView
@@ -10,6 +12,7 @@ module ActionView
def check_box(extra_html_options = {})
html_options = extra_html_options.merge(@input_html_options)
html_options[:multiple] = true
+ html_options[:skip_default_ids] = false
@template_object.check_box(@object_name, @method_name, html_options, @value, nil)
end
end
diff --git a/actionview/lib/action_view/helpers/tags/collection_helpers.rb b/actionview/lib/action_view/helpers/tags/collection_helpers.rb
index 75d237eb35..e1ad11bff8 100644
--- a/actionview/lib/action_view/helpers/tags/collection_helpers.rb
+++ b/actionview/lib/action_view/helpers/tags/collection_helpers.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb b/actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb
index a5f72af9ff..16d37134e5 100644
--- a/actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb
+++ b/actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/helpers/tags/collection_helpers"
module ActionView
@@ -9,6 +11,7 @@ module ActionView
class RadioButtonBuilder < Builder # :nodoc:
def radio_button(extra_html_options = {})
html_options = extra_html_options.merge(@input_html_options)
+ html_options[:skip_default_ids] = false
@template_object.radio_button(@object_name, @method_name, @value, html_options)
end
end
diff --git a/actionview/lib/action_view/helpers/tags/collection_select.rb b/actionview/lib/action_view/helpers/tags/collection_select.rb
index 4365c714eb..6a3af1b256 100644
--- a/actionview/lib/action_view/helpers/tags/collection_select.rb
+++ b/actionview/lib/action_view/helpers/tags/collection_select.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
@@ -13,7 +15,7 @@ module ActionView
def render
option_tags_options = {
- selected: @options.fetch(:selected) { value(@object) },
+ selected: @options.fetch(:selected) { value },
disabled: @options[:disabled]
}
diff --git a/actionview/lib/action_view/helpers/tags/color_field.rb b/actionview/lib/action_view/helpers/tags/color_field.rb
index b4bbe92746..c5f0bb6bbb 100644
--- a/actionview/lib/action_view/helpers/tags/color_field.rb
+++ b/actionview/lib/action_view/helpers/tags/color_field.rb
@@ -1,10 +1,12 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
class ColorField < TextField # :nodoc:
def render
options = @options.stringify_keys
- options["value"] ||= validate_color_string(value(object))
+ options["value"] ||= validate_color_string(value)
@options = options
super
end
diff --git a/actionview/lib/action_view/helpers/tags/date_field.rb b/actionview/lib/action_view/helpers/tags/date_field.rb
index c22be0db29..b17a907651 100644
--- a/actionview/lib/action_view/helpers/tags/date_field.rb
+++ b/actionview/lib/action_view/helpers/tags/date_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/date_select.rb b/actionview/lib/action_view/helpers/tags/date_select.rb
index 638c134deb..fe4e3914d7 100644
--- a/actionview/lib/action_view/helpers/tags/date_select.rb
+++ b/actionview/lib/action_view/helpers/tags/date_select.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/time/calculations"
module ActionView
@@ -27,7 +29,7 @@ module ActionView
end
def datetime_selector(options, html_options)
- datetime = options.fetch(:selected) { value(object) || default_datetime(options) }
+ datetime = options.fetch(:selected) { value || default_datetime(options) }
@auto_index ||= nil
options = options.dup
diff --git a/actionview/lib/action_view/helpers/tags/datetime_field.rb b/actionview/lib/action_view/helpers/tags/datetime_field.rb
index b3940c7e44..5d9b639b1b 100644
--- a/actionview/lib/action_view/helpers/tags/datetime_field.rb
+++ b/actionview/lib/action_view/helpers/tags/datetime_field.rb
@@ -1,10 +1,12 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
class DatetimeField < TextField # :nodoc:
def render
options = @options.stringify_keys
- options["value"] ||= format_date(value(object))
+ options["value"] ||= format_date(value)
options["min"] = format_date(datetime_value(options["min"]))
options["max"] = format_date(datetime_value(options["max"]))
@options = options
diff --git a/actionview/lib/action_view/helpers/tags/datetime_local_field.rb b/actionview/lib/action_view/helpers/tags/datetime_local_field.rb
index b4a74185d1..d8f8fd00d1 100644
--- a/actionview/lib/action_view/helpers/tags/datetime_local_field.rb
+++ b/actionview/lib/action_view/helpers/tags/datetime_local_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/datetime_select.rb b/actionview/lib/action_view/helpers/tags/datetime_select.rb
index 563de1840e..dc5570931d 100644
--- a/actionview/lib/action_view/helpers/tags/datetime_select.rb
+++ b/actionview/lib/action_view/helpers/tags/datetime_select.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/email_field.rb b/actionview/lib/action_view/helpers/tags/email_field.rb
index 7ce3ccb9bf..0c3b9224fa 100644
--- a/actionview/lib/action_view/helpers/tags/email_field.rb
+++ b/actionview/lib/action_view/helpers/tags/email_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/file_field.rb b/actionview/lib/action_view/helpers/tags/file_field.rb
index 476b820d84..0b1d9bb778 100644
--- a/actionview/lib/action_view/helpers/tags/file_field.rb
+++ b/actionview/lib/action_view/helpers/tags/file_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/grouped_collection_select.rb b/actionview/lib/action_view/helpers/tags/grouped_collection_select.rb
index 20e312dd0f..f24cb4beea 100644
--- a/actionview/lib/action_view/helpers/tags/grouped_collection_select.rb
+++ b/actionview/lib/action_view/helpers/tags/grouped_collection_select.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
@@ -15,7 +17,7 @@ module ActionView
def render
option_tags_options = {
- selected: @options.fetch(:selected) { value(@object) },
+ selected: @options.fetch(:selected) { value },
disabled: @options[:disabled]
}
diff --git a/actionview/lib/action_view/helpers/tags/hidden_field.rb b/actionview/lib/action_view/helpers/tags/hidden_field.rb
index c3757c2461..e014bd3aef 100644
--- a/actionview/lib/action_view/helpers/tags/hidden_field.rb
+++ b/actionview/lib/action_view/helpers/tags/hidden_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/label.rb b/actionview/lib/action_view/helpers/tags/label.rb
index cab15ae201..56b48bbd62 100644
--- a/actionview/lib/action_view/helpers/tags/label.rb
+++ b/actionview/lib/action_view/helpers/tags/label.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/month_field.rb b/actionview/lib/action_view/helpers/tags/month_field.rb
index 4c0fb846ee..93b2bf11f0 100644
--- a/actionview/lib/action_view/helpers/tags/month_field.rb
+++ b/actionview/lib/action_view/helpers/tags/month_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/number_field.rb b/actionview/lib/action_view/helpers/tags/number_field.rb
index 4f95b1b4de..41c696423c 100644
--- a/actionview/lib/action_view/helpers/tags/number_field.rb
+++ b/actionview/lib/action_view/helpers/tags/number_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/password_field.rb b/actionview/lib/action_view/helpers/tags/password_field.rb
index 444ef65074..9f10f5236e 100644
--- a/actionview/lib/action_view/helpers/tags/password_field.rb
+++ b/actionview/lib/action_view/helpers/tags/password_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/placeholderable.rb b/actionview/lib/action_view/helpers/tags/placeholderable.rb
index cf7b117614..e9f7601e57 100644
--- a/actionview/lib/action_view/helpers/tags/placeholderable.rb
+++ b/actionview/lib/action_view/helpers/tags/placeholderable.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/radio_button.rb b/actionview/lib/action_view/helpers/tags/radio_button.rb
index 43dbd32083..621db2b1b5 100644
--- a/actionview/lib/action_view/helpers/tags/radio_button.rb
+++ b/actionview/lib/action_view/helpers/tags/radio_button.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/helpers/tags/checkable"
module ActionView
@@ -15,7 +17,7 @@ module ActionView
options = @options.stringify_keys
options["type"] = "radio"
options["value"] = @tag_value
- options["checked"] = "checked" if input_checked?(object, options)
+ options["checked"] = "checked" if input_checked?(options)
add_default_name_and_id_for_value(@tag_value, options)
tag("input", options)
end
diff --git a/actionview/lib/action_view/helpers/tags/range_field.rb b/actionview/lib/action_view/helpers/tags/range_field.rb
index f98ae88043..66d1bbac5b 100644
--- a/actionview/lib/action_view/helpers/tags/range_field.rb
+++ b/actionview/lib/action_view/helpers/tags/range_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/search_field.rb b/actionview/lib/action_view/helpers/tags/search_field.rb
index a848aeabfa..f209348904 100644
--- a/actionview/lib/action_view/helpers/tags/search_field.rb
+++ b/actionview/lib/action_view/helpers/tags/search_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/select.rb b/actionview/lib/action_view/helpers/tags/select.rb
index 667c7e945a..345484ba92 100644
--- a/actionview/lib/action_view/helpers/tags/select.rb
+++ b/actionview/lib/action_view/helpers/tags/select.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
@@ -6,14 +8,14 @@ module ActionView
@choices = block_given? ? template_object.capture { yield || "" } : choices
@choices = @choices.to_a if @choices.is_a?(Range)
- @html_options = html_options
+ @html_options = html_options.except(:skip_default_ids, :allow_method_names_outside_object)
super(object_name, method_name, template_object, options)
end
def render
option_tags_options = {
- selected: @options.fetch(:selected) { value(@object) },
+ selected: @options.fetch(:selected) { value },
disabled: @options[:disabled]
}
@@ -33,7 +35,7 @@ module ActionView
# [nil, []]
# { nil => [] }
def grouped_choices?
- !@choices.empty? && @choices.first.respond_to?(:last) && Array === @choices.first.last
+ !@choices.blank? && @choices.first.respond_to?(:last) && Array === @choices.first.last
end
end
end
diff --git a/actionview/lib/action_view/helpers/tags/tel_field.rb b/actionview/lib/action_view/helpers/tags/tel_field.rb
index 987bb9e67a..ab1caaac48 100644
--- a/actionview/lib/action_view/helpers/tags/tel_field.rb
+++ b/actionview/lib/action_view/helpers/tags/tel_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/text_area.rb b/actionview/lib/action_view/helpers/tags/text_area.rb
index 31e3a9e9b1..4519082ff6 100644
--- a/actionview/lib/action_view/helpers/tags/text_area.rb
+++ b/actionview/lib/action_view/helpers/tags/text_area.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/helpers/tags/placeholderable"
module ActionView
@@ -14,7 +16,7 @@ module ActionView
options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
end
- content_tag("textarea", options.delete("value") { value_before_type_cast(object) }, options)
+ content_tag("textarea", options.delete("value") { value_before_type_cast }, options)
end
end
end
diff --git a/actionview/lib/action_view/helpers/tags/text_field.rb b/actionview/lib/action_view/helpers/tags/text_field.rb
index 613cade7b3..d92967e212 100644
--- a/actionview/lib/action_view/helpers/tags/text_field.rb
+++ b/actionview/lib/action_view/helpers/tags/text_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/helpers/tags/placeholderable"
module ActionView
@@ -10,7 +12,7 @@ module ActionView
options = @options.stringify_keys
options["size"] = options["maxlength"] unless options.key?("size")
options["type"] ||= field_type
- options["value"] = options.fetch("value") { value_before_type_cast(object) } unless field_type == "file"
+ options["value"] = options.fetch("value") { value_before_type_cast } unless field_type == "file"
add_default_name_and_id(options)
tag("input", options)
end
diff --git a/actionview/lib/action_view/helpers/tags/time_field.rb b/actionview/lib/action_view/helpers/tags/time_field.rb
index 0e90a3aed7..9384a83a3e 100644
--- a/actionview/lib/action_view/helpers/tags/time_field.rb
+++ b/actionview/lib/action_view/helpers/tags/time_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/time_select.rb b/actionview/lib/action_view/helpers/tags/time_select.rb
index 0b06311d25..ba3dcb64e3 100644
--- a/actionview/lib/action_view/helpers/tags/time_select.rb
+++ b/actionview/lib/action_view/helpers/tags/time_select.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/time_zone_select.rb b/actionview/lib/action_view/helpers/tags/time_zone_select.rb
index 80d165ec7e..1d06096096 100644
--- a/actionview/lib/action_view/helpers/tags/time_zone_select.rb
+++ b/actionview/lib/action_view/helpers/tags/time_zone_select.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
@@ -11,7 +13,7 @@ module ActionView
def render
select_content_tag(
- time_zone_options_for_select(value(@object) || @options[:default], @priority_zones, @options[:model] || ActiveSupport::TimeZone), @options, @html_options
+ time_zone_options_for_select(value || @options[:default], @priority_zones, @options[:model] || ActiveSupport::TimeZone), @options, @html_options
)
end
end
diff --git a/actionview/lib/action_view/helpers/tags/translator.rb b/actionview/lib/action_view/helpers/tags/translator.rb
index ced835eaa8..fcf96d2c9c 100644
--- a/actionview/lib/action_view/helpers/tags/translator.rb
+++ b/actionview/lib/action_view/helpers/tags/translator.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/url_field.rb b/actionview/lib/action_view/helpers/tags/url_field.rb
index d76340178d..395fec67e7 100644
--- a/actionview/lib/action_view/helpers/tags/url_field.rb
+++ b/actionview/lib/action_view/helpers/tags/url_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/tags/week_field.rb b/actionview/lib/action_view/helpers/tags/week_field.rb
index 835d1667d7..572535d1d6 100644
--- a/actionview/lib/action_view/helpers/tags/week_field.rb
+++ b/actionview/lib/action_view/helpers/tags/week_field.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Helpers
module Tags # :nodoc:
diff --git a/actionview/lib/action_view/helpers/text_helper.rb b/actionview/lib/action_view/helpers/text_helper.rb
index bc922f9ce8..84d38aa416 100644
--- a/actionview/lib/action_view/helpers/text_helper.rb
+++ b/actionview/lib/action_view/helpers/text_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/string/filters"
require "active_support/core_ext/array/extract_options"
@@ -420,7 +422,7 @@ module ActionView
def to_s
value = @values[@index].to_s
@index = next_index
- return value
+ value
end
private
@@ -444,7 +446,7 @@ module ActionView
# uses an instance variable of ActionView::Base.
def get_cycle(name)
@_cycles = Hash.new unless defined?(@_cycles)
- return @_cycles[name]
+ @_cycles[name]
end
def set_cycle(name, cycle_object)
diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb
index 47ed41a129..1860bc4732 100644
--- a/actionview/lib/action_view/helpers/translation_helper.rb
+++ b/actionview/lib/action_view/helpers/translation_helper.rb
@@ -1,18 +1,19 @@
+# frozen_string_literal: true
+
require "action_view/helpers/tag_helper"
require "active_support/core_ext/string/access"
require "i18n/exceptions"
module ActionView
# = Action View Translation Helpers
- module Helpers
+ module Helpers #:nodoc:
module TranslationHelper
extend ActiveSupport::Concern
include TagHelper
included do
- mattr_accessor :debug_missing_translation
- self.debug_missing_translation = true
+ mattr_accessor :debug_missing_translation, default: true
end
# Delegates to <tt>I18n#translate</tt> but also performs three additional
@@ -96,7 +97,7 @@ module ActionView
raise e if raise_error
keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
- title = "translation missing: #{keys.join('.')}"
+ title = "translation missing: #{keys.join('.')}".dup
interpolations = options.except(:default, :scope)
if interpolations.any?
diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb
index 70fc57c35f..02335c72ec 100644
--- a/actionview/lib/action_view/helpers/url_helper.rb
+++ b/actionview/lib/action_view/helpers/url_helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/helpers/javascript_helper"
require "active_support/core_ext/array/access"
require "active_support/core_ext/hash/keys"
@@ -542,7 +544,7 @@ module ActionView
return false unless request.get? || request.head?
- check_parameters ||= !options.is_a?(String) && options.try(:delete, :check_parameters)
+ check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
url_string = URI.parser.unescape(url_for(options)).force_encoding(Encoding::BINARY)
# We ignore any extra parameters in the request_uri if the
@@ -552,7 +554,10 @@ module ActionView
request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
request_uri = URI.parser.unescape(request_uri).force_encoding(Encoding::BINARY)
- url_string.chomp!("/") if url_string.start_with?("/") && url_string != "/"
+ if url_string.start_with?("/") && url_string != "/"
+ url_string.chomp!("/")
+ request_uri.chomp!("/")
+ end
if %r{^\w+://}.match?(url_string)
url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
@@ -584,10 +589,27 @@ module ActionView
end
def add_method_to_attributes!(html_options, method)
- if method && method.to_s.downcase != "get".freeze && html_options["rel".freeze] !~ /nofollow/
- html_options["rel".freeze] = "#{html_options["rel".freeze]} nofollow".lstrip
+ if method_not_get_method?(method) && html_options["rel"] !~ /nofollow/
+ if html_options["rel"].blank?
+ html_options["rel"] = "nofollow"
+ else
+ html_options["rel"] = "#{html_options["rel"]} nofollow"
+ end
end
- html_options["data-method".freeze] = method
+ html_options["data-method"] = method
+ end
+
+ STRINGIFIED_COMMON_METHODS = {
+ get: "get",
+ delete: "delete",
+ patch: "patch",
+ post: "post",
+ put: "put",
+ }.freeze
+
+ def method_not_get_method?(method)
+ return false unless method
+ (STRINGIFIED_COMMON_METHODS[method] || method.to_s.downcase) != "get"
end
def token_tag(token = nil, form_options: {})
diff --git a/actionview/lib/action_view/layouts.rb b/actionview/lib/action_view/layouts.rb
index 81feb90486..3e6d352c15 100644
--- a/actionview/lib/action_view/layouts.rb
+++ b/actionview/lib/action_view/layouts.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "action_view/rendering"
-require "active_support/core_ext/module/remove_method"
+require "active_support/core_ext/module/redefine_method"
module ActionView
# Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
@@ -204,9 +206,9 @@ module ActionView
include ActionView::Rendering
included do
- class_attribute :_layout, :_layout_conditions, instance_accessor: false
- self._layout = nil
- self._layout_conditions = {}
+ class_attribute :_layout, instance_accessor: false
+ class_attribute :_layout_conditions, instance_accessor: false, default: {}
+
_write_layout_method
end
@@ -277,7 +279,7 @@ module ActionView
# If a layout is not explicitly mentioned then look for a layout with the controller's name.
# if nothing is found then try same procedure to find super class's layout.
def _write_layout_method # :nodoc:
- remove_possible_method(:_layout)
+ silence_redefinition_of_method(:_layout)
prefixes = /\blayouts/.match?(_implied_layout_name) ? [] : ["layouts"]
default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false, [], { formats: formats }).first || super"
diff --git a/actionview/lib/action_view/log_subscriber.rb b/actionview/lib/action_view/log_subscriber.rb
index d03e1a51b8..d4ac77e10f 100644
--- a/actionview/lib/action_view/log_subscriber.rb
+++ b/actionview/lib/action_view/log_subscriber.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/log_subscriber"
module ActionView
@@ -14,7 +16,7 @@ module ActionView
def render_template(event)
info do
- message = " Rendered #{from_rails_root(event.payload[:identifier])}"
+ message = " Rendered #{from_rails_root(event.payload[:identifier])}".dup
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
message << " (#{event.duration.round(1)}ms)"
end
@@ -22,10 +24,10 @@ module ActionView
def render_partial(event)
info do
- message = " Rendered #{from_rails_root(event.payload[:identifier])}"
+ message = " Rendered #{from_rails_root(event.payload[:identifier])}".dup
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
message << " (#{event.duration.round(1)}ms)"
- message << " #{cache_message(event.payload)}" if event.payload.key?(:cache_hit)
+ message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
message
end
end
@@ -73,16 +75,17 @@ module ActionView
end
def cache_message(payload) # :doc:
- if payload[:cache_hit]
+ case payload[:cache_hit]
+ when :hit
"[cache hit]"
- else
+ when :miss
"[cache miss]"
end
end
def log_rendering_start(payload)
info do
- message = " Rendering #{from_rails_root(payload[:identifier])}"
+ message = " Rendering #{from_rails_root(payload[:identifier])}".dup
message << " within #{from_rails_root(payload[:layout])}" if payload[:layout]
message
end
diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb
index f385a7cd04..0e56eca35c 100644
--- a/actionview/lib/action_view/lookup_context.rb
+++ b/actionview/lib/action_view/lookup_context.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "concurrent/map"
require "active_support/core_ext/module/remove_method"
require "active_support/core_ext/module/attribute_accessors"
@@ -14,11 +16,9 @@ module ActionView
class LookupContext #:nodoc:
attr_accessor :prefixes, :rendered_format
- mattr_accessor :fallbacks
- @@fallbacks = FallbackFileSystemResolver.instances
+ mattr_accessor :fallbacks, default: FallbackFileSystemResolver.instances
- mattr_accessor :registered_details
- self.registered_details = []
+ mattr_accessor :registered_details, default: []
def self.register_detail(name, &block)
registered_details << name
diff --git a/actionview/lib/action_view/model_naming.rb b/actionview/lib/action_view/model_naming.rb
index b6ed13424e..23cca8d607 100644
--- a/actionview/lib/action_view/model_naming.rb
+++ b/actionview/lib/action_view/model_naming.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module ModelNaming #:nodoc:
# Converts the given object to an ActiveModel compliant one.
diff --git a/actionview/lib/action_view/path_set.rb b/actionview/lib/action_view/path_set.rb
index 6688519ffd..691b53e2da 100644
--- a/actionview/lib/action_view/path_set.rb
+++ b/actionview/lib/action_view/path_set.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView #:nodoc:
# = Action View PathSet
#
diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb
index 61678933e9..b22347c55c 100644
--- a/actionview/lib/action_view/railtie.rb
+++ b/actionview/lib/action_view/railtie.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view"
require "rails"
diff --git a/actionview/lib/action_view/record_identifier.rb b/actionview/lib/action_view/record_identifier.rb
index 48bea315a9..1310a1ce0a 100644
--- a/actionview/lib/action_view/record_identifier.rb
+++ b/actionview/lib/action_view/record_identifier.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/module"
require "action_view/model_naming"
diff --git a/actionview/lib/action_view/renderer/abstract_renderer.rb b/actionview/lib/action_view/renderer/abstract_renderer.rb
index 0b315eb569..20b2523cac 100644
--- a/actionview/lib/action_view/renderer/abstract_renderer.rb
+++ b/actionview/lib/action_view/renderer/abstract_renderer.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
# This class defines the interface for a renderer. Each class that
# subclasses +AbstractRenderer+ is used by the base +Renderer+ class to
diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb
index 647b15ea94..5b40af4f2f 100644
--- a/actionview/lib/action_view/renderer/partial_renderer.rb
+++ b/actionview/lib/action_view/renderer/partial_renderer.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "concurrent/map"
require "action_view/renderer/partial_renderer/collection_caching"
@@ -50,12 +52,12 @@ module ActionView
# <%= render partial: "ad", locals: { ad: ad } %>
# <% end %>
#
- # This would first render "advertiser/_account.html.erb" with @buyer passed in as the local variable +account+, then
- # render "advertiser/_ad.html.erb" and pass the local variable +ad+ to the template for display.
+ # This would first render <tt>advertiser/_account.html.erb</tt> with <tt>@buyer</tt> passed in as the local variable +account+, then
+ # render <tt>advertiser/_ad.html.erb</tt> and pass the local variable +ad+ to the template for display.
#
# == The :as and :object options
#
- # By default <tt>ActionView::PartialRenderer</tt> doesn't have any local variables.
+ # By default ActionView::PartialRenderer doesn't have any local variables.
# The <tt>:object</tt> option can be used to pass an object to the partial. For instance:
#
# <%= render partial: "account", object: @buyer %>
@@ -83,7 +85,7 @@ module ActionView
#
# <%= render partial: "ad", collection: @advertisements %>
#
- # This will render "advertiser/_ad.html.erb" and pass the local variable +ad+ to the template for display. An
+ # This will render <tt>advertiser/_ad.html.erb</tt> and pass the local variable +ad+ to the template for display. An
# iteration object will automatically be made available to the template with a name of the form
# +partial_name_iteration+. The iteration object has knowledge about which index the current object has in
# the collection and the total size of the collection. The iteration object also has two convenience methods,
@@ -98,7 +100,7 @@ module ActionView
#
# <%= render partial: "ad", collection: @advertisements, spacer_template: "ad_divider" %>
#
- # If the given <tt>:collection</tt> is +nil+ or empty, <tt>render</tt> will return nil. This will allow you
+ # If the given <tt>:collection</tt> is +nil+ or empty, <tt>render</tt> will return +nil+. This will allow you
# to specify a text which will be displayed instead by using this form:
#
# <%= render(partial: "ad", collection: @advertisements) || "There's no ad to be displayed" %>
@@ -112,18 +114,18 @@ module ActionView
#
# <%= render partial: "advertisement/ad", locals: { ad: @advertisement } %>
#
- # This will render the partial "advertisement/_ad.html.erb" regardless of which controller this is being called from.
+ # This will render the partial <tt>advertisement/_ad.html.erb</tt> regardless of which controller this is being called from.
#
- # == \Rendering objects that respond to `to_partial_path`
+ # == \Rendering objects that respond to +to_partial_path+
#
# Instead of explicitly naming the location of a partial, you can also let PartialRenderer do the work
- # and pick the proper path by checking `to_partial_path` method.
+ # and pick the proper path by checking +to_partial_path+ method.
#
# # @account.to_partial_path returns 'accounts/account', so it can be used to replace:
# # <%= render partial: "accounts/account", locals: { account: @account} %>
# <%= render partial: @account %>
#
- # # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`,
+ # # @posts is an array of Post instances, so every post record returns 'posts/post' on +to_partial_path+,
# # that's why we can replace:
# # <%= render partial: "posts/post", collection: @posts %>
# <%= render partial: @posts %>
@@ -143,7 +145,7 @@ module ActionView
# # <%= render partial: "accounts/account", locals: { account: @account} %>
# <%= render @account %>
#
- # # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`,
+ # # @posts is an array of Post instances, so every post record returns 'posts/post' on +to_partial_path+,
# # that's why we can replace:
# # <%= render partial: "posts/post", collection: @posts %>
# <%= render @posts %>
@@ -344,7 +346,7 @@ module ActionView
end
content = layout.render(view, locals) { content } if layout
- payload[:cache_hit] = view.cache_hit
+ payload[:cache_hit] = view.view_renderer.cache_hits[@template.virtual_path]
content
end
end
@@ -353,7 +355,7 @@ module ActionView
# finds the options and details and extracts them. The method also contains
# logic that handles the type of object passed in as the partial.
#
- # If +options[:partial]+ is a string, then the +@path+ instance variable is
+ # If +options[:partial]+ is a string, then the <tt>@path</tt> instance variable is
# set to that string. Otherwise, the +options[:partial]+ object must
# respond to +to_partial_path+ in order to setup the path.
def setup(context, options, block)
diff --git a/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb b/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb
index 1fbe209200..db52919e91 100644
--- a/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb
+++ b/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module CollectionCaching # :nodoc:
extend ActiveSupport::Concern
@@ -5,7 +7,7 @@ module ActionView
included do
# Fallback cache store if Action View is used without Rails.
# Otherwise overridden in Railtie to use Rails.cache.
- mattr_accessor(:collection_cache) { ActiveSupport::Cache::MemoryStore.new }
+ mattr_accessor :collection_cache, default: ActiveSupport::Cache::MemoryStore.new
end
private
@@ -38,7 +40,7 @@ module ActionView
end
def expanded_cache_key(key)
- key = @view.fragment_cache_key(@view.cache_fragment_name(key, virtual_path: @template.virtual_path))
+ key = @view.combined_fragment_cache_key(@view.cache_fragment_name(key, virtual_path: @template.virtual_path))
key.frozen? ? key.dup : key # #read_multi & #write may require mutability, Dalli 2.6.0.
end
diff --git a/actionview/lib/action_view/renderer/renderer.rb b/actionview/lib/action_view/renderer/renderer.rb
index 2a3b89aebf..3f3a97529d 100644
--- a/actionview/lib/action_view/renderer/renderer.rb
+++ b/actionview/lib/action_view/renderer/renderer.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
# This is the main entry point for rendering. It basically delegates
# to other objects like TemplateRenderer and PartialRenderer which
@@ -46,5 +48,9 @@ module ActionView
def render_partial(context, options, &block) #:nodoc:
PartialRenderer.new(@lookup_context).render(context, options, block)
end
+
+ def cache_hits # :nodoc:
+ @cache_hits ||= {}
+ end
end
end
diff --git a/actionview/lib/action_view/renderer/streaming_template_renderer.rb b/actionview/lib/action_view/renderer/streaming_template_renderer.rb
index 62ce985243..ca49eb1144 100644
--- a/actionview/lib/action_view/renderer/streaming_template_renderer.rb
+++ b/actionview/lib/action_view/renderer/streaming_template_renderer.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "fiber"
module ActionView
@@ -31,7 +33,7 @@ module ActionView
logger = ActionView::Base.logger
return unless logger
- message = "\n#{exception.class} (#{exception.message}):\n"
+ message = "\n#{exception.class} (#{exception.message}):\n".dup
message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
message << " " << exception.backtrace.join("\n ")
logger.fatal("#{message}\n\n")
diff --git a/actionview/lib/action_view/renderer/template_renderer.rb b/actionview/lib/action_view/renderer/template_renderer.rb
index 54317199de..ce8908924a 100644
--- a/actionview/lib/action_view/renderer/template_renderer.rb
+++ b/actionview/lib/action_view/renderer/template_renderer.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/object/try"
module ActionView
diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb
index cf18562c45..4e5fdfbb2d 100644
--- a/actionview/lib/action_view/rendering.rb
+++ b/actionview/lib/action_view/rendering.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/view_paths"
module ActionView
@@ -73,8 +75,7 @@ module ActionView
end
# Returns an object that is able to render templates.
- # :api: private
- def view_renderer
+ def view_renderer # :nodoc:
@_view_renderer ||= ActionView::Renderer.new(lookup_context)
end
@@ -90,7 +91,6 @@ module ActionView
private
# Find and render a template based on the options given.
- # :api: private
def _render_template(options)
variant = options.delete(:variant)
assigns = options.delete(:assigns)
@@ -112,7 +112,6 @@ module ActionView
# Normalize args by converting render "foo" to render :action => "foo" and
# render "foo/bar" to render :template => "foo/bar".
- # :api: private
def _normalize_args(action = nil, options = {})
options = super(action, options)
case action
@@ -135,7 +134,6 @@ module ActionView
end
# Normalize options.
- # :api: private
def _normalize_options(options)
options = super(options)
if options[:partial] == true
diff --git a/actionview/lib/action_view/routing_url_for.rb b/actionview/lib/action_view/routing_url_for.rb
index 687ba7c1b4..fd563f34a9 100644
--- a/actionview/lib/action_view/routing_url_for.rb
+++ b/actionview/lib/action_view/routing_url_for.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_dispatch/routing/polymorphic_routes"
module ActionView
diff --git a/actionview/lib/action_view/tasks/cache_digests.rake b/actionview/lib/action_view/tasks/cache_digests.rake
index d30b3f7797..dd8e94bd88 100644
--- a/actionview/lib/action_view/tasks/cache_digests.rake
+++ b/actionview/lib/action_view/tasks/cache_digests.rake
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
namespace :cache_digests do
desc "Lookup nested dependencies for TEMPLATE (like messages/show or comments/_comment.html)"
task nested_dependencies: :environment do
diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb
index b0e2f1e54e..0c4bb73acb 100644
--- a/actionview/lib/action_view/template.rb
+++ b/actionview/lib/action_view/template.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/object/try"
require "active_support/core_ext/kernel/singleton_class"
require "thread"
@@ -282,7 +284,7 @@ module ActionView
# Make sure that the resulting String to be eval'd is in the
# encoding of the code
- source = <<-end_src
+ source = <<-end_src.dup
def #{method_name}(local_assigns, output_buffer)
_old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
ensure
@@ -328,13 +330,13 @@ module ActionView
locals = @locals - Module::RUBY_RESERVED_KEYWORDS
locals = locals.grep(/\A@?(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/)
- # Double assign to suppress the dreaded 'assigned but unused variable' warning
- locals.each_with_object("") { |key, code| code << "#{key} = #{key} = local_assigns[:#{key}];" }
+ # Assign for the same variable is to suppress unused variable warning
+ locals.each_with_object("".dup) { |key, code| code << "#{key} = local_assigns[:#{key}]; #{key} = #{key};" }
end
def method_name
@method_name ||= begin
- m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}"
+ m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}".dup
m.tr!("-".freeze, "_".freeze)
m
end
diff --git a/actionview/lib/action_view/template/error.rb b/actionview/lib/action_view/template/error.rb
index cc90477190..4e3c02e05e 100644
--- a/actionview/lib/action_view/template/error.rb
+++ b/actionview/lib/action_view/template/error.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/enumerable"
module ActionView
@@ -8,9 +10,6 @@ module ActionView
class EncodingError < StandardError #:nodoc:
end
- class MissingRequestError < StandardError #:nodoc:
- end
-
class WrongEncodingError < EncodingError #:nodoc:
def initialize(string, encoding)
@string, @encoding = string, encoding
diff --git a/actionview/lib/action_view/template/handlers.rb b/actionview/lib/action_view/template/handlers.rb
index f4301f6f07..7ec76dcc3f 100644
--- a/actionview/lib/action_view/template/handlers.rb
+++ b/actionview/lib/action_view/template/handlers.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
module ActionView #:nodoc:
# = Action View Template Handlers
- class Template
+ class Template #:nodoc:
module Handlers #:nodoc:
autoload :Raw, "action_view/template/handlers/raw"
autoload :ERB, "action_view/template/handlers/erb"
diff --git a/actionview/lib/action_view/template/handlers/builder.rb b/actionview/lib/action_view/template/handlers/builder.rb
index e99b921cb7..61492ce448 100644
--- a/actionview/lib/action_view/template/handlers/builder.rb
+++ b/actionview/lib/action_view/template/handlers/builder.rb
@@ -1,9 +1,9 @@
+# frozen_string_literal: true
+
module ActionView
module Template::Handlers
class Builder
- # Default format used by Builder.
- class_attribute :default_format
- self.default_format = :xml
+ class_attribute :default_format, default: :xml
def call(template)
require_engine
@@ -14,7 +14,6 @@ module ActionView
end
private
-
def require_engine # :doc:
@required ||= begin
require "builder"
diff --git a/actionview/lib/action_view/template/handlers/erb.rb b/actionview/lib/action_view/template/handlers/erb.rb
index 58c7fd1a88..b7b749f9da 100644
--- a/actionview/lib/action_view/template/handlers/erb.rb
+++ b/actionview/lib/action_view/template/handlers/erb.rb
@@ -1,24 +1,20 @@
+# frozen_string_literal: true
+
module ActionView
class Template
module Handlers
- autoload :Erubis, "action_view/template/handlers/erb/deprecated_erubis"
-
class ERB
autoload :Erubi, "action_view/template/handlers/erb/erubi"
- autoload :Erubis, "action_view/template/handlers/erb/erubis"
# Specify trim mode for the ERB compiler. Defaults to '-'.
# See ERB documentation for suitable values.
- class_attribute :erb_trim_mode
- self.erb_trim_mode = "-"
+ class_attribute :erb_trim_mode, default: "-"
# Default implementation used.
- class_attribute :erb_implementation
- self.erb_implementation = Erubi
+ class_attribute :erb_implementation, default: Erubi
# Do not escape templates of these mime types.
- class_attribute :escape_whitelist
- self.escape_whitelist = ["text/plain"]
+ class_attribute :escape_whitelist, default: ["text/plain"]
ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
diff --git a/actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb b/actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb
deleted file mode 100644
index 427ea20064..0000000000
--- a/actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-::ActiveSupport::Deprecation.warn("ActionView::Template::Handlers::Erubis is deprecated and will be removed from Rails 5.2. Switch to ActionView::Template::Handlers::ERB::Erubi instead.")
-
-module ActionView
- class Template
- module Handlers
- Erubis = ERB::Erubis
- end
- end
-end
diff --git a/actionview/lib/action_view/template/handlers/erb/erubi.rb b/actionview/lib/action_view/template/handlers/erb/erubi.rb
index 755cc84015..db75f028ed 100644
--- a/actionview/lib/action_view/template/handlers/erb/erubi.rb
+++ b/actionview/lib/action_view/template/handlers/erb/erubi.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "erubi"
module ActionView
diff --git a/actionview/lib/action_view/template/handlers/erb/erubis.rb b/actionview/lib/action_view/template/handlers/erb/erubis.rb
deleted file mode 100644
index f3c35e1aec..0000000000
--- a/actionview/lib/action_view/template/handlers/erb/erubis.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-gem "erubis"
-require "erubis"
-
-module ActionView
- class Template
- module Handlers
- class ERB
- class Erubis < ::Erubis::Eruby
- # :nodoc: all
- def add_preamble(src)
- @newline_pending = 0
- src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;"
- end
-
- def add_text(src, text)
- return if text.empty?
-
- if text == "\n"
- @newline_pending += 1
- else
- src << "@output_buffer.safe_append='"
- src << "\n" * @newline_pending if @newline_pending > 0
- src << escape_text(text)
- src << "'.freeze;"
-
- @newline_pending = 0
- end
- end
-
- # Erubis toggles <%= and <%== behavior when escaping is enabled.
- # We override to always treat <%== as escaped.
- def add_expr(src, code, indicator)
- case indicator
- when "=="
- add_expr_escaped(src, code)
- else
- super
- end
- end
-
- BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
-
- def add_expr_literal(src, code)
- flush_newline_if_pending(src)
- if BLOCK_EXPR.match?(code)
- src << "@output_buffer.append= " << code
- else
- src << "@output_buffer.append=(" << code << ");"
- end
- end
-
- def add_expr_escaped(src, code)
- flush_newline_if_pending(src)
- if BLOCK_EXPR.match?(code)
- src << "@output_buffer.safe_expr_append= " << code
- else
- src << "@output_buffer.safe_expr_append=(" << code << ");"
- end
- end
-
- def add_stmt(src, code)
- flush_newline_if_pending(src)
- super
- end
-
- def add_postamble(src)
- flush_newline_if_pending(src)
- src << "@output_buffer.to_s"
- end
-
- def flush_newline_if_pending(src)
- if @newline_pending > 0
- src << "@output_buffer.safe_append='#{"\n" * @newline_pending}'.freeze;"
- @newline_pending = 0
- end
- end
- end
- end
- end
- end
-end
diff --git a/actionview/lib/action_view/template/handlers/html.rb b/actionview/lib/action_view/template/handlers/html.rb
index ccaa8d1469..27004a318c 100644
--- a/actionview/lib/action_view/template/handlers/html.rb
+++ b/actionview/lib/action_view/template/handlers/html.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Template::Handlers
class Html < Raw
diff --git a/actionview/lib/action_view/template/handlers/raw.rb b/actionview/lib/action_view/template/handlers/raw.rb
index e7519e94f9..5cd23a0060 100644
--- a/actionview/lib/action_view/template/handlers/raw.rb
+++ b/actionview/lib/action_view/template/handlers/raw.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
module ActionView
module Template::Handlers
class Raw
diff --git a/actionview/lib/action_view/template/html.rb b/actionview/lib/action_view/template/html.rb
index 0ffae10432..a262c6d9ad 100644
--- a/actionview/lib/action_view/template/html.rb
+++ b/actionview/lib/action_view/template/html.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
module ActionView #:nodoc:
# = Action View HTML Template
- class Template
+ class Template #:nodoc:
class HTML #:nodoc:
attr_accessor :type
diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb
index d3905b5f23..5a86f10973 100644
--- a/actionview/lib/action_view/template/resolver.rb
+++ b/actionview/lib/action_view/template/resolver.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "pathname"
require "active_support/core_ext/class"
require "active_support/core_ext/module/attribute_accessors"
@@ -14,7 +16,7 @@ module ActionView
alias_method :partial?, :partial
def self.build(name, prefix, partial)
- virtual = ""
+ virtual = "".dup
virtual << "#{prefix}/" unless prefix.empty?
virtual << (partial ? "_#{name}" : name)
new name, prefix, partial, virtual
@@ -125,8 +127,7 @@ module ActionView
end
end
- cattr_accessor :caching
- self.caching = true
+ cattr_accessor :caching, default: true
class << self
alias :caching? :caching
@@ -309,13 +310,13 @@ module ActionView
# ==== Examples
#
# Default pattern, loads views the same way as previous versions of rails, eg. when you're
- # looking for `users/new` it will produce query glob: `users/new{.{en},}{.{html,js},}{.{erb,haml},}`
+ # looking for <tt>users/new</tt> it will produce query glob: <tt>users/new{.{en},}{.{html,js},}{.{erb,haml},}</tt>
#
# FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
#
# This one allows you to keep files with different formats in separate subdirectories,
- # eg. `users/new.html` will be loaded from `users/html/new.erb` or `users/new.html.erb`,
- # `users/new.js` from `users/js/new.erb` or `users/new.js.erb`, etc.
+ # eg. <tt>users/new.html</tt> will be loaded from <tt>users/html/new.erb</tt> or <tt>users/new.html.erb</tt>,
+ # <tt>users/new.js</tt> from <tt>users/js/new.erb</tt> or <tt>users/new.js.erb</tt>, etc.
#
# FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
#
diff --git a/actionview/lib/action_view/template/text.rb b/actionview/lib/action_view/template/text.rb
index 380528d6ef..f8d6c2811f 100644
--- a/actionview/lib/action_view/template/text.rb
+++ b/actionview/lib/action_view/template/text.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
module ActionView #:nodoc:
# = Action View Text Template
- class Template
+ class Template #:nodoc:
class Text #:nodoc:
attr_accessor :type
diff --git a/actionview/lib/action_view/template/types.rb b/actionview/lib/action_view/template/types.rb
index 21959a3798..67b7a62de6 100644
--- a/actionview/lib/action_view/template/types.rb
+++ b/actionview/lib/action_view/template/types.rb
@@ -1,7 +1,9 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/module/attribute_accessors"
module ActionView
- class Template
+ class Template #:nodoc:
class Types
class Type
SET = Struct.new(:symbols).new([ :html, :text, :js, :css, :xml, :json ])
diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb
index ae4fec4337..e1cbae5845 100644
--- a/actionview/lib/action_view/test_case.rb
+++ b/actionview/lib/action_view/test_case.rb
@@ -1,4 +1,6 @@
-require "active_support/core_ext/module/remove_method"
+# frozen_string_literal: true
+
+require "active_support/core_ext/module/redefine_method"
require "action_controller"
require "action_controller/test_case"
require "action_view"
@@ -71,7 +73,7 @@ module ActionView
def helper_method(*methods)
# Almost a duplicate from ActionController::Helpers
methods.flatten.each do |method|
- _helpers.module_eval <<-end_eval
+ _helpers.module_eval <<-end_eval, __FILE__, __LINE__ + 1
def #{method}(*args, &block) # def current_user(*args, &block)
_test_case.send(%(#{method}), *args, &block) # _test_case.send(%(current_user), *args, &block)
end # end
@@ -101,10 +103,11 @@ module ActionView
def setup_with_controller
@controller = ActionView::TestCase::TestController.new
@request = @controller.request
+ @view_flow = ActionView::OutputFlow.new
# empty string ensures buffer has UTF-8 encoding as
# new without arguments returns ASCII-8BIT encoded buffer like String#new
@output_buffer = ActiveSupport::SafeBuffer.new ""
- @rendered = ""
+ @rendered = "".dup
make_test_case_available_to_view!
say_no_to_protect_against_forgery!
@@ -168,7 +171,7 @@ module ActionView
def say_no_to_protect_against_forgery!
_helpers.module_eval do
- remove_possible_method :protect_against_forgery?
+ silence_redefinition_of_method :protect_against_forgery?
def protect_against_forgery?
false
end
@@ -244,6 +247,7 @@ module ActionView
:@test_passed,
:@view,
:@view_context_class,
+ :@view_flow,
:@_subscribers,
:@html_document
]
@@ -266,7 +270,7 @@ module ActionView
begin
routes = @controller.respond_to?(:_routes) && @controller._routes
rescue
- # Dont call routes, if there is an error on _routes call
+ # Don't call routes, if there is an error on _routes call
end
if routes &&
@@ -277,6 +281,18 @@ module ActionView
super
end
end
+
+ def respond_to_missing?(name, include_private = false)
+ begin
+ routes = @controller.respond_to?(:_routes) && @controller._routes
+ rescue
+ # Don't call routes, if there is an error on _routes call
+ end
+
+ routes &&
+ (routes.named_routes.route_defined?(name) ||
+ routes.mounted_helpers.method_defined?(name))
+ end
end
include Behavior
diff --git a/actionview/lib/action_view/testing/resolvers.rb b/actionview/lib/action_view/testing/resolvers.rb
index 3188526b63..68186c3bf8 100644
--- a/actionview/lib/action_view/testing/resolvers.rb
+++ b/actionview/lib/action_view/testing/resolvers.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "action_view/template/resolver"
module ActionView #:nodoc:
@@ -20,7 +22,7 @@ module ActionView #:nodoc:
private
def query(path, exts, _, _)
- query = ""
+ query = "".dup
EXTENSIONS.each_key do |ext|
query << "(" << exts[ext].map { |e| e && Regexp.escape(".#{e}") }.join("|") << "|)"
end
diff --git a/actionview/lib/action_view/version.rb b/actionview/lib/action_view/version.rb
index 315404864d..be53797a14 100644
--- a/actionview/lib/action_view/version.rb
+++ b/actionview/lib/action_view/version.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require_relative "gem_version"
module ActionView
diff --git a/actionview/lib/action_view/view_paths.rb b/actionview/lib/action_view/view_paths.rb
index f0fe6831fa..d5694d77f4 100644
--- a/actionview/lib/action_view/view_paths.rb
+++ b/actionview/lib/action_view/view_paths.rb
@@ -1,11 +1,11 @@
+# frozen_string_literal: true
+
module ActionView
module ViewPaths
extend ActiveSupport::Concern
included do
- class_attribute :_view_paths
- self._view_paths = ActionView::PathSet.new
- _view_paths.freeze
+ class_attribute :_view_paths, default: ActionView::PathSet.new.freeze
end
delegate :template_exists?, :any_templates?, :view_paths, :formats, :formats=,