actionview 7.2.3 → 8.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -186
  3. data/README.rdoc +1 -1
  4. data/lib/action_view/base.rb +9 -6
  5. data/lib/action_view/dependency_tracker/erb_tracker.rb +35 -27
  6. data/lib/action_view/dependency_tracker/ruby_tracker.rb +2 -19
  7. data/lib/action_view/dependency_tracker/wildcard_resolver.rb +32 -0
  8. data/lib/action_view/dependency_tracker.rb +1 -0
  9. data/lib/action_view/digestor.rb +2 -6
  10. data/lib/action_view/gem_version.rb +4 -4
  11. data/lib/action_view/helpers/asset_tag_helper.rb +4 -4
  12. data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
  13. data/lib/action_view/helpers/cache_helper.rb +10 -2
  14. data/lib/action_view/helpers/date_helper.rb +1 -8
  15. data/lib/action_view/helpers/form_helper.rb +90 -91
  16. data/lib/action_view/helpers/form_options_helper.rb +19 -20
  17. data/lib/action_view/helpers/form_tag_helper.rb +18 -16
  18. data/lib/action_view/helpers/output_safety_helper.rb +2 -1
  19. data/lib/action_view/helpers/rendering_helper.rb +160 -50
  20. data/lib/action_view/helpers/tag_helper.rb +41 -38
  21. data/lib/action_view/helpers/tags/collection_check_boxes.rb +4 -3
  22. data/lib/action_view/helpers/tags/collection_helpers.rb +1 -2
  23. data/lib/action_view/helpers/text_helper.rb +4 -11
  24. data/lib/action_view/helpers/url_helper.rb +2 -4
  25. data/lib/action_view/layouts.rb +7 -7
  26. data/lib/action_view/render_parser/prism_render_parser.rb +13 -1
  27. data/lib/action_view/render_parser/ripper_render_parser.rb +10 -1
  28. data/lib/action_view/renderer/partial_renderer.rb +2 -2
  29. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -1
  30. data/lib/action_view/renderer/template_renderer.rb +3 -3
  31. data/lib/action_view/rendering.rb +2 -3
  32. data/lib/action_view/template/error.rb +0 -11
  33. data/lib/action_view/template/handlers/erb.rb +37 -45
  34. data/lib/action_view/template/resolver.rb +0 -1
  35. data/lib/action_view/template.rb +3 -14
  36. data/lib/action_view/test_case.rb +1 -0
  37. data/lib/action_view.rb +0 -1
  38. metadata +17 -27
@@ -496,8 +496,7 @@ module ActionView
496
496
  # <option value="France">France</option>
497
497
  # </optgroup>
498
498
  #
499
- # ==== Parameters
500
- #
499
+ # Parameters:
501
500
  # * +grouped_options+ - Accepts a nested array or hash of strings. The first value serves as the
502
501
  # <tt><optgroup></tt> label while the second value must be an array of options. The second value can be a
503
502
  # nested array of text-value pairs. See <tt>options_for_select</tt> for more info.
@@ -508,8 +507,7 @@ module ActionView
508
507
  # which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
509
508
  # as you might have the same option in multiple groups. Each will then get <tt>selected="selected"</tt>.
510
509
  #
511
- # ==== Options
512
- #
510
+ # Options:
513
511
  # * <tt>:prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this
514
512
  # prepends an option with a generic prompt - "Please select" - or the given prompt string.
515
513
  # * <tt>:divider</tt> - the divider for the options groups.
@@ -601,8 +599,7 @@ module ActionView
601
599
 
602
600
  # Returns a string of option tags for the days of the week.
603
601
  #
604
- # ====Options
605
- #
602
+ # Options:
606
603
  # * <tt>:index_as_value</tt> - Defaults to false, set to true to use the indexes from
607
604
  # <tt>I18n.translate("date.day_names")</tt> as the values. By default, Sunday is always 0.
