view_component 4.1.1 → 4.3.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: 7468565c85b97035ae072333ef8c3851467920aa5ddda57078929106ca32c6ae
4
- data.tar.gz: d9cb57ffb7b7de0236774e0836853ca6c33b717ffce1cc1dd20264784829dc2b
3
+ metadata.gz: 7cc3bb1d940451beebb05d7424ae9fe3124ddbfd2acc21e407c0b3c4964c7570
4
+ data.tar.gz: 2db13b63611d87477814e3567e2aca332879a50e1a500ecc560b8a9d0537c411
5
5
  SHA512:
6
- metadata.gz: 1c714baf334d711d94be596712484baf758fb9e03411c6adb1f9e476230e048a3ebe066ef6eeffd079eabaee1240caf68f133c5fb35f82256cff825999ba3852
7
- data.tar.gz: cf63306f08750f07b6d966c21cae7b169d995372dbf249312752ea6b699e5b118ce16f699b03e2c231dac10ea740b0cc9f1ca8aa9185a4247741c1558bfe12a2
6
+ metadata.gz: 8dd9367ebb7c528a5a89d0a76d1294a0fa0276eed80b8c819d338c82d86c131386851903fb3fe0c1be43416980ebf9cb4ca405599f4e58f73084b1d5aee8fa8d
7
+ data.tar.gz: 4cca85cd44103692aed7039a7c0b044d78adbff6bbc0e5d99be0fe72590dae160047cf34ce731ec079141cf2ed22485d32898ce5917ec225e637951151c9d544
data/docs/CHANGELOG.md CHANGED
@@ -10,11 +10,83 @@ nav_order: 6
10
10
 
11
11
  ## main
12
12
 
