view_component 3.2.0 → 3.5.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/concerns/view_component/preview_actions.rb +1 -1
- data/docs/CHANGELOG.md +38 -0
- data/lib/view_component/base.rb +38 -5
- data/lib/view_component/compiler.rb +21 -11
- data/lib/view_component/config.rb +8 -0
- data/lib/view_component/engine.rb +8 -1
- data/lib/view_component/inline_template.rb +1 -1
- data/lib/view_component/instrumentation.rb +9 -1
- data/lib/view_component/preview.rb +1 -1
- data/lib/view_component/rails/tasks/view_component.rake +2 -0
- data/lib/view_component/test_helpers.rb +13 -1
- data/lib/view_component/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce590ddce7011ae4362dde0733f78ba65992c31add6bac215555515d02ae1dc6
|
4
|
+
data.tar.gz: df4867599a61d2757e2f226a3c6b187981772e2d225fc442f9184484c0423e64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a39d71f089c0f4285dc1eecd324e44afc73f55565002a45c2d37292cc4fa8b05713f7237f04b530617ddc0bb2ccd08fab0c7d010400790dc00daf2d6c9c0546
|
7
|
+
data.tar.gz: 252a63a4ed7eefd7db529dc93081d3ccfb78555ac1d051540f7a69829a41d4d22fd94557fa2fe9eb88c012bd8dccfd2ceb813aae2582877e387a2df347e2d915
|
@@ -59,7 +59,7 @@ module ViewComponent
|
|
59
59
|
def find_preview
|
60
60
|
candidates = []
|
61
61
|
params[:path].to_s.scan(%r{/|$}) { candidates << Regexp.last_match.pre_match }
|
62
|
-
preview = candidates.detect { |candidate| ViewComponent::Preview.exists?(candidate) }
|
62
|
+
preview = candidates.sort_by(&:length).reverse_each.detect { |candidate| ViewComponent::Preview.exists?(candidate) }
|
63
63
|
|
64
64
|
if preview
|
65
65
|
@preview = ViewComponent::Preview.find(preview)
|
data/docs/CHANGELOG.md
CHANGED
@@ -10,6 +10,44 @@ nav_order: 5
|
|
10
10
|
|
11
11
|
## main
|
12
12
|
|
13
|
+
## 3.5.0
|
14
|
+
|
15
|
+
* Add Skroutz to users list.
|
16
|
+
|
17
|
+
*Chris Nitsas*
|
18
|
+
|
19
|
+
* Improve implementation of `#render_parent` so it respects variants and deep inheritance hierarchies.
|
20
|
+
|
21
|
+
*Cameron Dutro*
|
22
|
+
|
23
|
+
* Add CharlieHR to users list.
|
24
|
+
|
25
|
+
*Alex Balhatchet*
|
26
|
+
|
27
|
+
## 3.4.0
|
28
|
+
|
29
|
+
* Avoid including Rails `url_helpers` into `Preview` class when they're not defined.
|
30
|
+
|
31
|
+
*Richard Macklin*
|
32
|
+
|
33
|
+
* Allow instrumentation to be automatically included in Server-Timing headers generated by Rails. To enable this set the config `config.use_deprecated_instrumentation_name = false`. The old key `!render.view_component` is deprecated: update ActiveSupport::Notification subscriptions to `render.view_component`.
|
34
|
+
|
35
|
+
*Travis Gaff*
|
36
|
+
|
37
|
+
## 3.3.0
|
38
|
+
|
39
|
+
* Include InlineTemplate by default in Base. **Note:** It's no longer necessary to include `ViewComponent::InlineTemplate` to use inline templates.
|
40
|
+
|
41
|
+
*Joel Hawksley*
|
42
|
+
|
43
|
+
* Allow Setting host when using the `with_request_url` test helper.
|
44
|
+
|
45
|
+
*Daniel Alfaro*
|
46
|
+
|
47
|
+
* Resolve ambiguous preview paths when using components without the Component suffix.
|
48
|
+
|
49
|
+
*Reed Law*
|
50
|
+
|
13
51
|
## 3.2.0
|
14
52
|
|
15
53
|
* Fix viewcomponent.org Axe violations.
|
data/lib/view_component/base.rb
CHANGED
@@ -7,6 +7,7 @@ require "view_component/compile_cache"
|
|
7
7
|
require "view_component/compiler"
|
8
8
|
require "view_component/config"
|
9
9
|
require "view_component/errors"
|
10
|
+
require "view_component/inline_template"
|
10
11
|
require "view_component/preview"
|
11
12
|
require "view_component/slotable"
|
12
13
|
require "view_component/translatable"
|
@@ -29,6 +30,7 @@ module ViewComponent
|
|
29
30
|
attr_writer :config
|
30
31
|
end
|
31
32
|
|
33
|
+
include ViewComponent::InlineTemplate
|
32
34
|
include ViewComponent::Slotable
|
33
35
|
include ViewComponent::Translatable
|
34
36
|
include ViewComponent::WithContentHelper
|
@@ -114,20 +116,44 @@ module ViewComponent
|
|
114
116
|
end
|
115
117
|
|
116
118
|
# Subclass components that call `super` inside their template code will cause a
|
117
|
-
# double render if they emit the result
|
119
|
+
# double render if they emit the result.
|
118
120
|
#
|
119
121
|
# ```erb
|
120
122
|
# <%= super %> # double-renders
|
121
|
-
# <% super %> #
|
123
|
+
# <% super %> # doesn't double-render
|
122
124
|
# ```
|
123
125
|
#
|
124
|
-
#
|
126
|
+
# `super` also doesn't consider the current variant. `render_parent` renders the
|
127
|
+
# parent template considering the current variant and emits the result without
|
128
|
+
# double-rendering.
|
125
129
|
def render_parent
|
126
|
-
|
127
|
-
method(mtd).super_method.call
|
130
|
+
render_parent_to_string
|
128
131
|
nil
|
129
132
|
end
|
130
133
|
|
134
|
+
# Renders the parent component to a string and returns it. This method is meant
|
135
|
+
# to be used inside custom #call methods when a string result is desired, eg.
|
136
|
+
#
|
137
|
+
# ```ruby
|
138
|
+
# def call
|
139
|
+
# "<div>#{render_parent_to_string}</div>"
|
140
|
+
# end
|
141
|
+
# ```
|
142
|
+
#
|
143
|
+
# When rendering the parent inside an .erb template, use `#render_parent` instead.
|
144
|
+
def render_parent_to_string
|
145
|
+
@__vc_parent_render_level ||= 0 # ensure a good starting value
|
146
|
+
|
147
|
+
begin
|
148
|
+
target_render = self.class.instance_variable_get(:@__vc_ancestor_calls)[@__vc_parent_render_level]
|
149
|
+
@__vc_parent_render_level += 1
|
150
|
+
|
151
|
+
target_render.bind_call(self, @__vc_variant)
|
152
|
+
ensure
|
153
|
+
@__vc_parent_render_level -= 1
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
131
157
|
# Optional content to be returned after the rendered template.
|
132
158
|
#
|
133
159
|
# @return [String]
|
@@ -457,6 +483,13 @@ module ViewComponent
|
|
457
483
|
# Set collection parameter to the extended component
|
458
484
|
child.with_collection_parameter provided_collection_parameter
|
459
485
|
|
486
|
+
if instance_methods(false).include?(:render_template_for)
|
487
|
+
vc_ancestor_calls = defined?(@__vc_ancestor_calls) ? @__vc_ancestor_calls.dup : []
|
488
|
+
|
489
|
+
vc_ancestor_calls.unshift(instance_method(:render_template_for))
|
490
|
+
child.instance_variable_set(:@__vc_ancestor_calls, vc_ancestor_calls)
|
491
|
+
end
|
492
|
+
|
460
493
|
super
|
461
494
|
end
|
462
495
|
|
@@ -56,17 +56,17 @@ module ViewComponent
|
|
56
56
|
RUBY
|
57
57
|
# rubocop:enable Style/EvalWithLocation
|
58
58
|
|
59
|
+
component_class.define_method("_call_#{safe_class_name}", component_class.instance_method(:call))
|
60
|
+
|
59
61
|
component_class.silence_redefinition_of_method("render_template_for")
|
60
62
|
component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
61
63
|
def render_template_for(variant = nil)
|
62
|
-
|
64
|
+
_call_#{safe_class_name}
|
63
65
|
end
|
64
66
|
RUBY
|
65
67
|
end
|
66
68
|
else
|
67
69
|
templates.each do |template|
|
68
|
-
# Remove existing compiled template methods,
|
69
|
-
# as Ruby warns when redefining a method.
|
70
70
|
method_name = call_method_name(template[:variant])
|
71
71
|
|
72
72
|
redefinition_lock.synchronize do
|
@@ -95,15 +95,20 @@ module ViewComponent
|
|
95
95
|
|
96
96
|
def define_render_template_for
|
97
97
|
variant_elsifs = variants.compact.uniq.map do |variant|
|
98
|
-
|
98
|
+
safe_name = "_call_variant_#{normalized_variant_name(variant)}_#{safe_class_name}"
|
99
|
+
component_class.define_method(safe_name, component_class.instance_method(call_method_name(variant)))
|
100
|
+
|
101
|
+
"elsif variant.to_sym == :'#{variant}'\n #{safe_name}"
|
99
102
|
end.join("\n")
|
100
103
|
|
104
|
+
component_class.define_method("_call_#{safe_class_name}", component_class.instance_method(:call))
|
105
|
+
|
101
106
|
body = <<-RUBY
|
102
107
|
if variant.nil?
|
103
|
-
|
108
|
+
_call_#{safe_class_name}
|
104
109
|
#{variant_elsifs}
|
105
110
|
else
|
106
|
-
|
111
|
+
_call_#{safe_class_name}
|
107
112
|
end
|
108
113
|
RUBY
|
109
114
|
|
@@ -276,12 +281,17 @@ module ViewComponent
|
|
276
281
|
variant.to_s.gsub("-", "__").gsub(".", "___")
|
277
282
|
end
|
278
283
|
|
284
|
+
def safe_class_name
|
285
|
+
@safe_class_name ||= component_class.name.underscore.gsub("/", "__")
|
286
|
+
end
|
287
|
+
|
279
288
|
def should_compile_superclass?
|
280
|
-
development? && templates.empty? && !has_inline_template? &&
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
289
|
+
development? && templates.empty? && !has_inline_template? && !call_defined?
|
290
|
+
end
|
291
|
+
|
292
|
+
def call_defined?
|
293
|
+
component_class.instance_methods(false).include?(:call) ||
|
294
|
+
component_class.private_instance_methods(false).include?(:call)
|
285
295
|
end
|
286
296
|
end
|
287
297
|
end
|
@@ -17,6 +17,7 @@ module ViewComponent
|
|
17
17
|
preview_route: "/rails/view_components",
|
18
18
|
show_previews_source: false,
|
19
19
|
instrumentation_enabled: false,
|
20
|
+
use_deprecated_instrumentation_name: true,
|
20
21
|
render_monkey_patch_enabled: true,
|
21
22
|
view_component_path: "app/components",
|
22
23
|
component_parent_class: nil,
|
@@ -99,6 +100,13 @@ module ViewComponent
|
|
99
100
|
# Whether ActiveSupport notifications are enabled.
|
100
101
|
# Defaults to `false`.
|
101
102
|
|
103
|
+
# @!attribute use_deprecated_instrumentation_name
|
104
|
+
# @return [Boolean]
|
105
|
+
# Whether ActiveSupport Notifications use the private name `"!render.view_component"`
|
106
|
+
# or are made more publicly available via `"render.view_component"`.
|
107
|
+
# Will default to `false` in next major version.
|
108
|
+
# Defaults to `true`.
|
109
|
+
|
102
110
|
# @!attribute render_monkey_patch_enabled
|
103
111
|
# @return [Boolean] Whether the #render method should be monkey patched.
|
104
112
|
# If this is disabled, use `#render_component` or
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "rails"
|
4
4
|
require "view_component/config"
|
5
|
+
require "view_component/deprecation"
|
5
6
|
|
6
7
|
module ViewComponent
|
7
8
|
class Engine < Rails::Engine # :nodoc:
|
@@ -39,8 +40,14 @@ module ViewComponent
|
|
39
40
|
Base.config = app.config.view_component
|
40
41
|
|
41
42
|
if app.config.view_component.instrumentation_enabled.present?
|
42
|
-
# :nocov:
|
43
|
+
# :nocov: Re-executing the below in tests duplicates initializers and causes order-dependent failures.
|
43
44
|
ViewComponent::Base.prepend(ViewComponent::Instrumentation)
|
45
|
+
if app.config.view_component.use_deprecated_instrumentation_name
|
46
|
+
ViewComponent::Deprecation.deprecation_warning(
|
47
|
+
"!render.view_component",
|
48
|
+
"Use the new instrumentation key `render.view_component` instead. See https://viewcomponent.org/guide/instrumentation.html"
|
49
|
+
)
|
50
|
+
end
|
44
51
|
# :nocov:
|
45
52
|
end
|
46
53
|
end
|
@@ -10,7 +10,7 @@ module ViewComponent # :nodoc:
|
|
10
10
|
|
11
11
|
def render_in(view_context, &block)
|
12
12
|
ActiveSupport::Notifications.instrument(
|
13
|
-
|
13
|
+
notification_name,
|
14
14
|
{
|
15
15
|
name: self.class.name,
|
16
16
|
identifier: self.class.identifier
|
@@ -19,5 +19,13 @@ module ViewComponent # :nodoc:
|
|
19
19
|
super(view_context, &block)
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def notification_name
|
26
|
+
return "!render.view_component" if ViewComponent::Base.config.use_deprecated_instrumentation_name
|
27
|
+
|
28
|
+
"render.view_component"
|
29
|
+
end
|
22
30
|
end
|
23
31
|
end
|
@@ -4,7 +4,7 @@ require "active_support/descendants_tracker"
|
|
4
4
|
|
5
5
|
module ViewComponent # :nodoc:
|
6
6
|
class Preview
|
7
|
-
include Rails.application.routes.url_helpers
|
7
|
+
include Rails.application.routes.url_helpers if defined?(Rails.application.routes.url_helpers)
|
8
8
|
include ActionView::Helpers::TagHelper
|
9
9
|
include ActionView::Helpers::AssetTagHelper
|
10
10
|
extend ActiveSupport::DescendantsTracker
|
@@ -155,8 +155,18 @@ module ViewComponent
|
|
155
155
|
# end
|
156
156
|
# ```
|
157
157
|
#
|
158
|
+
# To use a specific host, pass the host param:
|
159
|
+
#
|
160
|
+
# ```ruby
|
161
|
+
# with_request_url("/users/42", host: "app.example.com") do
|
162
|
+
# render_inline(MyComponent.new)
|
163
|
+
# end
|
164
|
+
# ```
|
165
|
+
#
|
158
166
|
# @param path [String] The path to set for the current request.
|
159
|
-
|
167
|
+
# @param host [String] The host to set for the current request.
|
168
|
+
def with_request_url(path, host: nil)
|
169
|
+
old_request_host = vc_test_request.host
|
160
170
|
old_request_path_info = vc_test_request.path_info
|
161
171
|
old_request_path_parameters = vc_test_request.path_parameters
|
162
172
|
old_request_query_parameters = vc_test_request.query_parameters
|
@@ -164,12 +174,14 @@ module ViewComponent
|
|
164
174
|
old_controller = defined?(@vc_test_controller) && @vc_test_controller
|
165
175
|
|
166
176
|
path, query = path.split("?", 2)
|
177
|
+
vc_test_request.host = host if host
|
167
178
|
vc_test_request.path_info = path
|
168
179
|
vc_test_request.path_parameters = Rails.application.routes.recognize_path_with_request(vc_test_request, path, {})
|
169
180
|
vc_test_request.set_header("action_dispatch.request.query_parameters", Rack::Utils.parse_nested_query(query))
|
170
181
|
vc_test_request.set_header(Rack::QUERY_STRING, query)
|
171
182
|
yield
|
172
183
|
ensure
|
184
|
+
vc_test_request.host = old_request_host
|
173
185
|
vc_test_request.path_info = old_request_path_info
|
174
186
|
vc_test_request.path_parameters = old_request_path_parameters
|
175
187
|
vc_test_request.set_header("action_dispatch.request.query_parameters", old_request_query_parameters)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: view_component
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ViewComponent Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|