608
605
  # * <tt>:day_format</tt> - The I18n key of the array to use for the weekday options.
@@ -689,7 +686,7 @@ module ActionView
689
686
  # if a +User+ model has a +category_id+ field and in the form no category is selected, no +category_id+ parameter is sent. So,
690
687
  # any strong parameters idiom like:
691
688
  #
692
- # params.require(:user).permit(...)
689
+ # params.expect(user: [...])
693
690
  #
694
691
  # will raise an error since no <tt>{user: ...}</tt> will be present.
695
692
  #
@@ -726,7 +723,7 @@ module ActionView
726
723
  # end
727
724
  #
728
725
  # Sample usage (selecting the associated Author for an instance of Post, <tt>@post</tt>):
729
- # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)
726
+ # collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial)
730
727
  #
731
728
  # If <tt>@post.author_ids</tt> is already <tt>[1]</tt>, this would return:
732
729
  # <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
@@ -739,8 +736,8 @@ module ActionView
739
736
  #
740
737
  # It is also possible to customize the way the elements will be shown by
741
738
  # giving a block to the method:
742
- # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
743
- # b.label { b.check_box }
739
+ # collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
740
+ # b.label { b.checkbox }
744
741
  # end
745
742
  #
746
743
  # The argument passed to the block is a special kind of builder for this
@@ -749,17 +746,17 @@ module ActionView
749
746
  # Using it, you can change the label and check box display order or even
750
747
  # use the label as wrapper, as in the example above.
751
748
  #
752
- # The builder methods <tt>label</tt> and <tt>check_box</tt> also accept
749
+ # The builder methods <tt>label</tt> and <tt>checkbox</tt> also accept
753
750
  # extra HTML options:
754
- # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
755
- # b.label(class: "check_box") { b.check_box(class: "check_box") }
751
+ # collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
752
+ # b.label(class: "checkbox") { b.checkbox(class: "checkbox") }
756
753
  # end
757
754
  #
758
755
  # There are also three special methods available: <tt>object</tt>, <tt>text</tt> and
759
756
  # <tt>value</tt>, which are the current item being rendered, its text and value methods,
760
757
  # respectively. You can use them like this:
761
- # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
762
- # b.label(:"data-value" => b.value) { b.check_box + b.text }
758
+ # collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
759
+ # b.label(:"data-value" => b.value) { b.checkbox + b.text }
763
760
  # end
764
761
  #
765
762
  # ==== Gotcha
@@ -782,9 +779,10 @@ module ActionView
782
779
  #
783
780
  # In the rare case you don't want this hidden field, you can pass the
784
781
  # <tt>include_hidden: false</tt> option to the helper method.
785
- def collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
782
+ def collection_checkboxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
786
783
  Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
787
784
  end
785
+ alias_method :collection_check_boxes, :collection_checkboxes
788
786
 
789
787
  private
790
788
  def option_html_attributes(element)
@@ -900,17 +898,18 @@ module ActionView
900
898
  @template.weekday_select(@object_name, method, objectify_options(options), @default_html_options.merge(html_options))
901
899
  end
902
900
 
903
- # Wraps ActionView::Helpers::FormOptionsHelper#collection_check_boxes for form builders:
901
+ # Wraps ActionView::Helpers::FormOptionsHelper#collection_checkboxes for form builders:
904
902
  #
905
903
  # <%= form_for @post do |f| %>
906
- # <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %>
904
+ # <%= f.collection_checkboxes :author_ids, Author.all, :id, :name_with_initial %>
907
905
  # <%= f.submit %>
908
906
  # <% end %>
909
907
  #
910
908
  # Please refer to the documentation of the base helper for details.
911
- def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
912
- @template.collection_check_boxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
909
+ def collection_checkboxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
910
+ @template.collection_checkboxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
913
911
  end
912
+ alias_method :collection_check_boxes, :collection_checkboxes
914
913
 
