view_component 3.20.0 → 3.21.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84bc019145d592e5a7f4dbb439cc960497ac347e12c2a6f73d7544a777365522
4
- data.tar.gz: 2832c147430779d124335b8e82c915115b5b6840ab02365df551f5313621e85c
3
+ metadata.gz: 24be9824d2f5208831e8de57930415019c781a1245224659efb9258372dcafbc
4
+ data.tar.gz: 33182c814b14959c85370e274619a3da70ea19906dd40c8d0be0cd12c9f16a2b
5
5
  SHA512:
6
- metadata.gz: ccbe1677fec16d8de063aafe220ada3ee0647d9963d91f269ef3081b9b2edffc4bf2f535c2097a730d72e80521a9367e97353927997f353f3ec59923e2611deb
7
- data.tar.gz: d52f357464701228bc686f4ea367974a287ce4fcd895845814f9a175635750664b705411c096f3f01c0bad0914a1db95573f50d12ff1b0e7d9029a55adf492b8
6
+ metadata.gz: 0d856adb4c86acc808277c7fcc17291b41328b932b53991db003dccab6e23f2a02177e200065e78d3004f8233df98b0926202138b8b536f67c8f848f876231e2
7
+ data.tar.gz: a7c6b583fd6eaf4bdb20cdc9d7ca86ed0a5e818e90d1099c5fd799d2127122c058d5d58285251ea0713aeb73d719cabad8ab971e994e0f658767235089953dfd
data/docs/CHANGELOG.md CHANGED
@@ -10,6 +10,36 @@ nav_order: 5
10
10
 
11
11
  ## main
12
12
 
13
+ ## 3.21.0
14
+
15
+ * Updates testing docs to include an example of how to use with RSpec.
16
+
17
+ *Rylan Bowers*
18
+
19
+ * Add `--skip-suffix` option to component generator.
20
+
21
+ *KAWAKAMI Moeki*
22
+
23
+ * Add FreeATS to list of companies using ViewComponent.
24
+
25
+ *Ilia Liamshin*
26
+
27
+ * Ensure HTML output safety wrapper is used for all inline templates.
28
+
29
+ *Joel Hawksley*
30
+
31
+ * Expose `.identifier` method as part of public API.
32
+
33
+ *Joel Hawksley*
34
+
35
+ * Add rails 8 support to CI.
36
+
37
+ *Reegan Viljoen*
38
+
39
+ * Updates ActionText compatibility documentation to reference `rich_textarea_tag` for Rails 8.0 support.
40
+
41
+ *Alvin Crespo*
42
+
13
43
  ## 3.20.0
14
44
 
15
45
  * Allow rendering `with_collection` to accept an optional `spacer_component` to be rendered between each item.
@@ -19,9 +19,10 @@ module Rails
19
19
  class_option :sidecar, type: :boolean, default: false
20
20
  class_option :stimulus, type: :boolean,
21
21
  default: ViewComponent::Base.config.generate.stimulus_controller
22
+ class_option :skip_suffix, type: :boolean, default: false
22
23
 
23
24
  def create_component_file
24
- template "component.rb", File.join(component_path, class_path, "#{file_name}_component.rb")
25
+ template "component.rb", File.join(component_path, class_path, "#{file_name}#{options[:skip_suffix] ? "" : "_component"}.rb")
25
26
  end
26
27
 
27
28
  hook_for :test_framework
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  <% module_namespacing do -%>
4
- class <%= class_name %>Component < <%= parent_class %>
4
+ class <%= class_name %><%= options[:skip_suffix] ? "" : "Component" %> < <%= parent_class %>
5
5
  <%- if initialize_signature -%>
6
6
  def initialize(<%= initialize_signature %>)
7
7
  <%= initialize_body %>
@@ -108,14 +108,7 @@ module ViewComponent
108
108
  before_render
109
109
 
110
110
  if render?
111
- rendered_template =
112
- if compiler.renders_template_for?(@__vc_variant, __vc_request&.format&.to_sym)
113
- render_template_for(@__vc_variant, __vc_request&.format&.to_sym)
114
- else
115
- maybe_escape_html(render_template_for(@__vc_variant, __vc_request&.format&.to_sym)) do
116
- Kernel.warn("WARNING: The #{self.class} component rendered HTML-unsafe output. The output will be automatically escaped, but you may want to investigate.")
117
- end
118
- end.to_s
111
+ rendered_template = render_template_for(@__vc_variant, __vc_request&.format&.to_sym).to_s
119
112
 
120
113
  # Avoid allocating new string when output_preamble and output_postamble are blank
121
114
  if output_preamble.blank? && output_postamble.blank?
@@ -358,10 +351,6 @@ module ViewComponent
358
351
  end
