actionview 6.1.7.2 → 7.0.6

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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +268 -254
  3. data/MIT-LICENSE +1 -0
  4. data/README.rdoc +2 -2
  5. data/lib/action_view/base.rb +4 -7
  6. data/lib/action_view/buffers.rb +2 -2
  7. data/lib/action_view/cache_expiry.rb +46 -32
  8. data/lib/action_view/dependency_tracker/erb_tracker.rb +154 -0
  9. data/lib/action_view/dependency_tracker/ripper_tracker.rb +59 -0
  10. data/lib/action_view/dependency_tracker.rb +6 -147
  11. data/lib/action_view/digestor.rb +7 -4
  12. data/lib/action_view/flows.rb +4 -4
  13. data/lib/action_view/gem_version.rb +5 -5
  14. data/lib/action_view/helpers/active_model_helper.rb +2 -2
  15. data/lib/action_view/helpers/asset_tag_helper.rb +95 -39
  16. data/lib/action_view/helpers/asset_url_helper.rb +16 -16
  17. data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
  18. data/lib/action_view/helpers/cache_helper.rb +52 -3
  19. data/lib/action_view/helpers/capture_helper.rb +4 -4
  20. data/lib/action_view/helpers/controller_helper.rb +2 -2
  21. data/lib/action_view/helpers/csp_helper.rb +1 -1
  22. data/lib/action_view/helpers/csrf_helper.rb +2 -2
  23. data/lib/action_view/helpers/date_helper.rb +111 -43
  24. data/lib/action_view/helpers/debug_helper.rb +3 -1
  25. data/lib/action_view/helpers/form_helper.rb +211 -85
  26. data/lib/action_view/helpers/form_options_helper.rb +70 -33
  27. data/lib/action_view/helpers/form_tag_helper.rb +150 -53
  28. data/lib/action_view/helpers/javascript_helper.rb +3 -5
  29. data/lib/action_view/helpers/number_helper.rb +17 -16
  30. data/lib/action_view/helpers/output_safety_helper.rb +4 -4
  31. data/lib/action_view/helpers/rendering_helper.rb +5 -6
  32. data/lib/action_view/helpers/sanitize_helper.rb +3 -3
  33. data/lib/action_view/helpers/tag_helper.rb +37 -8
  34. data/lib/action_view/helpers/tags/base.rb +5 -25
  35. data/lib/action_view/helpers/tags/check_box.rb +1 -1
  36. data/lib/action_view/helpers/tags/collection_select.rb +1 -1
  37. data/lib/action_view/helpers/tags/file_field.rb +16 -0
  38. data/lib/action_view/helpers/tags/select.rb +1 -1
  39. data/lib/action_view/helpers/tags/time_field.rb +10 -1
  40. data/lib/action_view/helpers/tags/weekday_select.rb +28 -0
  41. data/lib/action_view/helpers/tags.rb +3 -2
  42. data/lib/action_view/helpers/text_helper.rb +25 -14
  43. data/lib/action_view/helpers/translation_helper.rb +12 -43
  44. data/lib/action_view/helpers/url_helper.rb +194 -123
  45. data/lib/action_view/helpers.rb +25 -25
  46. data/lib/action_view/layouts.rb +7 -4
  47. data/lib/action_view/lookup_context.rb +33 -52
  48. data/lib/action_view/model_naming.rb +2 -2
  49. data/lib/action_view/path_set.rb +16 -22
  50. data/lib/action_view/railtie.rb +19 -7
  51. data/lib/action_view/record_identifier.rb +1 -1
  52. data/lib/action_view/render_parser.rb +188 -0
  53. data/lib/action_view/renderer/abstract_renderer.rb +2 -2
  54. data/lib/action_view/renderer/partial_renderer.rb +1 -35
  55. data/lib/action_view/renderer/renderer.rb +4 -4
  56. data/lib/action_view/renderer/streaming_template_renderer.rb +3 -3
  57. data/lib/action_view/renderer/template_renderer.rb +6 -2
  58. data/lib/action_view/rendering.rb +3 -3
  59. data/lib/action_view/ripper_ast_parser.rb +198 -0
  60. data/lib/action_view/routing_url_for.rb +8 -5
  61. data/lib/action_view/template/error.rb +108 -13
  62. data/lib/action_view/template/handlers/erb.rb +6 -0
  63. data/lib/action_view/template/handlers.rb +3 -3
  64. data/lib/action_view/template/html.rb +3 -3
  65. data/lib/action_view/template/inline.rb +3 -3
  66. data/lib/action_view/template/raw_file.rb +3 -3
  67. data/lib/action_view/template/resolver.rb +89 -314
  68. data/lib/action_view/template/text.rb +3 -3
  69. data/lib/action_view/template/types.rb +14 -12
  70. data/lib/action_view/template.rb +18 -2
  71. data/lib/action_view/template_details.rb +66 -0
  72. data/lib/action_view/template_path.rb +64 -0
  73. data/lib/action_view/test_case.rb +7 -3
  74. data/lib/action_view/testing/resolvers.rb +11 -12
  75. data/lib/action_view/unbound_template.rb +33 -7
  76. data/lib/action_view/version.rb +1 -1
  77. data/lib/action_view/view_paths.rb +4 -4
  78. data/lib/action_view.rb +2 -3
  79. data/lib/assets/compiled/rails-ujs.js +36 -5
  80. metadata +23 -16
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "cgi"
4
- require "action_view/helpers/tag_helper"
4
+ require "action_view/helpers/url_helper"
5
+ require "action_view/helpers/text_helper"
5
6
  require "active_support/core_ext/string/output_safety"
