actionview 8.0.0.1 → 8.0.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +54 -0
- data/lib/action_view/base.rb +6 -9
- data/lib/action_view/digestor.rb +6 -2
- data/lib/action_view/gem_version.rb +2 -2
- data/lib/action_view/helpers/cache_helper.rb +2 -2
- data/lib/action_view/helpers/form_helper.rb +32 -32
- data/lib/action_view/helpers/output_safety_helper.rb +1 -2
- data/lib/action_view/helpers/sanitize_helper.rb +6 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +2 -1
- data/lib/action_view/layouts.rb +6 -6
- data/lib/action_view/renderer/partial_renderer.rb +2 -2
- data/lib/action_view/renderer/template_renderer.rb +3 -3
- data/lib/action_view/template/error.rb +11 -0
- data/lib/action_view/template/handlers/erb.rb +45 -37
- metadata +12 -15
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: cc81c16e4d502ce1736e2ff17c85dbb50ed6209d6ded187af4f846d05540f551
         | 
| 4 | 
            +
              data.tar.gz: faa7c34dff4cfc391389c56b52afd0cbbbdbaf5ee7805ae3e1d1fd78940f1195
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 1e9c0c527c580719aea26c3a8499d1b1b82e4da5074271403c0060d0d96b604e23fe953ae8ede37d901ba7830fd3700a82297be2d29d574845eb79b559277d0f
         | 
| 7 | 
            +
              data.tar.gz: 24a3fc73c41d00476204519044e278f8c545db961ac02e88d810325f6cc7d831d410e203e1691767b1cca6672c0ab2d0c5b19179276c47a672b8489827d0545d
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,57 @@ | |
| 1 | 
            +
            ## Rails 8.0.2 (March 12, 2025) ##
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            *   No changes.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
             | 
| 6 | 
            +
            ## Rails 8.0.2 (March 12, 2025) ##
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            *   Respect `html_options[:form]` when `collection_checkboxes` generates the
         | 
| 9 | 
            +
                hidden `<input>`.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                *Riccardo Odone*
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            *   Layouts have access to local variables passed to `render`.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                This fixes #31680 which was a regression in Rails 5.1.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                *Mike Dalessio*
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            *   Argument errors related to strict locals in templates now raise an
         | 
| 20 | 
            +
                `ActionView::StrictLocalsError`, and all other argument errors are reraised as-is.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                Previously, any `ArgumentError` raised during template rendering was swallowed during strict
         | 
| 23 | 
            +
                local error handling, so that an `ArgumentError` unrelated to strict locals (e.g., a helper
         | 
| 24 | 
            +
                method invoked with incorrect arguments) would be replaced by a similar `ArgumentError` with an
         | 
| 25 | 
            +
                unrelated backtrace, making it difficult to debug templates.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                Now, any `ArgumentError` unrelated to strict locals is reraised, preserving the original
         | 
| 28 | 
            +
                backtrace for developers.
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                Also note that `ActionView::StrictLocalsError` is a subclass of `ArgumentError`, so any existing
         | 
| 31 | 
            +
                code that rescues `ArgumentError` will continue to work.
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                Fixes #52227.
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                *Mike Dalessio*
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            *   Fix stack overflow error in dependency tracker when dealing with circular dependencies
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                *Jean Boussier*
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            ## Rails 8.0.1 (December 13, 2024) ##
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            *   Fix a crash in ERB template error highlighting when the error occurs on a
         | 
| 44 | 
            +
                line in the compiled template that is past the end of the source template.
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                *Martin Emde*
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            *   Improve reliability of ERB template error highlighting.
         | 
| 49 | 
            +
                Fix infinite loops and crashes in highlighting and
         | 
| 50 | 
            +
                improve tolerance for alternate ERB handlers.
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                *Martin Emde*
         | 
| 53 | 
            +
             | 
| 54 | 
            +
             | 
| 1 55 | 
             
            ## Rails 8.0.0.1 (December 10, 2024) ##
         | 
| 2 56 |  | 
| 3 57 | 
             
            *   No changes.
         | 
    
        data/lib/action_view/base.rb
    CHANGED
    
    | @@ -267,15 +267,12 @@ module ActionView # :nodoc: | |
| 267 267 | 
             
                    begin
         | 
| 268 268 | 
             
                      public_send(method, locals, buffer, **locals, &block)
         | 
| 269 269 | 
             
                    rescue ArgumentError => argument_error
         | 
| 270 | 
            -
                       | 
| 271 | 
            -
             | 
| 272 | 
            -
             | 
| 273 | 
            -
             | 
| 274 | 
            -
             | 
| 275 | 
            -
             | 
| 276 | 
            -
                            gsub("no keywords accepted", "no locals accepted").
         | 
| 277 | 
            -
                            concat(" for #{@current_template.short_identifier}")
         | 
| 278 | 
            -
                      )
         | 
| 270 | 
            +
                      public_send_line = __LINE__ - 2
         | 
| 271 | 
            +
                      frame = argument_error.backtrace_locations[1]
         | 
| 272 | 
            +
                      if frame.path == __FILE__ && frame.lineno == public_send_line
         | 
| 273 | 
            +
                        raise StrictLocalsError.new(argument_error, @current_template)
         | 
| 274 | 
            +
                      end
         | 
| 275 | 
            +
                      raise
         | 
| 279 276 | 
             
                    end
         | 
| 280 277 | 
             
                  else
         | 
| 281 278 | 
             
                    public_send(method, locals, buffer, &block)
         | 
    
        data/lib/action_view/digestor.rb
    CHANGED
    
    | @@ -107,8 +107,12 @@ module ActionView | |
| 107 107 | 
             
                    end.join("-")
         | 
| 108 108 | 
             
                  end
         | 
| 109 109 |  | 
| 110 | 
            -
                  def to_dep_map
         | 
| 111 | 
            -
                     | 
| 110 | 
            +
                  def to_dep_map(seen = Set.new.compare_by_identity)
         | 
| 111 | 
            +
                    if seen.add?(self)
         | 