359
352
  end
360
353
 
361
- def compiler
362
- @compiler ||= self.class.compiler
363
- end
364
-
365
354
  # Set the controller used for testing components:
366
355
  #
367
356
  # ```ruby
@@ -457,8 +446,16 @@ module ViewComponent
457
446
  # Defaults to `false`.
458
447
 
459
448
  class << self
449
+ # The file path of the component Ruby file.
450
+ #
451
+ # @return [String]
452
+ attr_reader :identifier
453
+
454
+ # @private
455
+ attr_writer :identifier
456
+
460
457
  # @private
461
- attr_accessor :source_location, :virtual_path
458
+ attr_accessor :virtual_path
462
459
 
463
460
  # Find sidecar files for the given extensions.
464
461
  #
@@ -468,13 +465,13 @@ module ViewComponent
468
465
  # For example, one might collect sidecar CSS files that need to be compiled.
469
466
  # @param extensions [Array<String>] Extensions of which to return matching sidecar files.
470
467
  def sidecar_files(extensions)
471
- return [] unless source_location
468
+ return [] unless identifier
472
469
 
473
470
  extensions = extensions.join(",")
474
471
 
475
472
  # view files in a directory named like the component
476
- directory = File.dirname(source_location)
477
- filename = File.basename(source_location, ".rb")
473
+ directory = File.dirname(identifier)
474
+ filename = File.basename(identifier, ".rb")
478
475
  component_name = name.demodulize.underscore
479
476
 
480
477
  # Add support for nested components defined in the same file.
@@ -499,7 +496,7 @@ module ViewComponent
499
496
 
500
497
  sidecar_directory_files = Dir["#{directory}/#{component_name}/#{filename}.*{#{extensions}}"]
501
498
 
502
- (sidecar_files - [source_location] + sidecar_directory_files + nested_component_files).uniq
499
+ (sidecar_files - [identifier] + sidecar_directory_files + nested_component_files).uniq
503
500
  end
504
501
 
505
502
  # Render a component for each element in a collection ([documentation](/guide/collections)):
@@ -548,11 +545,11 @@ module ViewComponent
548
545
  # has been re-defined by the consuming application, likely in ApplicationComponent.
549
546
  # We use `base_label` method here instead of `label` to avoid cases where the method
550
547
  # owner is included in a prefix like `ApplicationComponent.inherited`.
551
- child.source_location = caller_locations(1, 10).reject { |l| l.base_label == "inherited" }[0].path
548
+ child.identifier = caller_locations(1, 10).reject { |l| l.base_label == "inherited" }[0].path
552
549
 
553
550
  # If Rails application is loaded, removes the first part of the path and the extension.
554
551
  if defined?(Rails) && Rails.application
555
- child.virtual_path = child.source_location.gsub(
552
+ child.virtual_path = child.identifier.gsub(
556
553
  /(.*#{Regexp.quote(ViewComponent::Base.config.view_component_path)})|(\.rb)/, ""
557
554
  )
558
555
  end
@@ -590,15 +587,6 @@ module ViewComponent
590
587
  @__vc_compiler ||= Compiler.new(self)
591
588
  end
592
589
 
593
- # @private
594
- def identifier
595
- # :nocov:
596
- Kernel.warn("WARNING: The #{self.class}.identifier is undocumented and was meant for internal framework usage only. As it is no longer used by the framework it will be removed in a coming non-breaking ViewComponent release.")
597
-
598
- source_location
599
- # :nocov:
600
- end
601
-
602
590
  # Set the parameter name used when rendering elements of a collection ([documentation](/guide/collections)):
603
591
  #
604
592
  # ```ruby
@@ -636,7 +624,7 @@ module ViewComponent
636
624
  # validate that the default parameter name
637
625
  # is accepted, as support for collection
638
626
  # rendering is optional.
639
- # @private TODO: add documentation
627
+ # @private
640
628
  def validate_collection_parameter!(validate_default: false)
641
629
  parameter = validate_default ? collection_parameter : provided_collection_parameter
642
630
 
@@ -656,7 +644,7 @@ module ViewComponent
656
644
  # Ensure the component initializer doesn't define
657
645
  # invalid parameters that could override the framework's
658
646
  # methods.
659
- # @private TODO: add documentation
647
+ # @private
660
648
  def validate_initialization_parameters!
661
649
  return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
662
650
 
@@ -13,7 +13,6 @@ module ViewComponent
13
13
  def initialize(component)
14
14
  @component = component
15
15
  @lock = Mutex.new
16
- @rendered_templates = Set.new
17
16
  end
18
17
 
19
18
  def compiled?
@@ -56,10 +55,6 @@ module ViewComponent
56
55
  end
57
56
  end
58
57
 
59
- def renders_template_for?(variant, format)
60
- @rendered_templates.include?([variant, format])
61
- end
62
-
63
58
  private
64
59
 
65
60
  attr_reader :templates
@@ -71,9 +66,9 @@ module ViewComponent
71
66
 
72
67
  method_body =
73
68
  if @templates.one?
74
- @templates.first.safe_method_name
69
+ @templates.first.safe_method_name_call
75
70
  elsif (template = @templates.find(&:inline?))
76
- template.safe_method_name
71
+ template.safe_method_name_call
77
72
  else
78
73
  branches = []
79
74
 
@@ -88,13 +83,13 @@ module ViewComponent
88
83
  ].join(" && ")
89
84
  end
90
85
 
91
- branches << [conditional, template.safe_method_name]
86
+ branches << [conditional, template.safe_method_name_call]
92
87
  end
93
88
 
94
89
  out = branches.each_with_object(+"") do |(conditional, branch_body), memo|
95
90
  memo << "#{(!memo.present?) ? "if" : "elsif"} #{conditional}\n #{branch_body}\n"
96
91
  end
97
- out << "else\n #{templates.find { _1.variant.nil? && _1.default_format? }.safe_method_name}\nend"
92
+ out << "else\n #{templates.find { _1.variant.nil? && _1.default_format? }.safe_method_name_call}\nend"
98
93
  end
99
94
 
100
95
  @component.silence_redefinition_of_method(:render_template_for)
@@ -196,10 +191,6 @@ module ViewComponent
196
191
  variant: variant
197
192
  )
