@@ -104,12 +104,13 @@ def computed_props
104104 . tap do |props | # Add meta tags last (never transformed)
105105 props [ :_inertia_meta ] = meta_tags if meta_tags . present?
106106 end
107-
108107 # rubocop:enable Style/MultilineBlockChain
109108 end
110109
111110 def page
112- default_page = {
111+ return @page if defined? ( @page )
112+
113+ @page = {
113114 component : component ,
114115 props : computed_props ,
115116 url : @request . original_fullpath ,
@@ -119,21 +120,11 @@ def page
119120 }
120121
121122 deferred_props = deferred_props_keys
122- default_page [ :deferredProps ] = deferred_props if deferred_props . present?
123-
124- deep_merge_props , merge_props = all_merge_props . partition do |_key , prop |
125- prop . deep_merge?
126- end
123+ @page [ :deferredProps ] = deferred_props if deferred_props . present?
124+ @page [ :scrollProps ] = scroll_props if scroll_props . present?
125+ @page . merge! ( resolve_merge_props )
127126
128- match_props_on = all_merge_props . filter_map do |key , prop |
129- prop . match_on . map { |ms | "#{ key } .#{ ms } " } if prop . match_on . present?
130- end . flatten
131-
132- default_page [ :mergeProps ] = merge_props . map ( &:first ) if merge_props . present?
133- default_page [ :deepMergeProps ] = deep_merge_props . map ( &:first ) if deep_merge_props . present?
134- default_page [ :matchPropsOn ] = match_props_on if match_props_on . present?
135-
136- default_page
127+ @page
137128 end
138129
139130 def deep_transform_props ( props , parent_path = [ ] )
@@ -165,10 +156,28 @@ def deferred_props_keys
165156 end
166157 end
167158
168- def all_merge_props
169- @all_merge_props ||= @props . select do |key , prop |
159+ def resolve_merge_props
160+ deep_merge_props , merge_props = all_merge_props . partition do |_key , prop |
161+ prop . deep_merge?
162+ end
163+
164+ {
165+ mergeProps : append_merge_props ( merge_props ) ,
166+ prependProps : prepend_merge_props ( merge_props ) ,
167+ deepMergeProps : deep_merge_props . map! ( &:first ) ,
168+ matchPropsOn : resolve_match_on_props ,
169+ } . delete_if { |_ , v | v . blank? }
170+ end
171+
172+ def resolve_match_on_props
173+ all_merge_props . filter_map do |key , prop |
174+ prop . match_on . map! { |ms | "#{ key } .#{ ms } " } if prop . match_on . present?
175+ end . flatten
176+ end
177+
178+ def requested_merge_props
179+ @requested_merge_props ||= @props . select do |key , prop |
170180 next unless prop . try ( :merge? )
171- next if reset_keys . include? ( key )
172181 next if rendering_partial_component? && (
173182 ( partial_keys . present? && partial_keys . exclude? ( key . name ) ) ||
174183 ( partial_except_keys . present? && partial_except_keys . include? ( key . name ) )
@@ -178,16 +187,64 @@ def all_merge_props
178187 end
179188 end
180189
190+ def append_merge_props ( props )
191+ return props if props . empty?
192+
193+ root_append_props , nested_append_props = props . partition { |_key , prop | prop . appends_at_root? }
194+
195+ result = Set . new ( root_append_props . map! ( &:first ) )
196+
197+ nested_append_props . each do |key , prop |
198+ prop . appends_at_paths . each do |path |
199+ result . add ( "#{ key } .#{ path } " )
200+ end
201+ end
202+
203+ result . to_a
204+ end
205+
206+ def prepend_merge_props ( props )
207+ return props if props . empty?
208+
209+ root_prepend_props , nested_prepend_props = props . partition { |_key , prop | prop . prepends_at_root? }
210+
211+ result = Set . new ( root_prepend_props . map! ( &:first ) )
212+
213+ nested_prepend_props . each do |key , prop |
214+ prop . prepends_at_paths . each do |path |
215+ result . add ( "#{ key } .#{ path } " )
216+ end
217+ end
218+
219+ result . to_a
220+ end
221+
222+ def scroll_props
223+ return @scroll_props if defined? ( @scroll_props )
224+
225+ @scroll_props = { }
226+ requested_merge_props . each do |key , prop |
227+ next unless prop . is_a? ( ScrollProp )
228+
229+ @scroll_props [ key ] = prop . metadata . merge! ( reset : reset_keys . include? ( key ) )
230+ end
231+ @scroll_props
232+ end
233+
234+ def all_merge_props
235+ @all_merge_props ||= requested_merge_props . reject { |key , | reset_keys . include? ( key ) }
236+ end
237+
181238 def partial_keys
182- @partial_keys ||= ( @request . headers [ 'X-Inertia-Partial-Data' ] || '' ) . split ( ',' ) . compact
239+ @partial_keys ||= ( @request . headers [ 'X-Inertia-Partial-Data' ] || '' ) . split ( ',' ) . compact_blank!
183240 end
184241
185242 def reset_keys
186- ( @request . headers [ 'X-Inertia-Reset' ] || '' ) . split ( ',' ) . compact . map ( &:to_sym )
243+ @reset_keys ||= ( @request . headers [ 'X-Inertia-Reset' ] || '' ) . split ( ',' ) . compact_blank! . map! ( &:to_sym )
187244 end
188245
189246 def partial_except_keys
190- ( @request . headers [ 'X-Inertia-Partial-Except' ] || '' ) . split ( ',' ) . compact
247+ @partial_except_keys ||= ( @request . headers [ 'X-Inertia-Partial-Except' ] || '' ) . split ( ',' ) . compact_blank!
191248 end
192249
193250 def rendering_partial_component?
0 commit comments