| 112 | 
            +
                      children.any? ? { name => children.map { |c| c.to_dep_map(seen) } } : name
         | 
| 113 | 
            +
                    else # the tree has a cycle
         | 
| 114 | 
            +
                      name
         | 
| 115 | 
            +
                    end
         | 
| 112 116 | 
             
                  end
         | 
| 113 117 | 
             
                end
         | 
| 114 118 |  | 
| @@ -197,7 +197,7 @@ module ActionView | |
| 197 197 | 
             
                    CachingRegistry.caching?
         | 
| 198 198 | 
             
                  end
         | 
| 199 199 |  | 
| 200 | 
            -
                  # Raises  | 
| 200 | 
            +
                  # Raises UncacheableFragmentError when called from within a +cache+ block.
         | 
| 201 201 | 
             
                  #
         | 
| 202 202 | 
             
                  # Useful to denote helper methods that can't participate in fragment caching:
         | 
| 203 203 | 
             
                  #
         | 
| @@ -206,7 +206,7 @@ module ActionView | |
| 206 206 | 
             
                  #     "#{project.name} - #{Time.now}"
         | 
| 207 207 | 
             
                  #   end
         | 
| 208 208 | 
             
                  #
         | 
| 209 | 
            -
                  #   # Which will then raise if used within a  | 
| 209 | 
            +
                  #   # Which will then raise if used within a `cache` block:
         | 
| 210 210 | 
             
                  #   <% cache project do %>
         | 
| 211 211 | 
             
                  #     <%= project_name_with_time(project) %>
         | 
| 212 212 | 
             
                  #   <% end %>
         | 
| @@ -31,7 +31,7 @@ module ActionView | |
| 31 31 | 
             
                # of the resource should show the current values of those attributes.
         | 
| 32 32 | 
             
                #
         | 
| 33 33 | 
             
                # In \Rails, this is usually achieved by creating the form using either
         | 
| 34 | 
            -
                #  | 
| 34 | 
            +
                # #form_with or #form_for and a number of related helper methods. These
         | 
| 35 35 | 
             
                # methods generate an appropriate <tt>form</tt> tag and yield a form
         | 
| 36 36 | 
             
                # builder object that knows the model the form is about. Input fields are
         | 
| 37 37 | 
             
                # created by calling methods defined on the form builder, which means they
         | 
| @@ -42,7 +42,7 @@ module ActionView | |
| 42 42 | 
             
                #
         | 
| 43 43 | 
             
                # For example, to create a new person you typically set up a new instance of
         | 
| 44 44 | 
             
                # +Person+ in the <tt>PeopleController#new</tt> action, <tt>@person</tt>, and
         | 
| 45 | 
            -
                # in the view template pass that object to  | 
| 45 | 
            +
                # in the view template pass that object to #form_with or #form_for:
         | 
| 46 46 | 
             
                #
         | 
| 47 47 | 
             
                #   <%= form_with model: @person do |f| %>
         | 
| 48 48 | 
             
                #     <%= f.label :first_name %>:
         | 
| @@ -209,7 +209,7 @@ module ActionView | |
| 209 209 | 
             
                  # are designed to work with an object as base, like
         | 
| 210 210 | 
             
                  # FormOptionsHelper#collection_select and DateHelper#datetime_select.
         | 
| 211 211 | 
             
                  #
         | 
| 212 | 
            -
                  # ===  | 
| 212 | 
            +
                  # === +form_for+ with a model object
         | 
| 213 213 | 
             
                  #
         | 
| 214 214 | 
             
                  # In the examples above, the object to be created or edited was
         | 
| 215 215 | 
             
                  # represented by a symbol passed to +form_for+, and we noted that
         | 
| @@ -364,7 +364,7 @@ module ActionView | |
| 364 364 | 
             
                  #
         | 
| 365 365 | 
             
                  # === Removing hidden model id's
         | 
| 366 366 | 
             
                  #
         | 
| 367 | 
            -
                  # The form_for method automatically includes the model id as a hidden field in the form.
         | 
| 367 | 
            +
                  # The +form_for+ method automatically includes the model id as a hidden field in the form.
         | 
| 368 368 | 
             
                  # This is used to maintain the correlation between the form data and its associated model.
         | 
| 369 369 | 
             
                  # Some ORM systems do not use IDs on nested models so in this case you want to be able
         | 
| 370 370 | 
             
                  # to disable the hidden id.
         | 
| @@ -784,12 +784,12 @@ module ActionView | |
| 784 784 | 
             
                    end
         | 
| 785 785 | 
             
                  end
         | 
| 786 786 |  | 
| 787 | 
            -
                  # Creates a scope around a specific model object like  | 
| 787 | 
            +
                  # Creates a scope around a specific model object like #form_with, but
         | 
| 788 788 | 
             
                  # doesn't create the form tags themselves. This makes +fields_for+
         | 
| 789 789 | 
             
                  # suitable for specifying additional model objects in the same form.
         | 
| 790 790 | 
             
                  #
         | 
| 791 | 
            -
                  # Although the usage and purpose of +fields_for+ is similar to  | 
| 792 | 
            -
                  # its method signature is slightly different. Like  | 
| 791 | 
            +
                  # Although the usage and purpose of +fields_for+ is similar to #form_with's,
         | 
| 792 | 
            +
                  # its method signature is slightly different. Like #form_with, it yields
         | 
| 793 793 | 
             
                  # a FormBuilder object associated with a particular model object to a block,
         | 
| 794 794 | 
             
                  # and within the block allows methods to be called on the builder to
         | 
| 795 795 | 
             
                  # generate fields associated with the model object. Fields may reflect
         | 
| @@ -848,7 +848,7 @@ module ActionView | |
| 848 848 | 
             
                  # === Nested Attributes Examples
         | 
| 849 849 | 
             
                  #
         | 
| 850 850 | 
             
                  # When the object belonging to the current scope has a nested attribute
         | 
| 851 | 
            -
                  # writer for a certain attribute, fields_for will yield a new scope
         | 
| 851 | 
            +
                  # writer for a certain attribute, +fields_for+ will yield a new scope
         | 
