view_component 2.61.0 → 2.63.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/docs/CHANGELOG.md +48 -0
- data/lib/view_component/base.rb +4 -22
- data/lib/view_component/compile_cache.rb +1 -2
- data/lib/view_component/compiler.rb +7 -9
- data/lib/view_component/engine.rb +0 -16
- data/lib/view_component/polymorphic_slots.rb +6 -2
- data/lib/view_component/render_component_helper.rb +1 -0
- data/lib/view_component/slotable_v2.rb +4 -4
- data/lib/view_component/test_helpers.rb +1 -22
- data/lib/view_component/version.rb +1 -1
- data/lib/view_component.rb +0 -3
- metadata +2 -5
- data/lib/view_component/capybara_simple_session.rb +0 -132
- data/lib/view_component/global_output_buffer.rb +0 -100
- data/lib/view_component/output_buffer_stack.rb +0 -65
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 78c8a36fb19eb4c8a1c3737815113323acc9cd5a9c89a270163ca8336e44c41e
|
|
4
|
+
data.tar.gz: 6e4135faf54dfc7c519d7ef62080d6e779d04bbbc1efea32b7871fe65bd2c685
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f207e3d9e6980880876afa36521a3f63abafead81da8d4f5574c9e9164139fbd8029bf8b9eae3f034e2da849541b959025612b21dca548477a38327fe5aa97b
|
|
7
|
+
data.tar.gz: d65662034f4abf33feeae814b60dcfb82683302be1cf427a5c6f93297a575185963ca8d3a1df81fa9daf7855d25297c303c68e5abc225594be842e12fd657702
|
data/docs/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,54 @@ title: Changelog
|
|
|
9
9
|
|
|
10
10
|
## main
|
|
11
11
|
|
|
12
|
+
## 2.63.0
|
|
13
|
+
|
|
14
|
+
* Fixed typo in `renders_many` documentation.
|
|
15
|
+
|
|
16
|
+
*Graham Rogers*
|
|
17
|
+
|
|
18
|
+
* Add documentation about working with `turbo-rails`.
|
|
19
|
+
|
|
20
|
+
*Matheus Poli Camilo*
|
|
21
|
+
|
|
22
|
+
* Fix issue causing helper methods to not be available in nested components when the render monkey patch is disabled and `render_component` is used.
|
|
23
|
+
|
|
24
|
+
*Daniel Scheffknecht*
|
|
25
|
+
|
|
26
|
+
## 2.62.0
|
|
27
|
+
|
|
28
|
+
* Remove the experimental global output buffer feature.
|
|
29
|
+
* Restore functionality that used to attempt to compile templates on each call to `#render_in`.
|
|
30
|
+
* Un-pin `rails` `main` dependency.
|
|
31
|
+
|
|
32
|
+
*Cameron Dutro*
|
|
33
|
+
|
|
34
|
+
* Add blank space between "in" and "ViewComponent" in a deprecation warning.
|
|
35
|
+
|
|
36
|
+
*Vikram Dighe*
|
|
37
|
+
|
|
38
|
+
* Add HappyCo to list of companies using ViewComponent.
|
|
39
|
+
|
|
40
|
+
*Josh Clayton*
|
|
41
|
+
|
|
42
|
+
* Add predicate method support to polymorphic slots.
|
|
43
|
+
|
|
44
|
+
*Graham Rogers*
|
|
45
|
+
|
|
46
|
+
## 2.61.1
|
|
47
|
+
|
|
48
|
+
* Revert `Expose Capybara DSL methods directly inside tests.` This change unintentionally broke other Capybara methods and thus introduced a regression. We aren't confident that we can fail forward so we have decided to revert this change.
|
|
49
|
+
|
|
50
|
+
*Joel Hawksley*, *Blake Williams*
|
|
51
|
+
|
|
52
|
+
* Revert change making content evaluation consistent.
|
|
53
|
+
|
|
54
|
+
*Blake Williams*
|
|
55
|
+
|
|
56
|
+
* Pin `rails` `main` dependency due to incompatibility with Global Output Buffer.
|
|
57
|
+
|
|
58
|
+
*Joel Hawksley*
|
|
59
|
+
|
|
12
60
|
## 2.61.0
|
|
13
61
|
|
|
14
62
|
* Ensure side-effects in `content` are consistently evaluated before components are rendered. This change effectively means that `content` is evaluated for every component render where `render?` returns true. As a result, code that is passed to a component via a block/content will now always be evaluated, before `#call`, which can reveal bugs in existing components.
|
data/lib/view_component/base.rb
CHANGED
|
@@ -86,10 +86,12 @@ module ViewComponent
|
|
|
86
86
|
#
|
|
87
87
|
# @return [String]
|
|
88
88
|
def render_in(view_context, &block)
|
|
89
|
+
self.class.compile(raise_errors: true)
|
|
90
|
+
|
|
89
91
|
@view_context = view_context
|
|
90
92
|
self.__vc_original_view_context ||= view_context
|
|
91
93
|
|
|
92
|
-
@output_buffer = ActionView::OutputBuffer.new
|
|
94
|
+
@output_buffer = ActionView::OutputBuffer.new
|
|
93
95
|
|
|
94
96
|
@lookup_context ||= view_context.lookup_context
|
|
95
97
|
|
|
@@ -124,11 +126,7 @@ module ViewComponent
|
|
|
124
126
|
before_render
|
|
125
127
|
|
|
126
128
|
if render?
|
|
127
|
-
|
|
128
|
-
# side-effects that may exist in the block
|
|
129
|
-
content
|
|
130
|
-
|
|
131
|
-
perform_render
|
|
129
|
+
render_template_for(@__vc_variant).to_s + _output_postamble
|
|
132
130
|
else
|
|
133
131
|
""
|
|
134
132
|
end
|
|
@@ -136,11 +134,6 @@ module ViewComponent
|
|
|
136
134
|
@current_template = old_current_template
|
|
137
135
|
end
|
|
138
136
|
|
|
139
|
-
# @private
|
|
140
|
-
def perform_render
|
|
141
|
-
render_template_for(@__vc_variant).to_s + _output_postamble
|
|
142
|
-
end
|
|
143
|
-
|
|
144
137
|
# Subclass components that call `super` inside their template code will cause a
|
|
145
138
|
# double render if they emit the result:
|
|
146
139
|
#
|
|
@@ -156,17 +149,6 @@ module ViewComponent
|
|
|
156
149
|
nil
|
|
157
150
|
end
|
|
158
151
|
|
|
159
|
-
# @private
|
|
160
|
-
# :nocov:
|
|
161
|
-
def render_template_for(variant = nil)
|
|
162
|
-
# Force compilation here so the compiler always redefines render_template_for.
|
|
163
|
-
# This is mostly a safeguard to prevent infinite recursion.
|
|
164
|
-
self.class.compile(raise_errors: true, force: true)
|
|
165
|
-
# .compile replaces this method; call the new one
|
|
166
|
-
render_template_for(variant)
|
|
167
|
-
end
|
|
168
|
-
# :nocov:
|
|
169
|
-
|
|
170
152
|
# EXPERIMENTAL: Optional content to be returned after the rendered template.
|
|
171
153
|
#
|
|
172
154
|
# @return [String]
|
|
@@ -34,6 +34,8 @@ module ViewComponent
|
|
|
34
34
|
component_class.superclass.compile(raise_errors: raise_errors) if should_compile_superclass?
|
|
35
35
|
|
|
36
36
|
with_lock do
|
|
37
|
+
CompileCache.invalidate_class!(component_class)
|
|
38
|
+
|
|
37
39
|
subclass_instance_methods = component_class.instance_methods(false)
|
|
38
40
|
|
|
39
41
|
if subclass_instance_methods.include?(:with_content) && raise_errors
|
|
@@ -66,8 +68,8 @@ module ViewComponent
|
|
|
66
68
|
# as Ruby warns when redefining a method.
|
|
67
69
|
method_name = call_method_name(template[:variant])
|
|
68
70
|
|
|
69
|
-
if component_class.instance_methods
|
|
70
|
-
component_class.send(:
|
|
71
|
+
if component_class.instance_methods.include?(method_name.to_sym)
|
|
72
|
+
component_class.send(:undef_method, method_name.to_sym)
|
|
71
73
|
end
|
|
72
74
|
|
|
73
75
|
# rubocop:disable Style/EvalWithLocation
|
|
@@ -96,18 +98,14 @@ module ViewComponent
|
|
|
96
98
|
end
|
|
97
99
|
end
|
|
98
100
|
|
|
99
|
-
def reset_render_template_for
|
|
100
|
-
if component_class.instance_methods(false).include?(:render_template_for)
|
|
101
|
-
component_class.send(:remove_method, :render_template_for)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
101
|
private
|
|
106
102
|
|
|
107
103
|
attr_reader :component_class
|
|
108
104
|
|
|
109
105
|
def define_render_template_for
|
|
110
|
-
|
|
106
|
+
if component_class.instance_methods.include?(:render_template_for)
|
|
107
|
+
component_class.send(:undef_method, :render_template_for)
|
|
108
|
+
end
|
|
111
109
|
|
|
112
110
|
variant_elsifs = variants.compact.uniq.map do |variant|
|
|
113
111
|
"elsif variant.to_sym == :#{variant}\n #{call_method_name(variant)}"
|
|
@@ -20,7 +20,6 @@ module ViewComponent
|
|
|
20
20
|
options.instrumentation_enabled = false if options.instrumentation_enabled.nil?
|
|
21
21
|
options.preview_route ||= ViewComponent::Base.preview_route
|
|
22
22
|
options.preview_controller ||= ViewComponent::Base.preview_controller
|
|
23
|
-
options.use_global_output_buffer = false if options.use_global_output_buffer.nil?
|
|
24
23
|
|
|
25
24
|
if options.show_previews
|
|
26
25
|
options.preview_paths << "#{Rails.root}/test/components/previews" if defined?(Rails.root) && Dir.exist?(
|
|
@@ -58,21 +57,6 @@ module ViewComponent
|
|
|
58
57
|
end
|
|
59
58
|
end
|
|
60
59
|
|
|
61
|
-
initializer "view_component.enable_global_output_buffer" do |app|
|
|
62
|
-
ActiveSupport.on_load(:view_component) do
|
|
63
|
-
env_use_gob = ENV.fetch("VIEW_COMPONENT_USE_GLOBAL_OUTPUT_BUFFER", "false") == "true"
|
|
64
|
-
config_use_gob = app.config.view_component.use_global_output_buffer
|
|
65
|
-
|
|
66
|
-
if config_use_gob || env_use_gob
|
|
67
|
-
# :nocov:
|
|
68
|
-
app.config.view_component.use_global_output_buffer = true
|
|
69
|
-
ViewComponent::Base.prepend(ViewComponent::GlobalOutputBuffer)
|
|
70
|
-
ActionView::Base.prepend(ViewComponent::GlobalOutputBuffer::ActionViewMods)
|
|
71
|
-
# :nocov:
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
60
|
initializer "view_component.set_autoload_paths" do |app|
|
|
77
61
|
options = app.config.view_component
|
|
78
62
|
|
|
@@ -10,7 +10,7 @@ module ViewComponent
|
|
|
10
10
|
location = Kernel.caller_locations(1, 1)[0]
|
|
11
11
|
|
|
12
12
|
warn(
|
|
13
|
-
"warning: ViewComponent::PolymorphicSlots is now included in ViewComponent::Base by default "\
|
|
13
|
+
"warning: ViewComponent::PolymorphicSlots is now included in ViewComponent::Base by default " \
|
|
14
14
|
"and can be removed from #{location.path}:#{location.lineno}"
|
|
15
15
|
)
|
|
16
16
|
# :nocov:
|
|
@@ -42,6 +42,10 @@ module ViewComponent
|
|
|
42
42
|
define_method(getter_name) do
|
|
43
43
|
get_slot(slot_name)
|
|
44
44
|
end
|
|
45
|
+
|
|
46
|
+
define_method("#{getter_name}?") do
|
|
47
|
+
get_slot(slot_name).present?
|
|
48
|
+
end
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
renderable_hash = types.each_with_object({}) do |(poly_type, poly_callable), memo|
|
|
@@ -58,7 +62,7 @@ module ViewComponent
|
|
|
58
62
|
|
|
59
63
|
define_method(setter_name) do |*args, &block|
|
|
60
64
|
ViewComponent::Deprecation.warn(
|
|
61
|
-
"polymorphic slot setters like `#{setter_name}` are deprecated and will be removed in"\
|
|
65
|
+
"polymorphic slot setters like `#{setter_name}` are deprecated and will be removed in " \
|
|
62
66
|
"ViewComponent v3.0.0.\n\nUse `with_#{setter_name}` instead."
|
|
63
67
|
)
|
|
64
68
|
|
|
@@ -98,11 +98,11 @@ module ViewComponent
|
|
|
98
98
|
#
|
|
99
99
|
# = Example
|
|
100
100
|
#
|
|
101
|
-
#
|
|
101
|
+
# renders_many :items, -> (name:) { ItemComponent.new(name: name }
|
|
102
102
|
#
|
|
103
103
|
# # OR
|
|
104
104
|
#
|
|
105
|
-
#
|
|
105
|
+
# renders_many :items, ItemComponent
|
|
106
106
|
#
|
|
107
107
|
# = Rendering sub-components
|
|
108
108
|
#
|
|
@@ -266,8 +266,8 @@ module ViewComponent
|
|
|
266
266
|
def raise_if_slot_ends_with_question_mark(slot_name)
|
|
267
267
|
if slot_name.to_s.ends_with?("?")
|
|
268
268
|
raise ArgumentError.new(
|
|
269
|
-
"#{self} declares a slot named #{slot_name}, which ends with a question mark.\n\n"\
|
|
270
|
-
"This is not allowed because the ViewComponent framework already provides predicate "\
|
|
269
|
+
"#{self} declares a slot named #{slot_name}, which ends with a question mark.\n\n" \
|
|
270
|
+
"This is not allowed because the ViewComponent framework already provides predicate " \
|
|
271
271
|
"methods ending in `?`.\n\n" \
|
|
272
272
|
"To fix this issue, choose a different name."
|
|
273
273
|
)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "view_component/render_preview_helper"
|
|
4
|
-
require "view_component/capybara_simple_session"
|
|
5
4
|
|
|
6
5
|
module ViewComponent
|
|
7
6
|
module TestHelpers
|
|
@@ -10,28 +9,8 @@ module ViewComponent
|
|
|
10
9
|
|
|
11
10
|
include Capybara::Minitest::Assertions
|
|
12
11
|
|
|
13
|
-
CapybaraSimpleSession::DSL_METHODS.each do |method|
|
|
14
|
-
if RUBY_VERSION >= "2.7"
|
|
15
|
-
class_eval <<~METHOD, __FILE__, __LINE__ + 1
|
|
16
|
-
def #{method}(...)
|
|
17
|
-
page.method("#{method}").call(...)
|
|
18
|
-
end
|
|
19
|
-
METHOD
|
|
20
|
-
else
|
|
21
|
-
define_method method do |*args, &block|
|
|
22
|
-
page.send method, *args, &block
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def self.included(mod)
|
|
28
|
-
Capybara::Node::Simple.send(:define_method, :to_capybara_node) do
|
|
29
|
-
self
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
12
|
def page
|
|
34
|
-
@page ||=
|
|
13
|
+
@page ||= Capybara::Node::Simple.new(rendered_content)
|
|
35
14
|
end
|
|
36
15
|
|
|
37
16
|
def refute_component_rendered
|
data/lib/view_component.rb
CHANGED
|
@@ -7,14 +7,11 @@ module ViewComponent
|
|
|
7
7
|
extend ActiveSupport::Autoload
|
|
8
8
|
|
|
9
9
|
autoload :Base
|
|
10
|
-
autoload :CapybaraSimpleSession
|
|
11
10
|
autoload :Compiler
|
|
12
11
|
autoload :CompileCache
|
|
13
12
|
autoload :ComponentError
|
|
14
13
|
autoload :Deprecation
|
|
15
|
-
autoload :GlobalOutputBuffer
|
|
16
14
|
autoload :Instrumentation
|
|
17
|
-
autoload :OutputBufferStack
|
|
18
15
|
autoload :Preview
|
|
19
16
|
autoload :PreviewTemplateError
|
|
20
17
|
autoload :TestHelpers
|
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: 2.
|
|
4
|
+
version: 2.63.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GitHub Open Source
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-08-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -325,7 +325,6 @@ files:
|
|
|
325
325
|
- lib/rails/generators/test_unit/templates/component_test.rb.tt
|
|
326
326
|
- lib/view_component.rb
|
|
327
327
|
- lib/view_component/base.rb
|
|
328
|
-
- lib/view_component/capybara_simple_session.rb
|
|
329
328
|
- lib/view_component/collection.rb
|
|
330
329
|
- lib/view_component/compile_cache.rb
|
|
331
330
|
- lib/view_component/compiler.rb
|
|
@@ -335,9 +334,7 @@ files:
|
|
|
335
334
|
- lib/view_component/docs_builder_component.html.erb
|
|
336
335
|
- lib/view_component/docs_builder_component.rb
|
|
337
336
|
- lib/view_component/engine.rb
|
|
338
|
-
- lib/view_component/global_output_buffer.rb
|
|
339
337
|
- lib/view_component/instrumentation.rb
|
|
340
|
-
- lib/view_component/output_buffer_stack.rb
|
|
341
338
|
- lib/view_component/polymorphic_slots.rb
|
|
342
339
|
- lib/view_component/preview.rb
|
|
343
340
|
- lib/view_component/preview_template_error.rb
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ViewComponent
|
|
4
|
-
# This is a simpler version of {Capybara::Session}.
|
|
5
|
-
#
|
|
6
|
-
# It only includes {Capybara::Node::Finders}, {Capybara::Node::Matchers},
|
|
7
|
-
# {#within} and {#within_element}. It is useful in that it does not require a
|
|
8
|
-
# session, an application or a driver, but can still use Capybara's finders
|
|
9
|
-
# and matchers on any string that contains HTML.
|
|
10
|
-
class CapybaraSimpleSession
|
|
11
|
-
# Most of the code in this class is shamelessly stolen from the
|
|
12
|
-
# {Capybara::Session} class in the Capybara gem
|
|
13
|
-
# (https://github.com/teamcapybara/capybara/blob/e704d00879fb1d1e1a0cc01e04c101bcd8af4a68/lib/capybara/session.rb#L38).
|
|
14
|
-
|
|
15
|
-
NODE_METHODS = %i[
|
|
16
|
-
all
|
|
17
|
-
first
|
|
18
|
-
text
|
|
19
|
-
|
|
20
|
-
find
|
|
21
|
-
find_all
|
|
22
|
-
find_button
|
|
23
|
-
find_by_id
|
|
24
|
-
find_field
|
|
25
|
-
find_link
|
|
26
|
-
|
|
27
|
-
has_content?
|
|
28
|
-
has_text?
|
|
29
|
-
has_css?
|
|
30
|
-
has_no_content?
|
|
31
|
-
has_no_text?
|
|
32
|
-
has_no_css?
|
|
33
|
-
has_no_xpath?
|
|
34
|
-
has_xpath?
|
|
35
|
-
has_link?
|
|
36
|
-
has_no_link?
|
|
37
|
-
has_button?
|
|
38
|
-
has_no_button?
|
|
39
|
-
has_field?
|
|
40
|
-
has_no_field?
|
|
41
|
-
has_checked_field?
|
|
42
|
-
has_unchecked_field?
|
|
43
|
-
has_no_table?
|
|
44
|
-
has_table?
|
|
45
|
-
has_select?
|
|
46
|
-
has_no_select?
|
|
47
|
-
has_selector?
|
|
48
|
-
has_no_selector?
|
|
49
|
-
has_no_checked_field?
|
|
50
|
-
has_no_unchecked_field?
|
|
51
|
-
|
|
52
|
-
assert_selector
|
|
53
|
-
assert_no_selector
|
|
54
|
-
assert_all_of_selectors
|
|
55
|
-
assert_none_of_selectors
|
|
56
|
-
assert_any_of_selectors
|
|
57
|
-
assert_text
|
|
58
|
-
assert_no_text
|
|
59
|
-
].freeze
|
|
60
|
-
|
|
61
|
-
private_constant :NODE_METHODS
|
|
62
|
-
|
|
63
|
-
SESSION_METHODS = %i[within within_element within_fieldset within_table].freeze
|
|
64
|
-
|
|
65
|
-
private_constant :SESSION_METHODS
|
|
66
|
-
|
|
67
|
-
DSL_METHODS = (NODE_METHODS + SESSION_METHODS).freeze
|
|
68
|
-
|
|
69
|
-
# Stolen from: https://github.com/teamcapybara/capybara/blob/e704d00879fb1d1e1a0cc01e04c101bcd8af4a68/lib/capybara/session.rb#L767-L774.
|
|
70
|
-
NODE_METHODS.each do |method|
|
|
71
|
-
if RUBY_VERSION >= "2.7"
|
|
72
|
-
class_eval <<~METHOD, __FILE__, __LINE__ + 1
|
|
73
|
-
def #{method}(...)
|
|
74
|
-
current_scope.#{method}(...)
|
|
75
|
-
end
|
|
76
|
-
METHOD
|
|
77
|
-
else
|
|
78
|
-
define_method method do |*args, &block|
|
|
79
|
-
current_scope.send(method, *args, &block)
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Initializes the receiver with the given string of HTML.
|
|
85
|
-
#
|
|
86
|
-
# @param html [String] the HTML to create the session out of
|
|
87
|
-
def initialize(html)
|
|
88
|
-
@document = Capybara::Node::Simple.new(html)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# (see Capybara::Session#within)
|
|
92
|
-
def within(*args, **kw_args)
|
|
93
|
-
new_scope = args.first.respond_to?(:to_capybara_node) ? args.first.to_capybara_node : find(*args, **kw_args)
|
|
94
|
-
begin
|
|
95
|
-
scopes.push(new_scope)
|
|
96
|
-
yield if block_given?
|
|
97
|
-
ensure
|
|
98
|
-
scopes.pop
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# (see Capybara::Session#within_element)
|
|
103
|
-
alias_method :within_element, :within
|
|
104
|
-
|
|
105
|
-
# (see Capybara::Session#within_fieldset)
|
|
106
|
-
def within_fieldset(locator, &block)
|
|
107
|
-
within(:fieldset, locator, &block)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# (see Capybara::Session#within_table)
|
|
111
|
-
def within_table(locator, &block)
|
|
112
|
-
within(:table, locator, &block)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# (see Capybara::Node::Element#native)
|
|
116
|
-
def native
|
|
117
|
-
current_scope.native
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
private
|
|
121
|
-
|
|
122
|
-
attr_reader :document
|
|
123
|
-
|
|
124
|
-
def scopes
|
|
125
|
-
@scopes ||= [nil]
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def current_scope
|
|
129
|
-
scopes.last.presence || document
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ViewComponent
|
|
4
|
-
module GlobalOutputBuffer
|
|
5
|
-
def render_in(view_context, &block)
|
|
6
|
-
unless view_context.output_buffer.is_a?(OutputBufferStack)
|
|
7
|
-
# use instance_variable_set here to avoid triggering the code in the #output_buffer= method below
|
|
8
|
-
view_context.instance_variable_set(:@output_buffer, OutputBufferStack.new(view_context.output_buffer))
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
@output_buffer = view_context.output_buffer
|
|
12
|
-
@global_buffer_in_use = true
|
|
13
|
-
|
|
14
|
-
super(view_context, &block)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def perform_render
|
|
18
|
-
# HAML unhelpfully assigns to @output_buffer directly, so we hold onto a reference to
|
|
19
|
-
# it and restore @output_buffer when the HAML engine is finished. In non-HAML cases,
|
|
20
|
-
# @output_buffer and orig_buf will point to the same object, making the reassignment
|
|
21
|
-
# statements no-ops.
|
|
22
|
-
orig_buf = @output_buffer
|
|
23
|
-
@output_buffer.push
|
|
24
|
-
result = render_template_for(@__vc_variant).to_s + _output_postamble
|
|
25
|
-
@output_buffer = orig_buf
|
|
26
|
-
@output_buffer.pop
|
|
27
|
-
result
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def output_buffer=(other_buffer)
|
|
31
|
-
@output_buffer.replace(other_buffer)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def with_output_buffer(buf = nil)
|
|
35
|
-
unless buf
|
|
36
|
-
buf = ActionView::OutputBuffer.new
|
|
37
|
-
# rubocop:disable Style/SafeNavigation
|
|
38
|
-
if output_buffer && output_buffer.respond_to?(:encoding)
|
|
39
|
-
buf.force_encoding(output_buffer.encoding)
|
|
40
|
-
end
|
|
41
|
-
# rubocop:enable Style/SafeNavigation
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
output_buffer.push(buf)
|
|
45
|
-
|
|
46
|
-
begin
|
|
47
|
-
yield
|
|
48
|
-
ensure
|
|
49
|
-
# assign result here to avoid a return statement, which will
|
|
50
|
-
# immediately return to the caller and swallow any errors
|
|
51
|
-
result = output_buffer.pop
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
result
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
module ActionViewMods
|
|
58
|
-
def output_buffer=(other_buffer)
|
|
59
|
-
if @output_buffer.is_a?(OutputBufferStack)
|
|
60
|
-
@output_buffer.replace(other_buffer)
|
|
61
|
-
else
|
|
62
|
-
super
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def with_output_buffer(buf = nil)
|
|
67
|
-
unless buf
|
|
68
|
-
buf = ActionView::OutputBuffer.new
|
|
69
|
-
# rubocop:disable Style/SafeNavigation
|
|
70
|
-
if @output_buffer && @output_buffer.respond_to?(:encoding)
|
|
71
|
-
buf.force_encoding(@output_buffer.encoding)
|
|
72
|
-
end
|
|
73
|
-
# rubocop:enable Style/SafeNavigation
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
if @output_buffer.is_a?(OutputBufferStack)
|
|
77
|
-
@output_buffer.push(buf)
|
|
78
|
-
|
|
79
|
-
begin
|
|
80
|
-
yield
|
|
81
|
-
ensure
|
|
82
|
-
result = @output_buffer.pop
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
result
|
|
86
|
-
else
|
|
87
|
-
@output_buffer, old_buffer = buf, output_buffer
|
|
88
|
-
|
|
89
|
-
begin
|
|
90
|
-
yield
|
|
91
|
-
ensure
|
|
92
|
-
@output_buffer = old_buffer
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
buf
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ViewComponent
|
|
4
|
-
class OutputBufferStack
|
|
5
|
-
delegate_missing_to :@current_buffer
|
|
6
|
-
delegate :presence, :present?, :html_safe?, to: :@current_buffer
|
|
7
|
-
|
|
8
|
-
attr_reader :buffer_stack
|
|
9
|
-
|
|
10
|
-
def self.make_frame(*args)
|
|
11
|
-
ActionView::OutputBuffer.new(*args)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def initialize(initial_buffer = nil)
|
|
15
|
-
if initial_buffer.is_a?(self.class)
|
|
16
|
-
@current_buffer = self.class.make_frame(initial_buffer.current)
|
|
17
|
-
@buffer_stack = [*initial_buffer.buffer_stack[0..-2], @current_buffer]
|
|
18
|
-
else
|
|
19
|
-
@current_buffer = initial_buffer || self.class.make_frame
|
|
20
|
-
@buffer_stack = [@current_buffer]
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def replace(buffer)
|
|
25
|
-
return if self == buffer
|
|
26
|
-
|
|
27
|
-
@current_buffer = buffer.current
|
|
28
|
-
@buffer_stack = buffer.buffer_stack
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def append=(arg)
|
|
32
|
-
@current_buffer.append = arg
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def safe_append=(arg)
|
|
36
|
-
@current_buffer.safe_append = arg
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def safe_concat(arg)
|
|
40
|
-
@current_buffer.safe_concat(arg)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def length
|
|
44
|
-
@current_buffer.length
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def push(buffer = nil)
|
|
48
|
-
buffer ||= self.class.make_frame
|
|
49
|
-
@buffer_stack.push(buffer)
|
|
50
|
-
@current_buffer = buffer
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def pop
|
|
54
|
-
@buffer_stack.pop.tap do
|
|
55
|
-
@current_buffer = @buffer_stack.last
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def to_s
|
|
60
|
-
@current_buffer
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
alias_method :current, :to_s
|
|
64
|
-
end
|
|
65
|
-
end
|