diff options
Diffstat (limited to 'actionview/lib/action_view')
38 files changed, 204 insertions, 202 deletions
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb index 637c8e7708..d41fe2a608 100644 --- a/actionview/lib/action_view/base.rb +++ b/actionview/lib/action_view/base.rb @@ -3,11 +3,11 @@ require "active_support/core_ext/module/attr_internal" require "active_support/core_ext/module/attribute_accessors" require "active_support/ordered_options" -require_relative "log_subscriber" -require_relative "helpers" -require_relative "context" -require_relative "template" -require_relative "lookup_context" +require "action_view/log_subscriber" +require "action_view/helpers" +require "action_view/context" +require "action_view/template" +require "action_view/lookup_context" module ActionView #:nodoc: # = Action View Base diff --git a/actionview/lib/action_view/context.rb b/actionview/lib/action_view/context.rb index e1b02fbde4..665a9e3171 100644 --- a/actionview/lib/action_view/context.rb +++ b/actionview/lib/action_view/context.rb @@ -19,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 @@ -29,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 02bd0545c2..182f6e2eef 100644 --- a/actionview/lib/action_view/dependency_tracker.rb +++ b/actionview/lib/action_view/dependency_tracker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "concurrent/map" -require_relative "path_set" +require "action_view/path_set" module ActionView class DependencyTracker # :nodoc: diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index e404ebb6b6..dfd62bdcfd 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "concurrent/map" -require_relative "dependency_tracker" +require "action_view/dependency_tracker" require "monitor" module ActionView diff --git a/actionview/lib/action_view/gem_version.rb b/actionview/lib/action_view/gem_version.rb index ed92490be7..ff7f2bb853 100644 --- a/actionview/lib/action_view/gem_version.rb +++ b/actionview/lib/action_view/gem_version.rb @@ -10,7 +10,7 @@ module ActionView MAJOR = 5 MINOR = 2 TINY = 0 - PRE = "alpha" + PRE = "beta2" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end diff --git a/actionview/lib/action_view/helpers/active_model_helper.rb b/actionview/lib/action_view/helpers/active_model_helper.rb index f1ef715710..e41a95d2ce 100644 --- a/actionview/lib/action_view/helpers/active_model_helper.rb +++ b/actionview/lib/action_view/helpers/active_model_helper.rb @@ -17,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, *) @@ -43,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 bc2713d13e..da630129cb 100644 --- a/actionview/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb @@ -2,8 +2,10 @@ require "active_support/core_ext/array/extract_options" require "active_support/core_ext/hash/keys" -require_relative "asset_url_helper" -require_relative "tag_helper" +require "active_support/core_ext/object/inclusion" +require "active_support/core_ext/object/try" +require "action_view/helpers/asset_url_helper" +require "action_view/helpers/tag_helper" module ActionView # = Action View Asset Tag Helpers @@ -37,6 +39,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 @@ -77,12 +82,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) && request + + sources_tags end # Returns a stylesheet link tag for the sources specified as arguments. If @@ -92,6 +105,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" /> # @@ -113,14 +129,22 @@ 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) && request + + sources_tags end # Returns a link tag that browsers and feed readers can use to auto-detect @@ -199,6 +223,67 @@ module ActionView }.merge!(options.symbolize_keys)) end + # Returns a link tag that browsers can use to preload the +source+. + # The +source+ can be the path of an resource managed by asset pipeline, + # a full path or an URI. + # + # ==== Options + # + # * <tt>:type</tt> - Override the auto-generated mime type, defaults to the mime type for +source+ extension. + # * <tt>:as</tt> - Override the auto-generated value for as attribute, calculated using +source+ extension and mime type. + # * <tt>:crossorigin</tt> - Specify the crossorigin attribute, required to load cross-origin resources. + # * <tt>:nopush</tt> - Specify if the use of server push is not desired for the resource. Defaults to +false+. + # + # ==== Examples + # + # preload_link_tag("custom_theme.css") + # # => <link rel="preload" href="/assets/custom_theme.css" as="style" type="text/css" /> + # + # preload_link_tag("/videos/video.webm") + # # => <link rel="preload" href="/videos/video.mp4" as="video" type="video/webm" /> + # + # preload_link_tag(post_path(format: :json), as: "fetch") + # # => <link rel="preload" href="/posts.json" as="fetch" type="application/json" /> + # + # preload_link_tag("worker.js", as: "worker") + # # => <link rel="preload" href="/assets/worker.js" as="worker" type="text/javascript" /> + # + # preload_link_tag("//example.com/font.woff2") + # # => <link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="anonymous"/> + # + # preload_link_tag("//example.com/font.woff2", crossorigin: "use-credentials") + # # => <link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="use-credentials" /> + # + # preload_link_tag("/media/audio.ogg", nopush: true) + # # => <link rel="preload" href="/media/audio.ogg" as="audio" type="audio/ogg" /> + # + def preload_link_tag(source, options = {}) + href = asset_path(source, skip_pipeline: options.delete(:skip_pipeline)) + extname = File.extname(source).downcase.delete(".") + mime_type = options.delete(:type) || Template::Types[extname].try(:to_s) + as_type = options.delete(:as) || resolve_link_as(extname, mime_type) + crossorigin = options.delete(:crossorigin) + crossorigin = "anonymous" if crossorigin == true || (crossorigin.blank? && as_type == "font") + nopush = options.delete(:nopush) || false + + link_tag = tag.link({ + rel: "preload", + href: href, + as: as_type, + type: mime_type, + crossorigin: crossorigin + }.merge!(options.symbolize_keys)) + + early_hints_link = "<#{href}>; rel=preload; as=#{as_type}" + early_hints_link += "; type=#{mime_type}" if mime_type + early_hints_link += "; crossorigin=#{crossorigin}" if crossorigin + early_hints_link += "; nopush" if nopush + + request.send_early_hints("Link" => early_hints_link) if respond_to?(:request) && request + + link_tag + end + # Returns an HTML image tag for the +source+. The +source+ can be a full # path, a file or an Active Storage attachment. # @@ -395,6 +480,18 @@ module ActionView raise ArgumentError, "Cannot pass a :size option with a :height or :width option" end end + + def resolve_link_as(extname, mime_type) + if extname == "js" + "script" + elsif extname == "css" + "style" + elsif extname == "vtt" + "track" + elsif (type = mime_type.to_s.split("/")[0]) && type.in?(%w(audio video font)) + type + end + end end end end diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb index a4dcfc9a6c..f7690104ee 100644 --- a/actionview/lib/action_view/helpers/asset_url_helper.rb +++ b/actionview/lib/action_view/helpers/asset_url_helper.rb @@ -324,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)) @@ -351,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)) @@ -381,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)) @@ -407,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)) @@ -433,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)) @@ -458,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/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index 642bd0fec6..09040ccbc4 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "date" -require_relative "tag_helper" +require "action_view/helpers/tag_helper" require "active_support/core_ext/array/extract_options" require "active_support/core_ext/date/conversions" require "active_support/core_ext/hash/slice" diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb index 6702c65ccb..6185aa133f 100644 --- a/actionview/lib/action_view/helpers/form_helper.rb +++ b/actionview/lib/action_view/helpers/form_helper.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true require "cgi" -require_relative "date_helper" -require_relative "tag_helper" -require_relative "form_tag_helper" -require_relative "active_model_helper" -require_relative "../model_naming" -require_relative "../record_identifier" +require "action_view/helpers/date_helper" +require "action_view/helpers/tag_helper" +require "action_view/helpers/form_tag_helper" +require "action_view/helpers/active_model_helper" +require "action_view/model_naming" +require "action_view/record_identifier" require "active_support/core_ext/module/attribute_accessors" require "active_support/core_ext/hash/slice" require "active_support/core_ext/string/output_safety" @@ -478,6 +478,8 @@ module ActionView mattr_accessor :form_with_generates_remote_forms, default: true + mattr_accessor :form_with_generates_ids, default: false + # Creates a form tag based on mixing URLs, scopes, or models. # # # Using just a URL: @@ -640,16 +642,6 @@ module ActionView # # Where <tt>@document = Document.find(params[:id])</tt>. # - # When using labels +form_with+ requires setting the id on the field being - # labelled: - # - # <%= form_with(model: @post) do |form| %> - # <%= form.label :title %> - # <%= form.text_field :title, id: :post_title %> - # <% end %> - # - # See +label+ for more on how the +for+ attribute is derived. - # # === Mixing with other form helpers # # While +form_with+ uses a FormBuilder object it's possible to mix and @@ -746,7 +738,7 @@ module ActionView # end def form_with(model: nil, scope: nil, url: nil, format: nil, **options) options[:allow_method_names_outside_object] = true - options[:skip_default_ids] = true + options[:skip_default_ids] = !form_with_generates_ids if model url ||= polymorphic_path(model, format: format) @@ -1044,16 +1036,6 @@ module ActionView # or model is yielded, so any generated field names are prefixed with # either the passed scope or the scope inferred from the <tt>:model</tt>. # - # When using labels +fields+ requires setting the id on the field being - # labelled: - # - # <%= fields :comment do |fields| %> - # <%= fields.label :body %> - # <%= fields.text_field :body, id: :comment_body %> - # <% end %> - # - # See +label+ for more on how the +for+ attribute is derived. - # # === Mixing with other form helpers # # While +form_with+ uses a FormBuilder object it's possible to mix and @@ -1072,7 +1054,7 @@ module ActionView # FormOptionsHelper#collection_select and DateHelper#datetime_select. def fields(scope = nil, model: nil, **options, &block) options[:allow_method_names_outside_object] = true - options[:skip_default_ids] = true + options[:skip_default_ids] = !form_with_generates_ids if model scope ||= model_name_from_record_or_class(model).param_key @@ -1985,7 +1967,7 @@ module ActionView # See the docs for the <tt>ActionView::FormHelper.fields</tt> helper method. def fields(scope = nil, model: nil, **options, &block) options[:allow_method_names_outside_object] = true - options[:skip_default_ids] = true + options[:skip_default_ids] = !FormHelper.form_with_generates_ids convert_to_legacy_options(options) diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb index 1517abfad0..02a44477c1 100644 --- a/actionview/lib/action_view/helpers/form_options_helper.rb +++ b/actionview/lib/action_view/helpers/form_options_helper.rb @@ -2,7 +2,7 @@ require "cgi" require "erb" -require_relative "form_helper" +require "action_view/helpers/form_helper" require "active_support/core_ext/string/output_safety" require "active_support/core_ext/array/extract_options" require "active_support/core_ext/array/wrap" @@ -279,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 31a1f8be8c..e86e18dd78 100644 --- a/actionview/lib/action_view/helpers/form_tag_helper.rb +++ b/actionview/lib/action_view/helpers/form_tag_helper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "cgi" -require_relative "tag_helper" +require "action_view/helpers/tag_helper" require "active_support/core_ext/string/output_safety" require "active_support/core_ext/module/attribute_accessors" @@ -115,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> @@ -394,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" /> diff --git a/actionview/lib/action_view/helpers/javascript_helper.rb b/actionview/lib/action_view/helpers/javascript_helper.rb index 11eefe0ee0..dd2cd57ac3 100644 --- a/actionview/lib/action_view/helpers/javascript_helper.rb +++ b/actionview/lib/action_view/helpers/javascript_helper.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "tag_helper" +require "action_view/helpers/tag_helper" module ActionView module Helpers #:nodoc: diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb index a64d7e396e..a6cec3f69c 100644 --- a/actionview/lib/action_view/helpers/tag_helper.rb +++ b/actionview/lib/action_view/helpers/tag_helper.rb @@ -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="["Chicago","IL"]"></div> # # The generated attributes are escaped by default. This can be disabled using diff --git a/actionview/lib/action_view/helpers/tags/base.rb b/actionview/lib/action_view/helpers/tags/base.rb index 8934a9894c..fed908fcdb 100644 --- a/actionview/lib/action_view/helpers/tags/base.rb +++ b/actionview/lib/action_view/helpers/tags/base.rb @@ -97,7 +97,7 @@ module ActionView index = name_and_id_index(options) options["name"] = options.fetch("name") { tag_name(options["multiple"], index) } - unless skip_default_ids? + if generate_ids? options["id"] = options.fetch("id") { tag_id(index) } if namespace = options.delete("namespace") options["id"] = options["id"] ? "#{namespace}_#{options['id']}" : namespace @@ -183,8 +183,8 @@ module ActionView end end - def skip_default_ids? - @skip_default_ids + def generate_ids? + !@skip_default_ids end end end diff --git a/actionview/lib/action_view/helpers/tags/check_box.rb b/actionview/lib/action_view/helpers/tags/check_box.rb index 6b34dfef90..4327e07cae 100644 --- a/actionview/lib/action_view/helpers/tags/check_box.rb +++ b/actionview/lib/action_view/helpers/tags/check_box.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "checkable" +require "action_view/helpers/tags/checkable" module ActionView module Helpers 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 91c1135d20..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,6 +1,6 @@ # frozen_string_literal: true -require_relative "collection_helpers" +require "action_view/helpers/tags/collection_helpers" module ActionView module Helpers 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 0b0482f74e..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,6 +1,6 @@ # frozen_string_literal: true -require_relative "collection_helpers" +require "action_view/helpers/tags/collection_helpers" module ActionView module Helpers diff --git a/actionview/lib/action_view/helpers/tags/label.rb b/actionview/lib/action_view/helpers/tags/label.rb index 56b48bbd62..02bd099784 100644 --- a/actionview/lib/action_view/helpers/tags/label.rb +++ b/actionview/lib/action_view/helpers/tags/label.rb @@ -75,10 +75,6 @@ module ActionView def render_component(builder) builder.translation end - - def skip_default_ids? - false # The id is used as the `for` attribute. - end end end end diff --git a/actionview/lib/action_view/helpers/tags/radio_button.rb b/actionview/lib/action_view/helpers/tags/radio_button.rb index 3cfdcbea3f..621db2b1b5 100644 --- a/actionview/lib/action_view/helpers/tags/radio_button.rb +++ b/actionview/lib/action_view/helpers/tags/radio_button.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "checkable" +require "action_view/helpers/tags/checkable" module ActionView module Helpers diff --git a/actionview/lib/action_view/helpers/tags/text_area.rb b/actionview/lib/action_view/helpers/tags/text_area.rb index 9c162b59f5..4519082ff6 100644 --- a/actionview/lib/action_view/helpers/tags/text_area.rb +++ b/actionview/lib/action_view/helpers/tags/text_area.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "placeholderable" +require "action_view/helpers/tags/placeholderable" module ActionView module Helpers diff --git a/actionview/lib/action_view/helpers/tags/text_field.rb b/actionview/lib/action_view/helpers/tags/text_field.rb index 3553942048..d92967e212 100644 --- a/actionview/lib/action_view/helpers/tags/text_field.rb +++ b/actionview/lib/action_view/helpers/tags/text_field.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "placeholderable" +require "action_view/helpers/tags/placeholderable" module ActionView module Helpers diff --git a/actionview/lib/action_view/helpers/text_helper.rb b/actionview/lib/action_view/helpers/text_helper.rb index 3044a2c0ef..84d38aa416 100644 --- a/actionview/lib/action_view/helpers/text_helper.rb +++ b/actionview/lib/action_view/helpers/text_helper.rb @@ -422,7 +422,7 @@ module ActionView def to_s value = @values[@index].to_s @index = next_index - return value + value end private @@ -446,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 e663892592..1860bc4732 100644 --- a/actionview/lib/action_view/helpers/translation_helper.rb +++ b/actionview/lib/action_view/helpers/translation_helper.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "tag_helper" +require "action_view/helpers/tag_helper" require "active_support/core_ext/string/access" require "i18n/exceptions" diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 2d5aac6dc7..889562c478 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "javascript_helper" +require "action_view/helpers/javascript_helper" require "active_support/core_ext/array/access" require "active_support/core_ext/hash/keys" require "active_support/core_ext/string/output_safety" @@ -139,6 +139,11 @@ module ActionView # link_to "Profiles", controller: "profiles" # # => <a href="/profiles">Profiles</a> # + # When name is +nil+ the href is presented instead + # + # link_to nil, "http://example.com" + # # => <a href="http://www.example.com">http://www.example.com</a> + # # You can use a block as well if your link target is hard to fit into the name parameter. ERB example: # # <%= link_to(@profile) do %> @@ -589,10 +594,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 b11ef6e133..3e6d352c15 100644 --- a/actionview/lib/action_view/layouts.rb +++ b/actionview/lib/action_view/layouts.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "rendering" +require "action_view/rendering" require "active_support/core_ext/module/redefine_method" module ActionView diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb index acc0f57f1d..0e56eca35c 100644 --- a/actionview/lib/action_view/lookup_context.rb +++ b/actionview/lib/action_view/lookup_context.rb @@ -3,7 +3,7 @@ require "concurrent/map" require "active_support/core_ext/module/remove_method" require "active_support/core_ext/module/attribute_accessors" -require_relative "template/resolver" +require "action_view/template/resolver" module ActionView # = Action View Lookup Context diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb index b22347c55c..73dfb267bb 100644 --- a/actionview/lib/action_view/railtie.rb +++ b/actionview/lib/action_view/railtie.rb @@ -22,8 +22,15 @@ module ActionView initializer "action_view.form_with_generates_remote_forms" do |app| ActiveSupport.on_load(:action_view) do form_with_generates_remote_forms = app.config.action_view.delete(:form_with_generates_remote_forms) - unless form_with_generates_remote_forms.nil? - ActionView::Helpers::FormHelper.form_with_generates_remote_forms = form_with_generates_remote_forms + ActionView::Helpers::FormHelper.form_with_generates_remote_forms = form_with_generates_remote_forms + end + end + + initializer "action_view.form_with_generates_ids" do |app| + ActiveSupport.on_load(:action_view) do + form_with_generates_ids = app.config.action_view.delete(:form_with_generates_ids) + unless form_with_generates_ids.nil? + ActionView::Helpers::FormHelper.form_with_generates_ids = form_with_generates_ids end end end diff --git a/actionview/lib/action_view/record_identifier.rb b/actionview/lib/action_view/record_identifier.rb index b34a793c89..1310a1ce0a 100644 --- a/actionview/lib/action_view/record_identifier.rb +++ b/actionview/lib/action_view/record_identifier.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "active_support/core_ext/module" -require_relative "model_naming" +require "action_view/model_naming" module ActionView # RecordIdentifier encapsulates methods used by various ActionView helpers diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index beb0a18b65..5b40af4f2f 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "concurrent/map" -require_relative "partial_renderer/collection_caching" +require "action_view/renderer/partial_renderer/collection_caching" module ActionView class PartialIteration diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb index 2648f9153f..4e5fdfbb2d 100644 --- a/actionview/lib/action_view/rendering.rb +++ b/actionview/lib/action_view/rendering.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "view_paths" +require "action_view/view_paths" module ActionView # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request, @@ -75,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 @@ -92,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) @@ -114,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 @@ -137,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/template/error.rb b/actionview/lib/action_view/template/error.rb index 2b0b25817b..4e3c02e05e 100644 --- a/actionview/lib/action_view/template/error.rb +++ b/actionview/lib/action_view/template/error.rb @@ -10,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/erb.rb b/actionview/lib/action_view/template/handlers/erb.rb index c41de62e52..b7b749f9da 100644 --- a/actionview/lib/action_view/template/handlers/erb.rb +++ b/actionview/lib/action_view/template/handlers/erb.rb @@ -3,11 +3,8 @@ 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. 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 00c7d7cc7d..0000000000 --- a/actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -::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/erubis.rb b/actionview/lib/action_view/template/handlers/erb/erubis.rb deleted file mode 100644 index dc3bf1ff27..0000000000 --- a/actionview/lib/action_view/template/handlers/erb/erubis.rb +++ /dev/null @@ -1,83 +0,0 @@ -# frozen_string_literal: true - -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/resolver.rb b/actionview/lib/action_view/template/resolver.rb index a58d375293..5a86f10973 100644 --- a/actionview/lib/action_view/template/resolver.rb +++ b/actionview/lib/action_view/template/resolver.rb @@ -3,7 +3,7 @@ require "pathname" require "active_support/core_ext/class" require "active_support/core_ext/module/attribute_accessors" -require_relative "../template" +require "action_view/template" require "thread" require "concurrent/map" diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb index 93be2be2d1..e1cbae5845 100644 --- a/actionview/lib/action_view/test_case.rb +++ b/actionview/lib/action_view/test_case.rb @@ -270,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 && @@ -286,7 +286,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 routes && diff --git a/actionview/lib/action_view/testing/resolvers.rb b/actionview/lib/action_view/testing/resolvers.rb index 92fdb24a5e..68186c3bf8 100644 --- a/actionview/lib/action_view/testing/resolvers.rb +++ b/actionview/lib/action_view/testing/resolvers.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "../template/resolver" +require "action_view/template/resolver" module ActionView #:nodoc: # Use FixtureResolver in your tests to simulate the presence of files on the |