view_component 4.23.0 → 4.24.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d782aede72b310a730951e5b9357dcf8b02184f4d459d0ef0c7106671bfa80a1
4
- data.tar.gz: 6edb2094b07d7245782cb1d1292dbd7983e70ce5d1872165a4bae99bde537275
3
+ metadata.gz: 3c6a2ef3282bf3383716c47d113e3a9ed1dccc6aee4f643080aedece5961445a
4
+ data.tar.gz: ad941d4a4ca2b8e155dff3bd2ed52a0213d6bfc808c65abc67e5d2e069d300e7
5
5
  SHA512:
6
- metadata.gz: f9fbe9cd4bfdb862d5a6d2bda711380d43abbf744af542b09158f57adf0c5de0b32002fcd7710859743cc3abe80fce416f4280c638a0b436dd5495beff4c0269
7
- data.tar.gz: '09cf2dd6d5b054283943b02feecd1037bc41cfcac37553ef1bc4823d32ab4e34ac2bb469105579d6144ec76972944c7ac5ace6bd4c711e5bdff1cc4e1b1227b7'
6
+ metadata.gz: ed286a2767cb14109d867255023c4feb6945288cc2dd4351c64ffa03203a89702a8ca75b7a79cd68c64ebc7b9e96a1a2e81e7445f61fc975ce06311c4a47d872
7
+ data.tar.gz: 9893da43af8559c0aee6226b4d0dd2fa96f32ec41b1fc60b14106e0d689666a5a1833af99da1cf72d568ef8a85b79854a3bbe4ef198128d9dde35c0f86cea24a
data/docs/CHANGELOG.md CHANGED
@@ -10,6 +10,40 @@ nav_order: 6
10
10
 
11
11
  ## main
12
12
 
13
+ ## 4.24.0
14
+
15
+ * Harden GitHub Actions workflows and dependency updates to address code-scanning alerts.
16
+
17
+ *Joel Hawksley*
18
+
19
+ * Check component templates for changes from the Rails reloader instead of every executor run, avoiding filesystem scans for Action Cable broadcasts and other executor-only work.
20
+
21
+ *Joel Hawksley*
22
+
23
+ * Avoid missing-template digest errors for namespaced component renders when using Rails' regex ERB dependency tracker.
24
+
25
+ *Joel Hawksley*
26
+
27
+ * Raise `NoMethodError` on the slot instead of on `nil` when calling an undefined method on a slot without a component, including methods only `nil` defines such as `to_a` or `=~`, which used to return `nil`'s result.
28
+
29
+ *Clément Joubert*
30
+
31
+ * Update both Rails main builds to the same Rails commit through a weekly automated pull request.
32
+
33
+ *Joel Hawksley*
34
+
35
+ * Update Nokogiri to 1.19.5 for compatibility with Rails main.
36
+
37
+ *Joel Hawksley*
38
+
39
+ * Fix missing-template errors and request URL restoration with Rails main.
40
+
41
+ *Joel Hawksley*
42
+
43
+ * Keep compensating ERB line numbers for the annotation newline on future major Rails versions. The version check required a minor version above 0, so it would have stopped compensating on the next major's `.0` release.
44
+
45
+ *Clément Joubert*
46
+
13
47
  ## 4.23.0
14
48
 
15
49
  * Restore request-dependent URL generation when using `render_preview` inside `with_request_url`.
@@ -35,8 +35,24 @@ module ViewComponent
35
35
 
36
36
  next dependencies unless CacheDigest.template_dependencies?(source, template.handler)
37
37
 
38
+ # ERB's regex tracker guesses different paths than the Ruby parser,
39
+ # especially for namespaced components. Ask the registered tracker
40
+ # about isolated render calls without reentering this extension.
41
+ if template.handler.is_a?(ActionView::Template::Handlers::ERB)
42
+ tracker = lambda do |calls|
43
+ isolated = ActionView::Template.new(
44
+ calls.map { |call| "<% #{call} %>" }.join("\n"),
45
+ template.identifier,
46
+ template.handler,
47
+ locals: [],
48
+ virtual_path: name
49
+ )
50
+ super(name, isolated, view_paths)
51
+ end
52
+ end
53
+
38
54
  component_paths, inferred_partials =
39
- CacheDigest.template_renders_in(CacheDigest.compiled_source(template), name, view_paths: view_paths)
55
+ CacheDigest.template_renders_in(CacheDigest.compiled_source(template), name, view_paths: view_paths, &tracker)
40
56
  # Older ERB trackers omit the underscore on unqualified partial paths.
41
57
  inferred_partials |= inferred_partials.map { |path| path.delete_prefix("_") }
42
58
  declared = source.scan(CacheDigest::EXPLICIT_DEPENDENCY).flatten
@@ -178,14 +178,16 @@ module ViewComponent
178
178
  # @param source [String] Ruby source
179
179
  # @param name [String] virtual path the source is being digested under
180
180
  # @param view_paths [ActionView::PathSet, nil] paths to check dynamic partial guesses against
