reactive-ruby 0.7.30 → 0.7.31
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -10
- data/lib/generators/reactive_ruby/test_app/templates/application.rb.erb +15 -0
- data/lib/generators/reactive_ruby/test_app/templates/{boot.rb → boot.rb.erb} +0 -0
- data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +2 -2
- data/lib/rails-helpers/top_level_rails_component.rb +3 -3
- data/lib/react/component.rb +3 -3
- data/lib/react/component/class_methods.rb +12 -12
- data/lib/react/rendering_context.rb +9 -9
- data/lib/react/state.rb +3 -3
- data/lib/reactive-ruby/isomorphic_helpers.rb +2 -2
- data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +1 -1
- data/lib/reactive-ruby/version.rb +1 -1
- metadata +4 -4
- data/lib/generators/reactive_ruby/test_app/templates/application.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03ea6c95ebe59edebe184cba6f058d429f6e9f03
|
4
|
+
data.tar.gz: f68ee94ee71d55e877a19f253f012da2cba98fa1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51dffbcc520e2969b83f04c4820af42c100f7d3b6f340a5468e0dc847330a4f5fe4fdfa54722a0bb7a266de19bc827e6d3ed23cc66b27f1a2f6910ce32be66dd
|
7
|
+
data.tar.gz: 29ee24cee796f6ada843fbac91dd089a5d421d44be2318ba1dd5b1d600fa8c3b4e48ef4f8bd5a4d21cf3ee616c584cc77d87659f17a741083f7bc66705e14a50
|
data/README.md
CHANGED
@@ -102,8 +102,9 @@ require 'opal-jquery' # They must be in this order.
|
|
102
102
|
### Rendering Components
|
103
103
|
|
104
104
|
Components may be rendered directly from a controller action by simply following
|
105
|
-
a naming convention. To render a component from the `home#show` action, create
|
106
|
-
component class `
|
105
|
+
a naming convention. To render a component from the `home#show` action, create a
|
106
|
+
component class named `Show`. For details on how to override this behavior, and how the the module tree is searched for
|
107
|
+
the class see the next section.
|
107
108
|
|
108
109
|
```ruby
|
109
110
|
# app/views/components/home/show.rb
|
@@ -151,18 +152,23 @@ and you can set break points etc.
|
|
151
152
|
|
152
153
|
You can control the top level component name and search path.
|
153
154
|
|
154
|
-
|
155
|
+
By default the component class name is inferred from the controller method rendering the component.
|
156
|
+
You can also specify the component name explicitly in the `render_component` method.
|
155
157
|
`render_component "Blatz` will search the for a component class named `Blatz`
|
156
|
-
regardless of the controller method.
|
158
|
+
regardless of the name of the controller method.
|
157
159
|
|
158
|
-
Searching for components
|
159
|
-
"Foo" then
|
160
|
-
|
161
|
-
|
162
|
-
|
160
|
+
Searching for components works like this: Given a controller named
|
161
|
+
"Foo" then react.rb will search for a module named `Foo` containing the component.
|
162
|
+
If this fails all modules will be searched (i.e. the name of the controller will be
|
163
|
+
ignored.) In either case the search begins at the outer most scope until a match is made.
|
164
|
+
|
165
|
+
Thus for example given a controller named `Foo`, components could be found in the `Foo` module,
|
166
|
+
the `Components::Foo` module, in the outer most scope, or in any nested module.
|
167
|
+
The way the search works allows for small projects that do not need a lot
|
168
|
+
of name spacing, and also allows components to be shared across several controllers.
|
163
169
|
|
164
170
|
Saying `render_component "::Blatz"` will only search the outer scope, while
|
165
|
-
`"::
|
171
|
+
`"::Bar::Blatz"` will look only in the module `Bar` for a class named `Blatz`.
|
166
172
|
|
167
173
|
|
168
174
|
## Integration with Sinatra
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<% if defined? application_definition %>
|
2
|
+
|
3
|
+
require File.expand_path('../boot', __FILE__)
|
4
|
+
|
5
|
+
require 'rails/all'
|
6
|
+
|
7
|
+
# Require the gems listed in Gemfile, including any gems
|
8
|
+
# you've limited to :test, :development, or :production.
|
9
|
+
Bundler.require(*Rails.groups(assets: %w(development test)))
|
10
|
+
|
11
|
+
require 'reactive-ruby'
|
12
|
+
|
13
|
+
<%= application_definition %>
|
14
|
+
|
15
|
+
<% end %>
|
File without changes
|
@@ -24,8 +24,8 @@ module ReactiveRuby
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def configure_test_app
|
27
|
-
template 'boot.rb', "#{test_app_path}/config/boot.rb", force: true
|
28
|
-
template 'application.rb', "#{test_app_path}/config/application.rb", force: true
|
27
|
+
template 'boot.rb.erb', "#{test_app_path}/config/boot.rb", force: true
|
28
|
+
template 'application.rb.erb', "#{test_app_path}/config/application.rb", force: true
|
29
29
|
template 'assets/javascripts/application.rb',
|
30
30
|
"#{test_app_path}/app/assets/javascripts/application.rb", force: true
|
31
31
|
template 'assets/javascripts/components.rb',
|
@@ -19,19 +19,19 @@ module React
|
|
19
19
|
if component_name.start_with? "::"
|
20
20
|
paths_searched << component_name.gsub(/^\:\:/,"")
|
21
21
|
component = component_name.gsub(/^\:\:/,"").split("::").inject(Module) { |scope, next_const| scope.const_get(next_const, false) } rescue nil
|
22
|
-
return present component, render_params if component
|
22
|
+
return present component, render_params if component && component.method_defined?(:render)
|
23
23
|
else
|
24
24
|
self.class.search_path.each do |path|
|
25
25
|
# try each path + controller + component_name
|
26
26
|
paths_searched << "#{path.name + '::' unless path == Module}#{controller}::#{component_name}"
|
27
27
|
component = "#{controller}::#{component_name}".split("::").inject(path) { |scope, next_const| scope.const_get(next_const, false) } rescue nil
|
28
|
-
return present component, render_params if component
|
28
|
+
return present component, render_params if component && component.method_defined?(:render)
|
29
29
|
end
|
30
30
|
self.class.search_path.each do |path|
|
31
31
|
# then try each path + component_name
|
32
32
|
paths_searched << "#{path.name + '::' unless path == Module}#{component_name}"
|
33
33
|
component = "#{component_name}".split("::").inject(path) { |scope, next_const| scope.const_get(next_const, false) } rescue nil
|
34
|
-
return present component, render_params if component
|
34
|
+
return present component, render_params if component && component.method_defined?(:render)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
raise "Could not find component class '#{component_name}' for controller '#{controller}' in any component directory. Tried [#{paths_searched.join(", ")}]"
|
data/lib/react/component.rb
CHANGED
@@ -25,7 +25,7 @@ module React
|
|
25
25
|
|
26
26
|
def render
|
27
27
|
raise "no render defined"
|
28
|
-
end unless method_defined?
|
28
|
+
end unless method_defined?(:render)
|
29
29
|
|
30
30
|
def children
|
31
31
|
nodes = [`#{@native}.props.children`].flatten
|
@@ -78,7 +78,7 @@ module React
|
|
78
78
|
rescue Exception
|
79
79
|
name = nil
|
80
80
|
end
|
81
|
-
unless name
|
81
|
+
unless name && name.method_defined?(:render)
|
82
82
|
return super
|
83
83
|
end
|
84
84
|
if node_only
|
@@ -214,7 +214,7 @@ module React
|
|
214
214
|
component = name_list.inject(scope) do |scope, class_name|
|
215
215
|
scope.const_get(class_name)
|
216
216
|
end rescue nil
|
217
|
-
return component if component
|
217
|
+
return component if component && component.method_defined?(:render)
|
218
218
|
end
|
219
219
|
nil
|
220
220
|
end
|
@@ -7,7 +7,7 @@ module React
|
|
7
7
|
|
8
8
|
def process_exception(e, component, reraise = nil)
|
9
9
|
message = ["Exception raised while rendering #{component}"]
|
10
|
-
if e.backtrace
|
10
|
+
if e.backtrace && e.backtrace.length > 1 && !@backtrace_off # seems like e.backtrace is empty in safari???
|
11
11
|
message << " #{e.backtrace[0]}"
|
12
12
|
message += e.backtrace[1..-1].collect { |line| line }
|
13
13
|
else
|
@@ -72,7 +72,7 @@ module React
|
|
72
72
|
define_method("#{name}") do
|
73
73
|
@processed_params[name] ||= if param_type.respond_to? :_react_param_conversion
|
74
74
|
param_type._react_param_conversion params[name]
|
75
|
-
elsif param_type.is_a?
|
75
|
+
elsif param_type.is_a?(Array) && param_type[0].respond_to?(:_react_param_conversion)
|
76
76
|
params[name].collect { |param| param_type[0]._react_param_conversion param }
|
77
77
|
else
|
78
78
|
params[name]
|
@@ -101,8 +101,8 @@ module React
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def define_state(*states, &block)
|
104
|
-
default_initial_value = (block
|
105
|
-
states_hash = (states.last.is_a?
|
104
|
+
default_initial_value = (block && block.arity == 0) ? yield : nil
|
105
|
+
states_hash = (states.last.is_a?(Hash)) ? states.pop : {}
|
106
106
|
states.each { |name| states_hash[name] = default_initial_value }
|
107
107
|
(self.initial_state ||= {}).merge! states_hash
|
108
108
|
states_hash.each do |name, initial_value|
|
@@ -111,8 +111,8 @@ module React
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def export_state(*states, &block)
|
114
|
-
default_initial_value = (block
|
115
|
-
states_hash = (states.last.is_a?
|
114
|
+
default_initial_value = (block && block.arity == 0) ? yield : nil
|
115
|
+
states_hash = (states.last.is_a?(Hash)) ? states.pop : {}
|
116
116
|
states.each { |name| states_hash[name] = default_initial_value }
|
117
117
|
React::State.initialize_states(self, states_hash)
|
118
118
|
states_hash.each do |name, initial_value|
|
@@ -126,22 +126,22 @@ module React
|
|
126
126
|
React::State.get_state(from || self, name)
|
127
127
|
end
|
128
128
|
this.define_method("#{name}=") do |new_state|
|
129
|
-
yield name, React::State.get_state(from || self, name), new_state if block
|
129
|
+
yield name, React::State.get_state(from || self, name), new_state if block && block.arity > 0
|
130
130
|
React::State.set_state(from || self, name, new_state)
|
131
131
|
end
|
132
132
|
this.define_method("#{name}!") do |*args|
|
133
133
|
#return unless @native
|
134
134
|
if args.count > 0
|
135
|
-
yield name, React::State.get_state(from || self, name), args[0] if block
|
135
|
+
yield name, React::State.get_state(from || self, name), args[0] if block && block.arity > 0
|
136
136
|
current_value = React::State.get_state(from || self, name)
|
137
137
|
React::State.set_state(from || self, name, args[0])
|
138
138
|
current_value
|
139
139
|
else
|
140
140
|
current_state = React::State.get_state(from || self, name)
|
141
|
-
yield name, React::State.get_state(from || self, name), current_state if block
|
141
|
+
yield name, React::State.get_state(from || self, name), current_state if block && block.arity > 0
|
142
142
|
React::State.set_state(from || self, name, current_state)
|
143
143
|
React::Observable.new(current_state) do |update|
|
144
|
-
yield name, React::State.get_state(from || self, name), update if block
|
144
|
+
yield name, React::State.get_state(from || self, name), update if block && block.arity > 0
|
145
145
|
React::State.set_state(from || self, name, update)
|
146
146
|
end
|
147
147
|
end
|
@@ -171,8 +171,8 @@ module React
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def add_item_to_tree(current_tree, new_item)
|
174
|
-
if Native(current_tree).class != Native::Object
|
175
|
-
new_item.inject
|
174
|
+
if Native(current_tree).class != Native::Object || new_item.length == 1
|
175
|
+
new_item.inject { |memo, sub_name| { sub_name => memo } }
|
176
176
|
else
|
177
177
|
Native(current_tree)[new_item.last] = add_item_to_tree(Native(current_tree)[new_item.last], new_item[0..-2])
|
178
178
|
current_tree
|
@@ -14,20 +14,20 @@ module React
|
|
14
14
|
result = block.call
|
15
15
|
# Todo figure out how children rendering should happen, probably should have special method that pushes children into the buffer
|
16
16
|
# i.e. render_child/render_children that takes Element/Array[Element] and does the push into the buffer
|
17
|
-
if !name
|
18
|
-
(@buffer.count > 1)
|
19
|
-
(@buffer.count == 1
|
20
|
-
(@buffer.count == 0
|
17
|
+
if !name && ( # !name means called from outer render so we check that it has rendered correctly
|
18
|
+
(@buffer.count > 1) || # should only render one element
|
19
|
+
(@buffer.count == 1 && @buffer.last != result) || # it should return that element
|
20
|
+
(@buffer.count == 0 && !(result.is_a?(String) || (result.respond_to?(:acts_as_string?) && result.acts_as_string?) || result.is_a?(Element))) #for convience we will also convert the return value to a span if its a string
|
21
21
|
)
|
22
22
|
raise "a components render method must generate and return exactly 1 element or a string"
|
23
23
|
end
|
24
24
|
|
25
|
-
@buffer << result.to_s if result.is_a? String
|
26
|
-
@buffer << result if result.is_a?
|
25
|
+
@buffer << result.to_s if result.is_a? String || (result.respond_to?(:acts_as_string?) && result.acts_as_string?) # For convience we push the last return value on if its a string
|
26
|
+
@buffer << result if result.is_a?(Element) && @buffer.count == 0
|
27
27
|
if name
|
28
28
|
buffer = @buffer.dup
|
29
29
|
React.create_element(name, *args) { buffer }.tap do |element|
|
30
|
-
element.waiting_on_resources = saved_waiting_on_resources || !!buffer.detect { |e| e.waiting_on_resources if e.respond_to?
|
30
|
+
element.waiting_on_resources = saved_waiting_on_resources || !!buffer.detect { |e| e.waiting_on_resources if e.respond_to?(:waiting_on_resources) }
|
31
31
|
end
|
32
32
|
elsif @buffer.last.is_a? React::Element
|
33
33
|
@buffer.last.tap { |element| element.waiting_on_resources ||= saved_waiting_on_resources }
|
@@ -71,8 +71,8 @@ module React
|
|
71
71
|
|
72
72
|
def self.remove_nodes_from_args(args)
|
73
73
|
args[0].each do |key, value|
|
74
|
-
value.as_node if value.is_a?
|
75
|
-
end if args[0]
|
74
|
+
value.as_node if value.is_a?(Element) rescue nil
|
75
|
+
end if args[0] && args[0].is_a?(Hash)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
data/lib/react/state.rb
CHANGED
@@ -9,7 +9,7 @@ module React
|
|
9
9
|
|
10
10
|
def get_state(object, name, current_observer = @current_observer)
|
11
11
|
# get current value of name for object, remember that the current object depends on this state, current observer can be overriden with last param
|
12
|
-
new_observers[current_observer][object] << name if current_observer
|
12
|
+
new_observers[current_observer][object] << name if current_observer && !new_observers[current_observer][object].include?(name)
|
13
13
|
states[object][name]
|
14
14
|
end
|
15
15
|
|
@@ -42,11 +42,11 @@ module React
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def will_be_observing?(object, name, current_observer)
|
45
|
-
current_observer
|
45
|
+
current_observer && new_observers[current_observer][object].include?(name)
|
46
46
|
end
|
47
47
|
|
48
48
|
def is_observing?(object, name, current_observer)
|
49
|
-
current_observer
|
49
|
+
current_observer && observers_by_name[object][name].include?(current_observer)
|
50
50
|
end
|
51
51
|
|
52
52
|
def update_states_to_observe(current_observer = @current_observer) # should be called after the last after_render callback, currently called after components render method
|
@@ -12,7 +12,7 @@ module React
|
|
12
12
|
else
|
13
13
|
def self.load_context(unique_id = nil, name = nil)
|
14
14
|
# can be called on the client to force re-initialization for testing purposes
|
15
|
-
if !unique_id
|
15
|
+
if !unique_id || !@context || @context.unique_id != unique_id
|
16
16
|
if on_opal_server?
|
17
17
|
message = "************************ React Prerendering Context Initialized #{name} ***********************"
|
18
18
|
else
|
@@ -147,7 +147,7 @@ module React
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def when_on_server(&block)
|
150
|
-
@result = [block.call.to_json] unless IsomorphicHelpers.on_opal_client?
|
150
|
+
@result = [block.call.to_json] unless IsomorphicHelpers.on_opal_client? || IsomorphicHelpers.on_opal_server?
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
@@ -8,7 +8,7 @@ module ReactiveRuby
|
|
8
8
|
|
9
9
|
def render(component_name, props, prerender_options)
|
10
10
|
if prerender_options.is_a? Hash
|
11
|
-
if v8_runtime?
|
11
|
+
if v8_runtime? && prerender_options[:context_initializer]
|
12
12
|
raise React::ServerRendering::PrerenderError.new(component_name, props, "you must use 'therubyracer' with the prerender[:context] option") unless v8_runtime?
|
13
13
|
else
|
14
14
|
prerender_options[:context_initializer].call v8_context
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reactive-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.31
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opal
|
@@ -249,10 +249,10 @@ files:
|
|
249
249
|
- example/todos/vendor/base.css
|
250
250
|
- example/todos/vendor/bg.png
|
251
251
|
- example/todos/vendor/jquery.js
|
252
|
-
- lib/generators/reactive_ruby/test_app/templates/application.rb
|
252
|
+
- lib/generators/reactive_ruby/test_app/templates/application.rb.erb
|
253
253
|
- lib/generators/reactive_ruby/test_app/templates/assets/javascripts/application.rb
|
254
254
|
- lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb
|
255
|
-
- lib/generators/reactive_ruby/test_app/templates/boot.rb
|
255
|
+
- lib/generators/reactive_ruby/test_app/templates/boot.rb.erb
|
256
256
|
- lib/generators/reactive_ruby/test_app/templates/script/rails
|
257
257
|
- lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb
|
258
258
|
- lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require File.expand_path('../boot', __FILE__)
|
2
|
-
|
3
|
-
require 'rails/all'
|
4
|
-
|
5
|
-
# Require the gems listed in Gemfile, including any gems
|
6
|
-
# you've limited to :test, :development, or :production.
|
7
|
-
Bundler.require(*Rails.groups(assets: %w(development test)))
|
8
|
-
|
9
|
-
require 'reactive-ruby'
|
10
|
-
|
11
|
-
<%= application_definition %>
|