6
7
  require "active_support/core_ext/module/attribute_accessors"
7
- require "active_support/core_ext/symbol/starts_ends_with"
8
8
 
9
9
  module ActionView
10
10
  # = Action View Form Tag Helpers
11
- module Helpers #:nodoc:
11
+ module Helpers # :nodoc:
12
12
  # Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like
13
13
  # FormHelper does. Instead, you provide the names and values manually.
14
14
  #
@@ -63,6 +63,9 @@ module ActionView
63
63
  # <%= form_tag('/posts', remote: true) %>
64
64
  # # => <form action="/posts" method="post" data-remote="true">
65
65
  #
66
+ # form_tag(false, method: :get)
67
+ # # => <form method="get">
68
+ #
66
69
  # form_tag('http://far.away.com/form', authenticity_token: false)
67
70
  # # form without authenticity token
68
71
  #
@@ -78,6 +81,65 @@ module ActionView
78
81
  end
79
82
  end
80
83
 
84
+ # Generate an HTML <tt>id</tt> attribute value for the given name and
85
+ # field combination
86
+ #
87
+ # Return the value generated by the <tt>FormBuilder</tt> for the given
88
+ # attribute name.
89
+ #
90
+ # <%= label_tag :post, :title %>
91
+ # <%= text_field_tag :post, :title, aria: { describedby: field_id(:post, :title, :error) } %>
92
+ # <%= tag.span("is blank", id: field_id(:post, :title, :error) %>
93
+ #
94
+ # In the example above, the <tt><input type="text"></tt> element built by
95
+ # the call to <tt>text_field_tag</tt> declares an
96
+ # <tt>aria-describedby</tt> attribute referencing the <tt><span></tt>
97
+ # element, sharing a common <tt>id</tt> root (<tt>post_title</tt>, in this
98
+ # case).
99
+ def field_id(object_name, method_name, *suffixes, index: nil, namespace: nil)
100
+ if object_name.respond_to?(:model_name)
101
+ object_name = object_name.model_name.singular
102
+ end
103
+
104
+ sanitized_object_name = object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").delete_suffix("_")
105
+
106
+ sanitized_method_name = method_name.to_s.delete_suffix("?")
107
+
108
+ [
109
+ namespace,
110
+ sanitized_object_name.presence,
111
+ (index unless sanitized_object_name.empty?),
112
+ sanitized_method_name,
113
+ *suffixes,
114
+ ].tap(&:compact!).join("_")
115
+ end
116
+
117
+ # Generate an HTML <tt>name</tt> attribute value for the given name and
118
+ # field combination
119
+ #
120
+ # Return the value generated by the <tt>FormBuilder</tt> for the given
121
+ # attribute name.
122
+ #
123
+ # <%= text_field_tag :post, :title, name: field_name(:post, :title, :subtitle) %>
124
+ # <%# => <input type="text" name="post[title][subtitle]">
125
+ #
126
+ # <%= text_field_tag :post, :tag, name: field_name(:post, :tag, multiple: true) %>
127
+ # <%# => <input type="text" name="post[tag][]">
128
+ #
129
+ def field_name(object_name, method_name, *method_names, multiple: false, index: nil)
130
+ names = method_names.map! { |name| "[#{name}]" }.join
131
+
132
+ # a little duplication to construct fewer strings
133
+ case
134
+ when object_name.blank?
135
+ "#{method_name}#{names}#{multiple ? "[]" : ""}"
136
+ when index
137
+ "#{object_name}[#{index}][#{method_name}]#{names}#{multiple ? "[]" : ""}"
138
+ else
139
+ "#{object_name}[#{method_name}]#{names}#{multiple ? "[]" : ""}"
140
+ end
141
+ end
142
+
81
143
  # Creates a dropdown selection box, or if the <tt>:multiple</tt> option is set to true, a multiple