915
914
  # Wraps ActionView::Helpers::FormOptionsHelper#collection_radio_buttons for form builders:
916
915
  #
@@ -393,24 +393,24 @@ module ActionView
393
393
  # * Any other key creates standard HTML attributes for the tag.
394
394
  #
395
395
  # ==== Examples
396
- # text_area_tag 'post'
396
+ # textarea_tag 'post'
397
397
  # # => <textarea id="post" name="post"></textarea>
398
398
  #
399
- # text_area_tag 'bio', @user.bio
399
+ # textarea_tag 'bio', @user.bio
400
400
  # # => <textarea id="bio" name="bio">This is my biography.</textarea>
401
401
  #
402
- # text_area_tag 'body', nil, rows: 10, cols: 25
402
+ # textarea_tag 'body', nil, rows: 10, cols: 25
403
403
  # # => <textarea cols="25" id="body" name="body" rows="10"></textarea>
404
404
  #
405
- # text_area_tag 'body', nil, size: "25x10"
405
+ # textarea_tag 'body', nil, size: "25x10"
406
406
  # # => <textarea name="body" id="body" cols="25" rows="10"></textarea>
407
407
  #
408
- # text_area_tag 'description', "Description goes here.", disabled: true
408
+ # textarea_tag 'description', "Description goes here.", disabled: true
409
409
  # # => <textarea disabled="disabled" id="description" name="description">Description goes here.</textarea>
410
410
  #
411
- # text_area_tag 'comment', nil, class: 'comment_input'
411
+ # textarea_tag 'comment', nil, class: 'comment_input'
412
412
  # # => <textarea class="comment_input" id="comment" name="comment"></textarea>
413
- def text_area_tag(name, content = nil, options = {})
413
+ def textarea_tag(name, content = nil, options = {})
414
414
  options = options.stringify_keys
415
415
 
416
416
  if size = options.delete("size")
@@ -422,12 +422,13 @@ module ActionView
422
422
 
423
423
  content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
424
424
  end
425
+ alias_method :text_area_tag, :textarea_tag
425
426
 
426
427
  ##
427
428
  # :call-seq:
428
- # check_box_tag(name, options = {})
429
- # check_box_tag(name, value, options = {})
430
- # check_box_tag(name, value, checked, options = {})
429
+ # checkbox_tag(name, options = {})
430
+ # checkbox_tag(name, value, options = {})
431
+ # checkbox_tag(name, value, checked, options = {})
431
432
  #
432
433
  # Creates a check box form input tag.
433
434
  #
@@ -438,21 +439,21 @@ module ActionView
438
439
  # * Any other key creates standard HTML options for the tag.
439
440
  #
440
441
  # ==== Examples
441
- # check_box_tag 'accept'
442
+ # checkbox_tag 'accept'
442
443
  # # => <input id="accept" name="accept" type="checkbox" value="1" />
443
444
  #
444
- # check_box_tag 'rock', 'rock music'
445
+ # checkbox_tag 'rock', 'rock music'
445
446
  # # => <input id="rock" name="rock" type="checkbox" value="rock music" />
446
447
  #
447
- # check_box_tag 'receive_email', 'yes', true
448
+ # checkbox_tag 'receive_email', 'yes', true
448
449
  # # => <input checked="checked" id="receive_email" name="receive_email" type="checkbox" value="yes" />
449
450
  #
450
- # check_box_tag 'tos', 'yes', false, class: 'accept_tos'
451
+ # checkbox_tag 'tos', 'yes', false, class: 'accept_tos'
451
452
  # # => <input class="accept_tos" id="tos" name="tos" type="checkbox" value="yes" />
452
453
  #
453
- # check_box_tag 'eula', 'accepted', false, disabled: true
454
+ # checkbox_tag 'eula', 'accepted', false, disabled: true
454
455
  # # => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />
455
- def check_box_tag(name, *args)
456
+ def checkbox_tag(name, *args)
456
457
  if args.length >= 4