| 852 852 | 
             
                  # for that attribute. This allows you to create forms that set or change
         | 
| 853 853 | 
             
                  # the attributes of a parent object and its associations in one go.
         | 
| 854 854 | 
             
                  #
         | 
| @@ -937,7 +937,7 @@ module ActionView | |
| 937 937 | 
             
                  #   end
         | 
| 938 938 | 
             
                  #
         | 
| 939 939 | 
             
                  # Note that the <tt>projects_attributes=</tt> writer method is in fact
         | 
| 940 | 
            -
                  # required for fields_for to correctly identify <tt>:projects</tt> as a
         | 
| 940 | 
            +
                  # required for +fields_for+ to correctly identify <tt>:projects</tt> as a
         | 
| 941 941 | 
             
                  # collection, and the correct indices to be set in the form markup.
         | 
| 942 942 | 
             
                  #
         | 
| 943 943 | 
             
                  # When projects is already an association on Person you can use
         | 
| @@ -949,7 +949,7 @@ module ActionView | |
| 949 949 | 
             
                  #   end
         | 
| 950 950 | 
             
                  #
         | 
| 951 951 | 
             
                  # This model can now be used with a nested fields_for. The block given to
         | 
| 952 | 
            -
                  # the nested fields_for call will be repeated for each instance in the
         | 
| 952 | 
            +
                  # the nested +fields_for+ call will be repeated for each instance in the
         | 
| 953 953 | 
             
                  # collection:
         | 
| 954 954 | 
             
                  #
         | 
| 955 955 | 
             
                  #   <%= form_with model: @person do |person_form| %>
         | 
| @@ -1021,10 +1021,10 @@ module ActionView | |
| 1021 1021 | 
             
                  #     ...
         | 
| 1022 1022 | 
             
                  #   <% end %>
         | 
| 1023 1023 | 
             
                  #
         | 
| 1024 | 
            -
                  # Note that fields_for will automatically generate a hidden field
         | 
| 1024 | 
            +
                  # Note that +fields_for+ will automatically generate a hidden field
         | 
| 1025 1025 | 
             
                  # to store the ID of the record if it responds to <tt>persisted?</tt>.
         | 
| 1026 1026 | 
             
                  # There are circumstances where this hidden field is not needed and you
         | 
| 1027 | 
            -
                  # can pass <tt>include_id: false</tt> to prevent fields_for from
         | 
| 1027 | 
            +
                  # can pass <tt>include_id: false</tt> to prevent +fields_for+ from
         | 
| 1028 1028 | 
             
                  # rendering it automatically.
         | 
| 1029 1029 | 
             
                  def fields_for(record_name, record_object = nil, options = {}, &block)
         | 
| 1030 1030 | 
             
                    options = { model: record_object, allow_method_names_outside_object: false, skip_default_ids: false }.merge!(options)
         | 
| @@ -1033,7 +1033,7 @@ module ActionView | |
| 1033 1033 | 
             
                  end
         | 
| 1034 1034 |  | 
| 1035 1035 | 
             
                  # Scopes input fields with either an explicit scope or model.
         | 
| 1036 | 
            -
                  # Like  | 
| 1036 | 
            +
                  # Like #form_with does with <tt>:scope</tt> or <tt>:model</tt>,
         | 
| 1037 1037 | 
             
                  # except it doesn't output the form tags.
         | 
| 1038 1038 | 
             
                  #
         | 
| 1039 1039 | 
             
                  #   # Using a scope prefixes the input field names:
         | 
| @@ -1048,7 +1048,7 @@ module ActionView | |
| 1048 1048 | 
             
                  #   <% end %>
         | 
| 1049 1049 | 
             
                  #   # => <input type="text" name="comment[body]" value="full bodied">
         | 
| 1050 1050 | 
             
                  #
         | 
| 1051 | 
            -
                  #   # Using  | 
| 1051 | 
            +
                  #   # Using `fields` with `form_with`:
         | 
| 1052 1052 | 
             
                  #   <%= form_with model: @article do |form| %>
         | 
| 1053 1053 | 
             
                  #     <%= form.text_field :title %>
         | 
| 1054 1054 | 
             
                  #
         | 
| @@ -1057,13 +1057,13 @@ module ActionView | |
| 1057 1057 | 
             
                  #     <% end %>
         | 
| 1058 1058 | 
             
                  #   <% end %>
         | 
| 1059 1059 | 
             
                  #
         | 
| 1060 | 
            -
                  # Much like  | 
| 1060 | 
            +
                  # Much like #form_with a FormBuilder instance associated with the scope
         | 
| 1061 1061 | 
             
                  # or model is yielded, so any generated field names are prefixed with
         | 
| 1062 1062 | 
             
                  # either the passed scope or the scope inferred from the <tt>:model</tt>.
         | 
| 1063 1063 | 
             
                  #
         | 
| 1064 1064 | 
             
                  # === Mixing with other form helpers
         | 
| 1065 1065 | 
             
                  #
         | 
| 1066 | 
            -
                  # While  | 
| 1066 | 
            +
                  # While #form_with uses a FormBuilder object it's possible to mix and
         | 
| 1067 1067 | 
             
                  # match the stand-alone FormHelper methods and methods
         | 
| 1068 1068 | 
             
                  # from FormTagHelper:
         | 
| 1069 1069 | 
             
                  #
         | 
| @@ -1221,7 +1221,7 @@ module ActionView | |
| 1221 1221 | 
             
                  # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
         | 
| 1222 1222 | 
             
                  # shown.
         | 
| 1223 1223 | 
             
                  #
         | 
| 1224 | 
            -
                  # Using this method inside a  | 
| 1224 | 
            +
                  # Using this method inside a #form_with block will set the enclosing form's encoding to <tt>multipart/form-data</tt>.
         | 
| 1225 1225 | 
             
                  #
         | 
| 1226 1226 | 
             
                  # ==== Options
         | 
| 1227 1227 | 
             
                  # * Creates standard HTML attributes for the tag.
         | 