198
193
 
199
- # TODO: We should consider inlining the HTML output safety logic into the compiled render_template_for
200
- # instead of this indirect approach
201
- @rendered_templates << [out.variant, out.this_format]
202
-
203
194
  out
204
195
  end
205
196
 
@@ -13,7 +13,7 @@ module ViewComponent # :nodoc:
13
13
  notification_name,
14
14
  {
15
15
  name: self.class.name,
16
- identifier: self.class.source_location
16
+ identifier: self.class.identifier
17
17
  }
18
18
  ) do
19
19
  super
@@ -59,6 +59,14 @@ module ViewComponent
59
59
  @component.define_method(safe_method_name, @component.instance_method(@call_method_name))
60
60
  end
61
61
 
62
+ def safe_method_name_call
63
+ return safe_method_name unless inline_call?
64
+
65
+ "maybe_escape_html(#{safe_method_name}) " \
66
+ "{ Kernel.warn('WARNING: The #{@component} component rendered HTML-unsafe output. " \
67
+ "The output will be automatically escaped, but you may want to investigate.') } "
68
+ end
69
+
62
70
  def requires_compiled_superclass?
63
71
  inline_call? && !defined_on_self?
64
72
  end
@@ -3,7 +3,7 @@
3
3
  module ViewComponent
4
4
  module VERSION
5
5
  MAJOR = 3
6
- MINOR = 20
6
+ MINOR = 21
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
 
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.20.0
4
+ version: 3.21.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: 2024-10-31 00:00:00.000000000 Z
11
+ date: 2024-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -324,6 +324,20 @@ dependencies:
324
324
  - - '='
325
325
  - !ruby/object:Gem::Version
326
326
  version: 4.9.0
327
+ - !ruby/object:Gem::Dependency
328
+ name: sprockets-rails
329
+ requirement: !ruby/object:Gem::Requirement
330
+ requirements:
331
+ - - "~>"
332
+ - !ruby/object:Gem::Version
333
+ version: 3.4.2
334
+ type: :development
335
+ prerelease: false
336
+ version_requirements: !ruby/object:Gem::Requirement
337
+ requirements:
338
+ - - "~>"
339
+ - !ruby/object:Gem::Version
340
+ version: 3.4.2
327
341
  - !ruby/object:Gem::Dependency
328
342
  name: standard
329
343
  requirement: !ruby/object:Gem::Requirement
@@ -380,20 +394,6 @@ dependencies:
380
394
  - - "~>"
381
395
  - !ruby/object:Gem::Version
382
396
  version: '5.1'
383
- - !ruby/object:Gem::Dependency
384
- name: sprockets-rails
385
- requirement: !ruby/object:Gem::Requirement
386
- requirements:
387
- - - "~>"
388
- - !ruby/object:Gem::Version
389
- version: 3.4.2
390
- type: :development
391
- prerelease: false
392
- version_requirements: !ruby/object:Gem::Requirement
393
- requirements:
394
- - - "~>"
395
- - !ruby/object:Gem::Version
396
- version: 3.4.2
397
397
  - !ruby/object:Gem::Dependency
398
398
  name: turbo-rails
399
399
  requirement: !ruby/object:Gem::Requirement