457
458
  raise ArgumentError, "wrong number of arguments (given #{args.length + 1}, expected 1..4)"
458
459
  end
@@ -462,6 +463,7 @@ module ActionView
462
463
  html_options["checked"] = "checked" if checked
463
464
  tag :input, html_options
464
465
  end
466
+ alias_method :check_box_tag, :checkbox_tag
465
467
 
466
468
  ##
467
469
  # :call-seq:
@@ -38,7 +38,8 @@ module ActionView # :nodoc:
38
38
 
39
39
  # Converts the array to a comma-separated sentence where the last element is
40
40
  # joined by the connector word. This is the html_safe-aware version of
41
- # ActiveSupport's Array#to_sentence.
41
+ # ActiveSupport's {Array#to_sentence}[https://api.rubyonrails.org/classes/Array.html#method-i-to_sentence].
42
+ #
42
43
  def to_sentence(array, options = {})
43
44
  options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
44
45
 
@@ -1,32 +1,140 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionView
4
6
  module Helpers # :nodoc:
5
- # = Action View \Rendering \Helpers
7
+ # # Action View Rendering Helpers
6
8
  #
7
- # Implements methods that allow rendering from a view context.
8
- # In order to use this module, all you need is to implement
9
- # view_renderer that returns an ActionView::Renderer object.
9
+ # Implements methods that allow rendering from a view context. In order to use
10
+ # this module, all you need is to implement view_renderer that returns an
11
+ # ActionView::Renderer object.
10
12
  module RenderingHelper
11
- # Returns the result of a render that's dictated by the options hash. The primary options are:
13
+ # Renders a template and returns the result.
14
+ #
15
+ # Pass the template to render as the first argument. This is shorthand
16
+ # syntax for partial rendering, so the template filename should be
17
+ # prefixed with an underscore. The partial renderer looks for the partial
18
+ # template in the directory of the calling template first.
19
+ #
20
+ # <% # app/views/posts/new.html.erb %>
21
+ # <%= render "form" %>
22
+ # # => renders app/views/posts/_form.html.erb
23
+ #
24
+ # Use the complete view path to render a partial from another directory.
25
+ #
26
+ # <% # app/views/posts/show.html.erb %>
27
+ # <%= render "comments/form" %>
28
+ # # => renders app/views/comments/_form.html.erb
29
+ #
30
+ # Without the rendering mode, the second argument can be a Hash of local
31
+ # variable assignments for the template.
32
+ #
33
+ # <% # app/views/posts/new.html.erb %>
34
+ # <%= render "form", post: Post.new %>
35
+ # # => renders app/views/posts/_form.html.erb
36
+ #
37
+ # If the first argument responds to `render_in`, the template will be rendered
38
+ # by calling `render_in` with the current view context.
39
+ #
40
+ # class Greeting
41
+ # def render_in(view_context)
42
+ # view_context.render html: "<h1>Hello, World</h1>"
43
+ # end
44
+ #
45
+ # def format
46
+ # :html
47
+ # end
48
+ # end
49
+ #
50
+ # <%= render Greeting.new %>
51
+ # # => "<h1>Hello, World</h1>"
52
+ #
53
+ # #### Rendering Mode
54
+ #
55
+ # Pass the rendering mode as first argument to override it.
56
+ #
57
+ # `:partial`
58
+ # : See ActionView::PartialRenderer for details.
59
+ #
60
+ # <%= render partial: "form", locals: { post: Post.new } %>
61
+ # # => renders app/views/posts/_form.html.erb
62
+ #
63
+ # `:file`
64
+ # : Renders the contents of a file. This option should **not** be used with
65
+ # unsanitized user input.
66
+ #
67
+ # <%= render file: "/path/to/some/file" %>
68
+ # # => renders /path/to/some/file
69
+ #
70
+ # `:inline`
71
+ # : Renders an ERB template string.
72
+ #
73
+ # <% name = "World" %>
74
+ # <%= render inline: "<h1>Hello, <%= name %>!</h1>" %>
75
+ # # => renders "<h1>Hello, World!</h1>"
76
+ #
77
+ # `:body`
78
+ # : Renders the provided text, and sets the format as `:text`.
79
+ #
80
+ # <%= render body: "Hello, World!" %>
81
+ # # => renders "Hello, World!"
82
+ #
83
+ # `:plain`
84
+ # : Renders the provided text, and sets the format as `:text`.
85
+ #
86
+ # <%= render plain: "Hello, World!" %>
87
+ # # => renders "Hello, World!"
88
+ #
89
+ # `:html`
90
+ # : Renders the provided HTML string, and sets the format as
91
+ # `:html`. If the string is not `html_safe?`, performs HTML escaping on
92
+ # the string before rendering.
93
+ #
94
+ # <%= render html: "<h1>Hello, World!</h1>".html_safe %>
95
+ # # => renders "<h1>Hello, World!</h1>"
96
+ #
97
+ # <%= render html: "<h1>Hello, World!</h1>" %>
98
+ # # => renders "&lt;h1&gt;Hello, World!&lt;/h1&gt;"
99
+ #
100
+ # `:renderable`
101
+ # : Renders the provided object by calling `render_in` with the current view
102
+ # context. The format is determined by calling `format` on the
103
+ # renderable if it responds to `format`, falling back to `:html` by
104
+ # default.
105
+ #
106
+ # <%= render renderable: Greeting.new %>
107
+ # # => renders "<h1>Hello, World</h1>"
108
+ #
109
+ #
110
+ # #### Options
111
+ #
112
+ # `:locals`
113
+ # : Hash of local variable assignments for the template.
114
+ #
115
+ # <%= render inline: "<h1>Hello, <%= name %>!</h1>", locals: { name: "World" } %>
116
+ # # => renders "<h1>Hello, World!</h1>"
117
+ #
118
+ # `:formats`
119
+ # : Override the current format to render a template for a different format.
120
+ #
121
+ # <% # app/views/posts/show.html.erb %>
122
+ # <%= render template: "posts/content", formats: [:text] %>
123
+ # # => renders app/views/posts/content.text.erb
12
124
  #