| @@ -1326,7 +1326,7 @@ module ActionView | |
| 1326 1326 | 
             
                  # the elements of the array. For each item with a checked check box you
         | 
| 1327 1327 | 
             
                  # get an extra ghost item with only that attribute, assigned to "0".
         | 
| 1328 1328 | 
             
                  #
         | 
| 1329 | 
            -
                  # In that case it is preferable to either use  | 
| 1329 | 
            +
                  # In that case it is preferable to either use FormTagHelper#checkbox_tag or to use
         | 
| 1330 1330 | 
             
                  # hashes instead of arrays.
         | 
| 1331 1331 | 
             
                  #
         | 
| 1332 1332 | 
             
                  # ==== Examples
         | 
| @@ -1632,7 +1632,7 @@ module ActionView | |
| 1632 1632 | 
             
                #
         | 
| 1633 1633 | 
             
                # A +FormBuilder+ object is associated with a particular model object and
         | 
| 1634 1634 | 
             
                # allows you to generate fields associated with the model object. The
         | 
| 1635 | 
            -
                # +FormBuilder+ object is yielded when using  | 
| 1635 | 
            +
                # +FormBuilder+ object is yielded when using #form_with or #fields_for.
         | 
| 1636 1636 | 
             
                # For example:
         | 
| 1637 1637 | 
             
                #
         | 
| 1638 1638 | 
             
                #   <%= form_with model: @person do |person_form| %>
         | 
| @@ -1770,7 +1770,7 @@ module ActionView | |
| 1770 1770 | 
             
                  #   <% end %>
         | 
| 1771 1771 | 
             
                  #
         | 
| 1772 1772 | 
             
                  # In the example above, the <tt><input type="text"></tt> element built by
         | 
| 1773 | 
            -
                  # the call to  | 
| 1773 | 
            +
                  # the call to #text_field declares an
         | 
| 1774 1774 | 
             
                  # <tt>aria-describedby</tt> attribute referencing the <tt><span></tt>
         | 
| 1775 1775 | 
             
                  # element, sharing a common <tt>id</tt> root (<tt>article_title</tt>, in this
         | 
| 1776 1776 | 
             
                  # case).
         | 
| @@ -2033,12 +2033,12 @@ module ActionView | |
| 2033 2033 | 
             
                  end
         | 
| 2034 2034 | 
             
                  alias_method :text_area, :textarea
         | 
| 2035 2035 |  | 
| 2036 | 
            -
                  # Creates a scope around a specific model object like  | 
| 2036 | 
            +
                  # Creates a scope around a specific model object like #form_with, but
         | 
| 2037 2037 | 
             
                  # doesn't create the form tags themselves. This makes +fields_for+
         | 
| 2038 2038 | 
             
                  # suitable for specifying additional model objects in the same form.
         | 
| 2039 2039 | 
             
                  #
         | 
| 2040 | 
            -
                  # Although the usage and purpose of +fields_for+ is similar to  | 
| 2041 | 
            -
                  # its method signature is slightly different. Like  | 
| 2040 | 
            +
                  # Although the usage and purpose of +fields_for+ is similar to #form_with's,
         | 
| 2041 | 
            +
                  # its method signature is slightly different. Like #form_with, it yields
         | 
| 2042 2042 | 
             
                  # a FormBuilder object associated with a particular model object to a block,
         | 
| 2043 2043 | 
             
                  # and within the block allows methods to be called on the builder to
         | 
| 2044 2044 | 
             
                  # generate fields associated with the model object. Fields may reflect
         | 
| @@ -2109,7 +2109,7 @@ module ActionView | |
| 2109 2109 | 
             
                  # === Nested Attributes Examples
         | 
| 2110 2110 | 
             
                  #
         | 
| 2111 2111 | 
             
                  # When the object belonging to the current scope has a nested attribute
         | 
| 2112 | 
            -
                  # writer for a certain attribute, fields_for will yield a new scope
         | 
| 2112 | 
            +
                  # writer for a certain attribute, +fields_for+ will yield a new scope
         | 
| 2113 2113 | 
             
                  # for that attribute. This allows you to create forms that set or change
         | 
| 2114 2114 | 
             
                  # the attributes of a parent object and its associations in one go.
         | 
| 2115 2115 | 
             
                  #
         | 
| @@ -2140,7 +2140,7 @@ module ActionView | |
| 2140 2140 | 
             
                  #     end
         | 
| 2141 2141 | 
             
                  #   end
         | 
| 2142 2142 | 
             
                  #
         | 
| 2143 | 
            -
                  # This model can now be used with a nested fields_for | 
| 2143 | 
            +
                  # This model can now be used with a nested +fields_for+, like so:
         | 
| 2144 2144 | 
             
                  #
         | 
| 2145 2145 | 
             
                  #   <%= form_with model: @person do |person_form| %>
         | 
| 2146 2146 | 
             
                  #     ...
         | 
| @@ -2198,7 +2198,7 @@ module ActionView | |
| 2198 2198 | 
             
                  #   end
         | 
| 2199 2199 | 
             
                  #
         | 
| 2200 2200 | 
             
                  # Note that the <tt>projects_attributes=</tt> writer method is in fact
         | 
| 2201 | 
            -
                  # required for fields_for to correctly identify <tt>:projects</tt> as a
         | 
| 2201 | 
            +
                  # required for +fields_for+ to correctly identify <tt>:projects</tt> as a
         | 
| 2202 2202 | 
             
                  # collection, and the correct indices to be set in the form markup.
         | 
| 2203 2203 | 
             
                  #
         | 
| 2204 2204 | 
             
                  # When projects is already an association on Person you can use
         | 
| @@ -2209,8 +2209,8 @@ module ActionView | |
| 2209 2209 | 
             
                  #     accepts_nested_attributes_for :projects
         | 
| 2210 2210 | 
             
                  #   end
         | 
| 2211 2211 | 
             
                  #
         | 
| 2212 | 
            -
                  # This model can now be used with a nested fields_for | 
| 2213 | 
            -
                  # the nested fields_for call will be repeated for each instance in the
         | 