82
144
  # choice selection box.
83
145
  #
@@ -167,8 +229,8 @@ module ActionView
167
229
  # * <tt>:size</tt> - The number of visible characters that will fit in the input.
168
230
  # * <tt>:maxlength</tt> - The maximum number of characters that the browser will allow the user to enter.
169
231
  # * <tt>:placeholder</tt> - The text contained in the field by default which is removed when the field receives focus.
170
- # If set to true, use a translation is found in the current I18n locale
171
- # (through helpers.placeholders.<modelname>.<attribute>).
232
+ # If set to true, use the translation found in the current I18n locale
233
+ # (through helpers.placeholder.<modelname>.<attribute>).
172
234
  # * Any other key creates standard HTML attributes for the tag.
173
235
  #
174
236
  # ==== Examples
@@ -232,14 +294,14 @@ module ActionView
232
294
  #
233
295
  # ==== Examples
234
296
  # hidden_field_tag 'tags_list'
235
- # # => <input id="tags_list" name="tags_list" type="hidden" />
297
+ # # => <input type="hidden" name="tags_list" id="tags_list" autocomplete="off" />
236
298
  #
237
299
  # hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
238
- # # => <input id="token" name="token" type="hidden" value="VUBJKB23UIVI1UU1VOBVI@" />
300
+ # # => <input type="hidden" name="token" id="token" value="VUBJKB23UIVI1UU1VOBVI@" autocomplete="off" />
239
301
  #
240
302
  # hidden_field_tag 'collected_input', '', onchange: "alert('Input collected!')"
241
- # # => <input id="collected_input" name="collected_input" onchange="alert('Input collected!')"
242
- # # type="hidden" value="" />
303
+ # # => <input type="hidden" name="collected_input" id="collected_input"
304
+ # value="" onchange="alert(&#39;Input collected!&#39;)" autocomplete="off" />
243
305
  def hidden_field_tag(name, value = nil, options = {})
244
306
  text_field_tag(name, value, options.merge(type: :hidden, autocomplete: "off"))
245
307
  end
@@ -417,16 +479,6 @@ module ActionView
417
479
  # * <tt>:disabled</tt> - If true, the user will not be able to use this input.
418
480
  # * Any other key creates standard HTML options for the tag.
419
481
  #
420
- # ==== Data attributes
421
- #
422
- # * <tt>confirm: 'question?'</tt> - If present the unobtrusive JavaScript
423
- # drivers will provide a prompt with the question specified. If the user accepts,
424
- # the form is processed normally, otherwise no action is taken.
425
- # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
426
- # disabled version of the submit button when the form is submitted. This feature is
427
- # provided by the unobtrusive JavaScript driver. To disable this feature for a single submit tag
428
- # pass <tt>:data => { disable_with: false }</tt> Defaults to value attribute.
429
- #
430
482
  # ==== Examples
431
483
  # submit_tag
432
484
  # # => <input name="commit" data-disable-with="Save changes" type="submit" value="Save changes" />
@@ -437,15 +489,28 @@ module ActionView
437
489
  # submit_tag "Save edits", disabled: true