13
- # * <tt>:partial</tt> - See ActionView::PartialRenderer.
14
- # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add +:locals+ to pass in those.
15
- # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
16
- # * <tt>:plain</tt> - Renders the text passed in out. Setting the content
17
- # type as <tt>text/plain</tt>.
18
- # * <tt>:html</tt> - Renders the HTML safe string passed in out, otherwise
19
- # performs HTML escape on the string first. Setting the content type as
20
- # <tt>text/html</tt>.
21
- # * <tt>:body</tt> - Renders the text passed in, and inherits the content
22
- # type of <tt>text/plain</tt> from ActionDispatch::Response object.
125
+ # `:variants`
126
+ # : Render a template for a different variant.
23
127
  #
24
- # If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
128
+ # <% # app/views/posts/show.html.erb %>
129
+ # <%= render template: "posts/content", variants: [:tablet] %>
130
+ # # => renders app/views/posts/content.html+tablet.erb
25
131
  #
26
- # If an object responding to +render_in+ is passed, +render_in+ is called on the object,
27
- # passing in the current view context.
132
+ # `:handlers`
133
+ # : Render a template for a different handler.
28
134
  #
29
- # Otherwise, a partial is rendered using the second parameter as the locals hash.
135
+ # <% # app/views/posts/show.html.erb %>
136
+ # <%= render template: "posts/content", handlers: [:builder] %>
137
+ # # => renders app/views/posts/content.html.builder
30
138
  def render(options = {}, locals = {}, &block)
31
139
  case options
32
140
  when Hash
@@ -47,52 +155,54 @@ module ActionView
47
155
  end