13
- ## 4.1.1
13
+ ## 4.3.0
14
+
15
+ * Fix load order issues for 3rd-party template handlers.
16
+
17
+ *Cameron Dutro*
18
+
19
+ * Fix segfault when Ruby coverage is enabled with Rails 8.1 ERB templates.
20
+
21
+ *George Holborn*
22
+
23
+ * Automatically merge dependabot PRs.
24
+
25
+ *Joel Hawksley*
26
+
27
+ * Use Ruby 4.0.0 in CI and dev.
28
+
29
+ *Joel Hawksley*
30
+
31
+ ## 4.2.0
32
+
33
+ * Fix translation scope resolution in deeply nested component blocks (3+ levels). Translations called inside deeply nested slot blocks using `renders_many`/`renders_one` were incorrectly resolving to an intermediate component's scope instead of the partial's scope where the block was defined. The fix captures the virtual path at block definition time and restores it during block execution, ensuring translations always resolve relative to where the block was created regardless of nesting depth.
34
+
35
+ *Nathaniel Watts*
36
+
37
+ * Allow `render_inline` with Nokogiri::HTML5 to parse more arbitrary content including bare table content otherwise illegal fragments like `<td>`.
38
+
39
+ *Jonathan Rochkind*
40
+
41
+ * Remove known issue from docs as ActiveScaffold is [now compatible](https://github.com/activescaffold/active_scaffold/pull/743) with ViewComponent.
42
+
43
+ *David Löwenfels*
44
+
45
+ * Add test to document the current behavior for resolving relative translation keys within partial blocks. When rendering a partial, relative translation keys are resolved relative to the partial's own path rather than the caller’s path. This test ensures that this behavior remains consistent.
46
+
47
+ *Oussama Hilal*
48
+
49
+ * Allow I18n calls in `render?`.
50
+
51
+ *23tux*
52
+
53
+ * ViewComponent now works without `rails` and `railties` gems loaded, enabling compatibility with Bridgetown 2.0.
54
+
55
+ *Tom Lord*
56
+
57
+ * Capture partial block in the component's context, allowing access to the component instance inside the block.
58
+
59
+ *23tux*
14
60
 
15
- * Add Consultport to list of companies using ViewComponent.
61
+ * Add `after_compile` class method hook to enable extensions to run logic after component compilation.
16
62
 
17
- *Sebastian Nepote*
63
+ *Jose Solás*
64
+
65
+ * Fix outdated reference to preview layout configuration in docs.
66
+
67
+ *Lucas Geron*
68
+
69
+ * Allow ruby-head CI job to fail without failing workflow.
70
+
71
+ *Hakan Ensari*
72
+
73
+ * Fix bug where error line numbers were incorrect in Rails 8.1.
74
+
75
+ *Joel Hawksley*
76
+
77
+ * Remove `< 8.2` upper bound for `activesupport` and `actionview` dependencies.
78
+
79
+ *Hans Lemuet*
80
+
81
+ * Test compatibility with Herb/ReActionView.
82
+
83
+ *Joel Hawksley*
84
+
85
+ * Remove Who Uses ViewComponent section from docs.
86
+
87
+ *Joel Hawksley*
88
+
89
+ ## 4.1.1
18
90
 
19
91
  * Resolve deprecation warning for `ActiveSupport::Configurable`.
20
92
 
@@ -24,20 +96,12 @@ nav_order: 6
24
96
 
25
97
  *Hans Lemuet*
26
98
 
27
- * Added Reinvented Hospitality to the list of companies using ViewComponent.
28
-
29
- *Torgil Zechel*
30
-
31
99
  ## 4.1.0
32
100
 
33
101
  * Add Rails 8.1 support.
34
102
 
35
103
  *Hans Lemuet*
36
104
 
37
- * Add Carwow to list of companies using ViewComponent.
38
-
39
- *Tom Lord*
40
-
41
105
  * Declare `actionview` as a `view_component` gem dependency.
42
106
 
43
107
  *Michal Cichra*
@@ -520,10 +584,6 @@ This release makes the following breaking changes:
520
584
 
521
585
  *Martin Meyerhoff*, *Joel Hawksley*
522
586
 
523
- * Add Content Harmony & Learn To Be to list of companies using ViewComponent.
524
-
525
- *Kane Jamison*
526
-
527
587
  * Clarify error message about render-dependent logic.
528
588
 
529
589
  Error messages about render-dependent logic were sometimes inaccurate, saying `during initialization` despite also being raised after a component had been initialized but before it was rendered.
@@ -542,10 +602,6 @@ This release makes the following breaking changes:
542
602
 
543
603
  *Reegan Viljoen*
544
604
 
545
- * Add HomeStyler AI to list of companies using ViewComponent.
546
-
547
- *JP Balarini*
548
-
549
605
  ## 3.21.0
550
606
 
551
607
  * Updates testing docs to include an example of how to use with RSpec.
@@ -556,10 +612,6 @@ This release makes the following breaking changes:
556
612
 
557
613
  *KAWAKAMI Moeki*
558
614
 
559
- * Add FreeATS to list of companies using ViewComponent.
560
-
561
- *Ilia Liamshin*
562
-
563
615
  * Ensure HTML output safety wrapper is used for all inline templates.
564
616
 
565
617
  *Joel Hawksley*
@@ -610,10 +662,6 @@ This release makes the following breaking changes:
610
662
 
611
663
  *Blake Williams*
612
664
 
613
- * Add [Niva]([niva.co](https://www.niva.co/)) to companies who use `ViewComponent`.
614
-
615
- *Daniel Vu Dao*
616
-
617
665
  * Fix `preview_paths` in docs.
618
666
 
619
667
  *Javier Aranda*
@@ -678,10 +726,6 @@ This release makes the following breaking changes:
678
726
 
679
727
  *Joel Hawksley*
680
728
 
681
- * Add Kicksite to list of companies using ViewComponent.
682
-
683
- *Adil Lari*
684
-
685
729
  * Allow overridden slot methods to use `super`.
686
730
 
687
731
  *Andrew Schwartz*
@@ -921,10 +965,6 @@ This release makes the following breaking changes:
921
965
 
922
966
  *Simon Fish*
923
967
 
924
- * Add Simundia to list of companies using ViewComponent.
925
-
926
- *Alexandre Ignjatovic*
927
-
928
968
  * Reduce UnboundMethod objects by memoizing initialize_parameters.
929
969
 
930
970
  *Rainer Borene*
@@ -975,10 +1015,6 @@ This release makes the following breaking changes:
975
1015
 
976
1016
  *milk1000cc*
977
1017
 
978
- * Add PeopleForce to list of companies using ViewComponent.
979
-
980
- *Volodymyr Khandiuk*
981
-
982
1018
  ## 3.5.0
983
1019
 
984
1020
  * Add Skroutz to users list.
@@ -1053,14 +1089,6 @@ This release makes the following breaking changes:
1053
1089
 
1054
1090
  *Joel Hawksley*
1055
1091
 
1056
- * Add Ophelos to list of companies using ViewComponent.
1057
-
1058
- *Graham Rogers*
1059
-
1060
- * Add FlightLogger to list of companies using ViewComponent.
1061
-
1062
- *Joseph Carpenter*
1063
-
1064
1092
  * Fix coverage reports overwriting each other when running locally.
1065
1093
 
1066
1094
  *Jonathan del Strother*
@@ -1300,14 +1328,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1300
1328
 
1301
1329
  *Graham Rogers*
1302
1330
 
1303
- * Add Krystal to list of companies using ViewComponent.
1304
-
1305
- *Matt Bearman*
1306
-
1307
- * Add Mon Ami to list of companies using ViewComponent.
1308
-
1309
- *Ethan Lee-Tyson*
1310
-
1311
1331
  ## 3.0.0.rc1
1312
1332
 
1313
1333
  1,000+ days and 100+ releases later, the 200+ contributors to ViewComponent are proud to ship v3.0.0!
@@ -1456,10 +1476,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1456
1476
 
1457
1477
  *Hans Lemuet*
1458
1478
 
1459
- * Add Startup Jobs to list of companies using ViewComponent.
1460
-
1461
- *Marc Köhlbrugge*
1462
-
1463
1479
  * Run PVC's accessibility tests in a single process to avoid resource contention in CI.
1464
1480
 
1465
1481
  *Cameron Dutro*
@@ -1500,10 +1516,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1500
1516
 
1501
1517
  ## 2.74.0
1502
1518
 
1503
- * Add Avo to list of companies using ViewComponent.
1504
-
1505
- *Adrian Marin*
1506
-
1507
1519
  * Promote experimental `_output_postamble` method to public API as `output_postamble`.
1508
1520
 
1509
1521
  *Joel Hawksley*
@@ -1530,10 +1542,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1530
1542
 
1531
1543
  *Erinna Chen*
1532
1544
 
1533
- * Add PrintReleaf to list of companies using ViewComponent.
1534
-
1535
- *Ry Kulp*
1536
-
1537
1545
  * Simplify CI configuration to a single build per Ruby/Rails version.
1538
1546
 
1539
1547
  *Joel Hawksley*
@@ -1542,10 +1550,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1542
1550
 
1543
1551
  *Ruben Smit*
1544
1552
 
1545
- * Add Yobbers to list of companies using ViewComponent.
1546
-
1547
- *Anton Prins*
1548
-
1549
1553
  ## 2.72.0
1550
1554
 
1551
1555
  * Deprecate support for Ruby < 2.7 for removal in v3.0.0.
@@ -1560,10 +1564,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1560
1564
 
1561
1565
  *Joel Hawksley.
1562
1566
 
1563
- * Add Aluuno to list of companies using ViewComponent.
1564
-
1565
- *Daniel Naves de Carvalho*
1566
-
1567
1567
  * Add `source_code_uri` to gemspec.
1568
1568
 
1569
1569
  *Yoshiyuki Hirano*
@@ -1598,22 +1598,10 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1598
1598
 
1599
1599
  *Joel Hawksley*
1600
1600
 
1601
- * Add Arrows to list of companies using ViewComponent.
1602
-
1603
- *Matt Swanson*
1604
-
1605
- * Add WIP to list of companies using ViewComponent.
1606
-
1607
- *Marc Köhlbrugge*
1608
-
1609
1601
  * Update slots documentation to include how to reference slots.
1610
1602
 
1611
1603
  *Brittany Ellich*
1612
1604
 
1613
- * Add Clio to list of companies using ViewComponent.
1614
-
1615
- *Mike Buckley*
1616
-
1617
1605
  ## 2.69.0
1618
1606
 
1619
1607
  * Add missing `require` to fix `pvc` build.
@@ -1731,10 +1719,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1731
1719
 
1732
1720
  *Vikram Dighe*
1733
1721
 
1734
- * Add HappyCo to list of companies using ViewComponent.
1735
-
1736
- *Josh Clayton*
1737
-
1738
1722
  * Add predicate method support to polymorphic slots.
1739
1723
 
1740
1724
  *Graham Rogers*
@@ -1845,10 +1829,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1845
1829
 
1846
1830
  *Thomas Hutterer*
1847
1831
 
1848
- * Add FreeAgent to list of companies using ViewComponent.
1849
-
1850
- *Simon Fish*
1851
-
1852
1832
  * Include polymorphic slots in `ViewComponent::Base` by default.
1853
1833
 
1854
1834
  *Cameron Dutro*
@@ -1904,18 +1884,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1904
1884
 
1905
1885
  *Joel Hawksley*
1906
1886
 
1907
- * Add G2 to list of companies that use ViewComponent.
1908
-
1909
- *Jack Shuff*
1910
-
1911
- * Add Within3 to list of companies that use ViewComponent.
1912
-
1913
- *Drew Bragg*
1914
-
1915
- * Add Mission Met to list of companies that use ViewComponent.
1916
-
1917
- *Nick Smith*
1918
-
1919
1887
  * Fix `#with_request_url` test helper not parsing nested query parameters into nested hashes.
1920
1888
 
1921
1889
  *Richard Marbach*
@@ -1955,10 +1923,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1955
1923
 
1956
1924
  *Blake Williams*
1957
1925
 
1958
- * Add QuickNode to list of companies that use ViewComponent.
1959
-
1960
- *Luc Castera*
1961
-
1962
1926
  * Include the `Translatable` module by default.
1963
1927
 
1964
1928
  *Elia Schito*
@@ -1989,10 +1953,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
1989
1953
 
1990
1954
  *Jason Swett*
1991
1955
 
1992
- * Add Bearer to list of companies that use ViewComponent.
1993
-
1994
- *Yaroslav Shmarov*
1995
-
1996
1956
  * Add articles to resources page.
1997
1957
 
1998
1958
  *Joel Hawksley*
@@ -2022,10 +1982,6 @@ Run into an issue with this release? [Let us know](https://github.com/ViewCompon
2022
1982
 
2023
1983
  *Hans Lemuet*
2024
1984
 
2025
- * Alphabetize companies using ViewComponent and add Brightline to the list.
2026
-
2027
- *Jack Schuss*
2028
-
2029
1985
  * Add CMYK value for ViewComponent Red color on logo page.
2030
1986
 
2031
1987
  *Dylan Smith*
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "action_view"
4
+ require "action_view/base"
4
5
  require "view_component/collection"
5
6
  require "view_component/compile_cache"
6
7
  require "view_component/compiler"
@@ -46,7 +47,7 @@ module ViewComponent
46
47
  end
47
48
 
48
49
  include ActionView::Helpers
49
- include Rails.application.routes.url_helpers if defined?(Rails) && Rails.application
50
+ include Rails.application.routes.url_helpers if defined?(Rails.application.routes)
50
51
  include ERB::Escape
51
52
  include ActiveSupport::CoreExt::ERBUtil
52
53
 
@@ -131,6 +132,7 @@ module ViewComponent
131
132
 
132
133
  @__vc_content_evaluated = false
133
134
  @__vc_render_in_block = block
135
+ @view_context.instance_variable_set(:@virtual_path, virtual_path)
134
136
 
135
137
  before_render
136
138
 
@@ -138,8 +140,6 @@ module ViewComponent
138
140
  value = nil
139
141
 
140
142
  @output_buffer.with_buffer do
141
- @view_context.instance_variable_set(:@virtual_path, virtual_path)
142
-
143
143
  rendered_template =
144
144
  around_render do
145
145
  render_template_for(@__vc_requested_details).to_s
@@ -260,6 +260,9 @@ module ViewComponent
260
260
  @view_context.render(options, args, &block)
261
261
  elsif block
262
262
  __vc_original_view_context.render(options, args) do
263
+ # capture the block output in the view context of the component
264
+ output = capture(&block)
265
+
263
266
  # Partials are rendered to their own buffer and do not append to the
264
267
  # original @output_buffer we retain a reference to in #render_in. This
265
268
  # is a problem since the block passed to us here in the #render method
@@ -267,7 +270,7 @@ module ViewComponent
267
270
  # appends to the original @output_buffer. To avoid this, we evaluate the
268
271
  # block in the view context instead, which will append to the output buffer
269
272
  # created for the partial.
270
- __vc_original_view_context.instance_exec(&block)
273
+ __vc_original_view_context.capture { output }
271
274
  end
272
275
  else
273
276
  __vc_original_view_context.render(options, args)
@@ -301,7 +304,7 @@ module ViewComponent
301
304
  @__vc_helpers ||= __vc_original_view_context || controller.view_context
302
305
  end
303
306
 
304
- if ::Rails.env.development? || ::Rails.env.test?
307
+ if defined?(Rails.env) && (::Rails.env.development? || ::Rails.env.test?)
305
308
  # @private
306
309
  def method_missing(method_name, *args) # rubocop:disable Style/MissingRespondToMissing
307
310
  super
@@ -330,7 +333,7 @@ module ViewComponent
330
333
  []
331
334
  end
332
335
 
333
- if Rails::VERSION::MAJOR == 7 && Rails::VERSION::MINOR == 1
336
+ if defined?(Rails::VERSION) && Rails::VERSION::MAJOR == 7 && Rails::VERSION::MINOR == 1
334
337
  # Rails expects us to define `format` on all renderables,
335
338
  # but we do not know the `format` of a ViewComponent until runtime.
336
339
  def format
@@ -361,7 +364,7 @@ module ViewComponent
361
364
 
362
365
  @__vc_content =
363
366
  if __vc_render_in_block_provided?
364
- with_original_virtual_path do
367
+ with_captured_virtual_path(@old_virtual_path) do
365
368
  view_context.capture(self, &@__vc_render_in_block)
366
369
  end
367
370
  elsif __vc_content_set_by_with_content_defined?
@@ -377,11 +380,14 @@ module ViewComponent
377
380
  end
378
381
 
379
382
  # @private
380
- def with_original_virtual_path
381
- @view_context.instance_variable_set(:@virtual_path, @old_virtual_path)
383
+ # Temporarily sets the virtual path to the captured value, then restores it.
384
+ # This ensures translations and other path-dependent code execute with the correct scope.
385
+ def with_captured_virtual_path(captured_path)
386
+ old_virtual_path = @view_context.instance_variable_get(:@virtual_path)
387
+ @view_context.instance_variable_set(:@virtual_path, captured_path)
382
388
  yield
383
389
  ensure
384
- @view_context.instance_variable_set(:@virtual_path, virtual_path)
390
+ @view_context.instance_variable_set(:@virtual_path, old_virtual_path)
385
391
  end
386
392
 
387
393
  private
@@ -572,7 +578,7 @@ module ViewComponent
572
578
  # eager loading is disabled and the parent component is rendered before the child. In
573
579
  # such a scenario, the parent will override ViewComponent::Base#render_template_for,
574
580
  # 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.__vc_compiled?
581
+ if !child.method_defined?(:render_template_for, false) && !child.__vc_compiled?
576
582
  child.class_eval <<~RUBY, __FILE__, __LINE__ + 1
577
583
  def render_template_for(requested_details)
578
584
  # Force compilation here so the compiler always redefines render_template_for.
@@ -595,7 +601,7 @@ module ViewComponent
595
601
  # Set collection parameter to the extended component
596
602
  child.with_collection_parameter(__vc_provided_collection_parameter)
597
603
 
598
- if instance_methods(false).include?(:render_template_for)
604
+ if method_defined?(:render_template_for, false)
599
605
  vc_ancestor_calls = defined?(@__vc_ancestor_calls) ? @__vc_ancestor_calls.dup : []
600
606
 
601
607
  vc_ancestor_calls.unshift(instance_method(:render_template_for))
@@ -610,6 +616,16 @@ module ViewComponent
610
616
  __vc_compiler.compiled?
611
617
  end
612
618
 
619
+ # Hook called by the compiler after a component is compiled.
620
+ #
621
+ # Extensions can override this class method to run logic after
622
+ # compilation (e.g., generate helpers, register metadata, etc.).
623
+ #
624
+ # By default, this is a no-op.
625
+ def after_compile
626
+ # no-op by default
627
+ end
628
+
613
629
  # @private
614
630
  def __vc_ensure_compiled
615
631
  __vc_compile unless __vc_compiled?
@@ -20,7 +20,7 @@ module ViewComponent
20
20
  components.each(&block)
21
21
  end
22
22
 
23
- if Rails::VERSION::MAJOR == 7 && Rails::VERSION::MINOR == 1
23
+ if defined?(Rails::VERSION) && Rails::VERSION::MAJOR == 7 && Rails::VERSION::MINOR == 1
24
24
  # Rails expects us to define `format` on all renderables,
25
25
  # but we do not know the `format` of a ViewComponent until runtime.
26
26
  def format
@@ -52,6 +52,8 @@ module ViewComponent
52
52
  @component.__vc_build_i18n_backend
53
53
 
54
54
  CompileCache.register(@component)
55
+
56
+ @component.after_compile
55
57
  end
56
58
  end
57
59
 
@@ -113,11 +115,11 @@ module ViewComponent
113
115
  .tally
114
116
  .select { |_, count| count > 1 }
115
117
  .each do |tally|
116
- variant, this_format = tally.first
118
+ variant, this_format = tally.first
117
119
 
118
- variant_string = " for variant `#{variant}`" if variant.present?
120
+ variant_string = " for variant `#{variant}`" if variant.present?
119
121
 
120
- errors << "More than one #{this_format.upcase} template found#{variant_string} for #{@component}. "
122
+ errors << "More than one #{this_format.upcase} template found#{variant_string} for #{@component}. "
121
123
  end
122
124
 
123
125
  default_template_types = @templates.each_with_object(Set.new) do |template, memo|
@@ -188,11 +190,11 @@ module ViewComponent
188
190
  ).flat_map { |ancestor| ancestor.instance_methods(false).grep(/^call(_|$)/) }
189
191
  .uniq
190
192
  .each do |method_name|
191
- templates << Template::InlineCall.new(
192
- component: @component,
193
- method_name: method_name,
194
- defined_on_self: component_instance_methods_on_self.include?(method_name)
195
- )
193
+ templates << Template::InlineCall.new(
194
+ component: @component,
195
+ method_name: method_name,
196
+ defined_on_self: component_instance_methods_on_self.include?(method_name)
197
+ )
196
198
  end
197
199
 
198
200
  templates
@@ -163,7 +163,7 @@ module ViewComponent
163
163
  options = ActiveSupport::OrderedOptions.new
164
164
  options.controller = "ViewComponentsController"
165
165
  options.route = "/rails/view_components"
166
- options.enabled = Rails.env.development? || Rails.env.test?
166
+ options.enabled = defined?(Rails.env) && (Rails.env.development? || Rails.env.test?)
167
167
  options.default_layout = nil
168
168
  options.paths = default_preview_paths
169
169
  options
@@ -6,7 +6,7 @@ module ViewComponent
6
6
  class Slot
7
7
  include ViewComponent::WithContentHelper
8
8
 
9
- attr_writer :__vc_component_instance, :__vc_content_block, :__vc_content
9
+ attr_writer :__vc_component_instance, :__vc_content_block, :__vc_content, :__vc_content_block_virtual_path
10
10
 
11
11
  def initialize(parent)
12
12
  @parent = parent
@@ -58,7 +58,7 @@ module ViewComponent
58
58
  if defined?(@__vc_content_block)
59
59
  # render_in is faster than `parent.render`
60
60
  @__vc_component_instance.render_in(view_context) do |*args|
61
- @parent.with_original_virtual_path do
61
+ @parent.with_captured_virtual_path(@__vc_content_block_virtual_path) do
62
62
  @__vc_content_block.call(*args)
63
63
  end
64
64
  end
@@ -68,7 +68,7 @@ module ViewComponent
68
68
  elsif defined?(@__vc_content)
69
69
  @__vc_content
70
70
  elsif defined?(@__vc_content_block)
71
- @parent.with_original_virtual_path do
71
+ @parent.with_captured_virtual_path(@__vc_content_block_virtual_path) do
72
72
  view_context.capture(&@__vc_content_block)
73
73
  end
74
74
  elsif defined?(@__vc_content_set_by_with_content)
@@ -259,7 +259,7 @@ module ViewComponent
259
259
 
260
260
  setter_method_name = :"with_#{poly_slot_name}"
261
261
 
262
- if instance_methods.include?(setter_method_name)
262
+ if method_defined?(setter_method_name)
263
263
  raise AlreadyDefinedPolymorphicSlotSetterError.new(setter_method_name, poly_slot_name)
264
264
  end
265
265
 
@@ -390,7 +390,12 @@ module ViewComponent
390
390
  # 2. Since we have to pass block content to components when calling
391
391
  # `render`, evaluating the block here would require us to call
392
392
  # `view_context.capture` twice, which is slower
393
- slot.__vc_content_block = block if block
393
+ if block
394
+ slot.__vc_content_block = block
395
+ # Capture the virtual path at the time the block is defined, so that
396
+ # translations resolve relative to where the block was created, not where it's rendered
397
+ slot.__vc_content_block_virtual_path = view_context.instance_variable_get(:@virtual_path)
398
+ end
394
399
 
395
400
  # If class
396
401
  if slot_definition[:renderable]
@@ -408,7 +413,9 @@ module ViewComponent
408
413
  renderable_value =
409
414
  if block
410
415
  renderable_function.call(*args, **kwargs) do |*rargs|
411
- view_context.capture(*rargs, &block)
416
+ with_captured_virtual_path(@old_virtual_path) do
417
+ view_context.capture(*rargs, &block)
418
+ end
412
419
  end
413
420
  else
414
421
  renderable_function.call(*args, **kwargs)
@@ -21,11 +21,30 @@ module ViewComponent
21
21
 
22
22
  class File < Template
23
23
  def initialize(component:, details:, path:)
24
+ @strip_annotation_line = false
25
+
26
+ # Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
27
+ # Use -1 to compensate for correct line numbers in stack traces.
28
+ # However, negative line numbers cause segfaults when Ruby's coverage
29
+ # is enabled (bugs.ruby-lang.org/issues/19363). In that case, strip the
30
+ # annotation line from compiled source instead.
31
+ lineno =
32
+ if Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR > 0 && details.handler == :erb
33
+ if coverage_running? && ActionView::Base.annotate_rendered_view_with_filenames
34
+ @strip_annotation_line = true
35
+ 0
36
+ else
37
+ -1
38
+ end
39
+ else
40
+ 0
41
+ end
42
+
24
43
  super(
25
44
  component: component,
26
45
  details: details,
27
46
  path: path,
28
- lineno: 0
47
+ lineno: lineno
29
48
  )
30
49
  end
31
50
 
@@ -37,6 +56,16 @@ module ViewComponent
37
56
  def source
38
57
  ::File.read(@path)
39
58
  end
59
+
60
+ private
61
+
62
+ def compiled_source
63
+ result = super
64
+ # Strip the annotation line to maintain correct line numbers when coverage
65
+ # is running (avoids segfault from negative lineno)
66
+ result = result.sub(/\A[^\n]*\n/, "") if @strip_annotation_line
67
+ result
68
+ end
40
69
  end
41
70
 
42
71
  class Inline < Template
@@ -45,11 +74,22 @@ module ViewComponent
45
74
  def initialize(component:, inline_template:)
46
75
  details = ActionView::TemplateDetails.new(nil, inline_template.language.to_sym, nil, nil)
47
76
 
77
+ # Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
78
+ # Subtract 1 to compensate for correct line numbers in stack traces.
79
+ # Inline templates start at line 2+ (defined inside a class), so this
80
+ # won't result in negative line numbers that cause segfaults with coverage.
81
+ lineno =
82
+ if Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR > 0 && details.handler == :erb
83
+ inline_template.lineno - 1
84
+ else
85
+ inline_template.lineno
86
+ end
87
+
48
88
  super(
49
89
  component: component,
50
90
  details: details,
51
91
  path: inline_template.path,
52
- lineno: inline_template.lineno,
92
+ lineno: lineno,
53
93
  )
54
94
 
55
95
  @source = inline_template.source.dup
@@ -108,6 +148,10 @@ module ViewComponent
108
148
  @component.define_method(safe_method_name, @component.instance_method(@call_method_name))
109
149
  end
110
150
 
151
+ def coverage_running?
152
+ defined?(Coverage) && Coverage.running?
153
+ end
154
+
111
155
  def safe_method_name_call
112
156
  m = safe_method_name
113
157
  proc { send(m) }
@@ -40,7 +40,7 @@ module ViewComponent
40
40
  @page = nil
41
41
  @rendered_content = vc_test_view_context.render(component, args, &block)
42
42
 
43
- fragment = Nokogiri::HTML5.fragment(@rendered_content)
43
+ fragment = Nokogiri::HTML5.fragment(@rendered_content, context: "template")
44
44
  @vc_test_view_context = nil
45
45
  fragment
46
46
  end
@@ -3,8 +3,8 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 4
6
- MINOR = 1
7
- PATCH = 1
6
+ MINOR = 3
7
+ PATCH = 0
8
8
  PRE = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join(".")
@@ -17,7 +17,7 @@ module ViewComponent
17
17
  autoload :Preview
18
18
  autoload :Translatable
19
19
 
20
- if Rails.env.test?
20
+ if defined?(Rails.env) && Rails.env.test?
21
21
  autoload :TestHelpers
22
22
  autoload :SystemSpecHelpers
23
23
  autoload :SystemTestHelpers
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.1.1
4
+ version: 4.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ViewComponent Team
@@ -16,9 +16,6 @@ dependencies:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
18
  version: 7.1.0
19
- - - "<"
20
- - !ruby/object:Gem::Version
21
- version: '8.2'
22
19
  type: :runtime
23
20
  prerelease: false
24
21
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,9 +23,6 @@ dependencies:
26
23
  - - ">="
27
24
  - !ruby/object:Gem::Version
28
25
  version: 7.1.0
29
- - - "<"
30
- - !ruby/object:Gem::Version
31
- version: '8.2'
32
26
  - !ruby/object:Gem::Dependency
33
27
  name: actionview
34
28
  requirement: !ruby/object:Gem::Requirement
@@ -36,9 +30,6 @@ dependencies:
36
30
  - - ">="
37
31
  - !ruby/object:Gem::Version
38
32
  version: 7.1.0
39
- - - "<"
40
- - !ruby/object:Gem::Version
41
- version: '8.2'
42
33
  type: :runtime
43
34
  prerelease: false
44
35
  version_requirements: !ruby/object:Gem::Requirement
@@ -46,9 +37,6 @@ dependencies:
46
37
  - - ">="
47
38
  - !ruby/object:Gem::Version
48
39
  version: 7.1.0
49
- - - "<"
50
- - !ruby/object:Gem::Version
51
- version: '8.2'
52
40
  - !ruby/object:Gem::Dependency
53
41
  name: concurrent-ruby
54
42
  requirement: !ruby/object:Gem::Requirement
@@ -147,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
135
  - !ruby/object:Gem::Version
148
136
  version: '0'
149
137
  requirements: []
150
- rubygems_version: 3.6.9
138
+ rubygems_version: 4.0.3
151
139
  specification_version: 4
152
140
  summary: A framework for building reusable, testable & encapsulated view components
153
141
  in Ruby on Rails.