181
+ # @yieldparam calls [Array<String>] Ruby render calls to track with the template's tracker
182
+ # @yieldreturn [Array<String>] partial paths inferred by that tracker
181
183
  # @return [Array(Array<String>, Array<String>)] synthetic virtual paths of
182
184
  # components and inferred partial virtual paths
183
- def template_renders_in(source, name, view_paths: nil)
185
+ def template_renders_in(source, name, view_paths: nil, &tracker)
184
186
  components, component_calls, other_calls = partition_render_calls(Prism.parse(source).value)
185
187
 
186
188
  [
187
189
  component_paths(components),
188
- (partials_rendered_by(component_calls, name) - partials_rendered_by(other_calls, name)) |
190
+ (partials_rendered_by(component_calls, name, &tracker) - partials_rendered_by(other_calls, name, &tracker)) |
189
191
  unresolved_partials_rendered_by(other_calls, name, view_paths)
190
192
  ]
191
193
  end
@@ -439,15 +441,14 @@ module ViewComponent
439
441
  renderable if renderable.is_a?(Class) && renderable < ViewComponent::Base
440
442
  end
441
443
 
442
- # Partials Action View's render parser finds in the given calls,
443
- # normalized to the form its trackers report. The calls are parsed
444
- # together, so the parser runs once rather than once per call. Blocks are
445
- # left out, as any renders inside them are calls of their own.
444
+ # Partials the given tracker, or Action View's render parser, finds in
445
+ # the given calls. Calls are tracked together rather than once per call.
446
+ # Blocks are left out, as any renders inside them are calls of their own.
446
447
  def partials_rendered_by(calls, name)
447
448
  return [] if calls.empty?
448
449
 
449
- source = calls.map { |call| "#{call.name}(#{call.arguments&.slice})" }.join("\n")
450
- partial_paths_in(source, name)
450
+ sources = calls.map { |call| "#{call.name}(#{call.arguments&.slice})" }
451
+ block_given? ? yield(sources) : partial_paths_in(sources.join("\n"), name)
451
452
  end
452
453
 
453
454
  def partial_paths_in(source, name)
@@ -141,7 +141,7 @@ module ViewComponent
141
141
  case @current_template
142
142
  #{calls}
143
143
  else
144
- raise ViewComponent::MissingTemplateError.new(self.class.name, details)
144
+ raise ViewComponent::MissingTemplateError.new(self.class.name, @lookup_context)
145
145
  end
146
146
  RUBY
147
147
  end
@@ -152,7 +152,9 @@ module ViewComponent
152
152
 
153
153
  template_watcher = CompileCache.template_watcher(app.config.file_watcher)
154
154
 
155
- app.executor.to_run :before do
155
+ app.reloaders << template_watcher
156
+ app.reloader.to_run do
157
+ require_unload_lock!
156
158
  template_watcher.execute_if_updated
157
159
  end
158
160
  end
@@ -108,7 +108,12 @@ module ViewComponent
108
108
  # end
109
109
  # end
110
110
  # end
111
+ #
112
+ # A slot that doesn't wrap a component raises `NoMethodError` for
113
+ # undefined methods, like any other object.
111
114
  def method_missing(symbol, *args, **kwargs, &block)
115
+ return super unless __vc_component_instance?
116
+
112
117
  @__vc_component_instance.public_send(symbol, *args, **kwargs, &block)
113
118
  end
114
119
 
@@ -5,6 +5,10 @@ module ViewComponent
5
5
  DEFAULT_FORMAT = :html
6
6
  private_constant :DEFAULT_FORMAT
7
7
 
8
+ # Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
9
+ ERB_NEWLINE_RAILS_VERSION = Gem::Version.new("8.1.0.alpha")
10
+ private_constant :ERB_NEWLINE_RAILS_VERSION
11
+
8
12
  DataWithSource = Struct.new(:format, :identifier, :short_identifier, :type)
9
13
 
10
14
  attr_reader :details, :path
@@ -209,7 +213,7 @@ module ViewComponent
209
213
  attr_reader :lineno
210
214
 
211
215
  def erb_newline_compensation_needed?
212
- Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR > 0 &&
216
+ Rails.gem_version >= ERB_NEWLINE_RAILS_VERSION &&
213
217
  details.handler == :erb &&
214
218
  annotated?
215
219
  end
@@ -251,7 +251,7 @@ module ViewComponent
251
251
  old_controller&.instance_variable_set(:@_url_options, nil)
252
252
  yield
253
253
  ensure
254
- vc_test_request.set_header("HTTP_HOST", old_request_host)
254
+ vc_test_request.host = old_request_host
255
255
  vc_test_request.request_method = old_request_method
256
256
  vc_test_request.set_header(Rack::RACK_URL_SCHEME, old_request_scheme)
257
257
  vc_test_request.instance_variable_set(:@protocol, old_request_protocol)
@@ -3,7 +3,7 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 4
6
- MINOR = 23
6
+ MINOR = 24
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.23.0
4
+ version: 4.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ViewComponent Team