48
156
 
49
157
  # Overrides _layout_for in the context object so it supports the case a block is
50
- # passed to a partial. Returns the contents that are yielded to a layout, given a
51
- # name or a block.
158
+ # passed to a partial. Returns the contents that are yielded to a layout, given
159
+ # a name or a block.
52
160
  #
53
- # You can think of a layout as a method that is called with a block. If the user calls
54
- # <tt>yield :some_name</tt>, the block, by default, returns <tt>content_for(:some_name)</tt>.
55
- # If the user calls simply +yield+, the default block returns <tt>content_for(:layout)</tt>.
161
+ # You can think of a layout as a method that is called with a block. If the user
162
+ # calls `yield :some_name`, the block, by default, returns
163
+ # `content_for(:some_name)`. If the user calls simply `yield`, the default block
164
+ # returns `content_for(:layout)`.
56
165
  #
57
166
  # The user can override this default by passing a block to the layout:
58
167
  #
59
- # # The template
60
- # <%= render layout: "my_layout" do %>
61
- # Content
62
- # <% end %>
168
+ # # The template
169
+ # <%= render layout: "my_layout" do %>
170
+ # Content
171
+ # <% end %>
63
172
  #
64
- # # The layout
65
- # <html>
66
- # <%= yield %>
67
- # </html>
173
+ # # The layout
174
+ # <html>
175
+ # <%= yield %>
176
+ # </html>
68
177
  #
69
- # In this case, instead of the default block, which would return <tt>content_for(:layout)</tt>,
70
- # this method returns the block that was passed in to <tt>render :layout</tt>, and the response
178
+ # In this case, instead of the default block, which would return `content_for(:layout)`,
179
+ # this method returns the block that was passed in to `render :layout`, and the response
71
180
  # would be
72
181
  #
73
- # <html>
74
- # Content
75
- # </html>
182
+ # <html>
183
+ # Content
184
+ # </html>
76
185
  #
77
- # Finally, the block can take block arguments, which can be passed in by +yield+:
186
+ # Finally, the block can take block arguments, which can be passed in by
187
+ # `yield`:
78
188
  #
79
- # # The template
80
- # <%= render layout: "my_layout" do |customer| %>
81
- # Hello <%= customer.name %>
82
- # <% end %>
189
+ # # The template
190
+ # <%= render layout: "my_layout" do |customer| %>
191
+ # Hello <%= customer.name %>
192
+ # <% end %>
83
193
  #
84
- # # The layout
85
- # <html>
86
- # <%= yield Struct.new(:name).new("David") %>
87
- # </html>
194
+ # # The layout
195
+ # <html>
196
+ # <%= yield Struct.new(:name).new("David") %>
197
+ # </html>
88
198
  #
89
- # In this case, the layout would receive the block passed into <tt>render :layout</tt>,
199
+ # In this case, the layout would receive the block passed into `render :layout`,
90
200
  # and the struct specified would be passed into the block as an argument. The result
91
201
  # would be
92
202
  #
93
- # <html>
94
- # Hello David
95
- # </html>
203
+ # <html>
204
+ # Hello David
205
+ # </html>
96
206
  #
97
207
  def _layout_for(*args, &block)
98
208
  name = args.first
@@ -48,48 +48,51 @@ module ActionView
48
48
  include CaptureHelper
49
49
  include OutputSafetyHelper
50
50
 