438
490
  # # => <input disabled="disabled" name="commit" data-disable-with="Save edits" type="submit" value="Save edits" />
439
491
  #
440
- # submit_tag "Complete sale", data: { disable_with: "Submitting..." }
441
- # # => <input name="commit" data-disable-with="Submitting..." type="submit" value="Complete sale" />
442
- #
443
492
  # submit_tag nil, class: "form_submit"
444
493
  # # => <input class="form_submit" name="commit" type="submit" />
445
494
  #
446
495
  # submit_tag "Edit", class: "edit_button"
447
496
  # # => <input class="edit_button" data-disable-with="Edit" name="commit" type="submit" value="Edit" />
448
497
  #
498
+ # ==== Deprecated: Rails UJS attributes
499
+ #
500
+ # Prior to Rails 7, Rails shipped with the JavaScript library called @rails/ujs on by default. Following Rails 7,
501
+ # this library is no longer on by default. This library integrated with the following options:
502
+ #
503
+ # * <tt>confirm: 'question?'</tt> - If present the unobtrusive JavaScript
504
+ # drivers will provide a prompt with the question specified. If the user accepts,
505
+ # the form is processed normally, otherwise no action is taken.
506
+ # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
507
+ # disabled version of the submit button when the form is submitted. This feature is
508
+ # provided by the unobtrusive JavaScript driver. To disable this feature for a single submit tag
509
+ # pass <tt>:data => { disable_with: false }</tt> Defaults to value attribute.
510
+ #
511
+ # submit_tag "Complete sale", data: { disable_with: "Submitting..." }
512
+ # # => <input name="commit" data-disable-with="Submitting..." type="submit" value="Complete sale" />
513
+ #
449
514
  # submit_tag "Save", data: { confirm: "Are you sure?" }
450
515
  # # => <input name='commit' type='submit' value='Save' data-disable-with="Save" data-confirm="Are you sure?" />
451
516
  #
@@ -470,17 +535,6 @@ module ActionView
470
535
  # use this input.
471
536
  # * Any other key creates standard HTML options for the tag.
472
537
  #
473
- # ==== Data attributes
474
- #
475
- # * <tt>confirm: 'question?'</tt> - If present, the
476
- # unobtrusive JavaScript drivers will provide a prompt with
477
- # the question specified. If the user accepts, the form is
478
- # processed normally, otherwise no action is taken.
479
- # * <tt>:disable_with</tt> - Value of this parameter will be
480
- # used as the value for a disabled version of the submit
481
- # button when the form is submitted. This feature is provided
482
- # by the unobtrusive JavaScript driver.
483
- #
484
538
  # ==== Examples
485
539
  # button_tag
486
540
  # # => <button name="button" type="submit">Button</button>
@@ -501,6 +555,20 @@ module ActionView
501
555
  # # <strong>Ask me!</strong>
502
556
  # # </button>
503
557
  #
558
+ # ==== Deprecated: Rails UJS attributes
559
+ #
560
+ # Prior to Rails 7, Rails shipped with a JavaScript library called @rails/ujs on by default. Following Rails 7,
561
+ # this library is no longer on by default. This library integrated with the following options:
562
+ #
563
+ # * <tt>confirm: 'question?'</tt> - If present, the
564
+ # unobtrusive JavaScript drivers will provide a prompt with
565
+ # the question specified. If the user accepts, the form is
566
+ # processed normally, otherwise no action is taken.
567
+ # * <tt>:disable_with</tt> - Value of this parameter will be
568
+ # used as the value for a disabled version of the submit
569
+ # button when the form is submitted. This feature is provided
570
+ # by the unobtrusive JavaScript driver.
571
+ #
504
572
  # button_tag "Save", data: { confirm: "Are you sure?" }
505
573
  # # => <button name="button" type="submit" data-confirm="Are you sure?">Save</button>
506
574
  #
@@ -589,9 +657,11 @@ module ActionView
589
657
  # Creates a text field of type "color".
590
658
  #
591
659
  # ==== Options
592
- # * Accepts the same options as text_field_tag.
660
+ #
661
+ # Supports the same options as #text_field_tag.
593
662
  #
