view_component 3.22.0 → 4.0.0.alpha2
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/app/controllers/concerns/view_component/preview_actions.rb +2 -9
- data/app/controllers/view_components_system_test_controller.rb +17 -20
- data/app/views/test_mailer/test_asset_email.html.erb +1 -0
- data/app/views/view_components/preview.html.erb +1 -9
- data/docs/CHANGELOG.md +133 -1
- data/lib/view_component/base.rb +42 -61
- data/lib/view_component/collection.rb +11 -17
- data/lib/view_component/compiler.rb +50 -74
- data/lib/view_component/config.rb +0 -21
- data/lib/view_component/deprecation.rb +1 -1
- data/lib/view_component/engine.rb +3 -82
- data/lib/view_component/errors.rb +16 -22
- data/lib/view_component/inline_template.rb +2 -3
- data/lib/view_component/instrumentation.rb +4 -10
- data/lib/view_component/preview.rb +3 -10
- data/lib/view_component/request_details.rb +30 -0
- data/lib/view_component/slot.rb +2 -5
- data/lib/view_component/slotable.rb +31 -39
- data/lib/view_component/system_test_helpers.rb +1 -2
- data/lib/view_component/template.rb +106 -83
- data/lib/view_component/test_helpers.rb +22 -42
- data/lib/view_component/translatable.rb +24 -23
- data/lib/view_component/use_helpers.rb +3 -4
- data/lib/view_component/version.rb +3 -3
- data/lib/view_component.rb +0 -1
- metadata +73 -220
- data/app/assets/vendor/prism.css +0 -4
- data/app/assets/vendor/prism.min.js +0 -12
- data/app/helpers/preview_helper.rb +0 -85
- data/app/views/view_components/_preview_source.html.erb +0 -17
- data/lib/rails/generators/abstract_generator.rb +0 -56
- data/lib/rails/generators/component/USAGE +0 -13
- data/lib/rails/generators/component/component_generator.rb +0 -67
- data/lib/rails/generators/component/templates/component.rb.tt +0 -16
- data/lib/rails/generators/erb/component_generator.rb +0 -33
- data/lib/rails/generators/erb/templates/component.html.erb.tt +0 -1
- data/lib/rails/generators/haml/component_generator.rb +0 -22
- data/lib/rails/generators/haml/templates/component.html.haml.tt +0 -1
- data/lib/rails/generators/locale/component_generator.rb +0 -46
- data/lib/rails/generators/preview/component_generator.rb +0 -39
- data/lib/rails/generators/preview/templates/component_preview.rb.tt +0 -9
- data/lib/rails/generators/rspec/component_generator.rb +0 -31
- data/lib/rails/generators/rspec/templates/component_spec.rb.tt +0 -15
- data/lib/rails/generators/slim/component_generator.rb +0 -22
- data/lib/rails/generators/slim/templates/component.html.slim.tt +0 -1
- data/lib/rails/generators/stimulus/component_generator.rb +0 -44
- data/lib/rails/generators/stimulus/templates/component_controller.js.tt +0 -7
- data/lib/rails/generators/stimulus/templates/component_controller.ts.tt +0 -9
- data/lib/rails/generators/tailwindcss/component_generator.rb +0 -11
- data/lib/rails/generators/tailwindcss/templates/component.html.erb.tt +0 -1
- data/lib/rails/generators/test_unit/component_generator.rb +0 -20
- data/lib/rails/generators/test_unit/templates/component_test.rb.tt +0 -12
- data/lib/view_component/component_error.rb +0 -6
- data/lib/view_component/docs_builder_component.html.erb +0 -22
- data/lib/view_component/docs_builder_component.rb +0 -96
- data/lib/view_component/rails/tasks/view_component.rake +0 -20
- data/lib/view_component/render_component_helper.rb +0 -10
- data/lib/view_component/render_component_to_string_helper.rb +0 -9
- data/lib/view_component/render_monkey_patch.rb +0 -13
- data/lib/view_component/render_to_string_monkey_patch.rb +0 -13
- data/lib/view_component/rendering_component_helper.rb +0 -9
- data/lib/view_component/rendering_monkey_patch.rb +0 -13
- data/lib/yard/mattr_accessor_handler.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35393079b843dba053e2e4acca6429b8181a5c255c5843c7ad39fcb5245b8762
|
4
|
+
data.tar.gz: a9a602a05dd03d1865bfef3115904f8f7afec7bccbddc2497469638982259875
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04e1d26d5f24f76c75cf4b105842b71ce31887ec8ec939e6c9a232f1c0bca48fe61bdad32e602773aa95f19c338a2d2fc4962a381fc025bf3ea356d1343cbf80
|
7
|
+
data.tar.gz: b2c254c725e460a0dc16cd90300218ffff424c889946b7df9e31561b93d89dba304510e07afd48d014fdf1f576d07aa9e59ac75e2dce0822fb45fac7b7f9fdf1
|
@@ -10,18 +10,11 @@ module ViewComponent
|
|
10
10
|
around_action :set_locale, only: :previews
|
11
11
|
before_action :require_local!, unless: :show_previews?
|
12
12
|
|
13
|
-
content_security_policy(false)
|
13
|
+
content_security_policy(false)
|
14
14
|
|
15
15
|
# Including helpers here ensures that we're loading the
|
16
16
|
# latest version of helpers if code-reloading is enabled
|
17
|
-
if include_all_helpers
|
18
|
-
helper :all
|
19
|
-
else
|
20
|
-
# :nocov:
|
21
|
-
# Always provide the #view_source helper
|
22
|
-
helper PreviewHelper
|
23
|
-
# :nocov:
|
24
|
-
end
|
17
|
+
helper :all if include_all_helpers
|
25
18
|
end
|
26
19
|
|
27
20
|
def index
|
@@ -1,30 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ViewComponentsSystemTestController < ActionController::Base # :nodoc:
|
4
|
-
|
5
|
-
|
4
|
+
if Rails.env.test?
|
5
|
+
before_action :validate_file_path
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def system_test_entrypoint
|
12
|
-
render file: @path
|
13
|
-
end
|
7
|
+
def self.temp_dir
|
8
|
+
@_tmpdir ||= FileUtils.mkdir_p("./tmp/view_components/").first
|
9
|
+
end
|
14
10
|
|
15
|
-
|
11
|
+
def system_test_entrypoint
|
12
|
+
render file: @path
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
raise ViewComponent::SystemTestControllerOnlyAllowedInTestError unless Rails.env.test?
|
19
|
-
end
|
15
|
+
private
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
17
|
+
# Ensure that the file path is valid and doesn't target files outside
|
18
|
+
# the expected directory (e.g. via a path traversal or symlink attack)
|
19
|
+
def validate_file_path
|
20
|
+
base_path = ::File.realpath(self.class.temp_dir)
|
21
|
+
@path = ::File.realpath(params.permit(:file)[:file], base_path)
|
22
|
+
unless @path.start_with?(base_path)
|
23
|
+
raise ViewComponent::SystemTestControllerNefariousPathError
|
24
|
+
end
|
28
25
|
end
|
29
26
|
end
|
30
27
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render AssetComponent.new %>
|
@@ -1,13 +1,5 @@
|
|
1
1
|
<% if @render_args[:component] %>
|
2
|
-
|
3
|
-
<%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
|
4
|
-
<% else %>
|
5
|
-
<%= render_component(@render_args[:component], &@render_args[:block]) %>
|
6
|
-
<% end %>
|
2
|
+
<%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
|
7
3
|
<% else %>
|
8
4
|
<%= render template: @render_args[:template], locals: @render_args[:locals] || {} %>
|
9
5
|
<% end %>
|
10
|
-
|
11
|
-
<% if ViewComponent::Base.config.show_previews_source %>
|
12
|
-
<%= preview_source %>
|
13
|
-
<% end %>
|
data/docs/CHANGELOG.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
layout: default
|
3
3
|
title: Changelog
|
4
|
-
nav_order:
|
4
|
+
nav_order: 6
|
5
5
|
---
|
6
6
|
|
7
7
|
<!-- Add unreleased changes under the "main" heading. -->
|
@@ -10,6 +10,138 @@ nav_order: 5
|
|
10
10
|
|
11
11
|
## main
|
12
12
|
|
13
|
+
## 4.0.0.alpha2
|
14
|
+
|
15
|
+
* Add `#current_template` accessor and `Template#path` for diagnostic usage.
|
16
|
+
|
17
|
+
*Joel Hawksley*
|
18
|
+
|
19
|
+
## 4.0.0.alpha1
|
20
|
+
|
21
|
+
Almost six years after releasing [v1.0.0](https://github.com/ViewComponent/view_component/releases/tag/v1.0.0), we're proud to ship ViewComponent 4. This release marks a shift towards a Long Term Support model for the project, having reached significant feature maturity. While contributions are always welcome, we're unlikely to accept further breaking changes or major feature additions.
|
22
|
+
|
23
|
+
This release makes the following breaking changes:
|
24
|
+
|
25
|
+
* BREAKING: `--inline` generator option now generates inline template. Use `--call` to generate `#call` method.
|
26
|
+
|
27
|
+
*Joel Hawksley*
|
28
|
+
|
29
|
+
* BREAKING: Remove `use_deprecated_instrumentation_name` configuration option. Events will always use `render.view_component` name.
|
30
|
+
|
31
|
+
*Joel Hawksley*
|
32
|
+
|
33
|
+
* BREAKING: Remove `preview_source` functionality. Consider using [Lookbook](https://lookbook.build/) instead.
|
34
|
+
|
35
|
+
*Joel Hawksley*
|
36
|
+
|
37
|
+
* BREAKING: Use `Nokogiri::HTML5` instead of `Nokogiri::HTML4` for test helpers.
|
38
|
+
|
39
|
+
*Noah Silvera*, *Joel Hawksley*
|
40
|
+
|
41
|
+
* BREAKING: Move generators to a ViewComponent namespace.
|
42
|
+
|
43
|
+
Before, ViewComponent generators pollute the generator namespace with a bunch of top level items, and claim the generic "component" name.
|
44
|
+
|
45
|
+
Now, generators live in a "view_component" module/namespace, so what was before `rails g
|
46
|
+
component` is now `rails g view_component:component`.
|
47
|
+
|
48
|
+
*Paul Sadauskas*
|
49
|
+
|
50
|
+
* BREAKING: Require [non-EOL](https://endoflife.date/rails) Rails (`>= 7.1.0`).
|
51
|
+
|
52
|
+
*Joel Hawksley*
|
53
|
+
|
54
|
+
* BREAKING: Require [non-EOL](https://www.ruby-lang.org/en/downloads/branches/) Ruby (`>= 3.2.0`).
|
55
|
+
|
56
|
+
*Joel Hawksley*
|
57
|
+
|
58
|
+
* BREAKING: Remove `render_component` and `render` monkey patch configured with `render_monkey_patch_enabled`.
|
59
|
+
|
60
|
+
*Joel Hawksley*
|
61
|
+
|
62
|
+
* BREAKING: Remove support for variant names containing `.` to be consistent with Rails.
|
63
|
+
|
64
|
+
*Stephen Nelson*
|
65
|
+
|
66
|
+
* BREAKING: Use ActionView's `lookup_context` for picking templates instead of the request format.
|
67
|
+
|
68
|
+
3.15 added support for using templates that match the request format, i.e. if `/resource.csv` is requested then
|
69
|
+
ViewComponents would pick `_component.csv.erb` over `_component.html.erb`.
|
70
|
+
|
71
|
+
With this release, the request format is no longer considered and instead ViewComponent will use the Rails logic
|
72
|
+
for picking the most appropriate template type, i.e. the csv template will be used if it matches the `Accept` header
|
73
|
+
or because the controller uses a `respond_to` block to pick the response format.
|
74
|
+
|
75
|
+
*Stephen Nelson*
|
76
|
+
|
77
|
+
* BREAKING: Rename internal methods to have `__vc_` prefix if they shouldn't be used by consumers. Make internal constants private. Make `Collection#components`, `Slotable#register_polymorphic_slot` private. Remove unused `ComponentError` class.
|
78
|
+
|
79
|
+
*Joel Hawksley*
|
80
|
+
|
81
|
+
* Fix bug where request-aware helpers did not work outside of the request context.
|
82
|
+
|
83
|
+
*Joel Hawksley*, *Stephen Nelson*
|
84
|
+
|
85
|
+
* `ViewComponentsSystemTestController` should not be useable outside of test environment
|
86
|
+
|
87
|
+
*Joel Hawksley*, *Stephen Nelson*
|
88
|
+
|
89
|
+
* Remove unnecessary ENABLE_RELOADING test suite flag.
|
90
|
+
|
91
|
+
*Joel Hawksley*
|
92
|
+
|
93
|
+
* Add test coverage for uncovered code.
|
94
|
+
|
95
|
+
*Joel Hawksley*
|
96
|
+
|
97
|
+
* Remove unnecessary `#format` methods that returned `nil`.
|
98
|
+
|
99
|
+
*Joel Hawksley*
|
100
|
+
|
101
|
+
* Clean up project dependencies, relaxing versions of development gems.
|
102
|
+
|
103
|
+
*Joel Hawksley*
|
104
|
+
|
105
|
+
* Test against `turbo-rails` `v2`.
|
106
|
+
|
107
|
+
*Joel Hawksley*
|
108
|
+
|
109
|
+
* Test against `rspec-rails` `v7`.
|
110
|
+
|
111
|
+
*Joel Hawksley*
|
112
|
+
|
113
|
+
* Remove unnecessary usage of `ruby2_keywords`.
|
114
|
+
|
115
|
+
*Joel Hawksley*
|
116
|
+
|
117
|
+
* Remove unnecessary `respond_to` checks.
|
118
|
+
|
119
|
+
*Tiago Menegaz*, *Joel Hawksley*
|
120
|
+
|
121
|
+
* Do not include internal `DocsBuilderComponent` or `YARD::MattrAccessorHandler` in published gem.
|
122
|
+
|
123
|
+
*Joel Hawksley*
|
124
|
+
|
125
|
+
* Only lock to `concurrent-ruby` `1.3.4` for Rails 6.1.
|
126
|
+
|
127
|
+
*Joel Hawksley*
|
128
|
+
|
129
|
+
* Fix generation of ViewComponent documentation that was broken due to HTML safety issues.
|
130
|
+
|
131
|
+
*Simon Fish*
|
132
|
+
|
133
|
+
* Add documentation on how ViewComponent works.
|
134
|
+
|
135
|
+
*Joel Hawksley*
|
136
|
+
|
137
|
+
* Clarify that `config.use_deprecated_instrumentation_name` will be removed in v4.
|
138
|
+
|
139
|
+
*Joel Hawksley*
|
140
|
+
|
141
|
+
* Run RSpec tests in CI.
|
142
|
+
|
143
|
+
*Joel Hawksley*
|
144
|
+
|
13
145
|
## 3.22.0
|
14
146
|
|
15
147
|
* Rewrite `ViewComponents at GitHub` documentation as more general `Best practices`.
|
data/lib/view_component/base.rb
CHANGED
@@ -9,6 +9,7 @@ require "view_component/config"
|
|
9
9
|
require "view_component/errors"
|
10
10
|
require "view_component/inline_template"
|
11
11
|
require "view_component/preview"
|
12
|
+
require "view_component/request_details"
|
12
13
|
require "view_component/slotable"
|
13
14
|
require "view_component/slotable_default"
|
14
15
|
require "view_component/template"
|
@@ -39,9 +40,6 @@ module ViewComponent
|
|
39
40
|
include ViewComponent::Translatable
|
40
41
|
include ViewComponent::WithContentHelper
|
41
42
|
|
42
|
-
RESERVED_PARAMETER = :content
|
43
|
-
VC_INTERNAL_DEFAULT_FORMAT = :html
|
44
|
-
|
45
43
|
# For CSRF authenticity tokens in forms
|
46
44
|
delegate :form_authenticity_token, :protect_against_forgery?, :config, to: :helpers
|
47
45
|
|
@@ -49,10 +47,10 @@ module ViewComponent
|
|
49
47
|
delegate :content_security_policy_nonce, to: :helpers
|
50
48
|
|
51
49
|
# Config option that strips trailing whitespace in templates before compiling them.
|
52
|
-
class_attribute :__vc_strip_trailing_whitespace, instance_accessor: false, instance_predicate: false
|
53
|
-
self.__vc_strip_trailing_whitespace = false # class_attribute:default doesn't work until Rails 5.2
|
50
|
+
class_attribute :__vc_strip_trailing_whitespace, instance_accessor: false, instance_predicate: false, default: false
|
54
51
|
|
55
52
|
attr_accessor :__vc_original_view_context
|
53
|
+
attr_reader :current_template
|
56
54
|
|
57
55
|
# Components render in their own view context. Helpers and other functionality
|
58
56
|
# require a reference to the original Rails view context, an instance of
|
@@ -67,6 +65,8 @@ module ViewComponent
|
|
67
65
|
self.__vc_original_view_context = view_context
|
68
66
|
end
|
69
67
|
|
68
|
+
using RequestDetails
|
69
|
+
|
70
70
|
# Entrypoint for rendering components.
|
71
71
|
#
|
72
72
|
# - `view_context`: ActionView context from calling view
|
@@ -76,7 +76,7 @@ module ViewComponent
|
|
76
76
|
#
|
77
77
|
# @return [String]
|
78
78
|
def render_in(view_context, &block)
|
79
|
-
self.class.
|
79
|
+
self.class.__vc_compile(raise_errors: true)
|
80
80
|
|
81
81
|
@view_context = view_context
|
82
82
|
self.__vc_original_view_context ||= view_context
|
@@ -85,22 +85,18 @@ module ViewComponent
|
|
85
85
|
|
86
86
|
@lookup_context ||= view_context.lookup_context
|
87
87
|
|
88
|
-
# required for path helpers in older Rails versions
|
89
|
-
@view_renderer ||= view_context.view_renderer
|
90
|
-
|
91
88
|
# For content_for
|
92
89
|
@view_flow ||= view_context.view_flow
|
93
90
|
|
94
91
|
# For i18n
|
95
92
|
@virtual_path ||= virtual_path
|
96
93
|
|
97
|
-
#
|
98
|
-
@
|
94
|
+
# Describes the inferred request constraints (locales, formats, variants)
|
95
|
+
@__vc_requested_details ||= @lookup_context.vc_requested_details
|
99
96
|
|
100
97
|
# For caching, such as #cache_if
|
101
98
|
@current_template = nil unless defined?(@current_template)
|
102
99
|
old_current_template = @current_template
|
103
|
-
@current_template = self
|
104
100
|
|
105
101
|
if block && defined?(@__vc_content_set_by_with_content)
|
106
102
|
raise DuplicateContentError.new(self.class.name)
|
@@ -112,7 +108,7 @@ module ViewComponent
|
|
112
108
|
before_render
|
113
109
|
|
114
110
|
if render?
|
115
|
-
rendered_template = render_template_for(@
|
111
|
+
rendered_template = render_template_for(@__vc_requested_details).to_s
|
116
112
|
|
117
113
|
# Avoid allocating new string when output_preamble and output_postamble are blank
|
118
114
|
if output_preamble.blank? && output_postamble.blank?
|
@@ -160,7 +156,7 @@ module ViewComponent
|
|
160
156
|
target_render = self.class.instance_variable_get(:@__vc_ancestor_calls)[@__vc_parent_render_level]
|
161
157
|
@__vc_parent_render_level += 1
|
162
158
|
|
163
|
-
target_render.bind_call(self, @
|
159
|
+
target_render.bind_call(self, @__vc_requested_details)
|
164
160
|
ensure
|
165
161
|
@__vc_parent_render_level -= 1
|
166
162
|
end
|
@@ -195,6 +191,8 @@ module ViewComponent
|
|
195
191
|
true
|
196
192
|
end
|
197
193
|
|
194
|
+
# Override the ActionView::Base initializer so that components
|
195
|
+
# do not need to define their own initializers.
|
198
196
|
# @private
|
199
197
|
def initialize(*)
|
200
198
|
end
|
@@ -203,7 +201,7 @@ module ViewComponent
|
|
203
201
|
#
|
204
202
|
# This prevents an exception when rendering a partial inside of a component that has also been rendered outside
|
205
203
|
# of the component. This is due to the partials compiled template method existing in the parent `view_context`,
|
206
|
-
#
|
204
|
+
# and not the component's `view_context`.
|
207
205
|
#
|
208
206
|
# @private
|
209
207
|
def render(options = {}, args = {}, &block)
|
@@ -271,13 +269,6 @@ module ViewComponent
|
|
271
269
|
[]
|
272
270
|
end
|
273
271
|
|
274
|
-
# For caching, such as #cache_if
|
275
|
-
#
|
276
|
-
# @private
|
277
|
-
def format
|
278
|
-
@__vc_variant if defined?(@__vc_variant)
|
279
|
-
end
|
280
|
-
|
281
272
|
# The current request. Use sparingly as doing so introduces coupling that
|
282
273
|
# inhibits encapsulation & reuse, often making testing difficult.
|
283
274
|
#
|
@@ -286,10 +277,9 @@ module ViewComponent
|
|
286
277
|
__vc_request
|
287
278
|
end
|
288
279
|
|
289
|
-
# Enables consumers to override request/@request
|
290
|
-
#
|
291
280
|
# @private
|
292
281
|
def __vc_request
|
282
|
+
# The current request (if present, as mailers/jobs/etc do not have a request)
|
293
283
|
@__vc_request ||= controller.request if controller.respond_to?(:request)
|
294
284
|
end
|
295
285
|
|
@@ -332,7 +322,7 @@ module ViewComponent
|
|
332
322
|
end
|
333
323
|
|
334
324
|
def maybe_escape_html(text)
|
335
|
-
return text if
|
325
|
+
return text if @current_template && !@current_template.html?
|
336
326
|
return text if text.blank?
|
337
327
|
|
338
328
|
if text.html_safe?
|
@@ -365,13 +355,6 @@ module ViewComponent
|
|
365
355
|
# configured on a per-test basis using `with_controller_class`.
|
366
356
|
#
|
367
357
|
|
368
|
-
# Set if render monkey patches should be included or not in Rails <6.1:
|
369
|
-
#
|
370
|
-
# ```ruby
|
371
|
-
# config.view_component.render_monkey_patch_enabled = false
|
372
|
-
# ```
|
373
|
-
#
|
374
|
-
|
375
358
|
# Path for component files
|
376
359
|
#
|
377
360
|
# ```ruby
|
@@ -520,20 +503,20 @@ module ViewComponent
|
|
520
503
|
def inherited(child)
|
521
504
|
# Compile so child will inherit compiled `call_*` template methods that
|
522
505
|
# `compile` defines
|
523
|
-
|
506
|
+
__vc_compile
|
524
507
|
|
525
508
|
# Give the child its own personal #render_template_for to protect against the case when
|
526
509
|
# eager loading is disabled and the parent component is rendered before the child. In
|
527
510
|
# such a scenario, the parent will override ViewComponent::Base#render_template_for,
|
528
511
|
# meaning it will not be called for any children and thus not compile their templates.
|
529
|
-
if !child.instance_methods(false).include?(:render_template_for) && !child.
|
512
|
+
if !child.instance_methods(false).include?(:render_template_for) && !child.__vc_compiled?
|
530
513
|
child.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
531
|
-
def render_template_for(
|
514
|
+
def render_template_for(requested_details)
|
532
515
|
# Force compilation here so the compiler always redefines render_template_for.
|
533
516
|
# This is mostly a safeguard to prevent infinite recursion.
|
534
|
-
self.class.
|
535
|
-
# .
|
536
|
-
render_template_for(
|
517
|
+
self.class.__vc_compile(raise_errors: true, force: true)
|
518
|
+
# .__vc_compile replaces this method; call the new one
|
519
|
+
render_template_for(requested_details)
|
537
520
|
end
|
538
521
|
RUBY
|
539
522
|
end
|
@@ -572,22 +555,22 @@ module ViewComponent
|
|
572
555
|
end
|
573
556
|
|
574
557
|
# @private
|
575
|
-
def
|
576
|
-
|
558
|
+
def __vc_compiled?
|
559
|
+
__vc_compiler.compiled?
|
577
560
|
end
|
578
561
|
|
579
562
|
# @private
|
580
|
-
def
|
581
|
-
|
563
|
+
def __vc_ensure_compiled
|
564
|
+
__vc_compile unless __vc_compiled?
|
582
565
|
end
|
583
566
|
|
584
567
|
# @private
|
585
|
-
def
|
586
|
-
|
568
|
+
def __vc_compile(raise_errors: false, force: false)
|
569
|
+
__vc_compiler.compile(raise_errors: raise_errors, force: force)
|
587
570
|
end
|
588
571
|
|
589
572
|
# @private
|
590
|
-
def
|
573
|
+
def __vc_compiler
|
591
574
|
@__vc_compiler ||= Compiler.new(self)
|
592
575
|
end
|
593
576
|
|
@@ -629,8 +612,8 @@ module ViewComponent
|
|
629
612
|
# is accepted, as support for collection
|
630
613
|
# rendering is optional.
|
631
614
|
# @private
|
632
|
-
def
|
633
|
-
parameter = validate_default ?
|
615
|
+
def __vc_validate_collection_parameter!(validate_default: false)
|
616
|
+
parameter = validate_default ? __vc_collection_parameter : provided_collection_parameter
|
634
617
|
|
635
618
|
return unless parameter
|
636
619
|
return if initialize_parameter_names.include?(parameter) || splatted_keyword_argument_present?
|
@@ -649,35 +632,35 @@ module ViewComponent
|
|
649
632
|
# invalid parameters that could override the framework's
|
650
633
|
# methods.
|
651
634
|
# @private
|
652
|
-
def
|
653
|
-
return unless initialize_parameter_names.include?(
|
635
|
+
def __vc_validate_initialization_parameters!
|
636
|
+
return unless initialize_parameter_names.include?(:content)
|
654
637
|
|
655
|
-
raise ReservedParameterError.new(name,
|
638
|
+
raise ReservedParameterError.new(name, :content)
|
656
639
|
end
|
657
640
|
|
658
641
|
# @private
|
659
|
-
def
|
642
|
+
def __vc_collection_parameter
|
660
643
|
provided_collection_parameter || name && name.demodulize.underscore.chomp("_component").to_sym
|
661
644
|
end
|
662
645
|
|
663
646
|
# @private
|
664
|
-
def
|
665
|
-
:"#{
|
647
|
+
def __vc_collection_counter_parameter
|
648
|
+
:"#{__vc_collection_parameter}_counter"
|
666
649
|
end
|
667
650
|
|
668
651
|
# @private
|
669
|
-
def
|
670
|
-
initialize_parameter_names.include?(
|
652
|
+
def __vc_counter_argument_present?
|
653
|
+
initialize_parameter_names.include?(__vc_collection_counter_parameter)
|
671
654
|
end
|
672
655
|
|
673
656
|
# @private
|
674
|
-
def
|
675
|
-
:"#{
|
657
|
+
def __vc_collection_iteration_parameter
|
658
|
+
:"#{__vc_collection_parameter}_iteration"
|
676
659
|
end
|
677
660
|
|
678
661
|
# @private
|
679
|
-
def
|
680
|
-
initialize_parameter_names.include?(
|
662
|
+
def __vc_iteration_argument_present?
|
663
|
+
initialize_parameter_names.include?(__vc_collection_iteration_parameter)
|
681
664
|
end
|
682
665
|
|
683
666
|
private
|
@@ -690,8 +673,6 @@ module ViewComponent
|
|
690
673
|
def initialize_parameter_names
|
691
674
|
return attribute_names.map(&:to_sym) if respond_to?(:attribute_names)
|
692
675
|
|
693
|
-
return attribute_types.keys.map(&:to_sym) if Rails::VERSION::MAJOR <= 5 && respond_to?(:attribute_types)
|
694
|
-
|
695
676
|
initialize_parameters.map(&:last)
|
696
677
|
end
|
697
678
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "action_view/renderer/collection_renderer"
|
3
|
+
require "action_view/renderer/collection_renderer"
|
4
4
|
|
5
5
|
module ViewComponent
|
6
6
|
class Collection
|
@@ -22,12 +22,18 @@ module ViewComponent
|
|
22
22
|
end.join(rendered_spacer(view_context)).html_safe
|
23
23
|
end
|
24
24
|
|
25
|
+
def each(&block)
|
26
|
+
components.each(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
25
31
|
def components
|
26
32
|
return @components if defined? @components
|
27
33
|
|
28
34
|
iterator = ActionView::PartialIteration.new(@collection.size)
|
29
35
|
|
30
|
-
component.
|
36
|
+
component.__vc_validate_collection_parameter!(validate_default: true)
|
31
37
|
|
32
38
|
@components = @collection.map do |item|
|
33
39
|
component.new(**component_options(item, iterator)).tap do |component|
|
@@ -36,18 +42,6 @@ module ViewComponent
|
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
39
|
-
def each(&block)
|
40
|
-
components.each(&block)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Rails expects us to define `format` on all renderables,
|
44
|
-
# but we do not know the `format` of a ViewComponent until runtime.
|
45
|
-
def format
|
46
|
-
nil
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
45
|
def initialize(component, object, spacer_component, **options)
|
52
46
|
@component = component
|
53
47
|
@collection = collection_variable(object || [])
|
@@ -64,9 +58,9 @@ module ViewComponent
|
|
64
58
|
end
|
65
59
|
|
66
60
|
def component_options(item, iterator)
|
67
|
-
item_options = {component.
|
68
|
-
item_options[component.
|
69
|
-
item_options[component.
|
61
|
+
item_options = {component.__vc_collection_parameter => item}
|
62
|
+
item_options[component.__vc_collection_counter_parameter] = iterator.index if component.__vc_counter_argument_present?
|
63
|
+
item_options[component.__vc_collection_iteration_parameter] = iterator.dup if component.__vc_iteration_argument_present?
|
70
64
|
|
71
65
|
@options.merge(item_options)
|
72
66
|
end
|