reactrb 0.7.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +6 -0
  3. data/.gitignore +33 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE +19 -0
  7. data/README.md +117 -0
  8. data/Rakefile +28 -0
  9. data/config.ru +16 -0
  10. data/example/examples/Gemfile +7 -0
  11. data/example/examples/app/basics.js.rb +42 -0
  12. data/example/examples/app/items.rb +11 -0
  13. data/example/examples/app/jquery.js +5 -0
  14. data/example/examples/app/nodes.rb +61 -0
  15. data/example/examples/app/react-router.js +6 -0
  16. data/example/examples/app/react_api_demo.rb +29 -0
  17. data/example/examples/app/rerendering.rb +72 -0
  18. data/example/examples/app/reuse.rb +59 -0
  19. data/example/examples/app/show.rb +52 -0
  20. data/example/examples/config.ru +38 -0
  21. data/example/rails-tutorial/.gitignore +17 -0
  22. data/example/rails-tutorial/Gemfile +51 -0
  23. data/example/rails-tutorial/README.rdoc +28 -0
  24. data/example/rails-tutorial/Rakefile +6 -0
  25. data/example/rails-tutorial/app/assets/images/.keep +0 -0
  26. data/example/rails-tutorial/app/assets/javascripts/application.rb +15 -0
  27. data/example/rails-tutorial/app/assets/stylesheets/application.css +15 -0
  28. data/example/rails-tutorial/app/controllers/application_controller.rb +6 -0
  29. data/example/rails-tutorial/app/controllers/concerns/.keep +0 -0
  30. data/example/rails-tutorial/app/controllers/home_controller.rb +6 -0
  31. data/example/rails-tutorial/app/helpers/application_helper.rb +2 -0
  32. data/example/rails-tutorial/app/mailers/.keep +0 -0
  33. data/example/rails-tutorial/app/models/.keep +0 -0
  34. data/example/rails-tutorial/app/models/concerns/.keep +0 -0
  35. data/example/rails-tutorial/app/views/components.rb +3 -0
  36. data/example/rails-tutorial/app/views/components/home/show.rb +47 -0
  37. data/example/rails-tutorial/app/views/layouts/application.html.erb +14 -0
  38. data/example/rails-tutorial/bin/bundle +3 -0
  39. data/example/rails-tutorial/bin/rails +8 -0
  40. data/example/rails-tutorial/bin/rake +8 -0
  41. data/example/rails-tutorial/bin/setup +29 -0
  42. data/example/rails-tutorial/bin/spring +15 -0
  43. data/example/rails-tutorial/config.ru +4 -0
  44. data/example/rails-tutorial/config/application.rb +26 -0
  45. data/example/rails-tutorial/config/boot.rb +3 -0
  46. data/example/rails-tutorial/config/database.yml +25 -0
  47. data/example/rails-tutorial/config/environment.rb +5 -0
  48. data/example/rails-tutorial/config/environments/development.rb +41 -0
  49. data/example/rails-tutorial/config/environments/production.rb +79 -0
  50. data/example/rails-tutorial/config/environments/test.rb +42 -0
  51. data/example/rails-tutorial/config/initializers/assets.rb +11 -0
  52. data/example/rails-tutorial/config/initializers/backtrace_silencers.rb +7 -0
  53. data/example/rails-tutorial/config/initializers/cookies_serializer.rb +3 -0
  54. data/example/rails-tutorial/config/initializers/filter_parameter_logging.rb +4 -0
  55. data/example/rails-tutorial/config/initializers/inflections.rb +16 -0
  56. data/example/rails-tutorial/config/initializers/mime_types.rb +4 -0
  57. data/example/rails-tutorial/config/initializers/session_store.rb +3 -0
  58. data/example/rails-tutorial/config/initializers/wrap_parameters.rb +14 -0
  59. data/example/rails-tutorial/config/locales/en.yml +23 -0
  60. data/example/rails-tutorial/config/routes.rb +59 -0
  61. data/example/rails-tutorial/config/secrets.yml +22 -0
  62. data/example/rails-tutorial/db/seeds.rb +7 -0
  63. data/example/rails-tutorial/lib/assets/.keep +0 -0
  64. data/example/rails-tutorial/lib/tasks/.keep +0 -0
  65. data/example/rails-tutorial/log/.keep +0 -0
  66. data/example/rails-tutorial/public/404.html +67 -0
  67. data/example/rails-tutorial/public/422.html +67 -0
  68. data/example/rails-tutorial/public/500.html +66 -0
  69. data/example/rails-tutorial/public/favicon.ico +0 -0
  70. data/example/rails-tutorial/public/robots.txt +5 -0
  71. data/example/rails-tutorial/test/controllers/.keep +0 -0
  72. data/example/rails-tutorial/test/fixtures/.keep +0 -0
  73. data/example/rails-tutorial/test/helpers/.keep +0 -0
  74. data/example/rails-tutorial/test/integration/.keep +0 -0
  75. data/example/rails-tutorial/test/mailers/.keep +0 -0
  76. data/example/rails-tutorial/test/models/.keep +0 -0
  77. data/example/rails-tutorial/test/test_helper.rb +10 -0
  78. data/example/rails-tutorial/vendor/assets/javascripts/.keep +0 -0
  79. data/example/rails-tutorial/vendor/assets/stylesheets/.keep +0 -0
  80. data/example/sinatra-tutorial/.DS_Store +0 -0
  81. data/example/sinatra-tutorial/Gemfile +5 -0
  82. data/example/sinatra-tutorial/README.md +8 -0
  83. data/example/sinatra-tutorial/_comments.json +42 -0
  84. data/example/sinatra-tutorial/app/example.rb +290 -0
  85. data/example/sinatra-tutorial/app/jquery.js +5 -0
  86. data/example/sinatra-tutorial/config.ru +58 -0
  87. data/example/sinatra-tutorial/public/base.css +62 -0
  88. data/example/todos/Gemfile +11 -0
  89. data/example/todos/README.md +37 -0
  90. data/example/todos/Rakefile +8 -0
  91. data/example/todos/app/application.rb +22 -0
  92. data/example/todos/app/components/app.react.rb +61 -0
  93. data/example/todos/app/components/footer.react.rb +31 -0
  94. data/example/todos/app/components/todo_item.react.rb +46 -0
  95. data/example/todos/app/components/todo_list.react.rb +25 -0
  96. data/example/todos/app/models/todo.rb +19 -0
  97. data/example/todos/config.ru +14 -0
  98. data/example/todos/index.html.haml +16 -0
  99. data/example/todos/spec/todo_spec.rb +28 -0
  100. data/example/todos/vendor/base.css +410 -0
  101. data/example/todos/vendor/bg.png +0 -0
  102. data/example/todos/vendor/jquery.js +4 -0
  103. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +4 -0
  104. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb +2 -0
  105. data/lib/generators/reactive_ruby/test_app/templates/boot.rb.erb +6 -0
  106. data/lib/generators/reactive_ruby/test_app/templates/script/rails +5 -0
  107. data/lib/generators/reactive_ruby/test_app/templates/test_application.rb.erb +13 -0
  108. data/lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +11 -0
  109. data/lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb +14 -0
  110. data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +105 -0
  111. data/lib/rails-helpers/top_level_rails_component.rb +54 -0
  112. data/lib/react/api.rb +127 -0
  113. data/lib/react/callbacks.rb +42 -0
  114. data/lib/react/component.rb +269 -0
  115. data/lib/react/component/api.rb +50 -0
  116. data/lib/react/component/base.rb +9 -0
  117. data/lib/react/component/class_methods.rb +190 -0
  118. data/lib/react/component/props_wrapper.rb +82 -0
  119. data/lib/react/element.rb +77 -0
  120. data/lib/react/event.rb +76 -0
  121. data/lib/react/ext/hash.rb +9 -0
  122. data/lib/react/ext/string.rb +8 -0
  123. data/lib/react/native_library.rb +53 -0
  124. data/lib/react/observable.rb +29 -0
  125. data/lib/react/rendering_context.rb +109 -0
  126. data/lib/react/state.rb +140 -0
  127. data/lib/react/top_level.rb +97 -0
  128. data/lib/react/validator.rb +136 -0
  129. data/lib/reactive-ruby/component_loader.rb +45 -0
  130. data/lib/reactive-ruby/isomorphic_helpers.rb +196 -0
  131. data/lib/reactive-ruby/rails.rb +7 -0
  132. data/lib/reactive-ruby/rails/component_mount.rb +44 -0
  133. data/lib/reactive-ruby/rails/controller_helper.rb +13 -0
  134. data/lib/reactive-ruby/rails/railtie.rb +14 -0
  135. data/lib/reactive-ruby/serializers.rb +15 -0
  136. data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +42 -0
  137. data/lib/reactive-ruby/version.rb +3 -0
  138. data/lib/reactrb.rb +50 -0
  139. data/lib/sources/react-latest.js +21167 -0
  140. data/lib/sources/react-v13.js +21642 -0
  141. data/lib/sources/react-v14.js +20818 -0
  142. data/lib/sources/react-v15.js +21167 -0
  143. data/logo1.png +0 -0
  144. data/logo2.png +0 -0
  145. data/logo3.png +0 -0
  146. data/path_release_steps.md +9 -0
  147. data/reactrb.gemspec +43 -0
  148. data/spec/controller_helper_spec.rb +22 -0
  149. data/spec/index.html.erb +12 -0
  150. data/spec/react/callbacks_spec.rb +106 -0
  151. data/spec/react/component/base_spec.rb +36 -0
  152. data/spec/react/component_spec.rb +721 -0
  153. data/spec/react/dsl_spec.rb +161 -0
  154. data/spec/react/element_spec.rb +47 -0
  155. data/spec/react/event_spec.rb +24 -0
  156. data/spec/react/native_library_spec.rb +10 -0
  157. data/spec/react/observable_spec.rb +7 -0
  158. data/spec/react/param_declaration_spec.rb +286 -0
  159. data/spec/react/react_spec.rb +211 -0
  160. data/spec/react/state_spec.rb +26 -0
  161. data/spec/react/top_level_component_spec.rb +68 -0
  162. data/spec/react/tutorial/tutorial_spec.rb +35 -0
  163. data/spec/react/validator_spec.rb +128 -0
  164. data/spec/reactive-ruby/component_loader_spec.rb +68 -0
  165. data/spec/reactive-ruby/isomorphic_helpers_spec.rb +155 -0
  166. data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +9 -0
  167. data/spec/reactive-ruby/rails/component_mount_spec.rb +66 -0
  168. data/spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb +35 -0
  169. data/spec/spec_helper.rb +109 -0
  170. data/spec/support/react/spec_helpers.rb +57 -0
  171. data/spec/vendor/es5-shim.min.js +6 -0
  172. data/spec/vendor/jquery-2.2.4.min.js +4 -0
  173. metadata +441 -0