| 2212 | 
            +
                  # This model can now be used with a nested +fields_for+. The block given to
         | 
| 2213 | 
            +
                  # the nested +fields_for+ call will be repeated for each instance in the
         | 
| 2214 2214 | 
             
                  # collection:
         | 
| 2215 2215 | 
             
                  #
         | 
| 2216 2216 | 
             
                  #   <%= form_with model: @person do |person_form| %>
         | 
| @@ -2282,10 +2282,10 @@ module ActionView | |
| 2282 2282 | 
             
                  #     ...
         | 
| 2283 2283 | 
             
                  #   <% end %>
         | 
| 2284 2284 | 
             
                  #
         | 
| 2285 | 
            -
                  # Note that fields_for will automatically generate a hidden field
         | 
| 2285 | 
            +
                  # Note that +fields_for+ will automatically generate a hidden field
         | 
| 2286 2286 | 
             
                  # to store the ID of the record. There are circumstances where this
         | 
| 2287 2287 | 
             
                  # hidden field is not needed and you can pass <tt>include_id: false</tt>
         | 
| 2288 | 
            -
                  # to prevent fields_for from rendering it automatically.
         | 
| 2288 | 
            +
                  # to prevent +fields_for+ from rendering it automatically.
         | 
| 2289 2289 | 
             
                  def fields_for(record_name, record_object = nil, fields_options = nil, &block)
         | 
| 2290 2290 | 
             
                    fields_options, record_object = record_object, nil if fields_options.nil? && record_object.is_a?(Hash) && record_object.extractable_options?
         | 
| 2291 2291 | 
             
                    fields_options ||= {}
         | 
| @@ -2451,7 +2451,7 @@ module ActionView | |
| 2451 2451 | 
             
                  # the elements of the array. For each item with a checked check box you
         | 
| 2452 2452 | 
             
                  # get an extra ghost item with only that attribute, assigned to "0".
         | 
| 2453 2453 | 
             
                  #
         | 
| 2454 | 
            -
                  # In that case it is preferable to either use  | 
| 2454 | 
            +
                  # In that case it is preferable to either use FormTagHelper#checkbox_tag or to use
         | 
| 2455 2455 | 
             
                  # hashes instead of arrays.
         | 
| 2456 2456 | 
             
                  #
         | 
| 2457 2457 | 
             
                  # ==== Examples
         | 
| @@ -2525,7 +2525,7 @@ module ActionView | |
| 2525 2525 | 
             
                  # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
         | 
| 2526 2526 | 
             
                  # shown.
         | 
| 2527 2527 | 
             
                  #
         | 
| 2528 | 
            -
                  # Using this method inside a  | 
| 2528 | 
            +
                  # Using this method inside a #form_with block will set the enclosing form's encoding to <tt>multipart/form-data</tt>.
         | 
| 2529 2529 | 
             
                  #
         | 
| 2530 2530 | 
             
                  # ==== Options
         | 
| 2531 2531 | 
             
                  # * Creates standard HTML attributes for the tag.
         | 
| @@ -38,8 +38,7 @@ 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  | 
| 42 | 
            -
                  #
         | 
| 41 | 
            +
                  # ActiveSupport's Array#to_sentence.
         | 
| 43 42 | 
             
                  def to_sentence(array, options = {})
         | 
| 44 43 | 
             
                    options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
         | 
| 45 44 |  | 
| @@ -24,6 +24,12 @@ module ActionView | |
| 24 24 | 
             
                  #
         | 
| 25 25 | 
             
                  # Custom sanitization rules can also be provided.
         | 
| 26 26 | 
             
                  #
         | 
| 27 | 
            +
                  # <b>Warning</b>: Adding disallowed tags or attributes to the allowlists may introduce
         | 
| 28 | 
            +
                  # vulnerabilities into your application. Please rely on the default allowlists whenever
         | 
| 29 | 
            +
                  # possible, because they are curated to maintain security and safety. If you think that the
         | 
| 30 | 
            +
                  # default allowlists should be expanded, please {open an issue on the rails-html-sanitizer
         | 
| 31 | 
            +
                  # project}[https://github.com/rails/rails-html-sanitizer/issues].
         | 
| 32 | 
            +
                  #
         | 
| 27 33 | 
             
                  # Please note that sanitizing user-provided text does not guarantee that the
         | 
| 28 34 | 
             
                  # resulting markup is valid or even well-formed.
         | 
| 29 35 | 
             
                  #
         | 
| @@ -106,7 +106,8 @@ module ActionView | |
| 106 106 |  | 
| 107 107 | 
             
                      def hidden_field
         | 
| 108 108 | 
             
                        hidden_name = @html_options[:name] || hidden_field_name
         | 
| 109 | 
            -
                         | 
| 109 | 
            +
                        options = { id: nil, form: @html_options[:form] }
         | 
| 110 | 
            +
                        @template_object.hidden_field_tag(hidden_name, "", options)
         | 
| 110 111 | 
             
                      end
         | 
| 111 112 |  | 
| 112 113 | 
             
                      def hidden_field_name
         | 
    
        data/lib/action_view/layouts.rb
    CHANGED
    
    | @@ -284,7 +284,7 @@ module ActionView | |
| 284 284 | 
             
                    silence_redefinition_of_method(:_layout)
         | 
| 285 285 |  | 
| 286 286 | 
             
                    prefixes = /\blayouts/.match?(_implied_layout_name) ? [] : ["layouts"]
         | 
| 287 | 
            -
                    default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false,  | 
| 287 | 
            +
                    default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false, keys, { formats: formats }).first || super"
         | 
| 288 288 | 
             
                    name_clause = if name
         | 
| 289 289 | 
             
                      default_behavior
         | 
| 290 290 | 
             
                    else
         | 
| @@ -325,7 +325,7 @@ module ActionView | |
| 325 325 |  | 
| 326 326 | 
             
                    class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 327 327 | 
             
                      # frozen_string_literal: true
         | 
| 328 | 
            -
                      def _layout(lookup_context, formats)
         | 