594
663
  # ==== Examples
664
+ #
595
665
  # color_field_tag 'name'
596
666
  # # => <input id="name" name="name" type="color" />
597
667
  #
@@ -610,9 +680,11 @@ module ActionView
610
680
  # Creates a text field of type "search".
611
681
  #
612
682
  # ==== Options
613
- # * Accepts the same options as text_field_tag.
683
+ #
684
+ # Supports the same options as #text_field_tag.
614
685
  #
615
686
  # ==== Examples
687
+ #
616
688
  # search_field_tag 'name'
617
689
  # # => <input id="name" name="name" type="search" />
618
690
  #
@@ -631,9 +703,11 @@ module ActionView
631
703
  # Creates a text field of type "tel".
632
704
  #
633
705
  # ==== Options
634
- # * Accepts the same options as text_field_tag.
706
+ #
707
+ # Supports the same options as #text_field_tag.
635
708
  #
636
709
  # ==== Examples
710
+ #
637
711
  # telephone_field_tag 'name'
638
712
  # # => <input id="name" name="name" type="tel" />
639
713
  #
@@ -653,9 +727,11 @@ module ActionView
653
727
  # Creates a text field of type "date".
654
728
  #
655
729
  # ==== Options
656
- # * Accepts the same options as text_field_tag.
730
+ #
731
+ # Supports the same options as #text_field_tag.
657
732
  #
658
733
  # ==== Examples
734
+ #
659
735
  # date_field_tag 'name'
660
736
  # # => <input id="name" name="name" type="date" />
661
737
  #
@@ -673,22 +749,27 @@ module ActionView
673
749
 
674
750
  # Creates a text field of type "time".
675
751
  #
676
- # === Options
752
+ # ==== Options
753
+ #
754
+ # Supports the same options as #text_field_tag. Additionally, supports:
755
+ #
677
756
  # * <tt>:min</tt> - The minimum acceptable value.
678
757
  # * <tt>:max</tt> - The maximum acceptable value.
679
758
  # * <tt>:step</tt> - The acceptable value granularity.
680
- # * Otherwise accepts the same options as text_field_tag.
759
+ # * <tt>:include_seconds</tt> - Include seconds and ms in the output timestamp format (true by default).
681
760
  def time_field_tag(name, value = nil, options = {})
682
761
  text_field_tag(name, value, options.merge(type: :time))
683
762
  end
684
763
 
685
764
  # Creates a text field of type "datetime-local".
686
765
  #
687
- # === Options
766
+ # ==== Options
767
+ #
768
+ # Supports the same options as #text_field_tag. Additionally, supports:
769
+ #
688
770
  # * <tt>:min</tt> - The minimum acceptable value.
689
771
  # * <tt>:max</tt> - The maximum acceptable value.
690
772
  # * <tt>:step</tt> - The acceptable value granularity.
691
- # * Otherwise accepts the same options as text_field_tag.
692
773
  def datetime_field_tag(name, value = nil, options = {})
693
774
  text_field_tag(name, value, options.merge(type: "datetime-local"))
694
775
  end
@@ -697,22 +778,26 @@ module ActionView
697
778
 
698
779
  # Creates a text field of type "month".
699
780
  #
700
- # === Options
781
+ # ==== Options
782
+ #
783
+ # Supports the same options as #text_field_tag. Additionally, supports:
784
+ #
701
785
  # * <tt>:min</tt> - The minimum acceptable value.
702
786
  # * <tt>:max</tt> - The maximum acceptable value.
703
787
  # * <tt>:step</tt> - The acceptable value granularity.
704
- # * Otherwise accepts the same options as text_field_tag.
705
788
  def month_field_tag(name, value = nil, options = {})
706
789
  text_field_tag(name, value, options.merge(type: :month))
707
790
  end
708
791
 
709
792
  # Creates a text field of type "week".
710
793
  #
711
- # === Options
794
+ # ==== Options
795
+ #
796
+ # Supports the same options as #text_field_tag. Additionally, supports:
797
+ #
712
798
  # * <tt>:min</tt> - The minimum acceptable value.
713
799
  # * <tt>:max</tt> - The maximum acceptable value.