51
- def self.define_element(name, code_generator:, method_name: name.to_s.underscore)
52
- code_generator.define_cached_method(method_name, namespace: :tag_builder) do |batch|
53
- batch.push(<<~RUBY) unless instance_methods.include?(method_name.to_sym)
54
- def #{method_name}(content = nil, escape: true, **options, &block)
55
- tag_string("#{name}", content, options, escape: escape, &block)
56
- end
57
- RUBY
51
+ def deprecated_void_content(name)
52
+ ActionView.deprecator.warn <<~TEXT
53
+ Putting content inside a void element (#{name}) is invalid
54
+ according to the HTML5 spec, and so it is being deprecated
55
+ without replacement. In Rails 8.0, passing content as a
56
+ positional argument will raise, and using a block will have
57
+ no effect.
58
+ TEXT
59
+ end
60
+
61
+ def self.define_element(name, code_generator:, method_name: name)
62
+ return if method_defined?(name)
63
+
64
+ code_generator.class_eval do |batch|
65
+ batch << "\n" <<
66
+ "def #{method_name}(content = nil, escape: true, **options, &block)" <<
67
+ " tag_string(#{name.inspect}, content, options, escape: escape, &block)" <<
68
+ "end"
58
69
  end
59
70
  end
60
71
 
61
- def self.define_void_element(name, code_generator:, method_name: name.to_s.underscore)
62
- code_generator.define_cached_method(method_name, namespace: :tag_builder) do |batch|
63
- batch.push(<<~RUBY)
64
- def #{method_name}(content = nil, escape: true, **options, &block)
65
- if content || block
66
- ActionView.deprecator.warn <<~TEXT
67
- Putting content inside a void element (#{name}) is invalid
68
- according to the HTML5 spec, and so it is being deprecated
69
- without replacement. In Rails 8.0, passing content as a
70
- positional argument will raise, and using a block will have
71
- no effect.
72
- TEXT
73
- tag_string("#{name}", content, options, escape: escape, &block)
74
- else
75
- self_closing_tag_string("#{name}", options, escape, ">")
76
- end
77
- end
78
- RUBY
72
+ def self.define_void_element(name, code_generator:, method_name: name)
73
+ code_generator.class_eval do |batch|
74
+ batch << "\n" <<
75
+ "def #{method_name}(content = nil, escape: true, **options, &block)" <<
76
+ " if content || block" <<
77
+ " deprecated_void_content(#{name.inspect})" <<
78
+ " tag_string(#{name.inspect}, content, options, escape: escape, &block)" <<
79
+ " else" <<
80
+ " self_closing_tag_string(#{name.inspect}, options, escape, '>')" <<
81
+ " end" <<
82
+ "end"
79
83
  end
80
84
  end
81
85
 
82
- def self.define_self_closing_element(name, code_generator:, method_name: name.to_s.underscore)
83
- code_generator.define_cached_method(method_name, namespace: :tag_builder) do |batch|
84
- batch.push(<<~RUBY)
85
- def #{method_name}(content = nil, escape: true, **options, &block)
86
- if content || block
87
- tag_string("#{name}", content, options, escape: escape, &block)
88
- else
89
- self_closing_tag_string("#{name}", options, escape)
90
- end
91
- end
92
- RUBY
86
+ def self.define_self_closing_element(name, code_generator:, method_name: name)
87
+ code_generator.class_eval do |batch|
88
+ batch << "\n" <<
89
+ "def #{method_name}(content = nil, escape: true, **options, &block)" <<
90
+ " if content || block" <<
91
+ " tag_string(#{name.inspect}, content, options, escape: escape, &block)" <<
92
+ " else" <<
93
+ " self_closing_tag_string(#{name.inspect}, options, escape)" <<
94
+ " end" <<
95
+ "end"
93
96
  end
94
97
  end
95
98
 
@@ -110,8 +113,8 @@ module ActionView
110
113
  define_void_element :wbr, code_generator: code_generator
111
114
 
112
115
  define_self_closing_element :animate, code_generator: code_generator
113
- define_self_closing_element :animateMotion, code_generator: code_generator
114
- define_self_closing_element :animateTransform, code_generator: code_generator
116
+ define_self_closing_element :animateMotion, code_generator: code_generator, method_name: :animate_motion
117
+ define_self_closing_element :animateTransform, code_generator: code_generator, method_name: :animate_transform
115
118
  define_self_closing_element :circle, code_generator: code_generator
116
119
  define_self_closing_element :ellipse, code_generator: code_generator
117
120
  define_self_closing_element :line, code_generator: code_generator
@@ -10,12 +10,13 @@ module ActionView
10
10
  include FormOptionsHelper
11
11
 
12
12
  class CheckBoxBuilder < Builder # :nodoc:
13
- def check_box(extra_html_options = {})
13
+ def checkbox(extra_html_options = {})
14
14
  html_options = extra_html_options.merge(@input_html_options)
15
15
  html_options[:multiple] = true
16
16
  html_options[:skip_default_ids] = false
17
- @template_object.check_box(@object_name, @method_name, html_options, @value, nil)
17
+ @template_object.checkbox(@object_name, @method_name, html_options, @value, nil)
18
18
  end
19
+ alias_method :check_box, :checkbox
19
20
  end
20
21
 
21
22
  def render(&block)
@@ -24,7 +25,7 @@ module ActionView
24
25
 
25
26
  private
26
27
  def render_component(builder)
27
- builder.check_box + builder.label
28
+ builder.checkbox + builder.label
28
29
  end
29
30
 
30
31
  def hidden_field_name
@@ -106,8 +106,7 @@ module ActionView
106
106
 
107
107
  def hidden_field
108
108
  hidden_name = @html_options[:name] || hidden_field_name
109
- options = { id: nil, form: @html_options[:form] }
110
- @template_object.hidden_field_tag(hidden_name, "", options)
109
+ @template_object.hidden_field_tag(hidden_name, "", id: nil)
111
110
  end
112
111
 
113
112
  def hidden_field_name
@@ -166,7 +166,7 @@ module ActionView
166
166
  # highlight('You searched for: rails', 'rails', highlighter: '<a href="search?q=\1">\1</a>')
167
167
  # # => "You searched for: <a href=\"search?q=rails\">rails</a>"
168
168
  #
169
- # highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match)) }
169
+ # highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match, match)) }
170
170
  # # => "You searched for: <a href=\"search?q=rails\">rails</a>"
171
171
  #
172
172
  # highlight('<a href="javascript:alert(\'no!\')">ruby</a> on rails', 'rails', sanitize: false)
@@ -260,14 +260,7 @@ module ActionView
260
260
  prefix, first_part = cut_excerpt_part(:first, first_part, separator, options)
261
261
  postfix, second_part = cut_excerpt_part(:second, second_part, separator, options)
262
262
 
263
- affix = [
264
- first_part,
265
- !first_part.empty? ? separator : "",
266
- phrase,
267
- !second_part.empty? ? separator : "",
268
- second_part
269
- ].join.strip
270
-
263
+ affix = [first_part, separator, phrase, separator, second_part].join.strip
271
264
  [prefix, affix, postfix].join
272
265
  end
273
266
 
@@ -278,7 +271,7 @@ module ActionView
278
271
  #
279
272
  # The word will be pluralized using rules defined for the locale
280
273
  # (you must define your own inflection rules for languages other than English).
281
- # See ActiveSupport::Inflector.pluralize.
274
+ # See ActiveSupport::Inflector.pluralize
282
275
  #
283
276
  # pluralize(1, 'person')
284
277
  # # => "1 person"
@@ -353,7 +346,7 @@ module ActionView
353
346
  # ==== Options
354
347
  # * <tt>:sanitize</tt> - If +false+, does not sanitize +text+.
355
348
  # * <tt>:sanitize_options</tt> - Any extra options you want appended to the sanitize.
356
- # * <tt>:wrapper_tag</tt> - String representing the wrapper tag, defaults to <tt>"p"</tt>.
349
+ # * <tt>:wrapper_tag</tt> - String representing the wrapper tag, defaults to <tt>"p"</tt>
357
350
  #
358
351
  # ==== Examples
359
352
  # my_text = "Here is some basic text...\n...with a line break."