| 328 | 
            +
                      def _layout(lookup_context, formats, keys)
         | 
| 329 329 | 
             
                        if _conditional_layout?
         | 
| 330 330 | 
             
                          #{layout_definition}
         | 
| 331 331 | 
             
                        else
         | 
| @@ -389,8 +389,8 @@ module ActionView | |
| 389 389 | 
             
                  case name
         | 
| 390 390 | 
             
                  when String     then _normalize_layout(name)
         | 
| 391 391 | 
             
                  when Proc       then name
         | 
| 392 | 
            -
                  when true       then Proc.new { |lookup_context, formats| _default_layout(lookup_context, formats, true)  }
         | 
| 393 | 
            -
                  when :default   then Proc.new { |lookup_context, formats| _default_layout(lookup_context, formats, false) }
         | 
| 392 | 
            +
                  when true       then Proc.new { |lookup_context, formats, keys| _default_layout(lookup_context, formats, keys, true)  }
         | 
| 393 | 
            +
                  when :default   then Proc.new { |lookup_context, formats, keys| _default_layout(lookup_context, formats, keys, false) }
         | 
| 394 394 | 
             
                  when false, nil then nil
         | 
| 395 395 | 
             
                  else
         | 
| 396 396 | 
             
                    raise ArgumentError,
         | 
| @@ -412,9 +412,9 @@ module ActionView | |
| 412 412 | 
             
                #
         | 
| 413 413 | 
             
                # ==== Returns
         | 
| 414 414 | 
             
                # * <tt>template</tt> - The template object for the default layout (or +nil+)
         | 
| 415 | 
            -
                def _default_layout(lookup_context, formats, require_layout = false)
         | 
| 415 | 
            +
                def _default_layout(lookup_context, formats, keys, require_layout = false)
         | 
| 416 416 | 
             
                  begin
         | 
| 417 | 
            -
                    value = _layout(lookup_context, formats) if action_has_layout?
         | 
| 417 | 
            +
                    value = _layout(lookup_context, formats, keys) if action_has_layout?
         | 
| 418 418 | 
             
                  rescue NameError => e
         | 
| 419 419 | 
             
                    raise e, "Could not render layout: #{e.message}"
         | 
| 420 420 | 
             
                  end
         | 
| @@ -94,7 +94,7 @@ module ActionView | |
| 94 94 | 
             
              #  # <%= render partial: "accounts/account", locals: { account: @account} %>
         | 
| 95 95 | 
             
              #  <%= render partial: @account %>
         | 
| 96 96 | 
             
              #
         | 
| 97 | 
            -
              #  # @posts is an array of Post instances, so every post record returns 'posts/post' on  | 
| 97 | 
            +
              #  # @posts is an array of Post instances, so every post record returns 'posts/post' on #to_partial_path,
         | 
| 98 98 | 
             
              #  # that's why we can replace:
         | 
| 99 99 | 
             
              #  # <%= render partial: "posts/post", collection: @posts %>
         | 
| 100 100 | 
             
              #  <%= render partial: @posts %>
         | 
| @@ -114,7 +114,7 @@ module ActionView | |
| 114 114 | 
             
              #  # <%= render partial: "accounts/account", locals: { account: @account} %>
         | 
| 115 115 | 
             
              #  <%= render @account %>
         | 
| 116 116 | 
             
              #
         | 
| 117 | 
            -
              #  # @posts is an array of Post instances, so every post record returns 'posts/post' on  | 
| 117 | 
            +
              #  # @posts is an array of Post instances, so every post record returns 'posts/post' on #to_partial_path,
         | 
| 118 118 | 
             
              #  # that's why we can replace:
         | 
| 119 119 | 
             
              #  # <%= render partial: "posts/post", collection: @posts %>
         | 
| 120 120 | 
             
              #  <%= render @posts %>
         | 
| @@ -99,14 +99,14 @@ module ActionView | |
| 99 99 | 
             
                        if layout.start_with?("/")
         | 
| 100 100 | 
             
                          raise ArgumentError, "Rendering layouts from an absolute path is not supported."
         | 
| 101 101 | 
             
                        else
         | 
