view_component 2.82.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of view_component might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/controllers/view_components_system_test_controller.rb +24 -1
- data/app/helpers/preview_helper.rb +2 -4
- data/docs/CHANGELOG.md +278 -0
- data/lib/view_component/base.rb +41 -92
- data/lib/view_component/capture_compatibility.rb +44 -0
- data/lib/view_component/collection.rb +2 -5
- data/lib/view_component/compiler.rb +51 -28
- data/lib/view_component/config.rb +9 -13
- data/lib/view_component/deprecation.rb +1 -1
- data/lib/view_component/docs_builder_component.html.erb +5 -1
- data/lib/view_component/docs_builder_component.rb +28 -9
- data/lib/view_component/engine.rb +12 -22
- data/lib/view_component/errors.rb +213 -0
- data/lib/view_component/inline_template.rb +55 -0
- data/lib/view_component/preview.rb +1 -7
- data/lib/view_component/rails/tasks/view_component.rake +1 -1
- data/lib/view_component/slot.rb +107 -1
- data/lib/view_component/slotable.rb +356 -96
- data/lib/view_component/system_test_helpers.rb +5 -5
- data/lib/view_component/test_helpers.rb +67 -54
- data/lib/view_component/translatable.rb +35 -23
- data/lib/view_component/version.rb +4 -3
- data/lib/view_component/with_content_helper.rb +3 -8
- data/lib/view_component.rb +3 -12
- metadata +28 -17
- data/lib/view_component/content_areas.rb +0 -56
- data/lib/view_component/polymorphic_slots.rb +0 -103
- data/lib/view_component/preview_template_error.rb +0 -6
- data/lib/view_component/slot_v2.rb +0 -98
- data/lib/view_component/slotable_v2.rb +0 -391
- data/lib/view_component/template_error.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 639cd1c50a78567738c9d90363e98cb740f1f45ca70c9cb7ea20d22aacbce6e9
|
4
|
+
data.tar.gz: cbec2597e6193dcb43ddab199d1147977d505dd320b765ed38eb11f877917f23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b26863964af13fd7c3bca798f4acd88c87709965badda42b02fe8125151f6e91b879e5118551d5b4c041509bbe26c2d463fcd4470bf6cbe5f946bc99c34f6a9c
|
7
|
+
data.tar.gz: e170eae333570563f5e068e8cbc1c4cfab05363671a9691169eaa2cbb30202076d38d8b59b8d7b28a73ab8777542c9173455e6f828f5f7344a3213424a69d049
|
@@ -1,7 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ViewComponentsSystemTestController < ActionController::Base # :nodoc:
|
4
|
+
before_action :validate_test_env
|
5
|
+
before_action :validate_file_path
|
6
|
+
|
7
|
+
def self.temp_dir
|
8
|
+
@_tmpdir ||= FileUtils.mkdir_p("./tmp/view_components/").first
|
9
|
+
end
|
10
|
+
|
4
11
|
def system_test_entrypoint
|
5
|
-
render file:
|
12
|
+
render file: @path
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def validate_test_env
|
18
|
+
raise ViewComponent::SystemTestControllerOnlyAllowedInTestError unless Rails.env.test?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Ensure that the file path is valid and doesn't target files outside
|
22
|
+
# the expected directory (e.g. via a path traversal or symlink attack)
|
23
|
+
def validate_file_path
|
24
|
+
base_path = ::File.realpath(self.class.temp_dir)
|
25
|
+
@path = ::File.realpath(params.permit(:file)[:file], base_path)
|
26
|
+
unless @path.start_with?(base_path)
|
27
|
+
raise ViewComponent::SystemTestControllerNefariousPathError
|
28
|
+
end
|
6
29
|
end
|
7
30
|
end
|
@@ -31,10 +31,8 @@ module PreviewHelper
|
|
31
31
|
path =~ /#{template_identifier}*.(html)/
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
raise "found 0 matches for templates for #{template_identifier}." if matching_templates.empty?
|
37
|
-
raise "found multiple templates for #{template_identifier}." if matching_templates.size > 1
|
34
|
+
raise ViewComponent::NoMatchingTemplatesForPreviewError.new(template_identifier) if matching_templates.empty?
|
35
|
+
raise ViewComponent::MultipleMatchingTemplatesForPreviewError.new(template_identifier) if matching_templates.size > 1
|
38
36
|
|
39
37
|
template_file_path = matching_templates.first
|
40
38
|
template_source = File.read(template_file_path)
|
data/docs/CHANGELOG.md
CHANGED
@@ -10,6 +10,284 @@ nav_order: 5
|
|
10
10
|
|
11
11
|
## main
|
12
12
|
|
13
|
+
### v3.0.0
|
14
|
+
|
15
|
+
1,000+ days and 100+ releases later, the 200+ contributors to ViewComponent are proud to ship v3.0.0!
|
16
|
+
|
17
|
+
We're so grateful for all the work of community members to get us to this release. Whether it’s filing bug reports, designing APIs in long-winded discussion threads, or writing code itself, ViewComponent is built by the community, for the community. We couldn’t be more proud of what we’re building together :heart:
|
18
|
+
|
19
|
+
This release makes the following breaking changes, many of which have long been deprecated:
|
20
|
+
|
21
|
+
* BREAKING: Remove deprecated slots setter methods. Use `with_SLOT_NAME` instead.
|
22
|
+
|
23
|
+
*Joel Hawksley*
|
24
|
+
|
25
|
+
* BREAKING: Remove deprecated SlotsV1 in favor of current SlotsV2.
|
26
|
+
|
27
|
+
*Joel Hawksley*
|
28
|
+
|
29
|
+
* BREAKING: Remove deprecated `content_areas` feature. Use Slots instead.
|
30
|
+
|
31
|
+
*Joel Hawksley*
|
32
|
+
|
33
|
+
* BREAKING: Remove deprecated support for loading ViewComponent engine manually. Make sure `require "view_component/engine"` is removed from `Gemfile`.
|
34
|
+
|
35
|
+
*Joel Hawksley*
|
36
|
+
|
37
|
+
* BREAKING: Remove deprecated `generate_*` methods. Use `generate.*` instead.
|
38
|
+
|
39
|
+
*Joel Hawksley*
|
40
|
+
|
41
|
+
* BREAKING: Remove deprecated `with_variant` method.
|
42
|
+
|
43
|
+
*Joel Hawksley*
|
44
|
+
|
45
|
+
* BREAKING: Remove deprecated `rendered_component` in favor of `rendered_content`.
|
46
|
+
|
47
|
+
*Joel Hawksley*
|
48
|
+
|
49
|
+
* BREAKING: Remove deprecated `config.preview_path` in favor of `config.preview_paths`.
|
50
|
+
|
51
|
+
*Joel Hawksley*
|
52
|
+
|
53
|
+
* BREAKING: Support Ruby 2.7+ instead of 2.4+
|
54
|
+
|
55
|
+
*Joel Hawksley*
|
56
|
+
|
57
|
+
* BREAKING: Remove deprecated `before_render_check`.
|
58
|
+
|
59
|
+
*Joel Hawksley*
|
60
|
+
|
61
|
+
* BREAKING: Change counter variable to start iterating from `0` instead of `1`.
|
62
|
+
|
63
|
+
*Frank S*
|
64
|
+
|
65
|
+
* BREAKING: `#SLOT_NAME` getter no longer accepts arguments. This change was missed as part of the earlier deprecation in `3.0.0.rc1`.
|
66
|
+
|
67
|
+
*Joel Hawksley*
|
68
|
+
|
69
|
+
* BREAKING: Raise `TranslateCalledBeforeRenderError`, `ControllerCalledBeforeRenderError`, or `HelpersCalledBeforeRenderError` instead of `ViewContextCalledBeforeRenderError`.
|
70
|
+
|
71
|
+
*Joel Hawksley*
|
72
|
+
|
73
|
+
* BREAKING: Raise `SlotPredicateNameError`, `RedefinedSlotError`, `ReservedSingularSlotNameError`, `ContentSlotNameError`, `InvalidSlotDefinitionError`, `ReservedPluralSlotNameError`, `ContentAlreadySetForPolymorphicSlotErrror`, `SystemTestControllerOnlyAllowedInTestError`, `SystemTestControllerNefariousPathError`, `NoMatchingTemplatesForPreviewError`, `MultipleMatchingTemplatesForPreviewError`, `DuplicateContentError`, `EmptyOrInvalidInitializerError`, `MissingCollectionArgumentError`, `ReservedParameterError`, `InvalidCollectionArgumentError`, `MultipleInlineTemplatesError`, `MissingPreviewTemplateError`, `DuplicateSlotContentError` or `NilWithContentError` instead of generic error classes.
|
74
|
+
|
75
|
+
*Joel Hawksley*
|
76
|
+
|
77
|
+
* BREAKING: Rename `SlotV2` to `Slot` and `SlotableV2` to `Slotable`.
|
78
|
+
|
79
|
+
*Joel Hawksley*
|
80
|
+
|
81
|
+
* BREAKING: Incorporate `PolymorphicSlots` into `Slotable`. To migrate, remove any references to `PolymorphicSlots` as they are no longer necessary.
|
82
|
+
|
83
|
+
*Joel Hawksley*
|
84
|
+
|
85
|
+
* BREAKING: Rename private TestHelpers#controller, #build_controller, #request, and #preview_class to avoid conflicts. Note: While these methods were undocumented and marked as private, they were accessible in tests. As such, we're considering this to be a breaking change.
|
86
|
+
|
87
|
+
*Joel Hawksley*
|
88
|
+
|
89
|
+
### v3.0.0.rc6
|
90
|
+
|
91
|
+
Run into an issue with this release candidate? [Let us know](https://github.com/ViewComponent/view_component/issues/1629). We hope to release v3.0.0 in the near future!
|
92
|
+
|
93
|
+
* BREAKING: `#SLOT_NAME` getter no longer accepts arguments. This change was missed as part of the earlier deprecation in `3.0.0.rc1`.
|
94
|
+
|
95
|
+
*Joel Hawksley*
|
96
|
+
|
97
|
+
* BREAKING: Raise `TranslateCalledBeforeRenderError`, `ControllerCalledBeforeRenderError`, or `HelpersCalledBeforeRenderError` instead of `ViewContextCalledBeforeRenderError`.
|
98
|
+
|
99
|
+
*Joel Hawksley*
|
100
|
+
|
101
|
+
* BREAKING: Raise `SlotPredicateNameError`, `RedefinedSlotError`, `ReservedSingularSlotNameError`, `ContentSlotNameError`, `InvalidSlotDefinitionError`, `ReservedPluralSlotNameError`, `ContentAlreadySetForPolymorphicSlotErrror`, `SystemTestControllerOnlyAllowedInTestError`, `SystemTestControllerNefariousPathError`, `NoMatchingTemplatesForPreviewError`, `MultipleMatchingTemplatesForPreviewError`, `DuplicateContentError`, `EmptyOrInvalidInitializerError`, `MissingCollectionArgumentError`, `ReservedParameterError`, `InvalidCollectionArgumentError`, `MultipleInlineTemplatesError`, `MissingPreviewTemplateError`, `DuplicateSlotContentError` or `NilWithContentError` instead of generic error classes.
|
102
|
+
|
103
|
+
*Joel Hawksley*
|
104
|
+
|
105
|
+
* Fix bug where `content?` and `with_content` didn't work reliably with slots.
|
106
|
+
|
107
|
+
*Derek Kniffin, Joel Hawksley*
|
108
|
+
|
109
|
+
* Add `with_SLOT_NAME_content` helper.
|
110
|
+
|
111
|
+
*Will Cosgrove*
|
112
|
+
|
113
|
+
* Allow ActiveRecord objects to be passed to `renders_many`.
|
114
|
+
|
115
|
+
*Leigh Halliday*
|
116
|
+
|
117
|
+
* Fix broken links in documentation.
|
118
|
+
|
119
|
+
*Ellen Keal*
|
120
|
+
|
121
|
+
* Run `standardrb` against markdown in docs.
|
122
|
+
|
123
|
+
*Joel Hawksley*
|
124
|
+
|
125
|
+
* Allow `.with_content` to be redefined by components.
|
126
|
+
|
127
|
+
*Joel Hawksley*
|
128
|
+
|
129
|
+
* Run `standardrb` against markdown in docs.
|
130
|
+
|
131
|
+
*Joel Hawksley*
|
132
|
+
|
133
|
+
* Raise error if translations are used in initializer.
|
134
|
+
|
135
|
+
*Joel Hawksley*
|
136
|
+
|
137
|
+
## v3.0.0.rc5
|
138
|
+
|
139
|
+
Run into an issue with this release candidate? [Let us know](https://github.com/ViewComponent/view_component/issues/1629).
|
140
|
+
|
141
|
+
* Fix bug where `mkdir_p` failed due to incorrect permissions.
|
142
|
+
|
143
|
+
*Joel Hawksley*
|
144
|
+
|
145
|
+
* Check for inline `erb_template` calls when deciding whether to compile a component's superclass.
|
146
|
+
|
147
|
+
*Justin Kenyon*
|
148
|
+
|
149
|
+
* Protect against `SystemStackError` if `CaptureCompatibility` module is included more than once.
|
150
|
+
|
151
|
+
*Cameron Dutro*
|
152
|
+
|
153
|
+
## v3.0.0.rc4
|
154
|
+
|
155
|
+
Run into an issue with this release candidate? [Let us know](https://github.com/ViewComponent/view_component/issues/1629).
|
156
|
+
|
157
|
+
* Add `TestHelpers#vc_test_request`.
|
158
|
+
|
159
|
+
*Joel Hawksley*
|
160
|
+
|
161
|
+
## v3.0.0.rc3
|
162
|
+
|
163
|
+
Run into an issue with this release candidate? [Let us know](https://github.com/ViewComponent/view_component/issues/1629).
|
164
|
+
|
165
|
+
* Fix typos in generator docs.
|
166
|
+
|
167
|
+
*Sascha Karnatz*
|
168
|
+
|
169
|
+
* Add `TestHelpers#vc_test_controller`.
|
170
|
+
|
171
|
+
*Joel Hawksley*
|
172
|
+
|
173
|
+
* Document `config.view_component.capture_compatibility_patch_enabled` as option for the known incompatibilities with Rails form helpers.
|
174
|
+
|
175
|
+
*Tobias L. Maier*
|
176
|
+
|
177
|
+
* Add support for experimental inline templates.
|
178
|
+
|
179
|
+
*Blake Williams*
|
180
|
+
|
181
|
+
* Expose `translate` and `t` I18n methods on component classes.
|
182
|
+
|
183
|
+
*Elia Schito*
|
184
|
+
|
185
|
+
* Protect against Arbitrary File Read edge case in `ViewComponentsSystemTestController`.
|
186
|
+
|
187
|
+
*Nick Malcolm*
|
188
|
+
|
189
|
+
## v3.0.0.rc2
|
190
|
+
|
191
|
+
Run into an issue with this release? [Let us know](https://github.com/ViewComponent/view_component/issues/1629).
|
192
|
+
|
193
|
+
* BREAKING: Rename `SlotV2` to `Slot` and `SlotableV2` to `Slotable`.
|
194
|
+
|
195
|
+
*Joel Hawksley*
|
196
|
+
|
197
|
+
* BREAKING: Incorporate `PolymorphicSlots` into `Slotable`. To migrate, remove any references to `PolymorphicSlots` as they are no longer necessary.
|
198
|
+
|
199
|
+
*Joel Hawksley*
|
200
|
+
|
201
|
+
* BREAKING: Rename private TestHelpers#controller, #build_controller, #request, and #preview_class to avoid conflicts. Note: While these methods were undocumented and marked as private, they were accessible in tests. As such, we're considering this to be a breaking change.
|
202
|
+
|
203
|
+
*Joel Hawksley*
|
204
|
+
|
205
|
+
* Avoid loading ActionView::Base during Rails initialization. Originally submitted in #1528.
|
206
|
+
|
207
|
+
*Jonathan del Strother*
|
208
|
+
|
209
|
+
* Improve documentation of known incompatibilities with Rails form helpers.
|
210
|
+
|
211
|
+
*Tobias L. Maier*
|
212
|
+
|
213
|
+
* Remove dependency on environment task from `view_component:statsetup`.
|
214
|
+
|
215
|
+
*Svetlin Simonyan*
|
216
|
+
|
217
|
+
* Add experimental `config.view_component.capture_compatibility_patch_enabled` option resolving rendering issues related to forms, capture, turbo frames, etc.
|
218
|
+
|
219
|
+
*Blake Williams*
|
220
|
+
|
221
|
+
* Add `#content?` method that indicates if content has been passed to component.
|
222
|
+
|
223
|
+
*Joel Hawksley*
|
224
|
+
|
225
|
+
* Added example of a custom preview controller.
|
226
|
+
|
227
|
+
*Graham Rogers*
|
228
|
+
|
229
|
+
* Add Krystal to list of companies using ViewComponent.
|
230
|
+
|
231
|
+
*Matt Bearman*
|
232
|
+
|
233
|
+
* Add Mon Ami to list of companies using ViewComponent.
|
234
|
+
|
235
|
+
*Ethan Lee-Tyson*
|
236
|
+
|
237
|
+
## 3.0.0.rc1
|
238
|
+
|
239
|
+
1,000+ days and 100+ releases later, the 200+ contributors to ViewComponent are proud to ship v3.0.0!
|
240
|
+
|
241
|
+
We're so grateful for all the work of community members to get us to this release. Whether it’s filing bug reports, designing APIs in long-winded discussion threads, or writing code itself, ViewComponent is built by the community, for the community. We couldn’t be more proud of what we’re building together :heart:
|
242
|
+
|
243
|
+
This release makes the following breaking changes, many of which have long been deprecated:
|
244
|
+
|
245
|
+
* BREAKING: Remove deprecated slots setter methods. Use `with_SLOT_NAME` instead.
|
246
|
+
|
247
|
+
*Joel Hawksley*
|
248
|
+
|
249
|
+
* BREAKING: Remove deprecated SlotsV1 in favor of current SlotsV2.
|
250
|
+
|
251
|
+
*Joel Hawksley*
|
252
|
+
|
253
|
+
* BREAKING: Remove deprecated `content_areas` feature. Use Slots instead.
|
254
|
+
|
255
|
+
*Joel Hawksley*
|
256
|
+
|
257
|
+
* BREAKING: Remove deprecated support for loading ViewComponent engine manually. Make sure `require "view_component/engine"` is removed from `Gemfile`.
|
258
|
+
|
259
|
+
*Joel Hawksley*
|
260
|
+
|
261
|
+
* BREAKING: Remove deprecated `generate_*` methods. Use `generate.*` instead.
|
262
|
+
|
263
|
+
*Joel Hawksley*
|
264
|
+
|
265
|
+
* BREAKING: Remove deprecated `with_variant` method.
|
266
|
+
|
267
|
+
*Joel Hawksley*
|
268
|
+
|
269
|
+
* BREAKING: Remove deprecated `rendered_component` in favor of `rendered_content`.
|
270
|
+
|
271
|
+
*Joel Hawksley*
|
272
|
+
|
273
|
+
* BREAKING: Remove deprecated `config.preview_path` in favor of `config.preview_paths`.
|
274
|
+
|
275
|
+
*Joel Hawksley*
|
276
|
+
|
277
|
+
* BREAKING: Support Ruby 2.7+ instead of 2.4+
|
278
|
+
|
279
|
+
*Joel Hawksley*
|
280
|
+
|
281
|
+
* BREAKING: Remove deprecated `before_render_check`.
|
282
|
+
|
283
|
+
*Joel Hawksley*
|
284
|
+
|
285
|
+
* BREAKING: Change counter variable to start iterating from `0` instead of `1`.
|
286
|
+
|
287
|
+
*Frank S*
|
288
|
+
|
289
|
+
Run into an issue with this release? [Let us know](https://github.com/ViewComponent/view_component/issues/1629).
|
290
|
+
|
13
291
|
## 2.82.0
|
14
292
|
|
15
293
|
* Revert "Avoid loading ActionView::Base during initialization (#1528)"
|
data/lib/view_component/base.rb
CHANGED
@@ -6,11 +6,9 @@ require "view_component/collection"
|
|
6
6
|
require "view_component/compile_cache"
|
7
7
|
require "view_component/compiler"
|
8
8
|
require "view_component/config"
|
9
|
-
require "view_component/
|
10
|
-
require "view_component/polymorphic_slots"
|
9
|
+
require "view_component/errors"
|
11
10
|
require "view_component/preview"
|
12
11
|
require "view_component/slotable"
|
13
|
-
require "view_component/slotable_v2"
|
14
12
|
require "view_component/translatable"
|
15
13
|
require "view_component/with_content_helper"
|
16
14
|
|
@@ -23,7 +21,7 @@ module ViewComponent
|
|
23
21
|
#
|
24
22
|
# @return [ViewComponent::Config]
|
25
23
|
def config
|
26
|
-
@config ||=
|
24
|
+
@config ||= ActiveSupport::OrderedOptions.new
|
27
25
|
end
|
28
26
|
|
29
27
|
# Replaces the entire config. You shouldn't need to use this directly
|
@@ -31,22 +29,15 @@ module ViewComponent
|
|
31
29
|
attr_writer :config
|
32
30
|
end
|
33
31
|
|
34
|
-
include ViewComponent::
|
35
|
-
include ViewComponent::PolymorphicSlots
|
36
|
-
include ViewComponent::SlotableV2
|
32
|
+
include ViewComponent::Slotable
|
37
33
|
include ViewComponent::Translatable
|
38
34
|
include ViewComponent::WithContentHelper
|
39
35
|
|
40
|
-
ViewContextCalledBeforeRenderError = Class.new(StandardError)
|
41
|
-
|
42
36
|
RESERVED_PARAMETER = :content
|
43
37
|
|
44
38
|
# For CSRF authenticity tokens in forms
|
45
39
|
delegate :form_authenticity_token, :protect_against_forgery?, :config, to: :helpers
|
46
40
|
|
47
|
-
class_attribute :content_areas
|
48
|
-
self.content_areas = [] # class_attribute:default doesn't work until Rails 5.2
|
49
|
-
|
50
41
|
# Config option that strips trailing whitespace in templates before compiling them.
|
51
42
|
class_attribute :__vc_strip_trailing_whitespace, instance_accessor: false, instance_predicate: false
|
52
43
|
self.__vc_strip_trailing_whitespace = false # class_attribute:default doesn't work until Rails 5.2
|
@@ -66,23 +57,6 @@ module ViewComponent
|
|
66
57
|
self.__vc_original_view_context = view_context
|
67
58
|
end
|
68
59
|
|
69
|
-
# @!macro [attach] deprecated_generate_mattr_accessor
|
70
|
-
# @method generate_$1
|
71
|
-
# @deprecated Use `#generate.$1` instead. Will be removed in v3.0.0.
|
72
|
-
def self._deprecated_generate_mattr_accessor(name)
|
73
|
-
define_singleton_method("generate_#{name}".to_sym) do
|
74
|
-
generate.public_send(name)
|
75
|
-
end
|
76
|
-
define_singleton_method("generate_#{name}=".to_sym) do |value|
|
77
|
-
generate.public_send("#{name}=".to_sym, value)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
_deprecated_generate_mattr_accessor :distinct_locale_files
|
82
|
-
_deprecated_generate_mattr_accessor :locale
|
83
|
-
_deprecated_generate_mattr_accessor :sidecar
|
84
|
-
_deprecated_generate_mattr_accessor :stimulus_controller
|
85
|
-
|
86
60
|
# Entrypoint for rendering components.
|
87
61
|
#
|
88
62
|
# - `view_context`: ActionView context from calling view
|
@@ -119,9 +93,7 @@ module ViewComponent
|
|
119
93
|
@current_template = self
|
120
94
|
|
121
95
|
if block && defined?(@__vc_content_set_by_with_content)
|
122
|
-
raise
|
123
|
-
"which means that ViewComponent doesn't know which content to use.\n\n" \
|
124
|
-
"To fix this issue, use either `with_content` or a block."
|
96
|
+
raise DuplicateContentError.new(self.class.name)
|
125
97
|
end
|
126
98
|
|
127
99
|
@__vc_content_evaluated = false
|
@@ -165,14 +137,6 @@ module ViewComponent
|
|
165
137
|
#
|
166
138
|
# @return [void]
|
167
139
|
def before_render
|
168
|
-
before_render_check
|
169
|
-
end
|
170
|
-
|
171
|
-
# Called after rendering the component.
|
172
|
-
#
|
173
|
-
# @deprecated Use `#before_render` instead. Will be removed in v3.0.0.
|
174
|
-
# @return [void]
|
175
|
-
def before_render_check
|
176
140
|
# noop
|
177
141
|
end
|
178
142
|
|
@@ -208,16 +172,7 @@ module ViewComponent
|
|
208
172
|
#
|
209
173
|
# @return [ActionController::Base]
|
210
174
|
def controller
|
211
|
-
if view_context.nil?
|
212
|
-
raise(
|
213
|
-
ViewContextCalledBeforeRenderError,
|
214
|
-
"`#controller` can't be used during initialization, as it depends " \
|
215
|
-
"on the view context that only exists once a ViewComponent is passed to " \
|
216
|
-
"the Rails render pipeline.\n\n" \
|
217
|
-
"It's sometimes possible to fix this issue by moving code dependent on " \
|
218
|
-
"`#controller` to a `#before_render` method: https://viewcomponent.org/api.html#before_render--void."
|
219
|
-
)
|
220
|
-
end
|
175
|
+
raise ControllerCalledBeforeRenderError if view_context.nil?
|
221
176
|
|
222
177
|
@__vc_controller ||= view_context.controller
|
223
178
|
end
|
@@ -227,16 +182,7 @@ module ViewComponent
|
|
227
182
|
#
|
228
183
|
# @return [ActionView::Base]
|
229
184
|
def helpers
|
230
|
-
if view_context.nil?
|
231
|
-
raise(
|
232
|
-
ViewContextCalledBeforeRenderError,
|
233
|
-
"`#helpers` can't be used during initialization, as it depends " \
|
234
|
-
"on the view context that only exists once a ViewComponent is passed to " \
|
235
|
-
"the Rails render pipeline.\n\n" \
|
236
|
-
"It's sometimes possible to fix this issue by moving code dependent on " \
|
237
|
-
"`#helpers` to a `#before_render` method: https://viewcomponent.org/api.html#before_render--void."
|
238
|
-
)
|
239
|
-
end
|
185
|
+
raise HelpersCalledBeforeRenderError if view_context.nil?
|
240
186
|
|
241
187
|
# Attempt to re-use the original view_context passed to the first
|
242
188
|
# component rendered in the rendering pipeline. This prevents the
|
@@ -265,22 +211,9 @@ module ViewComponent
|
|
265
211
|
#
|
266
212
|
# @private
|
267
213
|
def format
|
268
|
-
# Ruby 2.6 throws a warning without checking `defined?`, 2.7 doesn't
|
269
214
|
@__vc_variant if defined?(@__vc_variant)
|
270
215
|
end
|
271
216
|
|
272
|
-
# Use the provided variant instead of the one determined by the current request.
|
273
|
-
#
|
274
|
-
# @deprecated Will be removed in v3.0.0.
|
275
|
-
# @param variant [Symbol] The variant to be used by the component.
|
276
|
-
# @return [self]
|
277
|
-
def with_variant(variant)
|
278
|
-
@__vc_variant = variant
|
279
|
-
|
280
|
-
self
|
281
|
-
end
|
282
|
-
deprecate :with_variant, deprecator: ViewComponent::Deprecation
|
283
|
-
|
284
217
|
# The current request. Use sparingly as doing so introduces coupling that
|
285
218
|
# inhibits encapsulation & reuse, often making testing difficult.
|
286
219
|
#
|
@@ -289,24 +222,42 @@ module ViewComponent
|
|
289
222
|
@request ||= controller.request if controller.respond_to?(:request)
|
290
223
|
end
|
291
224
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
225
|
+
# The content passed to the component instance as a block.
|
226
|
+
#
|
227
|
+
# @return [String]
|
296
228
|
def content
|
297
229
|
@__vc_content_evaluated = true
|
298
230
|
return @__vc_content if defined?(@__vc_content)
|
299
231
|
|
300
232
|
@__vc_content =
|
301
|
-
if
|
233
|
+
if __vc_render_in_block_provided?
|
302
234
|
view_context.capture(self, &@__vc_render_in_block)
|
303
|
-
elsif
|
235
|
+
elsif __vc_content_set_by_with_content_defined?
|
304
236
|
@__vc_content_set_by_with_content
|
305
237
|
end
|
306
238
|
end
|
307
239
|
|
240
|
+
# Whether `content` has been passed to the component.
|
241
|
+
#
|
242
|
+
# @return [Boolean]
|
243
|
+
def content?
|
244
|
+
__vc_render_in_block_provided? || __vc_content_set_by_with_content_defined?
|
245
|
+
end
|
246
|
+
|
247
|
+
private
|
248
|
+
|
249
|
+
attr_reader :view_context
|
250
|
+
|
251
|
+
def __vc_render_in_block_provided?
|
252
|
+
defined?(@view_context) && @view_context && @__vc_render_in_block
|
253
|
+
end
|
254
|
+
|
255
|
+
def __vc_content_set_by_with_content_defined?
|
256
|
+
defined?(@__vc_content_set_by_with_content)
|
257
|
+
end
|
258
|
+
|
308
259
|
def content_evaluated?
|
309
|
-
@__vc_content_evaluated
|
260
|
+
defined?(@__vc_content_evaluated) && @__vc_content_evaluated
|
310
261
|
end
|
311
262
|
|
312
263
|
# Set the controller used for testing components:
|
@@ -509,6 +460,11 @@ module ViewComponent
|
|
509
460
|
compiler.compiled?
|
510
461
|
end
|
511
462
|
|
463
|
+
# @private
|
464
|
+
def ensure_compiled
|
465
|
+
compile unless compiled?
|
466
|
+
end
|
467
|
+
|
512
468
|
# Compile templates to instance methods, assuming they haven't been compiled already.
|
513
469
|
#
|
514
470
|
# Do as much work as possible in this step, as doing so reduces the amount
|
@@ -558,7 +514,7 @@ module ViewComponent
|
|
558
514
|
# end
|
559
515
|
# ```
|
560
516
|
#
|
561
|
-
# @param value [Boolean] Whether
|
517
|
+
# @param value [Boolean] Whether to strip newlines.
|
562
518
|
def strip_trailing_whitespace(value = true)
|
563
519
|
self.__vc_strip_trailing_whitespace = value
|
564
520
|
end
|
@@ -582,20 +538,14 @@ module ViewComponent
|
|
582
538
|
return unless parameter
|
583
539
|
return if initialize_parameter_names.include?(parameter) || splatted_keyword_argument_present?
|
584
540
|
|
585
|
-
# If Ruby can't parse the component class, then the
|
541
|
+
# If Ruby can't parse the component class, then the initialize
|
586
542
|
# parameters will be empty and ViewComponent will not be able to render
|
587
543
|
# the component.
|
588
544
|
if initialize_parameters.empty?
|
589
|
-
raise
|
590
|
-
"It must accept the parameter `#{parameter}` to render it as a collection.\n\n" \
|
591
|
-
"To fix this issue, update the initializer to accept `#{parameter}`.\n\n" \
|
592
|
-
"See https://viewcomponent.org/guide/collections.html for more information on rendering collections."
|
545
|
+
raise EmptyOrInvalidInitializerError.new(name, parameter)
|
593
546
|
end
|
594
547
|
|
595
|
-
raise
|
596
|
-
"which is required in order to render it as a collection.\n\n" \
|
597
|
-
"To fix this issue, update the initializer to accept `#{parameter}`.\n\n" \
|
598
|
-
"See https://viewcomponent.org/guide/collections.html for more information on rendering collections."
|
548
|
+
raise MissingCollectionArgumentError.new(name, parameter)
|
599
549
|
end
|
600
550
|
|
601
551
|
# Ensure the component initializer doesn't define
|
@@ -605,8 +555,7 @@ module ViewComponent
|
|
605
555
|
def validate_initialization_parameters!
|
606
556
|
return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
|
607
557
|
|
608
|
-
raise
|
609
|
-
"public ViewComponent method. To fix this issue, rename the parameter."
|
558
|
+
raise ReservedParameterError.new(name, RESERVED_PARAMETER)
|
610
559
|
end
|
611
560
|
|
612
561
|
# @private
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ViewComponent
|
4
|
+
# CaptureCompatibility is a module that patches #capture to fix issues
|
5
|
+
# related to ViewComponent and functionality that relies on `capture`
|
6
|
+
# like forms, capture itself, turbo frames, etc.
|
7
|
+
#
|
8
|
+
# This underlying incompatibility with ViewComponent and capture is
|
9
|
+
# that several features like forms keep a reference to the primary
|
10
|
+
# `ActionView::Base` instance which has its own @output_buffer. When
|
11
|
+
# `#capture` is called on the original `ActionView::Base` instance while
|
12
|
+
# evaluating a block from a ViewComponent the @output_buffer is overridden
|
13
|
+
# in the ActionView::Base instance, and *not* the component. This results
|
14
|
+
# in a double render due to `#capture` implementation details.
|
15
|
+
#
|
16
|
+
# To resolve the issue, we override `#capture` so that we can delegate
|
17
|
+
# the `capture` logic to the ViewComponent that created the block.
|
18
|
+
module CaptureCompatibility
|
19
|
+
def self.included(base)
|
20
|
+
return if base < InstanceMethods
|
21
|
+
|
22
|
+
base.class_eval do
|
23
|
+
alias_method :original_capture, :capture
|
24
|
+
end
|
25
|
+
|
26
|
+
base.prepend(InstanceMethods)
|
27
|
+
end
|
28
|
+
|
29
|
+
module InstanceMethods
|
30
|
+
def capture(*args, &block)
|
31
|
+
# Handle blocks that originate from C code and raise, such as `&:method`
|
32
|
+
return original_capture(*args, &block) if block.source_location.nil?
|
33
|
+
|
34
|
+
block_context = block.binding.receiver
|
35
|
+
|
36
|
+
if block_context != self && block_context.class < ActionView::Base
|
37
|
+
block_context.original_capture(*args, &block)
|
38
|
+
else
|
39
|
+
original_capture(*args, &block)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -53,16 +53,13 @@ module ViewComponent
|
|
53
53
|
if object.respond_to?(:to_ary)
|
54
54
|
object.to_ary
|
55
55
|
else
|
56
|
-
raise
|
57
|
-
"The value of the first argument passed to `with_collection` isn't a valid collection. " \
|
58
|
-
"Make sure it responds to `to_ary`."
|
59
|
-
)
|
56
|
+
raise InvalidCollectionArgumentError
|
60
57
|
end
|
61
58
|
end
|
62
59
|
|
63
60
|
def component_options(item, iterator)
|
64
61
|
item_options = {component.collection_parameter => item}
|
65
|
-
item_options[component.collection_counter_parameter] = iterator.index
|
62
|
+
item_options[component.collection_counter_parameter] = iterator.index if component.counter_argument_present?
|
66
63
|
item_options[component.collection_iteration_parameter] = iterator.dup if component.iteration_argument_present?
|
67
64
|
|
68
65
|
@options.merge(item_options)
|