reactrb 0.7.42

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.
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