view_component_reflex 3.1.4 → 3.1.9
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8df0782e33267ea91ff1e99610107ee004cdec87947087750227907af88a3674
|
4
|
+
data.tar.gz: 5f488b266c6ade0cc81317da9ed0cb3d08cb8680654aef045348b3809997c9f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 281166ac7c1e2589d9b97733ad3edca6986720c87b239dd779c55529644bff5f8fad352a46abd43dc53c2e46947525d3517335a0621c8fa6478ad23767ef2b31
|
7
|
+
data.tar.gz: dece5fcacf66ee99a5fb539b42bb37cd71904435851ac71e8804b5ed75f0d67b8473b4a7e25e288dfbf81299a9c9f1834c418241b3a3055042136d2308f3f4ff
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module ViewComponentReflex
|
2
2
|
class Component < ViewComponent::Base
|
3
3
|
class_attribute :reflex_base_class, default: ViewComponentReflex::Reflex
|
4
|
+
attr_reader :key
|
4
5
|
|
5
6
|
class << self
|
6
7
|
def init_stimulus_reflex
|
@@ -55,7 +56,7 @@ module ViewComponentReflex
|
|
55
56
|
end
|
56
57
|
|
57
58
|
def component_controller(opts_or_tag = :div, opts = {}, &blk)
|
58
|
-
|
59
|
+
initialize_component
|
59
60
|
|
60
61
|
tag = :div
|
61
62
|
options = if opts_or_tag.is_a? Hash
|
@@ -77,11 +78,64 @@ module ViewComponentReflex
|
|
77
78
|
omitted_from_state.empty?
|
78
79
|
end
|
79
80
|
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
|
81
|
+
# We can't truly initialize the component without the view_context,
|
82
|
+
# which isn't available in the `initialize` method. We require the
|
83
|
+
# developer to wrap components in `component_controller`, so this is where
|
84
|
+
# we truly initialize the component.
|
85
|
+
# This method is overridden in reflex.rb when the component is re-rendered. The
|
86
|
+
# override simply sets @key to element.dataset[:key]
|
87
|
+
# We don't want it to initialize the state again, and since we're rendering the component
|
88
|
+
# outside of the view, we need to skip the initialize_key method as well
|
89
|
+
def initialize_component
|
90
|
+
initialize_key
|
91
|
+
initialize_state
|
92
|
+
end
|
93
|
+
|
94
|
+
# Note to self:
|
95
|
+
# This has to be in the Component class because there are situations
|
96
|
+
# where the controller is the one rendering the component
|
97
|
+
# so we can't rely on the component created by the reflex
|
98
|
+
def initialize_state
|
99
|
+
return if state_initialized?
|
100
|
+
adapter = ViewComponentReflex::Engine.state_adapter
|
101
|
+
|
102
|
+
# newly mounted
|
103
|
+
if !stimulus_reflex? || adapter.state(request, @key).empty?
|
104
|
+
|
105
|
+
new_state = create_safe_state
|
106
|
+
|
107
|
+
adapter.wrap_write_async do
|
108
|
+
adapter.store_state(request, @key, new_state)
|
109
|
+
adapter.store_state(request, "#{@key}_initial", new_state)
|
110
|
+
end
|
111
|
+
|
112
|
+
# updating a mounted component
|
113
|
+
else
|
114
|
+
initial_state = adapter.state(request, "#{@key}_initial")
|
115
|
+
|
116
|
+
parameters_changed = []
|
117
|
+
adapter.state(request, @key).each do |k, v|
|
118
|
+
instance_value = instance_variable_get(k)
|
119
|
+
if permit_parameter?(initial_state[k], instance_value)
|
120
|
+
parameters_changed << k
|
121
|
+
adapter.wrap_write_async do
|
122
|
+
adapter.set_state(request, controller, "#{@key}_initial", {k => instance_value})
|
123
|
+
adapter.set_state(request, controller, @key, {k => instance_value})
|
124
|
+
end
|
125
|
+
else
|
126
|
+
instance_variable_set(k, v)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
after_state_initialized(parameters_changed)
|
130
|
+
end
|
131
|
+
@state_initialized = true
|
132
|
+
end
|
133
|
+
|
134
|
+
def state_initialized?
|
135
|
+
@state_initialized
|
136
|
+
end
|
137
|
+
|
138
|
+
def initialize_key
|
85
139
|
# we want the erb file that renders the component. `caller` gives the file name,
|
86
140
|
# and line number, which should be unique. We hash it to make it a nice number
|
87
141
|
erb_file = caller.select { |p| p.match? /.\.html\.(haml|erb|slim)/ }[1]
|
@@ -137,44 +191,6 @@ module ViewComponentReflex
|
|
137
191
|
# # no op
|
138
192
|
# end
|
139
193
|
|
140
|
-
def key
|
141
|
-
adapter = ViewComponentReflex::Engine.state_adapter
|
142
|
-
|
143
|
-
# initialize session state
|
144
|
-
if (!stimulus_reflex? || adapter.state(request, @key).empty?) && !@initialized_state
|
145
|
-
|
146
|
-
new_state = create_safe_state
|
147
|
-
|
148
|
-
adapter.wrap_write_async do
|
149
|
-
adapter.store_state(request, @key, new_state)
|
150
|
-
adapter.store_state(request, "#{@key}_initial", new_state)
|
151
|
-
end
|
152
|
-
elsif !@initialized_state
|
153
|
-
initial_state = adapter.state(request, "#{@key}_initial")
|
154
|
-
|
155
|
-
# incoming_params = safe_instance_variables.each_with_object({}) { |var, obj| obj[var] = instance_variable_get(var) }
|
156
|
-
# receive_params(ViewComponentReflex::Engine.state_adapter.state(request, @key), incoming_params)
|
157
|
-
|
158
|
-
parameters_changed = []
|
159
|
-
adapter.state(request, @key).each do |k, v|
|
160
|
-
instance_value = instance_variable_get(k)
|
161
|
-
if permit_parameter?(initial_state[k], instance_value)
|
162
|
-
parameters_changed << k
|
163
|
-
adapter.wrap_write_async do
|
164
|
-
adapter.set_state(request, controller, "#{@key}_initial", {k => instance_value})
|
165
|
-
adapter.set_state(request, controller, @key, {k => instance_value})
|
166
|
-
end
|
167
|
-
else
|
168
|
-
instance_variable_set(k, v)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
after_state_initialized(parameters_changed)
|
172
|
-
end
|
173
|
-
|
174
|
-
@initialized_state = true
|
175
|
-
@key
|
176
|
-
end
|
177
|
-
|
178
194
|
def safe_instance_variables
|
179
195
|
instance_variables - unsafe_instance_variables - omitted_from_state
|
180
196
|
end
|
@@ -185,10 +201,23 @@ module ViewComponentReflex
|
|
185
201
|
[
|
186
202
|
:@view_context, :@lookup_context, :@view_renderer, :@view_flow,
|
187
203
|
:@virtual_path, :@variant, :@current_template, :@output_buffer, :@key,
|
188
|
-
:@helpers, :@controller, :@request, :@tag_builder, :@
|
204
|
+
:@helpers, :@controller, :@request, :@tag_builder, :@state_initialized,
|
205
|
+
:@_content_evaluated, :@_render_in_block
|
189
206
|
]
|
190
207
|
end
|
191
208
|
|
209
|
+
def content
|
210
|
+
if cached_content && !@_render_in_block
|
211
|
+
cached_content
|
212
|
+
else
|
213
|
+
super
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def cached_content
|
218
|
+
@__cached_content__
|
219
|
+
end
|
220
|
+
|
192
221
|
def create_safe_state
|
193
222
|
new_state = {}
|
194
223
|
|
@@ -196,6 +225,9 @@ module ViewComponentReflex
|
|
196
225
|
safe_instance_variables.each do |k|
|
197
226
|
new_state[k] = instance_variable_get(k)
|
198
227
|
end
|
228
|
+
|
229
|
+
new_state[:@__cached_content__] = content
|
230
|
+
|
199
231
|
new_state
|
200
232
|
end
|
201
233
|
|
@@ -5,6 +5,13 @@ module ViewComponentReflex
|
|
5
5
|
attr_accessor :component_class
|
6
6
|
end
|
7
7
|
|
8
|
+
# pretty sure I can't memoize this because we need
|
9
|
+
# to re-render every time
|
10
|
+
def controller_document
|
11
|
+
controller.process(params[:action])
|
12
|
+
Nokogiri::HTML(controller.response.body)
|
13
|
+
end
|
14
|
+
|
8
15
|
def refresh!(primary_selector = nil, *rest)
|
9
16
|
save_state
|
10
17
|
|
@@ -14,24 +21,21 @@ module ViewComponentReflex
|
|
14
21
|
if primary_selector
|
15
22
|
prevent_refresh!
|
16
23
|
|
17
|
-
controller.process(params[:action])
|
18
|
-
document = Nokogiri::HTML(controller.response.body)
|
19
24
|
[primary_selector, *rest].each do |s|
|
20
|
-
html =
|
25
|
+
html = controller_document.css(s)
|
21
26
|
if html.present?
|
22
27
|
CableReady::Channels.instance[stream].morph(
|
23
28
|
selector: s,
|
24
29
|
html: html.inner_html,
|
25
30
|
children_only: true,
|
26
31
|
permanent_attribute_name: "data-reflex-permanent",
|
27
|
-
stimulus_reflex: stimulus_reflex_data
|
28
32
|
)
|
29
33
|
end
|
30
34
|
end
|
31
35
|
else
|
32
36
|
refresh_component!
|
33
37
|
end
|
34
|
-
CableReady::Channels.instance.broadcast
|
38
|
+
CableReady::Channels.instance[stream].broadcast
|
35
39
|
end
|
36
40
|
|
37
41
|
def stream
|
@@ -42,22 +46,35 @@ module ViewComponentReflex
|
|
42
46
|
@stream = channel
|
43
47
|
end
|
44
48
|
|
45
|
-
def
|
49
|
+
def component_document
|
46
50
|
component.tap do |k|
|
47
|
-
k.define_singleton_method(:
|
48
|
-
element.dataset[:key]
|
51
|
+
k.define_singleton_method(:initialize_component) do
|
52
|
+
@key = element.dataset[:key]
|
49
53
|
end
|
50
54
|
end
|
55
|
+
|
51
56
|
document = Nokogiri::HTML(component.render_in(controller.view_context))
|
57
|
+
end
|
58
|
+
|
59
|
+
def refresh_component!
|
52
60
|
CableReady::Channels.instance[stream].morph(
|
53
61
|
selector: selector,
|
54
62
|
children_only: true,
|
55
|
-
html:
|
63
|
+
html: component_document.css(selector).inner_html,
|
56
64
|
permanent_attribute_name: "data-reflex-permanent",
|
57
|
-
stimulus_reflex: stimulus_reflex_data
|
58
65
|
)
|
59
66
|
end
|
60
67
|
|
68
|
+
def default_morph
|
69
|
+
save_state
|
70
|
+
html = if component.can_render_to_string?
|
71
|
+
component_document.css(selector).to_html
|
72
|
+
else
|
73
|
+
controller_document.css(selector).to_html
|
74
|
+
end
|
75
|
+
morph selector, html
|
76
|
+
end
|
77
|
+
|
61
78
|
def stimulus_reflex_data
|
62
79
|
{
|
63
80
|
reflex_id: reflex_id,
|
@@ -96,27 +113,20 @@ module ViewComponentReflex
|
|
96
113
|
!!name.to_proc
|
97
114
|
end
|
98
115
|
|
99
|
-
# this is copied out of stimulus_reflex/reflex.rb and modified
|
100
|
-
def morph(selectors, html = "")
|
101
|
-
case selectors
|
102
|
-
when :nothing
|
103
|
-
@broadcaster = StimulusReflex::NothingBroadcaster.new(self)
|
104
|
-
else
|
105
|
-
@broadcaster = StimulusReflex::SelectorBroadcaster.new(self) unless broadcaster.selector?
|
106
|
-
broadcaster.morphs << [selectors, html]
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
116
|
def method_missing(name, *args, &blk)
|
111
|
-
morph :nothing
|
112
117
|
super unless respond_to_missing?(name)
|
118
|
+
|
113
119
|
state.each do |k, v|
|
114
120
|
component.instance_variable_set(k, v)
|
115
121
|
end
|
116
122
|
|
117
123
|
component.send(name, *args, &blk)
|
118
124
|
|
119
|
-
|
125
|
+
if @prevent_refresh
|
126
|
+
morph :nothing
|
127
|
+
else
|
128
|
+
default_morph
|
129
|
+
end
|
120
130
|
end
|
121
131
|
|
122
132
|
def prevent_refresh!
|
@@ -182,11 +192,23 @@ module ViewComponentReflex
|
|
182
192
|
end
|
183
193
|
|
184
194
|
def set_state(new_state = {})
|
185
|
-
|
195
|
+
state_adapter.set_state(request, controller, key, new_state)
|
196
|
+
end
|
197
|
+
|
198
|
+
def key
|
199
|
+
element.dataset[:key]
|
200
|
+
end
|
201
|
+
|
202
|
+
def state_adapter
|
203
|
+
ViewComponentReflex::Engine.state_adapter
|
186
204
|
end
|
187
205
|
|
188
206
|
def state
|
189
|
-
|
207
|
+
state_adapter.state(request, key)
|
208
|
+
end
|
209
|
+
|
210
|
+
def initial_state
|
211
|
+
state_adapter.state(request, "#{key}_initial")
|
190
212
|
end
|
191
213
|
|
192
214
|
def save_state
|
@@ -9,6 +9,7 @@ module ViewComponentReflex
|
|
9
9
|
new_state.each do |k, v|
|
10
10
|
state(request, key)[k] = v
|
11
11
|
end
|
12
|
+
p new_state
|
12
13
|
store = request.session.instance_variable_get("@by")
|
13
14
|
store.commit_session request, controller.response
|
14
15
|
end
|
@@ -18,6 +19,7 @@ module ViewComponentReflex
|
|
18
19
|
new_state.each do |k, v|
|
19
20
|
request.session[key][k] = v
|
20
21
|
end
|
22
|
+
p new_state
|
21
23
|
end
|
22
24
|
|
23
25
|
def self.wrap_write_async
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: view_component_reflex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua LeBlanc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -36,28 +36,28 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 3.4.
|
39
|
+
version: 3.4.1
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 3.4.
|
46
|
+
version: 3.4.1
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: view_component
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: 2.28.0
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
60
|
+
version: 2.28.0
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: sqlite3
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|