view_component 3.23.2 → 4.12.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 +4 -4
- data/app/controllers/concerns/view_component/preview_actions.rb +11 -14
- data/app/controllers/view_components_system_test_controller.rb +25 -19
- data/app/views/test_mailer/test_asset_email.html.erb +1 -0
- data/app/views/test_mailer/test_url_email.html.erb +1 -0
- data/app/views/view_components/preview.html.erb +1 -9
- data/docs/CHANGELOG.md +612 -108
- data/lib/{rails/generators → generators/view_component}/abstract_generator.rb +2 -2
- data/lib/{rails/generators → generators/view_component}/component/component_generator.rb +17 -4
- data/lib/{rails/generators → generators/view_component}/component/templates/component.rb.tt +6 -1
- data/lib/{rails/generators/erb/component_generator.rb → generators/view_component/erb/erb_generator.rb} +4 -3
- data/lib/{rails/generators/haml/component_generator.rb → generators/view_component/haml/haml_generator.rb} +3 -3
- data/lib/{rails/generators/locale/component_generator.rb → generators/view_component/locale/locale_generator.rb} +3 -3
- data/lib/{rails/generators/preview/component_generator.rb → generators/view_component/preview/preview_generator.rb} +3 -3
- data/lib/{rails/generators/rspec/component_generator.rb → generators/view_component/rspec/rspec_generator.rb} +3 -3
- data/lib/{rails/generators/slim/component_generator.rb → generators/view_component/slim/slim_generator.rb} +3 -3
- data/lib/{rails/generators/stimulus/component_generator.rb → generators/view_component/stimulus/stimulus_generator.rb} +3 -3
- data/lib/generators/view_component/tailwindcss/tailwindcss_generator.rb +11 -0
- data/lib/{rails/generators/test_unit/component_generator.rb → generators/view_component/test_unit/test_unit_generator.rb} +2 -2
- data/lib/view_component/base.rb +252 -163
- data/lib/view_component/collection.rb +33 -35
- data/lib/view_component/compiler.rb +55 -80
- data/lib/view_component/config.rb +55 -85
- data/lib/view_component/configurable.rb +19 -3
- data/lib/view_component/deprecation.rb +1 -1
- data/lib/view_component/engine.rb +46 -106
- data/lib/view_component/errors.rb +16 -34
- data/lib/view_component/inline_template.rb +4 -4
- data/lib/view_component/instrumentation.rb +21 -14
- data/lib/view_component/preview.rb +7 -12
- data/lib/view_component/request_details.rb +30 -0
- data/lib/view_component/slot.rb +7 -15
- data/lib/view_component/slotable.rb +94 -80
- data/lib/view_component/system_spec_helpers.rb +11 -0
- data/lib/view_component/system_test_helpers.rb +2 -2
- data/lib/view_component/template.rb +159 -83
- data/lib/view_component/test_helpers.rb +67 -50
- data/lib/view_component/translatable.rb +33 -32
- data/lib/view_component/version.rb +3 -3
- data/lib/view_component.rb +9 -6
- metadata +36 -556
- data/app/assets/vendor/prism.css +0 -4
- data/app/assets/vendor/prism.min.js +0 -12
- data/app/helpers/preview_helper.rb +0 -85
- data/app/views/view_components/_preview_source.html.erb +0 -17
- data/lib/rails/generators/tailwindcss/component_generator.rb +0 -11
- data/lib/view_component/capture_compatibility.rb +0 -44
- data/lib/view_component/component_error.rb +0 -6
- data/lib/view_component/rails/tasks/view_component.rake +0 -20
- data/lib/view_component/render_component_helper.rb +0 -10
- data/lib/view_component/render_component_to_string_helper.rb +0 -9
- data/lib/view_component/render_monkey_patch.rb +0 -13
- data/lib/view_component/render_to_string_monkey_patch.rb +0 -13
- data/lib/view_component/rendering_component_helper.rb +0 -9
- data/lib/view_component/rendering_monkey_patch.rb +0 -13
- data/lib/view_component/slotable_default.rb +0 -20
- data/lib/view_component/use_helpers.rb +0 -42
- /data/lib/{rails/generators → generators/view_component}/erb/templates/component.html.erb.tt +0 -0
- /data/lib/{rails/generators → generators/view_component}/haml/templates/component.html.haml.tt +0 -0
- /data/lib/{rails/generators → generators/view_component}/preview/templates/component_preview.rb.tt +0 -0
- /data/lib/{rails/generators → generators/view_component}/rspec/templates/component_spec.rb.tt +0 -0
- /data/lib/{rails/generators → generators/view_component}/slim/templates/component.html.slim.tt +0 -0
- /data/lib/{rails/generators → generators/view_component}/stimulus/templates/component_controller.js.tt +0 -0
- /data/lib/{rails/generators → generators/view_component}/stimulus/templates/component_controller.ts.tt +0 -0
- /data/lib/{rails/generators → generators/view_component}/tailwindcss/templates/component.html.erb.tt +0 -0
- /data/lib/{rails/generators → generators/view_component}/test_unit/templates/component_test.rb.tt +0 -0
|
@@ -18,18 +18,7 @@ module ViewComponent
|
|
|
18
18
|
def assert_component_rendered
|
|
19
19
|
assert_selector("body")
|
|
20
20
|
end
|
|
21
|
-
rescue LoadError
|
|
22
|
-
# We don't have a test case for running an application without capybara installed.
|
|
23
|
-
# It's probably fine to leave this without coverage.
|
|
24
|
-
# :nocov:
|
|
25
|
-
if ENV["DEBUG"]
|
|
26
|
-
warn(
|
|
27
|
-
"WARNING in `ViewComponent::TestHelpers`: Add `capybara` " \
|
|
28
|
-
"to Gemfile to use Capybara assertions."
|
|
29
|
-
)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# :nocov:
|
|
21
|
+
rescue LoadError # We don't have a test case for running an application without capybara installed.
|
|
33
22
|
end
|
|
34
23
|
|
|
35
24
|
# Returns the result of a render_inline call.
|
|
@@ -46,21 +35,23 @@ module ViewComponent
|
|
|
46
35
|
# ```
|
|
47
36
|
#
|
|
48
37
|
# @param component [ViewComponent::Base, ViewComponent::Collection] The instance of the component to be rendered.
|
|
49
|
-
#
|
|
38
|
+
#
|
|
39
|
+
# @return [Nokogiri::HTML5]
|
|
50
40
|
def render_inline(component, **args, &block)
|
|
51
41
|
@page = nil
|
|
52
|
-
@rendered_content =
|
|
53
|
-
if Rails.version.to_f >= 6.1
|
|
54
|
-
vc_test_controller.view_context.render(component, args, &block)
|
|
55
|
-
|
|
56
|
-
# :nocov:
|
|
57
|
-
else
|
|
58
|
-
vc_test_controller.view_context.render_component(component, &block)
|
|
59
|
-
end
|
|
42
|
+
@rendered_content = vc_test_view_context.render(component, args, &block)
|
|
60
43
|
|
|
61
|
-
|
|
44
|
+
fragment = Nokogiri::HTML5.fragment(@rendered_content, context: "template")
|
|
45
|
+
@vc_test_view_context = nil
|
|
46
|
+
fragment
|
|
47
|
+
end
|
|
62
48
|
|
|
63
|
-
|
|
49
|
+
# Returns the view context used to render components in tests. Note that the view context
|
|
50
|
+
# is reset after each call to `render_inline`.
|
|
51
|
+
#
|
|
52
|
+
# @return [ActionView::Base]
|
|
53
|
+
def vc_test_view_context
|
|
54
|
+
@vc_test_view_context ||= vc_test_controller.view_context
|
|
64
55
|
end
|
|
65
56
|
|
|
66
57
|
# `JSON.parse`-d component output.
|
|
@@ -81,19 +72,20 @@ module ViewComponent
|
|
|
81
72
|
# assert_text("Hello, World!")
|
|
82
73
|
# ```
|
|
83
74
|
#
|
|
84
|
-
# Note: `#rendered_preview` expects a preview to be defined with the same class
|
|
85
|
-
# name as the calling test, but with `Test` replaced with `Preview`:
|
|
86
|
-
#
|
|
87
|
-
# MyComponentTest -> MyComponentPreview etc.
|
|
88
|
-
#
|
|
89
|
-
# In RSpec, `Preview` is appended to `described_class`.
|
|
90
|
-
#
|
|
91
75
|
# @param name [String] The name of the preview to be rendered.
|
|
92
76
|
# @param from [ViewComponent::Preview] The class of the preview to be rendered.
|
|
93
77
|
# @param params [Hash] Parameters to be passed to the preview.
|
|
94
|
-
#
|
|
78
|
+
#
|
|
79
|
+
# @return [Nokogiri::HTML5]
|
|
80
|
+
#
|
|
81
|
+
# @note `#rendered_preview` expects a preview to be defined with the same class
|
|
82
|
+
# name as the calling test, but with `Test` replaced with `Preview`:
|
|
83
|
+
#
|
|
84
|
+
# MyComponentTest -> MyComponentPreview etc.
|
|
85
|
+
#
|
|
86
|
+
# In RSpec, `Preview` is appended to `described_class`.
|
|
95
87
|
def render_preview(name, from: __vc_test_helpers_preview_class, params: {})
|
|
96
|
-
previews_controller = __vc_test_helpers_build_controller(Rails.application.config.view_component.
|
|
88
|
+
previews_controller = __vc_test_helpers_build_controller(Rails.application.config.view_component.previews.controller.constantize)
|
|
97
89
|
|
|
98
90
|
# From what I can tell, it's not possible to overwrite all request parameters
|
|
99
91
|
# at once, so we set them individually here.
|
|
@@ -107,7 +99,7 @@ module ViewComponent
|
|
|
107
99
|
|
|
108
100
|
@rendered_content = result
|
|
109
101
|
|
|
110
|
-
Nokogiri::
|
|
102
|
+
Nokogiri::HTML5.fragment(@rendered_content)
|
|
111
103
|
end
|
|
112
104
|
|
|
113
105
|
# Execute the given block in the view context (using `instance_exec`).
|
|
@@ -121,12 +113,11 @@ module ViewComponent
|
|
|
121
113
|
#
|
|
122
114
|
# assert_text("Hello, World!")
|
|
123
115
|
# ```
|
|
124
|
-
def render_in_view_context(
|
|
116
|
+
def render_in_view_context(...)
|
|
125
117
|
@page = nil
|
|
126
|
-
@rendered_content =
|
|
127
|
-
Nokogiri::
|
|
118
|
+
@rendered_content = vc_test_view_context.instance_exec(...)
|
|
119
|
+
Nokogiri::HTML5.fragment(@rendered_content)
|
|
128
120
|
end
|
|
129
|
-
ruby2_keywords(:render_in_view_context) if respond_to?(:ruby2_keywords, true)
|
|
130
121
|
|
|
131
122
|
# Set the Action Pack request variant for the given block:
|
|
132
123
|
#
|
|
@@ -136,11 +127,11 @@ module ViewComponent
|
|
|
136
127
|
# end
|
|
137
128
|
# ```
|
|
138
129
|
#
|
|
139
|
-
# @param
|
|
140
|
-
def with_variant(
|
|
130
|
+
# @param variants [Array<Symbol>] The variants to be set for the provided block.
|
|
131
|
+
def with_variant(*variants)
|
|
141
132
|
old_variants = vc_test_controller.view_context.lookup_context.variants
|
|
142
133
|
|
|
143
|
-
vc_test_controller.view_context.lookup_context.variants
|
|
134
|
+
vc_test_controller.view_context.lookup_context.variants += variants
|
|
144
135
|
yield
|
|
145
136
|
ensure
|
|
146
137
|
vc_test_controller.view_context.lookup_context.variants = old_variants
|
|
@@ -173,9 +164,14 @@ module ViewComponent
|
|
|
173
164
|
# end
|
|
174
165
|
# ```
|
|
175
166
|
#
|
|
176
|
-
# @param
|
|
177
|
-
def with_format(
|
|
178
|
-
|
|
167
|
+
# @param formats [Array<Symbol>] The format(s) to be set for the provided block.
|
|
168
|
+
def with_format(*formats)
|
|
169
|
+
old_formats = vc_test_controller.view_context.lookup_context.formats
|
|
170
|
+
|
|
171
|
+
vc_test_controller.view_context.lookup_context.formats = formats
|
|
172
|
+
yield
|
|
173
|
+
ensure
|
|
174
|
+
vc_test_controller.view_context.lookup_context.formats = old_formats
|
|
179
175
|
end
|
|
180
176
|
|
|
181
177
|
# Set the URL of the current request (such as when using request-dependent path helpers):
|
|
@@ -202,10 +198,19 @@ module ViewComponent
|
|
|
202
198
|
# end
|
|
203
199
|
# ```
|
|
204
200
|
#
|
|
201
|
+
# To specify a protocol, pass the protocol param:
|
|
202
|
+
#
|
|
203
|
+
# ```ruby
|
|
204
|
+
# with_request_url("/users/42", protocol: :https) do
|
|
205
|
+
# render_inline(MyComponent.new)
|
|
206
|
+
# end
|
|
207
|
+
# ```
|
|
208
|
+
#
|
|
205
209
|
# @param full_path [String] The path to set for the current request.
|
|
206
210
|
# @param host [String] The host to set for the current request.
|
|
207
211
|
# @param method [String] The request method to set for the current request.
|
|
208
|
-
|
|
212
|
+
# @param protocol [Symbol] The protocol to set for the current request (e.g., `:http` or `:https`).
|
|
213
|
+
def with_request_url(full_path, host: nil, method: nil, protocol: nil)
|
|
209
214
|
old_request_host = vc_test_request.host
|
|
210
215
|
old_request_method = vc_test_request.request_method
|
|
211
216
|
old_request_path_info = vc_test_request.path_info
|
|
@@ -213,6 +218,7 @@ module ViewComponent
|
|
|
213
218
|
old_request_query_parameters = vc_test_request.query_parameters
|
|
214
219
|
old_request_query_string = vc_test_request.query_string
|
|
215
220
|
old_request_format = vc_test_request.format.symbol
|
|
221
|
+
old_request_scheme = vc_test_request.scheme
|
|
216
222
|
old_controller = defined?(@vc_test_controller) && @vc_test_controller
|
|
217
223
|
|
|
218
224
|
path, query = full_path.split("?", 2)
|
|
@@ -220,16 +226,17 @@ module ViewComponent
|
|
|
220
226
|
vc_test_request.instance_variable_set(:@original_fullpath, full_path)
|
|
221
227
|
vc_test_request.host = host if host
|
|
222
228
|
vc_test_request.request_method = method if method
|
|
229
|
+
vc_test_request.set_header(Rack::RACK_URL_SCHEME, protocol.to_s) if protocol
|
|
223
230
|
vc_test_request.path_info = path
|
|
224
231
|
vc_test_request.path_parameters = Rails.application.routes.recognize_path_with_request(vc_test_request, path, {})
|
|
225
232
|
vc_test_request.set_header("action_dispatch.request.query_parameters",
|
|
226
233
|
Rack::Utils.parse_nested_query(query).with_indifferent_access)
|
|
227
234
|
vc_test_request.set_header(Rack::QUERY_STRING, query)
|
|
228
|
-
vc_test_request.format = format
|
|
229
235
|
yield
|
|
230
236
|
ensure
|
|
231
237
|
vc_test_request.host = old_request_host
|
|
232
238
|
vc_test_request.request_method = old_request_method
|
|
239
|
+
vc_test_request.set_header(Rack::RACK_URL_SCHEME, old_request_scheme)
|
|
233
240
|
vc_test_request.path_info = old_request_path_info
|
|
234
241
|
vc_test_request.path_parameters = old_request_path_parameters
|
|
235
242
|
vc_test_request.set_header("action_dispatch.request.query_parameters", old_request_query_parameters)
|
|
@@ -250,7 +257,20 @@ module ViewComponent
|
|
|
250
257
|
#
|
|
251
258
|
# @return [ActionController::Base]
|
|
252
259
|
def vc_test_controller
|
|
253
|
-
@vc_test_controller ||= __vc_test_helpers_build_controller(
|
|
260
|
+
@vc_test_controller ||= __vc_test_helpers_build_controller(vc_test_controller_class)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Set the controller used by `render_inline`:
|
|
264
|
+
#
|
|
265
|
+
# ```ruby
|
|
266
|
+
# def vc_test_controller_class
|
|
267
|
+
# MyTestController
|
|
268
|
+
# end
|
|
269
|
+
# ```
|
|
270
|
+
def vc_test_controller_class
|
|
271
|
+
return @__vc_test_controller_class if defined?(@__vc_test_controller_class)
|
|
272
|
+
|
|
273
|
+
defined?(ApplicationController) ? ApplicationController : ActionController::Base
|
|
254
274
|
end
|
|
255
275
|
|
|
256
276
|
# Access the request used by `render_inline`:
|
|
@@ -284,11 +304,9 @@ module ViewComponent
|
|
|
284
304
|
|
|
285
305
|
def __vc_test_helpers_preview_class
|
|
286
306
|
result = if respond_to?(:described_class)
|
|
287
|
-
|
|
288
|
-
raise "`render_preview` expected a described_class, but it is nil." if described_class.nil?
|
|
307
|
+
raise ArgumentError.new("`render_preview` expected a described_class, but it is nil.") if described_class.nil?
|
|
289
308
|
|
|
290
309
|
"#{described_class}Preview"
|
|
291
|
-
# :nocov:
|
|
292
310
|
else
|
|
293
311
|
self.class.name.gsub("Test", "Preview")
|
|
294
312
|
end
|
|
@@ -296,6 +314,5 @@ module ViewComponent
|
|
|
296
314
|
rescue NameError
|
|
297
315
|
raise NameError, "`render_preview` expected to find #{result}, but it does not exist."
|
|
298
316
|
end
|
|
299
|
-
# :nocov:
|
|
300
317
|
end
|
|
301
318
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "erb"
|
|
4
|
-
require "set"
|
|
5
4
|
require "i18n"
|
|
6
5
|
require "active_support/concern"
|
|
7
6
|
|
|
@@ -10,19 +9,22 @@ module ViewComponent
|
|
|
10
9
|
extend ActiveSupport::Concern
|
|
11
10
|
|
|
12
11
|
HTML_SAFE_TRANSLATION_KEY = /(?:_|\b)html\z/
|
|
12
|
+
private_constant :HTML_SAFE_TRANSLATION_KEY
|
|
13
|
+
|
|
13
14
|
TRANSLATION_EXTENSIONS = %w[yml yaml].freeze
|
|
15
|
+
private_constant :TRANSLATION_EXTENSIONS
|
|
14
16
|
|
|
15
17
|
included do
|
|
16
|
-
class_attribute :
|
|
18
|
+
class_attribute :__vc_i18n_backend, instance_writer: false, instance_predicate: false
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
class_methods do
|
|
20
|
-
def
|
|
21
|
-
@
|
|
22
|
+
def __vc_i18n_scope
|
|
23
|
+
@__vc_i18n_scope ||= virtual_path.sub(%r{^/}, "").gsub(%r{/_?}, ".")
|
|
22
24
|
end
|
|
23
25
|
|
|
24
|
-
def
|
|
25
|
-
return if
|
|
26
|
+
def __vc_build_i18n_backend
|
|
27
|
+
return if __vc_compiled?
|
|
26
28
|
|
|
27
29
|
# We need to load the translations files from the ancestors so a component
|
|
28
30
|
# can inherit translations from its parent and is able to overwrite them.
|
|
@@ -33,31 +35,31 @@ module ViewComponent
|
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
# In development it will become nil if the translations file is removed
|
|
36
|
-
self.
|
|
38
|
+
self.__vc_i18n_backend = if translation_files.any?
|
|
37
39
|
I18nBackend.new(
|
|
38
|
-
|
|
40
|
+
scope: __vc_i18n_scope,
|
|
39
41
|
load_paths: translation_files
|
|
40
42
|
)
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
45
|
|
|
44
|
-
def
|
|
46
|
+
def __vc_i18n_key(key, scope = nil)
|
|
45
47
|
scope = scope.join(".") if scope.is_a? Array
|
|
46
48
|
key = key&.to_s unless key.is_a?(String)
|
|
47
49
|
key = "#{scope}.#{key}" if scope
|
|
48
|
-
key = "#{
|
|
50
|
+
key = "#{__vc_i18n_scope}#{key}" if key.start_with?(".")
|
|
49
51
|
key
|
|
50
52
|
end
|
|
51
53
|
|
|
52
54
|
def translate(key = nil, **options)
|
|
53
55
|
return key.map { |k| translate(k, **options) } if key.is_a?(Array)
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
__vc_ensure_compiled
|
|
56
58
|
|
|
57
59
|
locale = options.delete(:locale) || ::I18n.locale
|
|
58
|
-
key =
|
|
60
|
+
key = __vc_i18n_key(key, options.delete(:scope))
|
|
59
61
|
|
|
60
|
-
|
|
62
|
+
__vc_i18n_backend.translate(locale, key, options)
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
alias_method :t, :translate
|
|
@@ -66,18 +68,18 @@ module ViewComponent
|
|
|
66
68
|
class I18nBackend < ::I18n::Backend::Simple
|
|
67
69
|
EMPTY_HASH = {}.freeze
|
|
68
70
|
|
|
69
|
-
def initialize(
|
|
70
|
-
@
|
|
71
|
-
@
|
|
71
|
+
def initialize(scope:, load_paths:)
|
|
72
|
+
@__vc_i18n_scope = scope.split(".").map(&:to_sym)
|
|
73
|
+
@__vc_load_paths = load_paths
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
# Ensure the Simple backend won't load paths from ::I18n.load_path
|
|
75
77
|
def load_translations
|
|
76
|
-
super(@
|
|
78
|
+
super(@__vc_load_paths)
|
|
77
79
|
end
|
|
78
80
|
|
|
79
81
|
def scope_data(data)
|
|
80
|
-
@
|
|
82
|
+
@__vc_i18n_scope.reverse_each do |part|
|
|
81
83
|
data = {part => data}
|
|
82
84
|
end
|
|
83
85
|
data
|
|
@@ -91,44 +93,43 @@ module ViewComponent
|
|
|
91
93
|
def translate(key = nil, **options)
|
|
92
94
|
raise ViewComponent::TranslateCalledBeforeRenderError if view_context.nil?
|
|
93
95
|
|
|
94
|
-
return
|
|
96
|
+
return @view_context.translate(key, **options) unless __vc_i18n_backend
|
|
95
97
|
return key.map { |k| translate(k, **options) } if key.is_a?(Array)
|
|
96
98
|
|
|
97
99
|
locale = options.delete(:locale) || ::I18n.locale
|
|
98
|
-
key = self.class.
|
|
100
|
+
key = self.class.__vc_i18n_key(key, options.delete(:scope))
|
|
99
101
|
as_html = HTML_SAFE_TRANSLATION_KEY.match?(key)
|
|
100
102
|
|
|
101
|
-
|
|
103
|
+
__vc_html_escape_translation_options!(options) if as_html
|
|
102
104
|
|
|
103
|
-
if key.start_with?(
|
|
105
|
+
if key.start_with?(__vc_i18n_scope + ".")
|
|
104
106
|
translated =
|
|
105
107
|
catch(:exception) do
|
|
106
|
-
|
|
108
|
+
__vc_i18n_backend.translate(locale, key, options)
|
|
107
109
|
end
|
|
108
110
|
|
|
109
111
|
# Fallback to the global translations
|
|
110
112
|
if translated.is_a? ::I18n::MissingTranslation
|
|
111
|
-
return
|
|
113
|
+
return @view_context.translate(key, locale: locale, **options)
|
|
112
114
|
end
|
|
113
115
|
|
|
114
|
-
translated =
|
|
116
|
+
translated = __vc_html_safe_translation(translated) if as_html
|
|
115
117
|
translated
|
|
116
118
|
else
|
|
117
|
-
|
|
119
|
+
@view_context.translate(key, locale: locale, **options)
|
|
118
120
|
end
|
|
119
121
|
end
|
|
120
122
|
alias_method :t, :translate
|
|
121
123
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
self.class.i18n_scope
|
|
124
|
+
def __vc_i18n_scope
|
|
125
|
+
self.class.__vc_i18n_scope
|
|
125
126
|
end
|
|
126
127
|
|
|
127
128
|
private
|
|
128
129
|
|
|
129
|
-
def
|
|
130
|
+
def __vc_html_safe_translation(translation)
|
|
130
131
|
if translation.respond_to?(:map)
|
|
131
|
-
translation.map { |element|
|
|
132
|
+
translation.map { |element| __vc_html_safe_translation(element) }
|
|
132
133
|
else
|
|
133
134
|
# It's assumed here that objects loaded by the i18n backend will respond to `#html_safe?`.
|
|
134
135
|
# It's reasonable that if we're in Rails, `active_support/core_ext/string/output_safety.rb`
|
|
@@ -137,7 +138,7 @@ module ViewComponent
|
|
|
137
138
|
end
|
|
138
139
|
end
|
|
139
140
|
|
|
140
|
-
def
|
|
141
|
+
def __vc_html_escape_translation_options!(options)
|
|
141
142
|
options.except(*::I18n::RESERVED_KEYS).each do |name, value|
|
|
142
143
|
next if name == :count && value.is_a?(Numeric)
|
|
143
144
|
|
data/lib/view_component.rb
CHANGED
|
@@ -2,25 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
require "action_view"
|
|
4
4
|
require "active_support/dependencies/autoload"
|
|
5
|
+
require "view_component/version"
|
|
5
6
|
|
|
6
7
|
module ViewComponent
|
|
7
8
|
extend ActiveSupport::Autoload
|
|
8
9
|
|
|
9
10
|
autoload :Base
|
|
10
|
-
autoload :CaptureCompatibility
|
|
11
11
|
autoload :Compiler
|
|
12
12
|
autoload :CompileCache
|
|
13
|
-
autoload :ComponentError
|
|
14
13
|
autoload :Config
|
|
15
14
|
autoload :Deprecation
|
|
16
15
|
autoload :InlineTemplate
|
|
17
16
|
autoload :Instrumentation
|
|
18
17
|
autoload :Preview
|
|
19
|
-
autoload :TestHelpers
|
|
20
|
-
autoload :SystemTestHelpers
|
|
21
|
-
autoload :TestCase
|
|
22
|
-
autoload :SystemTestCase
|
|
23
18
|
autoload :Translatable
|
|
19
|
+
|
|
20
|
+
if defined?(Rails.env) && Rails.env.test?
|
|
21
|
+
autoload :TestHelpers
|
|
22
|
+
autoload :SystemSpecHelpers
|
|
23
|
+
autoload :SystemTestHelpers
|
|
24
|
+
autoload :TestCase
|
|
25
|
+
autoload :SystemTestCase
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
require "view_component/engine" if defined?(Rails::Engine)
|