view_component 3.27.0 → 4.0.0.alpha1
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 -29
- 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 +68 -24
- data/lib/view_component/base.rb +49 -115
- data/lib/view_component/collection.rb +16 -28
- data/lib/view_component/compiler.rb +51 -83
- 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 -35
- data/lib/view_component/inline_template.rb +2 -4
- data/lib/view_component/instrumentation.rb +5 -11
- data/lib/view_component/preview.rb +3 -12
- data/lib/view_component/request_details.rb +30 -0
- data/lib/view_component/slot.rb +3 -6
- data/lib/view_component/slotable.rb +30 -37
- 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 +71 -214
- data/app/assets/vendor/prism.css +0 -4
- data/app/assets/vendor/prism.min.js +0 -12
- data/app/helpers/preview_helper.rb +0 -93
- 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/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/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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e8c0d5be4a21f5c14ed5447caeaffb8d6e51397a1ec786f573bc58d9486fc747
|
|
4
|
+
data.tar.gz: 332de180e52e1b5eae806fb47e9d1dea4a32374cdf63a0642ca69d3661e4c802
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e298e8e18d147034b30fb60f32a7bbf5d5f42d1235d5947cfeba4e3e1b8ad65a57379f3a3fb361ba7ffdec727687689ceb98b4b893e038a16ea5496663d4423a
|
|
7
|
+
data.tar.gz: f6e8f8956abde8eac1e4825c09a2554dde1dd80efac74ba541210e2fe663e23399ddc01289ca44dee21e6c3551b32117b88444d9795fbb450b02639ebc9fadbf
|
|
@@ -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,39 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "view_component/errors"
|
|
4
|
-
|
|
5
3
|
class ViewComponentsSystemTestController < ActionController::Base # :nodoc:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
rescue_from ViewComponent::SystemTestControllerNefariousPathError, with: :render_not_found
|
|
10
|
-
|
|
11
|
-
def self.temp_dir
|
|
12
|
-
@_tmpdir ||= FileUtils.mkdir_p("./tmp/view_components/").first
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def system_test_entrypoint
|
|
16
|
-
render file: @path
|
|
17
|
-
end
|
|
4
|
+
if Rails.env.test?
|
|
5
|
+
before_action :validate_file_path
|
|
18
6
|
|
|
19
|
-
|
|
7
|
+
def self.temp_dir
|
|
8
|
+
@_tmpdir ||= FileUtils.mkdir_p("./tmp/view_components/").first
|
|
9
|
+
end
|
|
20
10
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
def system_test_entrypoint
|
|
12
|
+
render file: @path
|
|
13
|
+
end
|
|
24
14
|
|
|
25
|
-
|
|
26
|
-
raise ViewComponent::SystemTestControllerOnlyAllowedInTestError unless Rails.env.test?
|
|
27
|
-
end
|
|
15
|
+
private
|
|
28
16
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
|
37
25
|
end
|
|
38
26
|
end
|
|
39
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
|
@@ -10,63 +10,107 @@ nav_order: 6
|
|
|
10
10
|
|
|
11
11
|
## main
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## 4.0.0
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
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.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
This release makes the following breaking changes:
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
* BREAKING: `--inline` generator option now generates inline template. Use `--call` to generate `#call` method.
|
|
20
20
|
|
|
21
|
-
*
|
|
21
|
+
*Joel Hawksley*
|
|
22
|
+
|
|
23
|
+
* BREAKING: Remove `use_deprecated_instrumentation_name` configuration option. Events will always use `render.view_component` name.
|
|
22
24
|
|
|
23
|
-
*
|
|
25
|
+
*Joel Hawksley*
|
|
24
26
|
|
|
25
|
-
*
|
|
27
|
+
* BREAKING: Remove `preview_source` functionality. Consider using [Lookbook](https://lookbook.build/) instead.
|
|
26
28
|
|
|
27
29
|
*Joel Hawksley*
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
* BREAKING: Use `Nokogiri::HTML5` instead of `Nokogiri::HTML4` for test helpers.
|
|
32
|
+
|
|
33
|
+
*Noah Silvera*, *Joel Hawksley*
|
|
34
|
+
|
|
35
|
+
* BREAKING: Move generators to a ViewComponent namespace.
|
|
36
|
+
|
|
37
|
+
Before, ViewComponent generators pollute the generator namespace with a bunch of top level items, and claim the generic "component" name.
|
|
38
|
+
|
|
39
|
+
Now, generators live in a "view_component" module/namespace, so what was before `rails g
|
|
40
|
+
component` is now `rails g view_component:component`.
|
|
41
|
+
|
|
42
|
+
*Paul Sadauskas*
|
|
30
43
|
|
|
31
|
-
*
|
|
44
|
+
* BREAKING: Require [non-EOL](https://endoflife.date/rails) Rails (`>= 7.1.0`).
|
|
32
45
|
|
|
33
46
|
*Joel Hawksley*
|
|
34
47
|
|
|
35
|
-
*
|
|
48
|
+
* BREAKING: Require [non-EOL](https://www.ruby-lang.org/en/downloads/branches/) Ruby (`>= 3.2.0`).
|
|
36
49
|
|
|
37
50
|
*Joel Hawksley*
|
|
38
51
|
|
|
39
|
-
*
|
|
52
|
+
* BREAKING: Remove `render_component` and `render` monkey patch configured with `render_monkey_patch_enabled`.
|
|
40
53
|
|
|
41
54
|
*Joel Hawksley*
|
|
42
55
|
|
|
43
|
-
*
|
|
56
|
+
* BREAKING: Remove support for variant names containing `.` to be consistent with Rails.
|
|
57
|
+
|
|
58
|
+
*Stephen Nelson*
|
|
59
|
+
|
|
60
|
+
* BREAKING: Use ActionView's `lookup_context` for picking templates instead of the request format.
|
|
61
|
+
|
|
62
|
+
3.15 added support for using templates that match the request format, i.e. if `/resource.csv` is requested then
|
|
63
|
+
ViewComponents would pick `_component.csv.erb` over `_component.html.erb`.
|
|
64
|
+
|
|
65
|
+
With this release, the request format is no longer considered and instead ViewComponent will use the Rails logic
|
|
66
|
+
for picking the most appropriate template type, i.e. the csv template will be used if it matches the `Accept` header
|
|
67
|
+
or because the controller uses a `respond_to` block to pick the response format.
|
|
68
|
+
|
|
69
|
+
*Stephen Nelson*
|
|
70
|
+
|
|
71
|
+
* 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.
|
|
44
72
|
|
|
45
73
|
*Joel Hawksley*
|
|
46
74
|
|
|
47
|
-
|
|
75
|
+
* Fix bug where request-aware helpers did not work outside of the request context.
|
|
48
76
|
|
|
49
|
-
*
|
|
77
|
+
*Joel Hawksley*, *Stephen Nelson*
|
|
50
78
|
|
|
51
|
-
|
|
79
|
+
* `ViewComponentsSystemTestController` should not be useable outside of test environment
|
|
52
80
|
|
|
53
|
-
|
|
81
|
+
*Joel Hawksley*, *Stephen Nelson*
|
|
54
82
|
|
|
55
|
-
*
|
|
83
|
+
* Remove unnecessary ENABLE_RELOADING test suite flag.
|
|
56
84
|
|
|
57
|
-
*
|
|
85
|
+
*Joel Hawksley*
|
|
58
86
|
|
|
59
|
-
|
|
87
|
+
* Add test coverage for uncovered code.
|
|
60
88
|
|
|
61
|
-
*
|
|
89
|
+
*Joel Hawksley*
|
|
62
90
|
|
|
63
|
-
|
|
91
|
+
* Remove unnecessary `#format` methods that returned `nil`.
|
|
92
|
+
|
|
93
|
+
*Joel Hawksley*
|
|
94
|
+
|
|
95
|
+
* Clean up project dependencies, relaxing versions of development gems.
|
|
96
|
+
|
|
97
|
+
*Joel Hawksley*
|
|
98
|
+
|
|
99
|
+
* Test against `turbo-rails` `v2`.
|
|
64
100
|
|
|
65
|
-
|
|
101
|
+
*Joel Hawksley*
|
|
102
|
+
|
|
103
|
+
* Test against `rspec-rails` `v7`.
|
|
104
|
+
|
|
105
|
+
*Joel Hawksley*
|
|
106
|
+
|
|
107
|
+
* Remove unnecessary usage of `ruby2_keywords`.
|
|
108
|
+
|
|
109
|
+
*Joel Hawksley*
|
|
66
110
|
|
|
67
|
-
*
|
|
111
|
+
* Remove unnecessary `respond_to` checks.
|
|
68
112
|
|
|
69
|
-
*Joel Hawksley
|
|
113
|
+
*Tiago Menegaz*, *Joel Hawksley*
|
|
70
114
|
|
|
71
115
|
* Do not include internal `DocsBuilderComponent` or `YARD::MattrAccessorHandler` in published gem.
|
|
72
116
|
|
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"
|
|
@@ -25,10 +26,9 @@ module ViewComponent
|
|
|
25
26
|
#
|
|
26
27
|
# @return [ActiveSupport::OrderedOptions]
|
|
27
28
|
def config
|
|
28
|
-
module_parents.each do |
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return module_parent_config if module_parent_config
|
|
29
|
+
module_parents.each do |m|
|
|
30
|
+
config = m.try(:config).try(:view_component)
|
|
31
|
+
return config if config
|
|
32
32
|
end
|
|
33
33
|
ViewComponent::Config.current
|
|
34
34
|
end
|
|
@@ -40,9 +40,6 @@ module ViewComponent
|
|
|
40
40
|
include ViewComponent::Translatable
|
|
41
41
|
include ViewComponent::WithContentHelper
|
|
42
42
|
|
|
43
|
-
RESERVED_PARAMETER = :content
|
|
44
|
-
VC_INTERNAL_DEFAULT_FORMAT = :html
|
|
45
|
-
|
|
46
43
|
# For CSRF authenticity tokens in forms
|
|
47
44
|
delegate :form_authenticity_token, :protect_against_forgery?, :config, to: :helpers
|
|
48
45
|
|
|
@@ -50,8 +47,7 @@ module ViewComponent
|
|
|
50
47
|
delegate :content_security_policy_nonce, to: :helpers
|
|
51
48
|
|
|
52
49
|
# Config option that strips trailing whitespace in templates before compiling them.
|
|
53
|
-
class_attribute :__vc_strip_trailing_whitespace, instance_accessor: false, instance_predicate: false
|
|
54
|
-
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
|
|
55
51
|
|
|
56
52
|
attr_accessor :__vc_original_view_context
|
|
57
53
|
|
|
@@ -65,55 +61,41 @@ module ViewComponent
|
|
|
65
61
|
# @param view_context [ActionView::Base] The original view context.
|
|
66
62
|
# @return [void]
|
|
67
63
|
def set_original_view_context(view_context)
|
|
68
|
-
|
|
69
|
-
# parent component can call `set_original_view_context` immediately before
|
|
70
|
-
# `render_in` without having that value clobbered by the per-render reset.
|
|
71
|
-
@__vc_pending_original_view_context = view_context
|
|
64
|
+
self.__vc_original_view_context = view_context
|
|
72
65
|
end
|
|
73
66
|
|
|
67
|
+
using RequestDetails
|
|
68
|
+
|
|
74
69
|
# Entrypoint for rendering components.
|
|
75
70
|
#
|
|
76
71
|
# - `view_context`: ActionView context from calling view
|
|
77
|
-
# - `options`: optional render options (e.g., locals)
|
|
78
72
|
# - `block`: optional block to be captured within the view context
|
|
79
73
|
#
|
|
80
74
|
# Returns HTML that has been escaped by the respective template handler.
|
|
81
75
|
#
|
|
82
76
|
# @return [String]
|
|
83
|
-
def render_in(view_context,
|
|
84
|
-
self.class.
|
|
85
|
-
|
|
86
|
-
__vc_check_reused_instance!
|
|
87
|
-
__vc_reset_render_state!
|
|
77
|
+
def render_in(view_context, &block)
|
|
78
|
+
self.class.__vc_compile(raise_errors: true)
|
|
88
79
|
|
|
89
80
|
@view_context = view_context
|
|
90
|
-
self.__vc_original_view_context
|
|
91
|
-
if instance_variable_defined?(:@__vc_pending_original_view_context)
|
|
92
|
-
remove_instance_variable(:@__vc_pending_original_view_context) || view_context
|
|
93
|
-
else
|
|
94
|
-
view_context
|
|
95
|
-
end
|
|
81
|
+
self.__vc_original_view_context ||= view_context
|
|
96
82
|
|
|
97
83
|
@output_buffer = ActionView::OutputBuffer.new
|
|
98
84
|
|
|
99
|
-
@lookup_context
|
|
100
|
-
|
|
101
|
-
# required for path helpers in older Rails versions
|
|
102
|
-
@view_renderer = view_context.view_renderer
|
|
85
|
+
@lookup_context ||= view_context.lookup_context
|
|
103
86
|
|
|
104
87
|
# For content_for
|
|
105
|
-
@view_flow
|
|
88
|
+
@view_flow ||= view_context.view_flow
|
|
106
89
|
|
|
107
90
|
# For i18n
|
|
108
91
|
@virtual_path ||= virtual_path
|
|
109
92
|
|
|
110
|
-
#
|
|
111
|
-
@
|
|
93
|
+
# Describes the inferred request constraints (locales, formats, variants)
|
|
94
|
+
@__vc_requested_details ||= @lookup_context.vc_requested_details
|
|
112
95
|
|
|
113
96
|
# For caching, such as #cache_if
|
|
114
97
|
@current_template = nil unless defined?(@current_template)
|
|
115
98
|
old_current_template = @current_template
|
|
116
|
-
@current_template = self
|
|
117
99
|
|
|
118
100
|
if block && defined?(@__vc_content_set_by_with_content)
|
|
119
101
|
raise DuplicateContentError.new(self.class.name)
|
|
@@ -125,7 +107,7 @@ module ViewComponent
|
|
|
125
107
|
before_render
|
|
126
108
|
|
|
127
109
|
if render?
|
|
128
|
-
rendered_template = render_template_for(@
|
|
110
|
+
rendered_template = render_template_for(@__vc_requested_details).to_s
|
|
129
111
|
|
|
130
112
|
# Avoid allocating new string when output_preamble and output_postamble are blank
|
|
131
113
|
if output_preamble.blank? && output_postamble.blank?
|
|
@@ -138,7 +120,6 @@ module ViewComponent
|
|
|
138
120
|
end
|
|
139
121
|
ensure
|
|
140
122
|
@current_template = old_current_template
|
|
141
|
-
@__vc_rendered = true
|
|
142
123
|
end
|
|
143
124
|
|
|
144
125
|
# Subclass components that call `super` inside their template code will cause a
|
|
@@ -174,7 +155,7 @@ module ViewComponent
|
|
|
174
155
|
target_render = self.class.instance_variable_get(:@__vc_ancestor_calls)[@__vc_parent_render_level]
|
|
175
156
|
@__vc_parent_render_level += 1
|
|
176
157
|
|
|
177
|
-
target_render.bind_call(self, @
|
|
158
|
+
target_render.bind_call(self, @__vc_requested_details)
|
|
178
159
|
ensure
|
|
179
160
|
@__vc_parent_render_level -= 1
|
|
180
161
|
end
|
|
@@ -219,12 +200,12 @@ module ViewComponent
|
|
|
219
200
|
#
|
|
220
201
|
# This prevents an exception when rendering a partial inside of a component that has also been rendered outside
|
|
221
202
|
# of the component. This is due to the partials compiled template method existing in the parent `view_context`,
|
|
222
|
-
#
|
|
203
|
+
# and not the component's `view_context`.
|
|
223
204
|
#
|
|
224
205
|
# @private
|
|
225
206
|
def render(options = {}, args = {}, &block)
|
|
226
207
|
if options.respond_to?(:set_original_view_context)
|
|
227
|
-
options.set_original_view_context(__vc_original_view_context)
|
|
208
|
+
options.set_original_view_context(self.__vc_original_view_context)
|
|
228
209
|
super
|
|
229
210
|
else
|
|
230
211
|
__vc_original_view_context.render(options, args, &block)
|
|
@@ -267,7 +248,7 @@ module ViewComponent
|
|
|
267
248
|
raise e, <<~MESSAGE.chomp if view_context && e.is_a?(NameError) && helpers.respond_to?(method_name)
|
|
268
249
|
#{e.message}
|
|
269
250
|
|
|
270
|
-
You may be trying to call a method provided as a view helper. Did you mean `helpers.#{method_name}
|
|
251
|
+
You may be trying to call a method provided as a view helper. Did you mean `helpers.#{method_name}'?
|
|
271
252
|
MESSAGE
|
|
272
253
|
|
|
273
254
|
raise
|
|
@@ -287,13 +268,6 @@ module ViewComponent
|
|
|
287
268
|
[]
|
|
288
269
|
end
|
|
289
270
|
|
|
290
|
-
# For caching, such as #cache_if
|
|
291
|
-
#
|
|
292
|
-
# @private
|
|
293
|
-
def format
|
|
294
|
-
@__vc_variant if defined?(@__vc_variant)
|
|
295
|
-
end
|
|
296
|
-
|
|
297
271
|
# The current request. Use sparingly as doing so introduces coupling that
|
|
298
272
|
# inhibits encapsulation & reuse, often making testing difficult.
|
|
299
273
|
#
|
|
@@ -302,10 +276,9 @@ module ViewComponent
|
|
|
302
276
|
__vc_request
|
|
303
277
|
end
|
|
304
278
|
|
|
305
|
-
# Enables consumers to override request/@request
|
|
306
|
-
#
|
|
307
279
|
# @private
|
|
308
280
|
def __vc_request
|
|
281
|
+
# The current request (if present, as mailers/jobs/etc do not have a request)
|
|
309
282
|
@__vc_request ||= controller.request if controller.respond_to?(:request)
|
|
310
283
|
end
|
|
311
284
|
|
|
@@ -348,7 +321,7 @@ module ViewComponent
|
|
|
348
321
|
end
|
|
349
322
|
|
|
350
323
|
def maybe_escape_html(text)
|
|
351
|
-
return text if
|
|
324
|
+
return text if @current_template && !@current_template.html?
|
|
352
325
|
return text if text.blank?
|
|
353
326
|
|
|
354
327
|
if text.html_safe?
|
|
@@ -381,13 +354,6 @@ module ViewComponent
|
|
|
381
354
|
# configured on a per-test basis using `with_controller_class`.
|
|
382
355
|
#
|
|
383
356
|
|
|
384
|
-
# Set if render monkey patches should be included or not in Rails <6.1:
|
|
385
|
-
#
|
|
386
|
-
# ```ruby
|
|
387
|
-
# config.view_component.render_monkey_patch_enabled = false
|
|
388
|
-
# ```
|
|
389
|
-
#
|
|
390
|
-
|
|
391
357
|
# Path for component files
|
|
392
358
|
#
|
|
393
359
|
# ```ruby
|
|
@@ -407,36 +373,6 @@ module ViewComponent
|
|
|
407
373
|
# "ApplicationComponent" if defined, "ViewComponent::Base" otherwise.
|
|
408
374
|
#
|
|
409
375
|
|
|
410
|
-
# Resets every render-scoped instance variable derived from the calling view
|
|
411
|
-
# context so a reused instance cannot leak controller/helper/request/format
|
|
412
|
-
# state from a previous render. Slot state (`@__vc_set_slots`,
|
|
413
|
-
# `@__vc_content_set_by_with_content`) is intentionally preserved because it
|
|
414
|
-
# is populated by callers _before_ `render_in` runs (e.g. via `with_*`
|
|
415
|
-
# slot setters or `with_content`); reuse of an instance that has slot or
|
|
416
|
-
# `with_content` state is guarded against separately by
|
|
417
|
-
# `__vc_check_reused_instance!`.
|
|
418
|
-
def __vc_reset_render_state!
|
|
419
|
-
%i[
|
|
420
|
-
@__vc_controller
|
|
421
|
-
@__vc_helpers
|
|
422
|
-
@__vc_request
|
|
423
|
-
@__vc_original_view_context
|
|
424
|
-
].each do |ivar|
|
|
425
|
-
remove_instance_variable(ivar) if instance_variable_defined?(ivar)
|
|
426
|
-
end
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
# Raises when a component instance is rendered more than once.
|
|
430
|
-
# Reusing a component instance across renders can leak request-scoped state
|
|
431
|
-
# (controller, helpers, request, view_flow, slot content, `with_content`)
|
|
432
|
-
# from an earlier render into a later one. See
|
|
433
|
-
# `ViewComponent::ReusedInstanceError` and GHSA-8qw7-6phv-7q6p.
|
|
434
|
-
def __vc_check_reused_instance!
|
|
435
|
-
return unless defined?(@__vc_rendered) && @__vc_rendered
|
|
436
|
-
|
|
437
|
-
raise ReusedInstanceError.new(self.class.name)
|
|
438
|
-
end
|
|
439
|
-
|
|
440
376
|
# Configuration for generators.
|
|
441
377
|
#
|
|
442
378
|
# All options under this namespace default to `false` unless otherwise
|
|
@@ -566,20 +502,20 @@ module ViewComponent
|
|
|
566
502
|
def inherited(child)
|
|
567
503
|
# Compile so child will inherit compiled `call_*` template methods that
|
|
568
504
|
# `compile` defines
|
|
569
|
-
|
|
505
|
+
__vc_compile
|
|
570
506
|
|
|
571
507
|
# Give the child its own personal #render_template_for to protect against the case when
|
|
572
508
|
# eager loading is disabled and the parent component is rendered before the child. In
|
|
573
509
|
# such a scenario, the parent will override ViewComponent::Base#render_template_for,
|
|
574
510
|
# meaning it will not be called for any children and thus not compile their templates.
|
|
575
|
-
if !child.instance_methods(false).include?(:render_template_for) && !child.
|
|
511
|
+
if !child.instance_methods(false).include?(:render_template_for) && !child.__vc_compiled?
|
|
576
512
|
child.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
577
|
-
def render_template_for(
|
|
513
|
+
def render_template_for(requested_details)
|
|
578
514
|
# Force compilation here so the compiler always redefines render_template_for.
|
|
579
515
|
# This is mostly a safeguard to prevent infinite recursion.
|
|
580
|
-
self.class.
|
|
581
|
-
# .
|
|
582
|
-
render_template_for(
|
|
516
|
+
self.class.__vc_compile(raise_errors: true, force: true)
|
|
517
|
+
# .__vc_compile replaces this method; call the new one
|
|
518
|
+
render_template_for(requested_details)
|
|
583
519
|
end
|
|
584
520
|
RUBY
|
|
585
521
|
end
|
|
@@ -618,22 +554,22 @@ module ViewComponent
|
|
|
618
554
|
end
|
|
619
555
|
|
|
620
556
|
# @private
|
|
621
|
-
def
|
|
622
|
-
|
|
557
|
+
def __vc_compiled?
|
|
558
|
+
__vc_compiler.compiled?
|
|
623
559
|
end
|
|
624
560
|
|
|
625
561
|
# @private
|
|
626
|
-
def
|
|
627
|
-
|
|
562
|
+
def __vc_ensure_compiled
|
|
563
|
+
__vc_compile unless __vc_compiled?
|
|
628
564
|
end
|
|
629
565
|
|
|
630
566
|
# @private
|
|
631
|
-
def
|
|
632
|
-
|
|
567
|
+
def __vc_compile(raise_errors: false, force: false)
|
|
568
|
+
__vc_compiler.compile(raise_errors: raise_errors, force: force)
|
|
633
569
|
end
|
|
634
570
|
|
|
635
571
|
# @private
|
|
636
|
-
def
|
|
572
|
+
def __vc_compiler
|
|
637
573
|
@__vc_compiler ||= Compiler.new(self)
|
|
638
574
|
end
|
|
639
575
|
|
|
@@ -675,8 +611,8 @@ module ViewComponent
|
|
|
675
611
|
# is accepted, as support for collection
|
|
676
612
|
# rendering is optional.
|
|
677
613
|
# @private
|
|
678
|
-
def
|
|
679
|
-
parameter = validate_default ?
|
|
614
|
+
def __vc_validate_collection_parameter!(validate_default: false)
|
|
615
|
+
parameter = validate_default ? __vc_collection_parameter : provided_collection_parameter
|
|
680
616
|
|
|
681
617
|
return unless parameter
|
|
682
618
|
return if initialize_parameter_names.include?(parameter) || splatted_keyword_argument_present?
|
|
@@ -695,35 +631,35 @@ module ViewComponent
|
|
|
695
631
|
# invalid parameters that could override the framework's
|
|
696
632
|
# methods.
|
|
697
633
|
# @private
|
|
698
|
-
def
|
|
699
|
-
return unless initialize_parameter_names.include?(
|
|
634
|
+
def __vc_validate_initialization_parameters!
|
|
635
|
+
return unless initialize_parameter_names.include?(:content)
|
|
700
636
|
|
|
701
|
-
raise ReservedParameterError.new(name,
|
|
637
|
+
raise ReservedParameterError.new(name, :content)
|
|
702
638
|
end
|
|
703
639
|
|
|
704
640
|
# @private
|
|
705
|
-
def
|
|
641
|
+
def __vc_collection_parameter
|
|
706
642
|
provided_collection_parameter || name && name.demodulize.underscore.chomp("_component").to_sym
|
|
707
643
|
end
|
|
708
644
|
|
|
709
645
|
# @private
|
|
710
|
-
def
|
|
711
|
-
:"#{
|
|
646
|
+
def __vc_collection_counter_parameter
|
|
647
|
+
:"#{__vc_collection_parameter}_counter"
|
|
712
648
|
end
|
|
713
649
|
|
|
714
650
|
# @private
|
|
715
|
-
def
|
|
716
|
-
initialize_parameter_names.include?(
|
|
651
|
+
def __vc_counter_argument_present?
|
|
652
|
+
initialize_parameter_names.include?(__vc_collection_counter_parameter)
|
|
717
653
|
end
|
|
718
654
|
|
|
719
655
|
# @private
|
|
720
|
-
def
|
|
721
|
-
:"#{
|
|
656
|
+
def __vc_collection_iteration_parameter
|
|
657
|
+
:"#{__vc_collection_parameter}_iteration"
|
|
722
658
|
end
|
|
723
659
|
|
|
724
660
|
# @private
|
|
725
|
-
def
|
|
726
|
-
initialize_parameter_names.include?(
|
|
661
|
+
def __vc_iteration_argument_present?
|
|
662
|
+
initialize_parameter_names.include?(__vc_collection_iteration_parameter)
|
|
727
663
|
end
|
|
728
664
|
|
|
729
665
|
private
|
|
@@ -736,8 +672,6 @@ module ViewComponent
|
|
|
736
672
|
def initialize_parameter_names
|
|
737
673
|
return attribute_names.map(&:to_sym) if respond_to?(:attribute_names)
|
|
738
674
|
|
|
739
|
-
return attribute_types.keys.map(&:to_sym) if Rails::VERSION::MAJOR <= 5 && respond_to?(:attribute_types)
|
|
740
|
-
|
|
741
675
|
initialize_parameters.map(&:last)
|
|
742
676
|
end
|
|
743
677
|
|