11require 'react/ext/string'
22require 'react/ext/hash'
33require 'active_support/core_ext/class/attribute'
4- require 'active_support/core_ext/module/introspection'
54require 'react/callbacks'
6- require 'react/children'
75require 'react/rendering_context'
86require 'react/observable'
97require 'react/state'
@@ -17,6 +15,8 @@ module Component
1715 def self . included ( base )
1816 base . include ( API )
1917 base . include ( Callbacks )
18+ base . include ( Tags )
19+ base . include ( DslInstanceMethods )
2020 base . class_eval do
2121 class_attribute :initial_state
2222 define_callback :before_mount
@@ -27,28 +27,6 @@ def self.included(base)
2727 define_callback :before_unmount
2828 end
2929 base . extend ( ClassMethods )
30-
31- if base . name
32- parent = base . name . split ( "::" ) . inject ( [ Module ] ) { |nesting , next_const | nesting + [ nesting . last . const_get ( next_const ) ] } [ -2 ]
33- class << parent
34- def method_missing ( n , *args , &block )
35- name = n
36- if name =~ /_as_node$/
37- node_only = true
38- name = name . gsub ( /_as_node$/ , "" )
39- end
40- begin
41- name = const_get ( name )
42- rescue Exception
43- name = nil
44- end
45- unless name && name . method_defined? ( :render )
46- return super
47- end
48- React ::RenderingContext . build_or_render ( node_only , name , *args , &block )
49- end
50- end
51- end
5230 end
5331
5432 def initialize ( native_element )
@@ -59,30 +37,9 @@ def render
5937 raise "no render defined"
6038 end unless method_defined? ( :render )
6139
62- def children
63- Children . new ( `#{ @native } .props.children` )
64- end
65-
66- def params
67- @params ||= self . class . props_wrapper . new ( self )
68- end
69-
70- def props
71- Hash . new ( `#{ @native } .props` )
72- end
73-
74- def refs
75- Hash . new ( `#{ @native } .refs` )
76- end
77-
78- def state
79- @state_wrapper ||= StateWrapper . new ( @native , self )
80- end
81-
8240 def update_react_js_state ( object , name , value )
8341 if object
84- set_state ( { "***_state_updated_at-***" => Time . now . to_f ,
85- "#{ object . class . to_s +'.' unless object == self } #{ name } " => value } )
42+ set_state ( { "***_state_updated_at-***" => Time . now . to_f , "#{ object . class . to_s +'.' unless object == self } #{ name } " => value } )
8643 else
8744 set_state ( { name => value } )
8845 end rescue nil
@@ -94,11 +51,10 @@ def emit(event_name, *args)
9451
9552 def component_will_mount
9653 IsomorphicHelpers . load_context ( true ) if IsomorphicHelpers . on_opal_client?
54+ @props_wrapper = self . class . props_wrapper . new ( Hash . new ( `#{ @native } .props` ) )
9755 set_state! initial_state if initial_state
9856 State . initialize_states ( self , initial_state )
99- State . set_state_context_to ( self ) do
100- self . run_callback ( :before_mount )
101- end
57+ State . set_state_context_to ( self ) { self . run_callback ( :before_mount ) }
10258 rescue Exception => e
10359 self . class . process_exception ( e , self )
10460 end
@@ -113,23 +69,26 @@ def component_did_mount
11369 end
11470
11571 def component_will_receive_props ( next_props )
116- # need to rethink how this works in opal-react, or if its actually that
117- # useful within the react.rb environment for now we are just using it to
118- # clear processed_params
119- State . set_state_context_to ( self ) do
120- self . run_callback ( :before_receive_props , next_props )
121- end
72+ # need to rethink how this works in opal-react, or if its actually that useful within the react.rb environment
73+ # for now we are just using it to clear processed_params
74+ State . set_state_context_to ( self ) { self . run_callback ( :before_receive_props , Hash . new ( next_props ) ) }
12275 rescue Exception => e
12376 self . class . process_exception ( e , self )
12477 end
12578
79+ def props_changed? ( next_props )
80+ return true unless props . keys . sort == next_props . keys . sort
81+ props . detect { |k , v | `#{ next_props [ k ] } != #{ params [ k ] } ` }
82+ end
83+
12684 def should_component_update? ( next_props , next_state )
12785 State . set_state_context_to ( self ) do
86+ next_props = Hash . new ( next_props )
12887 if self . respond_to? ( :needs_update? )
129- !!self . needs_update? ( next_props , next_state )
88+ !!self . needs_update? ( next_props , Hash . new ( next_state ) )
13089 elsif false # switch to true to force updates per standard react
13190 true
132- elsif props != next_props
91+ elsif props_changed? next_props
13392 true
13493 elsif `!next_state != !#{ @native } .state`
13594 true
@@ -144,16 +103,15 @@ def should_component_update?(next_props, next_state)
144103 end
145104
146105 def component_will_update ( next_props , next_state )
147- State . set_state_context_to ( self ) do
148- self . run_callback ( :before_update , next_props , next_state )
149- end
106+ State . set_state_context_to ( self ) { self . run_callback ( :before_update , Hash . new ( next_props ) , Hash . new ( next_state ) ) }
107+ @props_wrapper = self . class . props_wrapper . new ( Hash . new ( next_props ) , @props_wrapper )
150108 rescue Exception => e
151109 self . class . process_exception ( e , self )
152110 end
153111
154112 def component_did_update ( prev_props , prev_state )
155113 State . set_state_context_to ( self ) do
156- self . run_callback ( :after_update , prev_props , prev_state )
114+ self . run_callback ( :after_update , Hash . new ( prev_props ) , Hash . new ( prev_state ) )
157115 State . update_states_to_observe
158116 end
159117 rescue Exception => e
@@ -169,47 +127,14 @@ def component_will_unmount
169127 self . class . process_exception ( e , self )
170128 end
171129
172- def p ( *args , &block )
173- if block || args . count == 0 || ( args . count == 1 && args . first . is_a? ( Hash ) )
174- _p_tag ( *args , &block )
175- else
176- Kernel . p ( *args )
177- end
178- end
179-
180- def component? ( name )
181- name_list = name . split ( "::" )
182- [ self . class , *self . class . parents ] . each do |scope |
183- component = name_list . inject ( scope ) do |scope , class_name |
184- scope . const_get ( class_name )
185- end rescue nil
186- return component if component && component . method_defined? ( :render )
187- end
188- nil
189- end
190-
191- def method_missing ( n , *args , &block )
192- # TODO deprecate and remove - done so that params shadow tags, no longer
193- # needed
194- return props [ n ] if props . key? ( n )
195- name = n
196- if name =~ /_as_node$/
197- node_only = true
198- name = name . gsub ( /_as_node$/ , "" )
199- end
200- unless ( React . html_tag? ( name ) || name == 'present' || name == '_p_tag' || ( name = component? ( name , self ) ) )
201- return super
202- end
203-
204- if name == "present"
205- name = args . shift
206- end
130+ attr_reader :waiting_on_resources
207131
208- if name == "_p_tag"
209- name = "p"
132+ def _render_wrapper
133+ State . set_state_context_to ( self ) do
134+ React ::RenderingContext . render ( nil ) { render || "" } . tap { |element | @waiting_on_resources = element . waiting_on_resources if element . respond_to? :waiting_on_resources }
210135 end
211-
212- React :: RenderingContext . build_or_render ( node_only , name , * args , & block )
136+ rescue Exception => e
137+ self . class . process_exception ( e , self )
213138 end
214139
215140 def watch ( value , &on_change )
@@ -220,18 +145,5 @@ def define_state(*args, &block)
220145 State . initialize_states ( self , self . class . define_state ( *args , &block ) )
221146 end
222147
223- attr_reader :waiting_on_resources
224-
225- def _render_wrapper
226- State . set_state_context_to ( self ) do
227- React ::RenderingContext . render ( nil ) { render || "" } . tap do |element |
228- if element . respond_to? ( :waiting_on_resources )
229- @waiting_on_resources = element . waiting_on_resources
230- end
231- end
232- end
233- rescue Exception => e
234- self . class . process_exception ( e , self )
235- end
236148 end
237149end
0 commit comments