view_component 3.2.0 → 3.5.0
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.
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
|