| 102 | 
            -
                          @lookup_context.find_template(layout, nil, false,  | 
| 102 | 
            +
                          @lookup_context.find_template(layout, nil, false, keys, details)
         | 
| 103 103 | 
             
                        end
         | 
| 104 104 | 
             
                      rescue ActionView::MissingTemplate
         | 
| 105 105 | 
             
                        all_details = @details.merge(formats: @lookup_context.default_formats)
         | 
| 106 | 
            -
                        raise unless template_exists?(layout, nil, false,  | 
| 106 | 
            +
                        raise unless template_exists?(layout, nil, false, keys, **all_details)
         | 
| 107 107 | 
             
                      end
         | 
| 108 108 | 
             
                    when Proc
         | 
| 109 | 
            -
                      resolve_layout(layout.call(@lookup_context, formats), keys, formats)
         | 
| 109 | 
            +
                      resolve_layout(layout.call(@lookup_context, formats, keys), keys, formats)
         | 
| 110 110 | 
             
                    else
         | 
| 111 111 | 
             
                      layout
         | 
| 112 112 | 
             
                    end
         | 
| @@ -27,6 +27,17 @@ module ActionView | |
| 27 27 | 
             
                end
         | 
| 28 28 | 
             
              end
         | 
| 29 29 |  | 
| 30 | 
            +
              class StrictLocalsError < ArgumentError # :nodoc:
         | 
| 31 | 
            +
                def initialize(argument_error, template)
         | 
| 32 | 
            +
                  message = argument_error.message.
         | 
| 33 | 
            +
                              gsub("unknown keyword:", "unknown local:").
         | 
| 34 | 
            +
                              gsub("missing keyword:", "missing local:").
         | 
| 35 | 
            +
                              gsub("no keywords accepted", "no locals accepted").
         | 
| 36 | 
            +
                              concat(" for #{template.short_identifier}")
         | 
| 37 | 
            +
                  super(message)
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 30 41 | 
             
              class MissingTemplate < ActionViewError # :nodoc:
         | 
| 31 42 | 
             
                attr_reader :path, :paths, :prefixes, :partial
         | 
| 32 43 |  | 
| @@ -42,7 +42,9 @@ module ActionView | |
| 42 42 | 
             
                    # source location inside the template.
         | 
| 43 43 | 
             
                    def translate_location(spot, backtrace_location, source)
         | 
| 44 44 | 
             
                      # Tokenize the source line
         | 
| 45 | 
            -
                       | 
| 45 | 
            +
                      source_lines = source.lines
         | 
| 46 | 
            +
                      return nil if source_lines.size < backtrace_location.lineno
         | 
| 47 | 
            +
                      tokens = ::ERB::Util.tokenize(source_lines[backtrace_location.lineno - 1])
         | 
| 46 48 | 
             
                      new_first_column = find_offset(spot[:snippet], tokens, spot[:first_column])
         | 
| 47 49 | 
             
                      lineno_delta = spot[:first_lineno] - backtrace_location.lineno
         | 
| 48 50 | 
             
                      spot[:first_lineno] -= lineno_delta
         | 
| @@ -51,7 +53,7 @@ module ActionView | |
| 51 53 | 
             
                      column_delta = spot[:first_column] - new_first_column
         | 
| 52 54 | 
             
                      spot[:first_column] -= column_delta
         | 
| 53 55 | 
             
                      spot[:last_column] -= column_delta
         | 
| 54 | 
            -
                      spot[:script_lines] =  | 
| 56 | 
            +
                      spot[:script_lines] = source_lines
         | 
| 55 57 |  | 
| 56 58 | 
             
                      spot
         | 
| 57 59 | 
             
                    rescue NotImplementedError, LocationParsingError
         | 
| @@ -105,51 +107,57 @@ module ActionView | |
| 105 107 | 
             
                      raise WrongEncodingError.new(string, string.encoding)
         | 
| 106 108 | 
             
                    end
         | 
| 107 109 |  | 
| 110 | 
            +
                    # Find which token in the source template spans the byte range that
         | 
| 111 | 
            +
                    # contains the error_column, then return the offset compared to the
         | 
| 112 | 
            +
                    # original source template.
         | 
| 113 | 
            +
                    #
         | 
| 114 | 
            +
                    # Iterate consecutive pairs of CODE or TEXT tokens, requiring
         | 
| 115 | 
            +
                    # a match of the first token before matching either token.
         | 
| 116 | 
            +
                    #
         | 
| 117 | 
            +
                    # For example, if we want to find tokens A, B, C, we do the following:
         | 
| 118 | 
            +
                    # 1. Find a match for A: test error_column or advance scanner.
         | 
| 119 | 
            +
                    # 2. Find a match for B or A:
         | 
| 120 | 
            +
                    #   a. If B: start over with next token set (B, C).
         | 
| 121 | 
            +
                    #   b. If A: test error_column or advance scanner.
         | 
| 122 | 
            +
                    #   c. Otherwise: Advance 1 byte
         | 
| 123 | 
            +
                    #
         | 
| 124 | 
            +
                    # Prioritize matching the next token over the current token once
         | 
| 125 | 
            +
                    # a match for the current token has been found. This is to prevent
         | 
| 126 | 
            +
                    # the current token from looping past the next token if they both
         | 
| 127 | 
            +
                    # match (i.e. if the current token is a single space character).
         | 
| 108 128 | 
             
                    def find_offset(compiled, source_tokens, error_column)
         | 
| 109 129 | 
             
                      compiled = StringScanner.new(compiled)
         | 
| 130 | 
            +
                      offset_source_tokens(source_tokens).each_cons(2) do |(name, str, offset), (_, next_str, _)|
         | 
| 131 | 
            +
                        matched_str = false
         | 
| 110 132 |  | 
| 111 | 
            -
             | 
| 133 | 
            +
                        until compiled.eos?
         | 
| 134 | 
            +
                          if matched_str && next_str && compiled.match?(next_str)
         | 
| 135 | 
            +
                            break
         | 
| 136 | 
            +
                          elsif compiled.match?(str)
         | 
| 137 | 
            +
                            matched_str = true
         | 
| 112 138 |  | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
                        when :TEXT
         | 
| 117 | 
            -
                          loop do
         | 
| 118 | 
            -
                            break if compiled.match?(str)
         | 
| 119 | 
            -
                            compiled.getch
         | 
| 120 | 
            -
                          end
         | 
| 121 | 
            -
                          raise LocationParsingError unless compiled.scan(str)
         | 
| 122 | 
            -
                        when :CODE
         | 
| 123 | 
            -
                          if compiled.pos > error_column
         | 
| 124 | 
            -
                            raise LocationParsingError, "We went too far"
         | 
| 125 | 
            -
                          end
         | 
| 139 | 
            +
                            if name == :CODE && compiled.pos <= error_column && compiled.pos + str.bytesize >= error_column
         | 
| 140 | 
            +
                              return error_column - compiled.pos + offset
         | 
| 141 | 
            +
                            end
         | 
| 126 142 |  | 
| 127 | 
            -
             | 
| 128 | 
            -
                            offset = error_column - compiled.pos
         | 
| 129 | 
            -
                            return passed_tokens.map(&:last).join.bytesize + offset
         | 
| 143 | 
            +
                            compiled.pos += str.bytesize
         | 
| 130 144 | 
             
                          else
         | 
| 131 | 
            -
                             | 
| 132 | 
            -
                              raise LocationParsingError, "Couldn't find code snippet"
         | 
| 133 | 
            -
                            end
         | 
| 134 | 
            -
                          end
         | 
| 135 | 
            -
                        when :OPEN
         | 
| 136 | 
            -
                          next_tok = source_tokens.first.last
         | 
| 137 | 
            -
                          loop do
         | 
| 138 | 
            -
                            break if compiled.match?(next_tok)
         | 
| 139 | 
            -
                            compiled.getch
         | 
| 145 | 
            +
                            compiled.pos += 1
         | 
| 140 146 | 
             
                          end
         | 
| 141 | 
            -
                        when :CLOSE
         | 
| 142 | 
            -
                          next_tok = source_tokens.first.last
         | 
| 143 | 
            -
                          loop do
         | 
| 144 | 
            -
                            break if compiled.match?(next_tok)
         | 
| 145 | 
            -
                            compiled.getch
         | 
| 146 | 
            -
                          end
         | 
| 147 | 
            -
                        else
         | 
| 148 | 
            -
                          raise LocationParsingError, "Not implemented: #{tok.first}"
         | 
| 149 147 | 
             
                        end
         | 
| 148 | 
            +
                      end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                      raise LocationParsingError, "Couldn't find code snippet"
         | 
| 151 | 
            +
                    end
         | 
| 150 152 |  | 
| 151 | 
            -
             | 
| 153 | 
            +
                    def offset_source_tokens(source_tokens)
         | 
| 154 | 
            +
                      source_offset = 0
         | 
| 155 | 
            +
                      with_offset = source_tokens.filter_map do |(name, str)|
         | 
| 156 | 
            +
                        result = [name, str, source_offset] if name == :CODE || name == :TEXT
         | 
| 157 | 
            +
                        source_offset += str.bytesize
         | 
| 158 | 
            +
                        result
         | 
| 152 159 | 
             
                      end
         | 
| 160 | 
            +
                      with_offset << [:EOS, nil, source_offset]
         | 
| 153 161 | 
             
                    end
         | 
| 154 162 | 
             
                  end
         | 
| 155 163 | 
             
                end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: actionview
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 8.0. | 
| 4 | 
            +
              version: 8.0.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - David Heinemeier Hansson
         | 
| 8 | 
            -
            autorequire: 
         | 
| 9 8 | 
             
            bindir: bin
         | 
| 10 9 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 10 | 
            +
            date: 2025-03-12 00:00:00.000000000 Z
         | 
| 12 11 | 
             
            dependencies:
         | 
| 13 12 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 13 | 
             
              name: activesupport
         | 
| @@ -16,14 +15,14 @@ dependencies: | |
| 16 15 | 
             
                requirements:
         | 
| 17 16 | 
             
                - - '='
         | 
| 18 17 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: 8.0. | 
| 18 | 
            +
                    version: 8.0.2
         | 
| 20 19 | 
             
              type: :runtime
         | 
| 21 20 | 
             
              prerelease: false
         | 
| 22 21 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 22 | 
             
                requirements:
         | 
| 24 23 | 
             
                - - '='
         | 
| 25 24 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: 8.0. | 
| 25 | 
            +
                    version: 8.0.2
         | 
| 27 26 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 27 | 
             
              name: builder
         | 
| 29 28 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -86,28 +85,28 @@ dependencies: | |
| 86 85 | 
             
                requirements:
         | 
| 87 86 | 
             
                - - '='
         | 
| 88 87 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            -
                    version: 8.0. | 
| 88 | 
            +
                    version: 8.0.2
         | 
| 90 89 | 
             
              type: :development
         | 
| 91 90 | 
             
              prerelease: false
         | 
| 92 91 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 92 | 
             
                requirements:
         | 
| 94 93 | 
             
                - - '='
         | 
| 95 94 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            -
                    version: 8.0. | 
| 95 | 
            +
                    version: 8.0.2
         | 
| 97 96 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 98 97 | 
             
              name: activemodel
         | 
| 99 98 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 99 | 
             
                requirements:
         | 
| 101 100 | 
             
                - - '='
         | 
| 102 101 | 
             
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            -
                    version: 8.0. | 
| 102 | 
            +
                    version: 8.0.2
         | 
| 104 103 | 
             
              type: :development
         | 
| 105 104 | 
             
              prerelease: false
         | 
| 106 105 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 106 | 
             
                requirements:
         | 
| 108 107 | 
             
                - - '='
         | 
| 109 108 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            -
                    version: 8.0. | 
| 109 | 
            +
                    version: 8.0.2
         | 
| 111 110 | 
             
            description: Simple, battle-tested conventions and helpers for building web pages.
         | 
| 112 111 | 
             
            email: david@loudthinking.com
         | 
| 113 112 | 
             
            executables: []
         | 
| @@ -247,12 +246,11 @@ licenses: | |
| 247 246 | 
             
            - MIT
         | 
| 248 247 | 
             
            metadata:
         | 
| 249 248 | 
             
              bug_tracker_uri: https://github.com/rails/rails/issues
         | 
| 250 | 
            -
              changelog_uri: https://github.com/rails/rails/blob/v8.0. | 
| 251 | 
            -
              documentation_uri: https://api.rubyonrails.org/v8.0. | 
| 249 | 
            +
              changelog_uri: https://github.com/rails/rails/blob/v8.0.2/actionview/CHANGELOG.md
         | 
| 250 | 
            +
              documentation_uri: https://api.rubyonrails.org/v8.0.2/
         | 
| 252 251 | 
             
              mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
         | 
| 253 | 
            -
              source_code_uri: https://github.com/rails/rails/tree/v8.0. | 
| 252 | 
            +
              source_code_uri: https://github.com/rails/rails/tree/v8.0.2/actionview
         | 
| 254 253 | 
             
              rubygems_mfa_required: 'true'
         | 
| 255 | 
            -
            post_install_message: 
         | 
| 256 254 | 
             
            rdoc_options: []
         | 
| 257 255 | 
             
            require_paths:
         | 
| 258 256 | 
             
            - lib
         | 
| @@ -268,8 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 268 266 | 
             
                  version: '0'
         | 
| 269 267 | 
             
            requirements:
         | 
| 270 268 | 
             
            - none
         | 
| 271 | 
            -
            rubygems_version: 3. | 
| 272 | 
            -
            signing_key: 
         | 
| 269 | 
            +
            rubygems_version: 3.6.2
         | 
| 273 270 | 
             
            specification_version: 4
         | 
| 274 271 | 
             
            summary: Rendering framework putting the V in MVC (part of Rails).
         | 
| 275 272 | 
             
            test_files: []
         |