714
800
  # * <tt>:step</tt> - The acceptable value granularity.
715
- # * Otherwise accepts the same options as text_field_tag.
716
801
  def week_field_tag(name, value = nil, options = {})
717
802
  text_field_tag(name, value, options.merge(type: :week))
718
803
  end
@@ -720,9 +805,11 @@ module ActionView
720
805
  # Creates a text field of type "url".
721
806
  #
722
807
  # ==== Options
723
- # * Accepts the same options as text_field_tag.
808
+ #
809
+ # Supports the same options as #text_field_tag.
724
810
  #
725
811
  # ==== Examples
812
+ #
726
813
  # url_field_tag 'name'
727
814
  # # => <input id="name" name="name" type="url" />
728
815
  #
@@ -741,9 +828,11 @@ module ActionView
741
828
  # Creates a text field of type "email".
742
829
  #
743
830
  # ==== Options
744
- # * Accepts the same options as text_field_tag.
831
+ #
832
+ # Supports the same options as #text_field_tag.
745
833
  #
746
834
  # ==== Examples
835
+ #
747
836
  # email_field_tag 'name'
748
837
  # # => <input id="name" name="name" type="email" />
749
838
  #
@@ -762,15 +851,18 @@ module ActionView
762
851
  # Creates a number field.
763
852
  #
764
853
  # ==== Options
854
+ #
855
+ # Supports the same options as #text_field_tag. Additionally, supports:
856
+ #
765
857
  # * <tt>:min</tt> - The minimum acceptable value.
766
858
  # * <tt>:max</tt> - The maximum acceptable value.
767
859
  # * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
768
860
  # <tt>:max</tt> values.
769
861
  # * <tt>:within</tt> - Same as <tt>:in</tt>.
770
862
  # * <tt>:step</tt> - The acceptable value granularity.
771
- # * Otherwise accepts the same options as text_field_tag.
772
863
  #
773
864
  # ==== Examples
865
+ #
774
866
  # number_field_tag 'quantity'
775
867
  # # => <input id="quantity" name="quantity" type="number" />
776
868
  #
@@ -812,12 +904,13 @@ module ActionView
812
904
  # Creates a range form element.
813
905
  #
814
906
  # ==== Options
815
- # * Accepts the same options as number_field_tag.
907
+ #
908
+ # Supports the same options as #number_field_tag.
816
909
  def range_field_tag(name, value = nil, options = {})
817
910
  number_field_tag(name, value, options.merge(type: :range))
818
911
  end
819
912
 
820
- # Creates the hidden UTF8 enforcer tag. Override this method in a helper
913
+ # Creates the hidden UTF-8 enforcer tag. Override this method in a helper
821
914
  # to customize the tag.
822
915
  def utf8_enforcer_tag
823
916
  # Use raw HTML to ensure the value is written as an HTML entity; it
@@ -832,13 +925,17 @@ module ActionView
832
925
  html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart")
833
926
  # The following URL is unescaped, this is just a hash of options, and it is the
834
927
  # responsibility of the caller to escape all the values.
835
- html_options["action"] = url_for(url_for_options)
928
+ if url_for_options == false || html_options["action"] == false
929
+ html_options.delete("action")
930
+ else
931
+ html_options["action"] = url_for(url_for_options)
932
+ end
836
933
  html_options["accept-charset"] = "UTF-8"
837
934
 
838
935
  html_options["data-remote"] = true if html_options.delete("remote")
839
936
 
840
937
  if html_options["data-remote"] &&
841
- !embed_authenticity_token_in_remote_forms &&
938
+ embed_authenticity_token_in_remote_forms == false &&
842
939
  html_options["authenticity_token"].blank?
843
940
  # The authenticity token is taken from the meta tag in this case
844
941
  html_options["authenticity_token"] = false
@@ -887,7 +984,7 @@ module ActionView
887
984
 
888
985
  def form_tag_with_body(html_options, content)
889
986
  output = form_tag_html(html_options)
890
- output << content
987
+ output << content.to_s if content
891
988
  output.safe_concat("</form>")
892
989
  end
893
990
 
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "action_view/helpers/tag_helper"
4
-
5
3
  module ActionView
