Skip to content

Commit

Permalink
Action View: Remove internal calls to tag with positional arguments
Browse files Browse the repository at this point in the history
Follow-up to [#49371][]

In the wake of the deprecation of `tag(:div)` in favor of `tag.div`,
this commit replaces all calls made internally with the more modern
syntax.

This change is separate from the deprecation cycle, since there are
**slight** behavioral changes, since the HTML output changes from
self-closing elements like `<input />` to open void elements like
`<input>`.

[#49371]: #49371
  • Loading branch information
seanpdoyle committed Apr 18, 2024
1 parent aaa8e9f commit 5c99edf
Show file tree
Hide file tree
Showing 20 changed files with 95 additions and 79 deletions.
28 changes: 22 additions & 6 deletions actionview/lib/action_view/helpers/active_model_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ module ActiveModelHelper

# = Active \Model Instance Tag \Helpers
module ActiveModelInstanceTag
class TagBuilder < ActionView::Helpers::TagHelper::TagBuilder # :nodoc:
def initialize(view_context, wrapper)
super(view_context)
@wrapper = wrapper
end

def self_closing_tag_string(name, options, escape = true, tag_suffix = " />")
generate_errors?(options) ? @wrapper.error_wrapping(super) : super
end

def tag_string(name, content = nil, escape: true, **options, &block)
generate_errors?(options) ? @wrapper.error_wrapping(super) : super
end

private
def generate_errors?(options)
options["type"] != "hidden"
end
end

def object
@active_model_object ||= begin
object = super
Expand All @@ -21,8 +41,8 @@ def content_tag(type, options, *)
select_markup_helper?(type) ? super : error_wrapping(super)
end

def tag(type, options, *)
tag_generate_errors?(options) ? error_wrapping(super) : super
def tag
TagBuilder.new(@template_object, self)
end

def error_wrapping(html_tag)
Expand All @@ -45,10 +65,6 @@ def object_has_errors?
def select_markup_helper?(type)
["optgroup", "option"].include?(type)
end

def tag_generate_errors?(options)
options["type"] != "hidden"
end
end
end
end
30 changes: 15 additions & 15 deletions actionview/lib/action_view/helpers/asset_tag_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def stylesheet_link_tag(*sources)
tag_options["media"] = "screen"
end

tag(:link, tag_options)
tag.link(**tag_options)
}.join("\n").html_safe

if use_preload_links_header
Expand Down Expand Up @@ -269,12 +269,11 @@ def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
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(
"link",
"rel" => tag_options[:rel] || "alternate",
"type" => tag_options[:type] || Template::Types[type].to_s,
"title" => tag_options[:title] || type.to_s.upcase,
"href" => url_options.is_a?(Hash) ? url_for(url_options.merge(only_path: false)) : url_options
tag.link(
rel: tag_options[:rel] || "alternate",
type: tag_options[:type] || Template::Types[type].to_s,
title: tag_options[:title] || type.to_s.upcase,
href: url_options.is_a?(Hash) ? url_for(url_options.merge(only_path: false)) : url_options
)
end

Expand Down Expand Up @@ -306,11 +305,12 @@ def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
# favicon_link_tag 'mb-icon.png', rel: 'apple-touch-icon', type: 'image/png'
# # => <link href="/assets/mb-icon.png" rel="apple-touch-icon" type="image/png" />
def favicon_link_tag(source = "favicon.ico", options = {})
tag("link", {
tag.link(
rel: "icon",
type: "image/x-icon",
href: path_to_image(source, skip_pipeline: options.delete(:skip_pipeline))
}.merge!(options.symbolize_keys))
href: path_to_image(source, skip_pipeline: options.delete(:skip_pipeline)),
**options.symbolize_keys
)
end

# Returns a link tag that browsers can use to preload the +source+.
Expand Down Expand Up @@ -442,7 +442,7 @@ def image_tag(source, options = {})
options[:loading] ||= image_loading if image_loading
options[:decoding] ||= image_decoding if image_decoding

tag("img", options)
tag.img(**options)
end

# Returns an HTML picture tag for the +sources+. If +sources+ is a string,
Expand Down Expand Up @@ -497,9 +497,9 @@ def picture_tag(*sources, &block)
image_tag(sources.last, image_options)
else
source_tags = sources.map do |source|
tag("source",
srcset: resolve_asset_source("image", source, skip_pipeline),
type: Template::Types[File.extname(source)[1..]]&.to_s)
tag.source(
srcset: resolve_asset_source("image", source, skip_pipeline),
type: Template::Types[File.extname(source)[1..]]&.to_s)
end
safe_join(source_tags << image_tag(sources.last, image_options))
end
Expand Down Expand Up @@ -600,7 +600,7 @@ def multiple_sources_tag_builder(type, sources)

if sources.size > 1
content_tag(type, options) do
safe_join sources.map { |source| tag("source", src: resolve_asset_source(type, source, skip_pipeline)) }
safe_join sources.map { |source| tag.source(src: resolve_asset_source(type, source, skip_pipeline)) }
end
else
options[:src] = resolve_asset_source(type, sources.first, skip_pipeline)
Expand Down
2 changes: 1 addition & 1 deletion actionview/lib/action_view/helpers/csp_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def csp_meta_tag(**options)
if content_security_policy?
options[:name] = "csp-nonce"
options[:content] = content_security_policy_nonce
tag("meta", options)
tag.meta(**options)
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions actionview/lib/action_view/helpers/csrf_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ module CsrfHelper
def csrf_meta_tags
if defined?(protect_against_forgery?) && protect_against_forgery?
[
tag("meta", name: "csrf-param", content: request_forgery_protection_token),
tag("meta", name: "csrf-token", content: form_authenticity_token)
tag.meta(name: "csrf-param", content: request_forgery_protection_token),
tag.meta(name: "csrf-token", content: form_authenticity_token)
].join("\n").html_safe
end
end
Expand Down
2 changes: 1 addition & 1 deletion actionview/lib/action_view/helpers/date_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ def build_hidden(type, value)
}.merge!(@html_options.slice(:disabled))
select_options[:disabled] = "disabled" if @options[:disabled]

tag(:input, select_options) + "\n".html_safe
tag.input(**select_options) + "\n".html_safe
end

# Returns the name attribute for the input tag.
Expand Down
14 changes: 7 additions & 7 deletions actionview/lib/action_view/helpers/form_tag_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ def select_tag(name, option_tags = nil, options = {})
# text_field_tag 'ip', '0.0.0.0', maxlength: 15, size: 20, class: "ip-input"
# # => <input class="ip-input" id="ip" maxlength="15" name="ip" size="20" type="text" value="0.0.0.0" />
def text_field_tag(name, value = nil, options = {})
tag :input, { "type" => "text", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
tag.input(**{ type: "text", name: name, id: sanitize_to_id(name), value: value }.update(options.symbolize_keys))
end

# Creates a label element. Accepts a block.
Expand Down Expand Up @@ -460,7 +460,7 @@ def check_box_tag(name, *args)
value, checked = args.empty? ? ["1", false] : [*args, false]
html_options = { "type" => "checkbox", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
html_options["checked"] = "checked" if checked
tag :input, html_options
tag.input(**html_options)
end

##
Expand Down Expand Up @@ -496,7 +496,7 @@ def radio_button_tag(name, value, *args)
checked = args.empty? ? false : args.first
html_options = { "type" => "radio", "name" => name, "id" => "#{sanitize_to_id(name)}_#{sanitize_to_id(value)}", "value" => value }.update(options.stringify_keys)
html_options["checked"] = "checked" if checked
tag :input, html_options
tag.input(**html_options)
end

# Creates a submit button with the text <tt>value</tt> as the caption.
Expand Down Expand Up @@ -526,7 +526,7 @@ def submit_tag(value = "Save changes", options = {})
options = options.deep_stringify_keys
tag_options = { "type" => "submit", "name" => "commit", "value" => value }.update(options)
set_default_disable_with value, tag_options
tag :input, tag_options
tag.input(**tag_options)
end

# Creates a button element that defines a <tt>submit</tt> button,
Expand Down Expand Up @@ -612,7 +612,7 @@ def button_tag(content_or_options = nil, options = nil, &block)
def image_submit_tag(source, options = {})
options = options.stringify_keys
src = path_to_image(source, skip_pipeline: options.delete("skip_pipeline"))
tag :input, { "type" => "image", "src" => src }.update(options)
tag.input(**{ type: "image", src: src }.update(options.symbolize_keys))
end

# Creates a field set for grouping HTML form elements.
Expand Down Expand Up @@ -970,8 +970,8 @@ def extra_tags_for_form(html_options)

def form_tag_html(html_options)
extra_tags = extra_tags_for_form(html_options)
html = tag(:form, html_options, true) + extra_tags
prevent_content_exfiltration(html)
html = content_tag(:form, extra_tags, html_options).then { |html| html.delete_suffix!("</form>") }
prevent_content_exfiltration(html.html_safe)
end

def form_tag_with_body(html_options, content)
Expand Down
4 changes: 2 additions & 2 deletions actionview/lib/action_view/helpers/tag_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,9 @@ def method_missing(called, *args, escape: true, **options, &block)
# <button <%= tag.attributes id: "call-to-action", disabled: false, aria: { expanded: false } %> class="primary">Get Started!</button>
# # => <button id="call-to-action" aria-expanded="false" class="primary">Get Started!</button>
#
# === Legacy syntax
# === Deprecated: Legacy syntax
#
# The following format is for legacy syntax support. It will be deprecated in future versions of \Rails.
# The following format is for legacy syntax support. It is deprecated, and will be removed in future versions of \Rails.
#
# tag(name, options = nil, open = false, escape = true)
#
Expand Down
4 changes: 2 additions & 2 deletions actionview/lib/action_view/helpers/tags/check_box.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def render
end

include_hidden = options.delete("include_hidden") { true }
checkbox = tag("input", options)
checkbox = tag.input(**options)

if include_hidden
hidden = hidden_field_for_checkbox(options)
Expand Down Expand Up @@ -57,7 +57,7 @@ def checked?(value)
end

def hidden_field_for_checkbox(options)
@unchecked_value ? tag("input", options.slice("name", "disabled", "form").merge!("type" => "hidden", "value" => @unchecked_value, "autocomplete" => "off")) : "".html_safe
@unchecked_value ? tag.input(**options.slice("name", "disabled", "form").merge!("type" => "hidden", "value" => @unchecked_value, "autocomplete" => "off")) : "".html_safe
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion actionview/lib/action_view/helpers/tags/file_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def render

private
def hidden_field_for_multiple_file(options)
tag("input", "name" => options["name"], "type" => "hidden", "value" => "", "autocomplete" => "off")
tag.input(name: options["name"], type: "hidden", value: "", autocomplete: "off")
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion actionview/lib/action_view/helpers/tags/radio_button.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def render
options["value"] = @tag_value
options["checked"] = "checked" if input_checked?(options)
add_default_name_and_id_for_value(@tag_value, options)
tag("input", options)
tag.input(**options)
end

private
Expand Down
2 changes: 1 addition & 1 deletion actionview/lib/action_view/helpers/tags/select_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def select_content_tag(option_tags, options, html_options)
select = content_tag("select", add_options(option_tags, options, value), html_options)

if html_options["multiple"] && options.fetch(:include_hidden, true)
tag("input", disabled: html_options["disabled"], name: html_options["name"], type: "hidden", value: "", autocomplete: "off") + select
tag.input(disabled: html_options["disabled"], name: html_options["name"], type: "hidden", value: "", autocomplete: "off") + select
else
select
end
Expand Down
2 changes: 1 addition & 1 deletion actionview/lib/action_view/helpers/tags/text_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def render
options["type"] ||= field_type
options["value"] = options.fetch("value") { value_before_type_cast } unless field_type == "file"
add_default_name_and_id(options)
tag("input", options)
tag.input(**options)
end

class << self
Expand Down
10 changes: 5 additions & 5 deletions actionview/lib/action_view/helpers/url_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,14 @@ def button_to(name = nil, options = nil, html_options = nil, &block)
content_tag("button", name || url, html_options, &block)
else
html_options["value"] = name || url
tag("input", html_options)
tag.input(**html_options)
end

inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
if params
to_form_params(params).each do |param|
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value],
autocomplete: "off")
inner_tags.safe_concat tag.input(type: "hidden", name: param[:name], value: param[:value],
autocomplete: "off")
end
end
html = content_tag("form", inner_tags, form_options)
Expand Down Expand Up @@ -751,14 +751,14 @@ def token_tag(token = nil, form_options: {})
else
token
end
tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token, autocomplete: "off")
tag.input(type: "hidden", name: request_forgery_protection_token.to_s, value: token, autocomplete: "off")
else
""
end
end

def method_tag(method)
tag("input", type: "hidden", name: "_method", value: method.to_s, autocomplete: "off")
tag.input(type: "hidden", name: "_method", value: method.to_s, autocomplete: "off")
end

# Returns an array of hashes each containing :name and :value keys
Expand Down
Loading

0 comments on commit 5c99edf

Please sign in to comment.