hyper-component 0.99.6 → 1.0.alpha1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -3
- data/Gemfile +4 -3
- data/Gemfile.lock +51 -36
- data/{misc/how-component-name-lookup-works.md → how-component-name-lookup-works.md} +1 -1
- data/hyper-component.gemspec +9 -8
- data/lib/hyper-component.rb +31 -43
- data/lib/hyperstack/component.rb +145 -0
- data/lib/hyperstack/component/auto-import.rb +44 -0
- data/lib/hyperstack/component/children.rb +40 -0
- data/lib/hyperstack/component/element.rb +129 -0
- data/lib/hyperstack/component/event.rb +78 -0
- data/lib/hyperstack/component/haml.rb +18 -0
- data/lib/hyperstack/component/isomorphic_helpers.rb +235 -0
- data/lib/hyperstack/component/jquery.rb +2 -0
- data/lib/hyperstack/component/native_library.rb +92 -0
- data/lib/hyperstack/component/react_api.rb +142 -0
- data/lib/hyperstack/component/server.rb +21 -0
- data/lib/hyperstack/component/version.rb +5 -0
- data/lib/hyperstack/ext/component/boolean.rb +14 -0
- data/lib/{react/ext/opal-jquery → hyperstack/ext/component}/element.rb +17 -12
- data/lib/{react/ext → hyperstack/ext/component}/hash.rb +0 -0
- data/lib/{react/to_key.rb → hyperstack/ext/component/number.rb} +0 -12
- data/lib/hyperstack/ext/component/object.rb +32 -0
- data/lib/{reactive-ruby → hyperstack/ext/component}/serializers.rb +0 -0
- data/lib/{react/ext → hyperstack/ext/component}/string.rb +0 -0
- data/lib/hyperstack/internal/component.rb +16 -0
- data/lib/hyperstack/internal/component/class_methods.rb +212 -0
- data/lib/hyperstack/internal/component/haml.rb +56 -0
- data/lib/hyperstack/internal/component/instance_methods.rb +92 -0
- data/lib/hyperstack/internal/component/props_wrapper.rb +125 -0
- data/lib/hyperstack/internal/component/rails.rb +11 -0
- data/lib/hyperstack/internal/component/rails/component_loader.rb +49 -0
- data/lib/hyperstack/internal/component/rails/component_mount.rb +52 -0
- data/lib/{reactive-ruby → hyperstack/internal/component}/rails/controller_helper.rb +0 -0
- data/lib/hyperstack/internal/component/rails/railtie.rb +24 -0
- data/lib/hyperstack/internal/component/rails/server_rendering/contextual_renderer.rb +52 -0
- data/lib/hyperstack/internal/component/rails/server_rendering/hyper_asset_container.rb +52 -0
- data/lib/hyperstack/internal/component/react_wrapper.rb +308 -0
- data/lib/hyperstack/internal/component/rendering_context.rb +165 -0
- data/lib/hyperstack/internal/component/should_component_update.rb +101 -0
- data/lib/hyperstack/internal/component/tags.rb +109 -0
- data/lib/hyperstack/internal/component/top_level_rails_component.rb +83 -0
- data/lib/hyperstack/internal/component/validator.rb +149 -0
- data/lib/react/react-source.rb +2 -2
- data/unmounting-objects.md +78 -0
- metadata +73 -85
- data/DOCS.md +0 -1515
- data/LICENSE +0 -19
- data/README.md +0 -49
- data/lib/hyper-component/jquery.rb +0 -2
- data/lib/rails-helpers/top_level_rails_component.rb +0 -79
- data/lib/react/api.rb +0 -272
- data/lib/react/callbacks.rb +0 -42
- data/lib/react/children.rb +0 -38
- data/lib/react/component.rb +0 -189
- data/lib/react/component/api.rb +0 -70
- data/lib/react/component/base.rb +0 -13
- data/lib/react/component/class_methods.rb +0 -175
- data/lib/react/component/dsl_instance_methods.rb +0 -23
- data/lib/react/component/params.rb +0 -6
- data/lib/react/component/props_wrapper.rb +0 -90
- data/lib/react/component/should_component_update.rb +0 -99
- data/lib/react/component/tags.rb +0 -116
- data/lib/react/config.rb +0 -5
- data/lib/react/element.rb +0 -167
- data/lib/react/event.rb +0 -76
- data/lib/react/native_library.rb +0 -87
- data/lib/react/object.rb +0 -15
- data/lib/react/ref_callback.rb +0 -31
- data/lib/react/rendering_context.rb +0 -149
- data/lib/react/server.rb +0 -19
- data/lib/react/state_wrapper.rb +0 -23
- data/lib/react/test.rb +0 -16
- data/lib/react/test/dsl.rb +0 -17
- data/lib/react/test/matchers/render_html_matcher.rb +0 -56
- data/lib/react/test/rspec.rb +0 -15
- data/lib/react/test/session.rb +0 -37
- data/lib/react/test/utils.rb +0 -71
- data/lib/react/top_level.rb +0 -110
- data/lib/react/top_level_render.rb +0 -30
- data/lib/react/validator.rb +0 -132
- data/lib/reactive-ruby/component_loader.rb +0 -43
- data/lib/reactive-ruby/isomorphic_helpers.rb +0 -233
- data/lib/reactive-ruby/rails.rb +0 -8
- data/lib/reactive-ruby/rails/component_mount.rb +0 -48
- data/lib/reactive-ruby/rails/railtie.rb +0 -20
- data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +0 -46
- data/lib/reactive-ruby/server_rendering/hyper_asset_container.rb +0 -46
- data/lib/reactive-ruby/version.rb +0 -5
- data/lib/reactrb/auto-import.rb +0 -27
- data/misc/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +0 -3
- data/misc/generators/reactive_ruby/test_app/templates/assets/javascripts/server_rendering.js +0 -5
- data/misc/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb +0 -2
- data/misc/generators/reactive_ruby/test_app/templates/boot.rb.erb +0 -6
- data/misc/generators/reactive_ruby/test_app/templates/script/rails +0 -5
- data/misc/generators/reactive_ruby/test_app/templates/test_application.rb.erb +0 -13
- data/misc/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +0 -11
- data/misc/generators/reactive_ruby/test_app/templates/views/components/todo.rb +0 -14
- data/misc/generators/reactive_ruby/test_app/templates/views/layouts/test_layout.html.erb +0 -0
- data/misc/generators/reactive_ruby/test_app/test_app_generator.rb +0 -121
- data/misc/hyperloop-logo-small-pink.png +0 -0
- data/misc/logo1.png +0 -0
- data/misc/logo2.png +0 -0
- data/misc/logo3.png +0 -0
- data/path_release_steps.md +0 -9
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'hyperstack/ext/component/string'
|
|
2
|
+
# see hyperstack/component/haml for this is to be included.
|
|
3
|
+
module Hyperstack
|
|
4
|
+
module Internal
|
|
5
|
+
module Component
|
|
6
|
+
module HAMLTagInstanceMethods
|
|
7
|
+
def self.included(base)
|
|
8
|
+
base.const_get('HTML_TAGS').each do |tag|
|
|
9
|
+
if tag == 'p'
|
|
10
|
+
base.define_method(tag) do |*params, &children|
|
|
11
|
+
if children || params.count == 0 || (params.count == 1 && params.first.is_a?(Hash))
|
|
12
|
+
RenderingContext.render(tag, *params, &children)
|
|
13
|
+
else
|
|
14
|
+
Kernel.p(*params)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
base.alias_method tag, tag.upcase
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module HAMLElementInstanceMethods
|
|
25
|
+
def method_missing(class_name, args = {}, &new_block)
|
|
26
|
+
return dup.render.method_missing(class_name, args, &new_block) unless rendered?
|
|
27
|
+
Hyperstack::Internal::Component::RenderingContext.replace(
|
|
28
|
+
self,
|
|
29
|
+
Hyperstack::Internal::Component::RenderingContext.build do
|
|
30
|
+
Hyperstack::Internal::Component::RenderingContext.render(type, build_new_properties(class_name, args), &new_block)
|
|
31
|
+
end
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def rendered?
|
|
36
|
+
Hyperstack::Internal::Component::RenderingContext.rendered? self
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def haml_class_name(class_name)
|
|
40
|
+
class_name.gsub(/__|_/, '__' => '_', '_' => '-')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def build_new_properties(class_name, args)
|
|
46
|
+
class_name = haml_class_name(class_name)
|
|
47
|
+
new_props = @properties.dup
|
|
48
|
+
new_props[:className] = "\
|
|
49
|
+
#{class_name} #{new_props[:className]} #{args.delete(:class)} #{args.delete(:className)}\
|
|
50
|
+
".split(' ').uniq.join(' ')
|
|
51
|
+
new_props.merge! args
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require "hyperstack/component/children"
|
|
2
|
+
|
|
3
|
+
module Hyperstack
|
|
4
|
+
module Internal
|
|
5
|
+
module Component
|
|
6
|
+
module InstanceMethods
|
|
7
|
+
def children
|
|
8
|
+
Hyperstack::Component::Children.new(`#{@__hyperstack_component_native}.props.children`)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def params
|
|
12
|
+
if @__hyperstack_component_params_wrapper.param_accessor_style == :hyperstack
|
|
13
|
+
raise "params are now directly accessible via instance variables.\n"\
|
|
14
|
+
' to access the legacy behavior add `param_accessor_style = :legacy` '\
|
|
15
|
+
"to your component class\n"\
|
|
16
|
+
' to access both behaviors add `param_accessor_style = :both` '\
|
|
17
|
+
'to your component class'
|
|
18
|
+
end
|
|
19
|
+
@__hyperstack_component_params_wrapper
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def props
|
|
23
|
+
Hash.new(`#{@__hyperstack_component_native}.props`)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def refs
|
|
27
|
+
Hash.new(`#{@__hyperstack_component_native}.refs`)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def dom_node
|
|
31
|
+
`ReactDOM.findDOMNode(#{self}.__hyperstack_component_native)` # react >= v0.15.0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def mounted?
|
|
35
|
+
`(#{self}.__hyperstack_component_is_mounted === undefined) ? false : #{self}.__hyperstack_component_is_mounted`
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def force_update!
|
|
39
|
+
`#{self}.__hyperstack_component_native.forceUpdate()`
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def set_state(state, &block)
|
|
44
|
+
set_or_replace_state_or_prop(state, 'setState', &block)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def set_state!(state, &block)
|
|
48
|
+
set_or_replace_state_or_prop(state, 'setState', &block)
|
|
49
|
+
`#{self}.__hyperstack_component_native.forceUpdate()`
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def set_or_replace_state_or_prop(state_or_prop, method, &block)
|
|
55
|
+
raise "No native ReactComponent associated" unless @__hyperstack_component_native
|
|
56
|
+
`var state_prop_n = #{state_or_prop.shallow_to_n}`
|
|
57
|
+
# the state object is initalized when the ruby component is instantiated
|
|
58
|
+
# this is detected by self.__hyperstack_component_native.__opalInstanceInitializedState
|
|
59
|
+
# which is set in the native component constructor in ReactWrapper
|
|
60
|
+
# the setState update callback is not called when initalizing initial state
|
|
61
|
+
if block
|
|
62
|
+
%x{
|
|
63
|
+
if (#{@__hyperstack_component_native}.__opalInstanceInitializedState === true) {
|
|
64
|
+
#{@__hyperstack_component_native}[method](state_prop_n, function(){
|
|
65
|
+
block.$call();
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
for (var sp in state_prop_n) {
|
|
69
|
+
if (state_prop_n.hasOwnProperty(sp)) {
|
|
70
|
+
#{@__hyperstack_component_native}.state[sp] = state_prop_n[sp];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
%x{
|
|
77
|
+
if (#{@__hyperstack_component_native}.__opalInstanceInitializedState === true) {
|
|
78
|
+
#{@__hyperstack_component_native}[method](state_prop_n);
|
|
79
|
+
} else {
|
|
80
|
+
for (var sp in state_prop_n) {
|
|
81
|
+
if (state_prop_n.hasOwnProperty(sp)) {
|
|
82
|
+
#{@__hyperstack_component_native}.state[sp] = state_prop_n[sp];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require 'active_support/core_ext/string'
|
|
2
|
+
module Hyperstack
|
|
3
|
+
module Internal
|
|
4
|
+
module Component
|
|
5
|
+
class PropsWrapper
|
|
6
|
+
attr_reader :component
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def instance_var_name_for(name)
|
|
10
|
+
case Hyperstack.naming_convention
|
|
11
|
+
when :camelize_params
|
|
12
|
+
name.camelize
|
|
13
|
+
when :prefix_params
|
|
14
|
+
"_#{name}"
|
|
15
|
+
else
|
|
16
|
+
name
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def param_accessor_style(style = nil)
|
|
21
|
+
@param_accessor_style = style if style
|
|
22
|
+
@param_accessor_style ||=
|
|
23
|
+
if superclass.respond_to? :param_accessor_style
|
|
24
|
+
superclass.param_accessor_style
|
|
25
|
+
else
|
|
26
|
+
:hyperstack
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def param_definitions
|
|
31
|
+
@param_definitions ||=
|
|
32
|
+
if superclass.respond_to? :param_definitions
|
|
33
|
+
superclass.param_definitions.dup
|
|
34
|
+
else
|
|
35
|
+
Hash.new
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def define_param(name, param_type, aka = nil)
|
|
40
|
+
meth_name = aka || name
|
|
41
|
+
var_name = aka || instance_var_name_for(name)
|
|
42
|
+
param_definitions[name] = lambda do |props|
|
|
43
|
+
@component.instance_variable_set :"@#{var_name}", fetch_from_cache(name, param_type, props)
|
|
44
|
+
end
|
|
45
|
+
if param_type == Proc
|
|
46
|
+
define_method(meth_name.to_sym) do |*args, &block|
|
|
47
|
+
props[name].call(*args, &block) if props[name]
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
define_method(meth_name.to_sym) do
|
|
51
|
+
fetch_from_cache(name, param_type, props)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def define_all_others(name)
|
|
57
|
+
var_name = instance_var_name_for(name)
|
|
58
|
+
param_definitions[name] = lambda do |props|
|
|
59
|
+
@component.instance_variable_set :"@#{var_name}", yield(props)
|
|
60
|
+
end
|
|
61
|
+
define_method(name.to_sym) do
|
|
62
|
+
@_all_others_cache ||= yield(props)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def param_accessor_style
|
|
68
|
+
self.class.param_accessor_style
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def initialize(component, incoming = nil)
|
|
72
|
+
@component = component
|
|
73
|
+
return if param_accessor_style == :legacy
|
|
74
|
+
self.class.param_definitions.each_value do |initializer|
|
|
75
|
+
instance_exec(incoming || props, &initializer)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def reload(next_props)
|
|
80
|
+
@_all_others_cache = nil # needed for legacy params wrapper
|
|
81
|
+
initialize(@component, next_props)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def [](prop)
|
|
85
|
+
props[prop]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def fetch_from_cache(name, param_type, props)
|
|
91
|
+
last, cached_value = cache[name]
|
|
92
|
+
return cached_value if last.equal?(props[name])
|
|
93
|
+
convert_param(name, param_type, props).tap do |value|
|
|
94
|
+
cache[name] = [props[name], value]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def convert_param(name, param_type, props)
|
|
99
|
+
if param_type.respond_to? :_react_param_conversion
|
|
100
|
+
param_type._react_param_conversion props[name], nil
|
|
101
|
+
elsif param_type.is_a?(Array) &&
|
|
102
|
+
param_type[0].respond_to?(:_react_param_conversion)
|
|
103
|
+
props[name].collect do |param|
|
|
104
|
+
param_type[0]._react_param_conversion param, nil
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
props[name]
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def cache
|
|
112
|
+
@cache ||= Hash.new { |h, k| h[k] = [] }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def props
|
|
116
|
+
component.props
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def value_for(name)
|
|
120
|
+
self[name].instance_variable_get('@value') if self[name]
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
if defined?(Rails)
|
|
2
|
+
require 'action_view'
|
|
3
|
+
require 'react-rails'
|
|
4
|
+
require 'hyperstack/internal/component/rails'
|
|
5
|
+
require 'hyperstack/internal/component/rails/server_rendering/hyper_asset_container'
|
|
6
|
+
require 'hyperstack/internal/component/rails/server_rendering/contextual_renderer'
|
|
7
|
+
require 'hyperstack/internal/component/rails/component_mount'
|
|
8
|
+
require 'hyperstack/internal/component/rails/railtie'
|
|
9
|
+
require 'hyperstack/internal/component/rails/controller_helper'
|
|
10
|
+
require 'hyperstack/internal/component/rails/component_loader'
|
|
11
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Hyperstack
|
|
2
|
+
module Internal
|
|
3
|
+
module Component
|
|
4
|
+
module Rails
|
|
5
|
+
class ComponentLoader
|
|
6
|
+
attr_reader :v8_context
|
|
7
|
+
private :v8_context
|
|
8
|
+
|
|
9
|
+
def initialize(v8_context)
|
|
10
|
+
unless v8_context
|
|
11
|
+
raise ArgumentError.new('Could not obtain ExecJS runtime context')
|
|
12
|
+
end
|
|
13
|
+
@v8_context = v8_context
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def load(file = components)
|
|
17
|
+
return true if loaded?
|
|
18
|
+
!!v8_context.eval(opal(file))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load!(file = components)
|
|
22
|
+
return true if loaded?
|
|
23
|
+
self.load(file)
|
|
24
|
+
ensure
|
|
25
|
+
raise "No Hyperstack components found in #{components}" unless loaded?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def loaded?
|
|
29
|
+
!!v8_context.eval('Opal.Hyperstack !== undefined')
|
|
30
|
+
rescue ::ExecJS::Error
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def components
|
|
37
|
+
opts = ::Rails.configuration.react.server_renderer_options
|
|
38
|
+
return opts[:files].first.gsub(/.js$/,'') if opts && opts[:files]
|
|
39
|
+
'components'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def opal(file)
|
|
43
|
+
Opal::Sprockets.load_asset(file)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Hyperstack
|
|
2
|
+
module Internal
|
|
3
|
+
module Component
|
|
4
|
+
module Rails
|
|
5
|
+
class ComponentMount < React::Rails::ComponentMount
|
|
6
|
+
attr_accessor :controller
|
|
7
|
+
|
|
8
|
+
def setup(controller)
|
|
9
|
+
self.controller = controller
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def react_component(name, props = {}, options = {}, &block)
|
|
13
|
+
if options[:prerender] || [:on, 'on', true].include?(Hyperstack.prerendering)
|
|
14
|
+
options = context_initializer_options(options, name)
|
|
15
|
+
end
|
|
16
|
+
props = serialized_props(props, name, controller)
|
|
17
|
+
result = super(top_level_name, props, options, &block).gsub("\n","")
|
|
18
|
+
result = result.gsub(/(<script.*<\/script>)<\/div>$/,'</div>\1').html_safe
|
|
19
|
+
result + footers
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def context_initializer_options(options, name)
|
|
25
|
+
options[:prerender] = {options[:prerender] => true} unless options[:prerender].is_a? Hash
|
|
26
|
+
existing_context_initializer = options[:prerender][:context_initializer]
|
|
27
|
+
|
|
28
|
+
options[:prerender][:context_initializer] = lambda do |ctx|
|
|
29
|
+
Hyperstack::Component::IsomorphicHelpers.load_context(ctx, controller, name)
|
|
30
|
+
existing_context_initializer.call(ctx) if existing_context_initializer
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
options
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def serialized_props(props, name, controller)
|
|
37
|
+
{ render_params: props, component_name: name,
|
|
38
|
+
controller: controller.class.name.gsub(/Controller$/,"") }.react_serializer
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def top_level_name
|
|
42
|
+
'Hyperstack.Internal.Component.TopLevelRailsComponent'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def footers
|
|
46
|
+
Hyperstack::Component::IsomorphicHelpers.prerender_footers(controller)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Hyperstack
|
|
2
|
+
module Internal
|
|
3
|
+
module Component
|
|
4
|
+
module Rails
|
|
5
|
+
class Railtie < ::Rails::Railtie
|
|
6
|
+
config.before_configuration do |app|
|
|
7
|
+
app.config.assets.enabled = true
|
|
8
|
+
app.config.assets.paths << ::Rails.root.join('app', 'views').to_s
|
|
9
|
+
app.config.react.server_renderer = ServerRendering::ContextualRenderer
|
|
10
|
+
app.config.react.view_helper_implementation = ComponentMount
|
|
11
|
+
ServerRendering::ContextualRenderer.asset_container_class = ServerRendering::HyperAssetContainer
|
|
12
|
+
end
|
|
13
|
+
config.after_initialize do
|
|
14
|
+
class ::HyperstackController < ::ApplicationController
|
|
15
|
+
def action_missing(_name)
|
|
16
|
+
render_component
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Hyperstack
|
|
2
|
+
module Internal
|
|
3
|
+
module Component
|
|
4
|
+
module Rails
|
|
5
|
+
module ServerRendering
|
|
6
|
+
def self.context_instance_name
|
|
7
|
+
'@context'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.context_instance_for(context)
|
|
11
|
+
context.instance_variable_get(context_instance_name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class ContextualRenderer < React::ServerRendering::BundleRenderer
|
|
15
|
+
def initialize(options = {})
|
|
16
|
+
super(options)
|
|
17
|
+
ComponentLoader.new(v8_context).load
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def before_render(*args)
|
|
21
|
+
# the base class clears the log history... we don't want that as it is taken
|
|
22
|
+
# care of in IsomorphicHelpers.load_context
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def render(component_name, props, prerender_options)
|
|
26
|
+
if prerender_options.is_a?(Hash)
|
|
27
|
+
if !v8_runtime? && prerender_options[:context_initializer]
|
|
28
|
+
raise React::ServerRendering::PrerenderError.new(component_name, props, "you must use 'mini_racer' with the prerender[:context] option") unless v8_runtime?
|
|
29
|
+
else
|
|
30
|
+
prerender_options[:context_initializer].call v8_context
|
|
31
|
+
prerender_options = prerender_options[:static] ? :static : true
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
super(component_name, props, prerender_options)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def v8_runtime?
|
|
41
|
+
ExecJS.runtime.name == 'mini_racer (V8)'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def v8_context
|
|
45
|
+
@v8_context ||= ServerRendering.context_instance_for(@context)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|