6
- module Helpers #:nodoc:
4
+ module Helpers # :nodoc:
7
5
  module JavaScriptHelper
8
6
  JS_ESCAPE_MAP = {
9
- '\\' => '\\\\',
7
+ "\\" => "\\\\",
10
8
  "</" => '<\/',
11
9
  "\r\n" => '\n',
12
10
  "\n" => '\n',
@@ -89,7 +87,7 @@ module ActionView
89
87
  content_tag("script", javascript_cdata_section(content), html_options)
90
88
  end
91
89
 
92
- def javascript_cdata_section(content) #:nodoc:
90
+ def javascript_cdata_section(content) # :nodoc:
93
91
  "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe
94
92
  end
95
93
  end
@@ -6,16 +6,16 @@ require "active_support/number_helper"
6
6
 
7
7
  module ActionView
8
8
  # = Action View Number Helpers
9
- module Helpers #:nodoc:
9
+ module Helpers # :nodoc:
10
10
  # Provides methods for converting numbers into formatted strings.
11
11
  # Methods are provided for phone numbers, currency, percentage,
12
- # precision, positional notation, file size and pretty printing.
12
+ # precision, positional notation, file size, and pretty printing.
13
13
  #
14
14
  # Most methods expect a +number+ argument, and will return it
15
15
  # unchanged if can't be converted into a valid number.
16
16
  module NumberHelper
17
17
  # Raised when argument +number+ param given to the helpers is invalid and
18
- # the option :raise is set to +true+.
18
+ # the option +:raise+ is set to +true+.
19
19
  class InvalidNumberError < StandardError
20
20
  attr_accessor :number
21
21
  def initialize(number)
@@ -202,7 +202,7 @@ module ActionView
202
202
  # number_with_delimiter("123456.78",
203
203
  # delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/) # => "1,23,456.78"
204
204
  #
205
- # number_with_delimiter("112a", raise: true) # => raise InvalidNumberError
205
+ # number_with_delimiter("112a", raise: true) # => raise InvalidNumberError
206
206
  def number_with_delimiter(number, options = {})
207
207
  delegate_number_helper_method(:number_to_delimited, number, options)
208
208
  end
@@ -370,13 +370,14 @@ module ActionView
370
370
  # out by default (set <tt>:strip_insignificant_zeros</tt> to
371
371
  # +false+ to change that):
372
372
  #
373
- # number_to_human(12.00001) # => "12"
374
- # number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0"
373
+ # number_to_human(12.00001) # => "12"
374
+ # number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0"
375
375
  #
376
376
  # ==== Custom Unit Quantifiers
377
377
  #
378
378
  # You can also use your own custom unit quantifiers:
379
- # number_to_human(500000, units: {unit: "ml", thousand: "lt"}) # => "500 lt"
379
+ #
380
+ # number_to_human(500000, units: {unit: "ml", thousand: "lt"}) # => "500 lt"
380
381
  #
381
382
  # If in your I18n locale you have:
382
383
  # distance:
@@ -393,12 +394,12 @@ module ActionView
393
394
  #
394
395
  # Then you could do:
395
396
  #
396
- # number_to_human(543934, units: :distance) # => "544 kilometers"
397
- # number_to_human(54393498, units: :distance) # => "54400 kilometers"
398
- # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance"
399
- # number_to_human(343, units: :distance, precision: 1) # => "300 meters"
400
- # number_to_human(1, units: :distance) # => "1 meter"
401
- # number_to_human(0.34, units: :distance) # => "34 centimeters"
397
+ # number_to_human(543934, units: :distance) # => "544 kilometers"
398
+ # number_to_human(54393498, units: :distance) # => "54400 kilometers"
399
+ # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance"
400
+ # number_to_human(343, units: :distance, precision: 1) # => "300 meters"
401
+ # number_to_human(1, units: :distance) # => "1 meter"
402
+ # number_to_human(0.34, units: :distance) # => "34 centimeters"
402
403
  #
403
404
  def number_to_human(number, options = {})
404
405
  delegate_number_helper_method(:number_to_human, number, options)
@@ -448,9 +449,9 @@ module ActionView
448
449
  end
449
450
 
450
451
  def parse_float(number, raise_error)
451
- Float(number)
452
- rescue ArgumentError, TypeError
453
- raise InvalidNumberError, number if raise_error
452
+ result = Float(number, exception: false)
453
+ raise InvalidNumberError, number if result.nil? && raise_error
454
+ result
454
455
  end
455
456
  end
456
457
  end
@@ -2,9 +2,9 @@
2
2
 
3
3
  require "active_support/core_ext/string/output_safety"
4
4
 
5
- module ActionView #:nodoc:
5
+ module ActionView # :nodoc:
6
6
  # = Action View Raw Output Helper
7
- module Helpers #:nodoc:
7
+ module Helpers # :nodoc:
8
8
  module OutputSafetyHelper
9
9
  # This method outputs without escaping a string. Since escaping tags is
10
10
  # now default, this can be used when you don't want Rails to automatically
@@ -13,8 +13,8 @@ module ActionView #:nodoc:
13
13
  #
14
14
  # For example:
15
15
  #
16
- # raw @user.name
17
- # # => 'Jimmy <alert>Tables</alert>'
16
+ # raw @user.name
17
+ # # => 'Jimmy <alert>Tables</alert>'
18
18
  def raw(stringish)
19
19
  stringish.to_s.html_safe
20
20
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionView
4
- module Helpers #:nodoc:
4
+ module Helpers # :nodoc:
5
5
  # = Action View Rendering
6
6
  #
7
7
  # Implements methods that allow rendering from a view context.
@@ -10,8 +10,8 @@ module ActionView
10
10
  module RenderingHelper
11
11
  # Returns the result of a render that's dictated by the options hash. The primary options are:
12
12
  #
13
- # * <tt>:partial</tt> - See <tt>ActionView::PartialRenderer</tt>.
14
- # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
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
15
  # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
16
16
  # * <tt>:plain</tt> - Renders the text passed in out. Setting the content
17
17
  # type as <tt>text/plain</tt>.
@@ -19,8 +19,7 @@ module ActionView
19
19
  # performs HTML escape on the string first. Setting the content type as
20
20
  # <tt>text/html</tt>.
21
21
  # * <tt>:body</tt> - Renders the text passed in, and inherits the content
22
- # type of <tt>text/plain</tt> from <tt>ActionDispatch::Response</tt>
23
- # object.
22
+ # type of <tt>text/plain</tt> from ActionDispatch::Response object.
24
23
  #
25
24
  # If no <tt>options</tt> hash is passed or if <tt>:update</tt> is specified, then:
26
25
  #
@@ -47,7 +46,7 @@ module ActionView
47
46
  end
48
47
  end
49
48
 
50
- # Overwrites _layout_for in the context object so it supports the case a block is
49
+ # Overrides _layout_for in the context object so it supports the case a block is
51
50
  # passed to a partial. Returns the contents that are yielded to a layout, given a
52
51
  # name or a block.
53
52
  #
@@ -4,7 +4,7 @@ require "rails-html-sanitizer"
4
4
 
5
5
  module ActionView
6
6
  # = Action View Sanitize Helpers
7
- module Helpers #:nodoc:
7
+ module Helpers # :nodoc:
8
8
  # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
9
9
  # These helper methods extend Action View making them callable within your template files.
10
10
  module SanitizeHelper
@@ -101,7 +101,7 @@ module ActionView
101
101
  # strip_tags("> A quote from Smith & Wesson")
102
102
  # # => &gt; A quote from Smith &amp; Wesson
103
103
  def strip_tags(html)
104
- self.class.full_sanitizer.sanitize(html)
104
+ self.class.full_sanitizer.sanitize(html)&.html_safe
105
105
  end
106
106
 
107
107
  # Strips all link tags from +html+ leaving just the link text.
@@ -121,7 +121,7 @@ module ActionView
121
121
  self.class.link_sanitizer.sanitize(html)
122
122
  end
123
123
 
124
- module ClassMethods #:nodoc:
124
+ module ClassMethods # :nodoc:
125
125
  attr_writer :full_sanitizer, :link_sanitizer, :safe_list_sanitizer
126
126
 
127
127
  def sanitizer_vendor