Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

Commit 2bd4db8

Browse files
committed
closes #252 #262 #263
1 parent ba4704c commit 2bd4db8

11 files changed

+86
-27
lines changed

hyper-react.gemspec

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Gem::Specification.new do |spec|
3838
spec.add_development_dependency 'opal-rails', '~> 0.9.4'
3939
spec.add_development_dependency 'opal-rspec'
4040
spec.add_development_dependency 'puma'
41+
spec.add_development_dependency 'pry'
4142
spec.add_development_dependency 'rails', '>= 4.0.0'
4243
spec.add_development_dependency 'rails-controller-testing'
4344
spec.add_development_dependency 'rake'

lib/hyper-react.rb

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class Component
3939
require 'react/rendering_context'
4040
require 'react/state'
4141
require 'react/object'
42+
require 'react/to_key'
4243
require 'react/ext/opal-jquery/element'
4344
require 'reactive-ruby/isomorphic_helpers'
4445
require 'rails-helpers/top_level_rails_component'

lib/react/ext/opal-jquery/element.rb

+11
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,15 @@ def self.[](selector)
2323

2424
React.render(React.create_element(`#{self.to_n}._reactrb_component_class`), self)
2525
end
26+
27+
# mount_components is useful for dynamically generated page segments for example
28+
# see react-rails documentation for more details
29+
30+
%x{
31+
$.fn.mount_components = function() {
32+
this.each(function(e) { ReactRailsUJS.mountComponents(e[0]) })
33+
return this;
34+
}
35+
}
36+
Element.expose :mount_components
2637
end if Object.const_defined?('Element')

lib/react/object.rb

-16
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,4 @@ def const_missing(const_name)
1212
React::Component::Tags.html_tag_class_for(const_name) || raise(e)
1313
end
1414
end
15-
16-
def to_key
17-
object_id
18-
end
19-
end
20-
21-
class Number
22-
def to_key
23-
self
24-
end
25-
end
26-
27-
class Boolean
28-
def to_key
29-
self
30-
end
3115
end

lib/react/to_key.rb

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# to_key method returns a suitable unique id that can be used as
2+
# a react `key`. Other classes may override to_key as needed
3+
# for example hyper_mesh returns the object id of the internal
4+
# backing record.
5+
#
6+
# to_key is automatically called on objects passed as keys for
7+
# example Foo(key: my_object) results in Foo(key: my_object.to_key)
8+
class Object
9+
def to_key
10+
object_id
11+
end
12+
end
13+
14+
# for Number to_key can just be the number itself
15+
class Number
16+
def to_key
17+
self
18+
end
19+
end
20+
21+
# for Boolean to_key can be true or false
22+
class Boolean
23+
def to_key
24+
self
25+
end
26+
end

lib/reactive-ruby/rails/component_mount.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ def react_component(name, props = {}, options = {}, &block)
1212
options = context_initializer_options(options, name)
1313
end
1414
props = serialized_props(props, name, controller)
15-
super(top_level_name, props, options, &block).gsub("\n","")
16-
.gsub(/(<script>.*<\/script>)<\/div>$/,'</div>\1').html_safe +
17-
footers
15+
result = super(top_level_name, props, options, &block).gsub("\n","")
16+
result = result.gsub(/(<script.*<\/script>)<\/div>$/,'</div>\1').html_safe
17+
result + footers
1818
end
1919

2020
private

lib/reactive-ruby/serializers.rb

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1-
[Bignum, FalseClass, Fixnum, Float, Integer, NilClass, String, Symbol, Time, TrueClass].each do |klass|
2-
klass.send(:define_method, :react_serializer) do
1+
[FalseClass, Float, Integer, NilClass, String, Symbol, Time, TrueClass].each do |klass|
2+
klass.send(:define_method, :react_serializer) do
33
as_json
44
end
55
end
66

7+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.4.0')
8+
[Bignum, Fixnum].each do |klass|
9+
klass.send(:define_method, :react_serializer) do
10+
as_json
11+
end
12+
end
13+
end
14+
715
BigDecimal.send(:define_method, :react_serializer) { as_json } rescue nil
816

9-
Array.send(:define_method, :react_serializer) do
17+
Array.send(:define_method, :react_serializer) do
1018
self.collect { |e| e.react_serializer }.as_json
1119
end
1220

lib/reactive-ruby/server_rendering/contextual_renderer.rb

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ def initialize(options = {})
1414
ComponentLoader.new(v8_context).load
1515
end
1616

17+
def before_render(*args)
18+
# the base class clears the log history... we don't want that as it is taken
19+
# care of in IsomorphicHelpers.load_context
20+
end
21+
1722
def render(component_name, props, prerender_options)
1823
if prerender_options.is_a?(Hash)
1924
if !v8_runtime? && prerender_options[:context_initializer]

spec/react/dsl_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def render
103103
end
104104
end
105105
end
106-
expect(page.body[-80..-19]).to match(/(<div data-reactroot=""|<div)><span>hello<(br|br\/|br \/)><\/span><\/div>/)
106+
expect(page.body[-285..-233]).to match(/(<div data-reactroot=""|<div)><span>hello<(br|br\/|br \/)><\/span><\/div>/)
107107
end
108108

109109
it "has a .td short hand String method" do
@@ -197,7 +197,7 @@ class Foo < React::Component::Base
197197
'raised for sure!'
198198
end
199199
end.to eq('raised for sure!')
200-
200+
201201
end
202202

203203
it "will treat the component class name as a first class component name" do

spec/react/element_spec.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def render
2828
end
2929
end
3030
end
31-
expect(page.body[-80..-19]).to match(/<input (type="text" value=""|value="" type="text").*\/>/)
31+
expect(page.body[-285..-233]).to match(/<input (type="text" value=""|value="" type="text").*\/>/)
3232
end
3333
end
3434

@@ -62,7 +62,7 @@ def render
6262
end
6363

6464
it 'will subscribe to a native components event param' do
65-
65+
6666
evaluate_ruby do
6767
"this makes sure everything is loaded"
6868
end
@@ -84,7 +84,7 @@ class Foo < React::Component::Base
8484
end
8585

8686
it 'will subscribe to a component event param with a non-default name' do
87-
87+
8888
evaluate_ruby do
8989
class Foo < React::Component::Base
9090
param :my_event, type: Proc, default: nil, allow_nil: true

spec/react/opal_jquery_extensions_spec.rb

+23
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,28 @@ def render
6767
expect(page.driver.browser.manage.logs.get(:browser).map { |m| m.message.gsub(/\\n/, "\n") }.to_a.join("\n"))
6868
.not_to match(/Exception|Error/)
6969
end
70+
71+
it "can dynamically mount components" do
72+
on_client do
73+
class DynoMount < Hyperloop::Component
74+
render(DIV) { 'I got rendered' }
75+
end
76+
end
77+
mount 'MountPoint' do
78+
class MountPoint < Hyperloop::Component
79+
render(DIV) do
80+
# simulate what react-rails render_component output
81+
DIV(
82+
'data-react-class' => 'React.TopLevelRailsComponent',
83+
'data-react-props' => '{"render_params": {}, "component_name": "DynoMount", "controller": ""}'
84+
)
85+
end
86+
end
87+
end
88+
evaluate_ruby do
89+
Element['body'].mount_components
90+
end
91+
expect(page).to have_content('I got rendered')
92+
end
7093
end
7194
end

0 commit comments

Comments
 (0)