@@ -0,0 +1,136 @@
1
+ module React
2
+
3
+ class Validator
4
+ attr_accessor :errors
5
+ private :errors
6
+
7
+ def initialize(component_class)
8
+ @component_class = component_class
9
+ end
10
+
11
+ def self.build(&block)
12
+ self.new.build(&block)
13
+ end
14
+
15
+ def build(&block)
16
+ instance_eval(&block)
17
+ self
18
+ end
19
+
20
+ def requires(name, options = {})
21
+ options[:required] = true
22
+ define_rule(name, options)
23
+ end
24
+
25
+ def optional(name, options = {})
26
+ options[:required] = false
27
+ define_rule(name, options)
28
+ end
29
+
30
+ def allow_undefined_props=(allow)
31
+ @allow_undefined_props = allow
32
+ end
33
+
34
+ def undefined_props(props)
35
+ self.allow_undefined_props = true
36
+ props.reject { |name, value| rules[name] }
37
+ end
38
+
39
+ def validate(props)
40
+ self.errors = []
41
+ validate_undefined(props) unless allow_undefined_props?
42
+ props = coerce_native_hash_values(defined_props(props))
43
+ validate_required(props)
44
+ props.each do |name, value|
45
+ validate_types(name, value)
46
+ validate_allowed(name, value)
47
+ end
48
+ errors
49
+ end
50
+
51
+ def default_props
52
+ rules
53
+ .select {|key, value| value.keys.include?("default") }
54
+ .inject({}) {|memo, (k,v)| memo[k] = v[:default]; memo}
55
+ end
56
+
57
+ private
58
+
59
+ def defined_props(props)
60
+ props.select { |name| rules.keys.include?(name) }
61
+ end
62
+
63
+ def allow_undefined_props?
64
+ !!@allow_undefined_props
65
+ end
66
+
67
+ def rules
68
+ @rules ||= { children: { required: false } }
69
+ end
70
+
71
+ def define_rule(name, options = {})
72
+ rules[name] = coerce_native_hash_values(options)
73
+ @component_class.define_param(name, options[:type]) unless name == :params
74
+ end
75
+
76
+ def errors
77
+ @errors ||= []
78
+ end
79
+
80
+ def validate_types(prop_name, value)
81
+ return unless klass = rules[prop_name][:type]
82
+ if !klass.is_a?(Array)
83
+ allow_nil = !!rules[prop_name][:allow_nil]
84
+ type_check("`#{prop_name}`", value, klass, allow_nil)
85
+ elsif klass.length > 0
86
+ validate_value_array(prop_name, value)
87
+ else
88
+ allow_nil = !!rules[prop_name][:allow_nil]
89
+ type_check("`#{prop_name}`", value, Array, allow_nil)
90
+ end
91
+ end
92
+
93
+ def type_check(prop_name, value, klass, allow_nil)
94
+ return if allow_nil && value.nil?
95
+ return if value.is_a?(klass)
96
+ return if klass.respond_to?(:_react_param_conversion) &&
97
+ klass._react_param_conversion(value, :validate_only)
98
+ errors << "Provided prop #{prop_name} could not be converted to #{klass}"
99
+ end
100
+
101
+ def validate_allowed(prop_name, value)
102
+ return unless values = rules[prop_name][:values]
103
+ return if values.include?(value)
104
+ errors << "Value `#{value}` for prop `#{prop_name}` is not an allowed value"
105
+ end
106
+
107
+ def validate_required(props)
108
+ (rules.keys - props.keys).each do |name|
109
+ next unless rules[name][:required]
110
+ errors << "Required prop `#{name}` was not specified"
111
+ end
112
+ end
113
+
114
+ def validate_undefined(props)
115
+ (props.keys - rules.keys).each do |prop_name|
116
+ errors << "Provided prop `#{prop_name}` not specified in spec"
117
+ end
118
+ end
119
+
120
+ def validate_value_array(name, value)
121
+ klass = rules[name][:type]
122
+ allow_nil = !!rules[name][:allow_nil]
123
+ value.each_with_index do |item, index|
124
+ type_check("`#{name}`[#{index}]", Native(item), klass[0], allow_nil)
125
+ end
126
+ rescue NoMethodError
127
+ errors << "Provided prop `#{name}` was not an Array"
128
+ end
129
+
130
+ def coerce_native_hash_values(hash)
131
+ hash.each do |key, value|
132
+ hash[key] = Native(value)
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,45 @@
1
+ module ReactiveRuby
2
+ class ComponentLoader
3
+ attr_reader :v8_context
4
+ private :v8_context
5
+
6
+ def initialize(v8_context)
7
+ unless v8_context
8
+ raise ArgumentError.new('Could not obtain ExecJS runtime context')
9
+ end
10
+ @v8_context = v8_context
11
+ end
12
+
13
+ def load(file = components)
14
+ return true if loaded?
15
+ !!v8_context.eval(opal(file))
16
+ end
17
+
18
+ def load!(file = components)
19
+ return true if loaded?
20
+ self.load(file)
21
+ ensure
22
+ raise "No react.rb components found in #{components}.rb" unless loaded?
23
+ end
24
+
25
+ def loaded?
26
+ !!v8_context.eval('Opal.React')
27
+ end
28
+
29
+ private
30
+
31
+ def components
32
+ # Make this configurable at some point
33
+ 'components'
34
+ end
35
+
36
+ def opal(file)
37
+ Opal::Processor.load_asset_code(assets, file)
38
+ rescue # What exception is being caught here?
39
+ end
40
+
41
+ def assets
42
+ ::Rails.application.assets
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,196 @@
1
+ module React
2
+ module IsomorphicHelpers
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ if RUBY_ENGINE != 'opal'
8
+ def self.load_context(ctx, controller, name = nil)
9
+ puts "************************** React Server Context Initialized #{name} *********************************************"
10
+ @context = Context.new("#{controller.object_id}-#{Time.now.to_i}", ctx, controller, name)
11
+ end
12
+ else
13
+ def self.load_context(unique_id = nil, name = nil)
14
+ # can be called on the client to force re-initialization for testing purposes
15
+ if !unique_id || !@context || @context.unique_id != unique_id
16
+ if on_opal_server?
17
+ message = "************************ React Prerendering Context Initialized #{name} ***********************"
18
+ else
19
+ message = "************************ React Browser Context Initialized ****************************"
20
+ end
21
+ log(message)
22
+ @context = Context.new(unique_id)
23
+ end
24
+ @context
25
+ end
26
+ end
27
+
28
+ def self.log(message, message_type = :info)
29
+ message = [message] unless message.is_a? Array
30
+ if message_type == :info
31
+ if on_opal_server?
32
+ style = 'background: #00FFFF; color: red'
33
+ else
34
+ style = 'background: #222; color: #bada55'
35
+ end
36
+ message = ["%c" + message[0], style]+message[1..-1]
37
+ `console.log.apply(console, message)`
38
+ elsif message_type == :warning
39
+ `console.warn.apply(console, message)`
40
+ else
41
+ `console.error.apply(console, message)`
42
+ end
43
+ end
44
+
45
+ if RUBY_ENGINE != 'opal'
46
+ def self.on_opal_server?
47
+ false
48
+ end
49
+
50
+ def self.on_opal_client?
51
+ false
52
+ end
53
+ else
54
+ def self.on_opal_server?
55
+ `typeof window.document === 'undefined'`
56
+ end
57
+
58
+ def self.on_opal_client?
59
+ !on_opal_server?
60
+ end
61
+ end
62
+
63
+ def log(*args)
64
+ IsomorphicHelpers.log(*args)
65
+ end
66
+
67
+ def on_opal_server?
68
+ self.class.on_opal_server?
69
+ end
70
+
71
+ def on_opal_client?
72
+ self.class.on_opal_client?
73
+ end
74
+
75
+ def self.prerender_footers
76
+ footer = Context.prerender_footer_blocks.collect { |block| block.call }.join("\n")
77
+ if RUBY_ENGINE != 'opal'
78
+ footer = (footer + "#{@context.send_to_opal(:prerender_footers)}") if @context
79
+ footer = footer.html_safe
80
+ end
81
+ footer
82
+ end
83
+
84
+ class Context
85
+ attr_reader :controller
86
+ attr_reader :unique_id
87
+
88
+ def self.before_first_mount_blocks
89
+ @before_first_mount_blocks ||= []
90
+ end
91
+
92
+ def self.prerender_footer_blocks
93
+ @prerender_footer_blocks ||= []
94
+ end
95
+
96
+ def initialize(unique_id, ctx = nil, controller = nil, name = nil)
97
+ @unique_id = unique_id
98
+ if RUBY_ENGINE != 'opal'
99
+ @controller = controller
100
+ @ctx = ctx
101
+ ctx["ServerSideIsomorphicMethods"] = self
102
+ send_to_opal(:load_context, @unique_id, name)
103
+ end
104
+ self.class.before_first_mount_blocks.each { |block| block.call(self) }
105
+ end
106
+
107
+ def eval(js)
108
+ @ctx.eval(js) if @ctx
109
+ end
110
+
111
+ def send_to_opal(method, *args)
112
+ return unless @ctx
113
+ args = [1] if args.length == 0
114
+ ::ReactiveRuby::ComponentLoader.new(@ctx).load!
115
+ @ctx.eval("Opal.React.IsomorphicHelpers.$#{method}(#{args.collect { |arg| "'#{arg}'"}.join(', ')})")
116
+ end
117
+
118
+ def self.register_before_first_mount_block(&block)
119
+ before_first_mount_blocks << block
120
+ end
121
+
122
+ def self.register_prerender_footer_block(&block)
123
+ prerender_footer_blocks << block
124
+ end
125
+ end
126
+
127
+ class IsomorphicProcCall
128
+ def result
129
+ @result.first if @result
130
+ end
131
+
132
+ def initialize(name, block, *args)
133
+ @name = name
134
+ block.call(self, *args)
135
+ @result ||= send_to_server(*args) if IsomorphicHelpers.on_opal_server?
136
+ end
137
+
138
+ def when_on_client(&block)
139
+ @result = [block.call] if IsomorphicHelpers.on_opal_client?
140
+ end
141
+
142
+ def send_to_server(*args)
143
+ if IsomorphicHelpers.on_opal_server?
144
+ args_as_json = args.to_json
145
+ @result = [JSON.parse(`window.ServerSideIsomorphicMethods[#{@name}](#{args_as_json})`)]
146
+ end
147
+ end
148
+
149
+ def when_on_server(&block)
150
+ @result = [block.call.to_json] unless IsomorphicHelpers.on_opal_client? || IsomorphicHelpers.on_opal_server?
151
+ end
152
+ end
153
+
154
+ module ClassMethods
155
+ def on_opal_server?
156
+ IsomorphicHelpers.on_opal_server?
157
+ end
158
+
159
+ def on_opal_client?
160
+ IsomorphicHelpers.on_opal_client?
161
+ end
162
+
163
+ def log(*args)
164
+ IsomorphicHelpers.log(*args)
165
+ end
166
+
167
+ def controller
168
+ IsomorphicHelpers.context.controller
169
+ end
170
+
171
+ def before_first_mount(&block)
172
+ React::IsomorphicHelpers::Context.register_before_first_mount_block &block
173
+ end
174
+
175
+ def prerender_footer(&block)
176
+ React::IsomorphicHelpers::Context.register_prerender_footer_block &block
177
+ end
178
+
179
+ if RUBY_ENGINE != 'opal'
180
+ def isomorphic_method(name, &block)
181
+ React::IsomorphicHelpers::Context.send(:define_method, name) do |args_as_json|
182
+ React::IsomorphicHelpers::IsomorphicProcCall.new(name, block, *JSON.parse(args_as_json)).result
183
+ end
184
+ end
185
+ else
186
+ require 'json'
187
+
188
+ def isomorphic_method(name, &block)
189
+ self.class.send(:define_method, name) do | *args |
190
+ React::IsomorphicHelpers::IsomorphicProcCall.new(name, block, *args).result
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,7 @@
1
+ require 'action_view'
2
+ require 'react-rails'
3
+ require 'reactive-ruby/server_rendering/contextual_renderer'
4
+ require 'reactive-ruby/rails/component_mount'
5
+ require 'reactive-ruby/rails/railtie'
6
+ require 'reactive-ruby/rails/controller_helper'
7
+ require 'reactive-ruby/component_loader'
@@ -0,0 +1,44 @@
1
+ module ReactiveRuby
2
+ module Rails
3
+ class ComponentMount < React::Rails::ComponentMount
4
+ attr_accessor :controller
5
+
6
+ def setup(controller)
7
+ self.controller = controller
8
+ end
9
+
10
+ def react_component(name, props = {}, options = {}, &block)
11
+ options = context_initializer_options(options, name) if options[:prerender]
12
+ props = serialized_props(props, name, controller)
13
+ super(top_level_name, props, options, &block) + footers
14
+ end
15
+
16
+ private
17
+
18
+ def context_initializer_options(options, name)
19
+ options[:prerender] = {options[:prerender] => true} unless options[:prerender].is_a? Hash
20
+ existing_context_initializer = options[:prerender][:context_initializer]
21
+
22
+ options[:prerender][:context_initializer] = lambda do |ctx|
23
+ React::IsomorphicHelpers.load_context(ctx, controller, name)
24
+ existing_context_initializer.call ctx if existing_context_initializer
25
+ end
26
+
27
+ options
28
+ end
29
+
30
+ def serialized_props(props, name, controller)
31
+ { render_params: props, component_name: name,
32
+ controller: controller.class.name.gsub(/Controller$/,"") }.react_serializer
33
+ end
34
+
35
+ def top_level_name
36
+ 'React.TopLevelRailsComponent'
37
+ end
38
+
39
+ def footers
40
+ React::IsomorphicHelpers.prerender_footers #if options[:prerender]
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,13 @@
1
+ require 'action_controller'
2
+
3
+ module ReactiveRuby
4
+ module Rails
5
+ class ActionController::Base
6
+ def render_component(*args)
7
+ @component_name = ((args[0].is_a? Hash) || args.empty?) ? params[:action].camelize : args.shift
8
+ @render_params = (args[0].is_a? Hash) ? args[0] : {}
9
+ render inline: "<%= react_component @component_name, @render_params, { prerender: !params[:no_prerender] } %>", layout: 'application'
10
+ end
11
+ end
12
+ end
13
+ end