reactrb 0.7.42
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +6 -0
- data/.gitignore +33 -0
- data/.travis.yml +9 -0
- data/Gemfile +2 -0
- data/LICENSE +19 -0
- data/README.md +117 -0
- data/Rakefile +28 -0
- data/config.ru +16 -0
- data/example/examples/Gemfile +7 -0
- data/example/examples/app/basics.js.rb +42 -0
- data/example/examples/app/items.rb +11 -0
- data/example/examples/app/jquery.js +5 -0
- data/example/examples/app/nodes.rb +61 -0
- data/example/examples/app/react-router.js +6 -0
- data/example/examples/app/react_api_demo.rb +29 -0
- data/example/examples/app/rerendering.rb +72 -0
- data/example/examples/app/reuse.rb +59 -0
- data/example/examples/app/show.rb +52 -0
- data/example/examples/config.ru +38 -0
- data/example/rails-tutorial/.gitignore +17 -0
- data/example/rails-tutorial/Gemfile +51 -0
- data/example/rails-tutorial/README.rdoc +28 -0
- data/example/rails-tutorial/Rakefile +6 -0
- data/example/rails-tutorial/app/assets/images/.keep +0 -0
- data/example/rails-tutorial/app/assets/javascripts/application.rb +15 -0
- data/example/rails-tutorial/app/assets/stylesheets/application.css +15 -0
- data/example/rails-tutorial/app/controllers/application_controller.rb +6 -0
- data/example/rails-tutorial/app/controllers/concerns/.keep +0 -0
- data/example/rails-tutorial/app/controllers/home_controller.rb +6 -0
- data/example/rails-tutorial/app/helpers/application_helper.rb +2 -0
- data/example/rails-tutorial/app/mailers/.keep +0 -0
- data/example/rails-tutorial/app/models/.keep +0 -0
- data/example/rails-tutorial/app/models/concerns/.keep +0 -0
- data/example/rails-tutorial/app/views/components.rb +3 -0
- data/example/rails-tutorial/app/views/components/home/show.rb +47 -0
- data/example/rails-tutorial/app/views/layouts/application.html.erb +14 -0
- data/example/rails-tutorial/bin/bundle +3 -0
- data/example/rails-tutorial/bin/rails +8 -0
- data/example/rails-tutorial/bin/rake +8 -0
- data/example/rails-tutorial/bin/setup +29 -0
- data/example/rails-tutorial/bin/spring +15 -0
- data/example/rails-tutorial/config.ru +4 -0
- data/example/rails-tutorial/config/application.rb +26 -0
- data/example/rails-tutorial/config/boot.rb +3 -0
- data/example/rails-tutorial/config/database.yml +25 -0
- data/example/rails-tutorial/config/environment.rb +5 -0
- data/example/rails-tutorial/config/environments/development.rb +41 -0
- data/example/rails-tutorial/config/environments/production.rb +79 -0
- data/example/rails-tutorial/config/environments/test.rb +42 -0
- data/example/rails-tutorial/config/initializers/assets.rb +11 -0
- data/example/rails-tutorial/config/initializers/backtrace_silencers.rb +7 -0
- data/example/rails-tutorial/config/initializers/cookies_serializer.rb +3 -0
- data/example/rails-tutorial/config/initializers/filter_parameter_logging.rb +4 -0
- data/example/rails-tutorial/config/initializers/inflections.rb +16 -0
- data/example/rails-tutorial/config/initializers/mime_types.rb +4 -0
- data/example/rails-tutorial/config/initializers/session_store.rb +3 -0
- data/example/rails-tutorial/config/initializers/wrap_parameters.rb +14 -0
- data/example/rails-tutorial/config/locales/en.yml +23 -0
- data/example/rails-tutorial/config/routes.rb +59 -0
- data/example/rails-tutorial/config/secrets.yml +22 -0
- data/example/rails-tutorial/db/seeds.rb +7 -0
- data/example/rails-tutorial/lib/assets/.keep +0 -0
- data/example/rails-tutorial/lib/tasks/.keep +0 -0
- data/example/rails-tutorial/log/.keep +0 -0
- data/example/rails-tutorial/public/404.html +67 -0
- data/example/rails-tutorial/public/422.html +67 -0
- data/example/rails-tutorial/public/500.html +66 -0
- data/example/rails-tutorial/public/favicon.ico +0 -0
- data/example/rails-tutorial/public/robots.txt +5 -0
- data/example/rails-tutorial/test/controllers/.keep +0 -0
- data/example/rails-tutorial/test/fixtures/.keep +0 -0
- data/example/rails-tutorial/test/helpers/.keep +0 -0
- data/example/rails-tutorial/test/integration/.keep +0 -0
- data/example/rails-tutorial/test/mailers/.keep +0 -0
- data/example/rails-tutorial/test/models/.keep +0 -0
- data/example/rails-tutorial/test/test_helper.rb +10 -0
- data/example/rails-tutorial/vendor/assets/javascripts/.keep +0 -0
- data/example/rails-tutorial/vendor/assets/stylesheets/.keep +0 -0
- data/example/sinatra-tutorial/.DS_Store +0 -0
- data/example/sinatra-tutorial/Gemfile +5 -0
- data/example/sinatra-tutorial/README.md +8 -0
- data/example/sinatra-tutorial/_comments.json +42 -0
- data/example/sinatra-tutorial/app/example.rb +290 -0
- data/example/sinatra-tutorial/app/jquery.js +5 -0
- data/example/sinatra-tutorial/config.ru +58 -0
- data/example/sinatra-tutorial/public/base.css +62 -0
- data/example/todos/Gemfile +11 -0
- data/example/todos/README.md +37 -0
- data/example/todos/Rakefile +8 -0
- data/example/todos/app/application.rb +22 -0
- data/example/todos/app/components/app.react.rb +61 -0
- data/example/todos/app/components/footer.react.rb +31 -0
- data/example/todos/app/components/todo_item.react.rb +46 -0
- data/example/todos/app/components/todo_list.react.rb +25 -0
- data/example/todos/app/models/todo.rb +19 -0
- data/example/todos/config.ru +14 -0
- data/example/todos/index.html.haml +16 -0
- data/example/todos/spec/todo_spec.rb +28 -0
- data/example/todos/vendor/base.css +410 -0
- data/example/todos/vendor/bg.png +0 -0
- data/example/todos/vendor/jquery.js +4 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +4 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb +2 -0
- data/lib/generators/reactive_ruby/test_app/templates/boot.rb.erb +6 -0
- data/lib/generators/reactive_ruby/test_app/templates/script/rails +5 -0
- data/lib/generators/reactive_ruby/test_app/templates/test_application.rb.erb +13 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +11 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb +14 -0
- data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +105 -0
- data/lib/rails-helpers/top_level_rails_component.rb +54 -0
- data/lib/react/api.rb +127 -0
- data/lib/react/callbacks.rb +42 -0
- data/lib/react/component.rb +269 -0
- data/lib/react/component/api.rb +50 -0
- data/lib/react/component/base.rb +9 -0
- data/lib/react/component/class_methods.rb +190 -0
- data/lib/react/component/props_wrapper.rb +82 -0
- data/lib/react/element.rb +77 -0
- data/lib/react/event.rb +76 -0
- data/lib/react/ext/hash.rb +9 -0
- data/lib/react/ext/string.rb +8 -0
- data/lib/react/native_library.rb +53 -0
- data/lib/react/observable.rb +29 -0
- data/lib/react/rendering_context.rb +109 -0
- data/lib/react/state.rb +140 -0
- data/lib/react/top_level.rb +97 -0
- data/lib/react/validator.rb +136 -0
- data/lib/reactive-ruby/component_loader.rb +45 -0
- data/lib/reactive-ruby/isomorphic_helpers.rb +196 -0
- data/lib/reactive-ruby/rails.rb +7 -0
- data/lib/reactive-ruby/rails/component_mount.rb +44 -0
- data/lib/reactive-ruby/rails/controller_helper.rb +13 -0
- data/lib/reactive-ruby/rails/railtie.rb +14 -0
- data/lib/reactive-ruby/serializers.rb +15 -0
- data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +42 -0
- data/lib/reactive-ruby/version.rb +3 -0
- data/lib/reactrb.rb +50 -0
- data/lib/sources/react-latest.js +21167 -0
- data/lib/sources/react-v13.js +21642 -0
- data/lib/sources/react-v14.js +20818 -0
- data/lib/sources/react-v15.js +21167 -0
- data/logo1.png +0 -0
- data/logo2.png +0 -0
- data/logo3.png +0 -0
- data/path_release_steps.md +9 -0
- data/reactrb.gemspec +43 -0
- data/spec/controller_helper_spec.rb +22 -0
- data/spec/index.html.erb +12 -0
- data/spec/react/callbacks_spec.rb +106 -0
- data/spec/react/component/base_spec.rb +36 -0
- data/spec/react/component_spec.rb +721 -0
- data/spec/react/dsl_spec.rb +161 -0
- data/spec/react/element_spec.rb +47 -0
- data/spec/react/event_spec.rb +24 -0
- data/spec/react/native_library_spec.rb +10 -0
- data/spec/react/observable_spec.rb +7 -0
- data/spec/react/param_declaration_spec.rb +286 -0
- data/spec/react/react_spec.rb +211 -0
- data/spec/react/state_spec.rb +26 -0
- data/spec/react/top_level_component_spec.rb +68 -0
- data/spec/react/tutorial/tutorial_spec.rb +35 -0
- data/spec/react/validator_spec.rb +128 -0
- data/spec/reactive-ruby/component_loader_spec.rb +68 -0
- data/spec/reactive-ruby/isomorphic_helpers_spec.rb +155 -0
- data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +9 -0
- data/spec/reactive-ruby/rails/component_mount_spec.rb +66 -0
- data/spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb +35 -0
- data/spec/spec_helper.rb +109 -0
- data/spec/support/react/spec_helpers.rb +57 -0
- data/spec/vendor/es5-shim.min.js +6 -0
- data/spec/vendor/jquery-2.2.4.min.js +4 -0
- metadata +441 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module API
|
4
|
+
def dom_node
|
5
|
+
if !(`typeof ReactDOM === 'undefined' || typeof ReactDOM.findDOMNode === 'undefined'`)
|
6
|
+
`ReactDOM.findDOMNode(#{self}.native)` # v0.14.0
|
7
|
+
elsif !(`typeof React.findDOMNode === 'undefined'`)
|
8
|
+
`React.findDOMNode(#{self}.native)` # v0.13.0
|
9
|
+
else
|
10
|
+
`#{self}.native.getDOMNode` # v0.12.0
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def mounted?
|
15
|
+
`#{self}.native.isMounted()`
|
16
|
+
end
|
17
|
+
|
18
|
+
def force_update!
|
19
|
+
`#{self}.native.forceUpdate()`
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_props(prop, &block)
|
23
|
+
set_or_replace_state_or_prop(prop, 'setProps', &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_props!(prop, &block)
|
27
|
+
set_or_replace_state_or_prop(prop, 'replaceProps', &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_state(state, &block)
|
31
|
+
set_or_replace_state_or_prop(state, 'setState', &block)
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_state!(state, &block)
|
35
|
+
set_or_replace_state_or_prop(state, 'replaceState', &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def set_or_replace_state_or_prop(state_or_prop, method, &block)
|
41
|
+
raise "No native ReactComponent associated" unless @native
|
42
|
+
%x{
|
43
|
+
#{@native}[#{method}](#{state_or_prop.shallow_to_n}, function(){
|
44
|
+
#{block.call if block}
|
45
|
+
});
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module ClassMethods
|
4
|
+
def backtrace(*args)
|
5
|
+
@backtrace_off = (args[0] == :off)
|
6
|
+
end
|
7
|
+
|
8
|
+
def process_exception(e, component, reraise = nil)
|
9
|
+
message = ["Exception raised while rendering #{component}"]
|
10
|
+
if e.backtrace && e.backtrace.length > 1 && !@backtrace_off # seems like e.backtrace is empty in safari???
|
11
|
+
message << " #{e.backtrace[0]}"
|
12
|
+
message += e.backtrace[1..-1].collect { |line| line }
|
13
|
+
else
|
14
|
+
message[0] += ": #{e.message}"
|
15
|
+
end
|
16
|
+
message = message.join("\n")
|
17
|
+
`console.error(message)`
|
18
|
+
raise e if reraise
|
19
|
+
end
|
20
|
+
|
21
|
+
def deprecation_warning(message)
|
22
|
+
@deprecation_messages ||= []
|
23
|
+
message = "Warning: Deprecated feature used in #{self.name}. #{message}"
|
24
|
+
unless @deprecation_messages.include? message
|
25
|
+
@deprecation_messages << message
|
26
|
+
IsomorphicHelpers.log message, :warning
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def validator
|
31
|
+
@validator ||= Validator.new(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
def prop_types
|
35
|
+
if self.validator
|
36
|
+
{
|
37
|
+
_componentValidator: %x{
|
38
|
+
function(props, propName, componentName) {
|
39
|
+
var errors = #{validator.validate(Hash.new(`props`))};
|
40
|
+
var error = new Error(#{"In component `" + self.name + "`\n" + `errors`.join("\n")});
|
41
|
+
return #{`errors`.count > 0 ? `error` : `undefined`};
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
else
|
46
|
+
{}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def default_props
|
51
|
+
validator.default_props
|
52
|
+
end
|
53
|
+
|
54
|
+
def params(&block)
|
55
|
+
validator.build(&block)
|
56
|
+
end
|
57
|
+
|
58
|
+
def props_wrapper
|
59
|
+
@props_wrapper ||= Class.new(PropsWrapper)
|
60
|
+
end
|
61
|
+
|
62
|
+
def define_param(name, param_type)
|
63
|
+
props_wrapper.define_param(name, param_type, self)
|
64
|
+
end
|
65
|
+
|
66
|
+
def param(*args)
|
67
|
+
if args[0].is_a? Hash
|
68
|
+
options = args[0]
|
69
|
+
name = options.first[0]
|
70
|
+
default = options.first[1]
|
71
|
+
options.delete(name)
|
72
|
+
options.merge!({default: default})
|
73
|
+
else
|
74
|
+
name = args[0]
|
75
|
+
options = args[1] || {}
|
76
|
+
end
|
77
|
+
if options[:default]
|
78
|
+
validator.optional(name, options)
|
79
|
+
else
|
80
|
+
validator.requires(name, options)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def required_param(name, options = {})
|
85
|
+
deprecation_warning "`required_param` is deprecated, use `param` instead."
|
86
|
+
validator.requires(name, options)
|
87
|
+
end
|
88
|
+
|
89
|
+
alias_method :require_param, :required_param
|
90
|
+
|
91
|
+
def optional_param(name, options = {})
|
92
|
+
deprecation_warning "`optional_param` is deprecated, use `param param_name: default_value` instead."
|
93
|
+
validator.optional(name, options)
|
94
|
+
end
|
95
|
+
|
96
|
+
def collect_other_params_as(name)
|
97
|
+
validator.allow_undefined_props = true
|
98
|
+
define_method(name) do
|
99
|
+
@_all_others ||= self.class.validator.undefined_props(props)
|
100
|
+
end
|
101
|
+
|
102
|
+
validator_in_lexial_scope = validator
|
103
|
+
props_wrapper.define_method(name) do
|
104
|
+
@_all_others ||= validator_in_lexial_scope.undefined_props(props)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def define_state(*states, &block)
|
109
|
+
default_initial_value = (block && block.arity == 0) ? yield : nil
|
110
|
+
states_hash = (states.last.is_a?(Hash)) ? states.pop : {}
|
111
|
+
states.each { |name| states_hash[name] = default_initial_value }
|
112
|
+
(self.initial_state ||= {}).merge! states_hash
|
113
|
+
states_hash.each do |name, initial_value|
|
114
|
+
define_state_methods(self, name, &block)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def export_state(*states, &block)
|
119
|
+
default_initial_value = (block && block.arity == 0) ? yield : nil
|
120
|
+
states_hash = (states.last.is_a?(Hash)) ? states.pop : {}
|
121
|
+
states.each { |name| states_hash[name] = default_initial_value }
|
122
|
+
State.initialize_states(self, states_hash)
|
123
|
+
states_hash.each do |name, initial_value|
|
124
|
+
define_state_methods(self, name, self, &block)
|
125
|
+
define_state_methods(singleton_class, name, self, &block)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def define_state_methods(this, name, from = nil, &block)
|
130
|
+
this.define_method("#{name}") do
|
131
|
+
self.class.deprecation_warning "Direct access to state `#{name}`. Use `state.#{name}` instead." if from.nil? || from == this
|
132
|
+
State.get_state(from || self, name)
|
133
|
+
end
|
134
|
+
this.define_method("#{name}=") do |new_state|
|
135
|
+
self.class.deprecation_warning "Direct assignment to state `#{name}`. Use `#{(from && from != this) ? from : 'state'}.#{name}!` instead."
|
136
|
+
yield name, State.get_state(from || self, name), new_state if block && block.arity > 0
|
137
|
+
State.set_state(from || self, name, new_state)
|
138
|
+
end
|
139
|
+
this.define_method("#{name}!") do |*args|
|
140
|
+
self.class.deprecation_warning "Direct access to state `#{name}`. Use `state.#{name}` instead." if from.nil? or from == this
|
141
|
+
if args.count > 0
|
142
|
+
yield name, State.get_state(from || self, name), args[0] if block && block.arity > 0
|
143
|
+
current_value = State.get_state(from || self, name)
|
144
|
+
State.set_state(from || self, name, args[0])
|
145
|
+
current_value
|
146
|
+
else
|
147
|
+
current_state = State.get_state(from || self, name)
|
148
|
+
yield name, State.get_state(from || self, name), current_state if block && block.arity > 0
|
149
|
+
State.set_state(from || self, name, current_state)
|
150
|
+
Observable.new(current_state) do |update|
|
151
|
+
yield name, State.get_state(from || self, name), update if block && block.arity > 0
|
152
|
+
State.set_state(from || self, name, update)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def native_mixin(item)
|
159
|
+
native_mixins << item
|
160
|
+
end
|
161
|
+
|
162
|
+
def native_mixins
|
163
|
+
@native_mixins ||= []
|
164
|
+
end
|
165
|
+
|
166
|
+
def static_call_back(name, &block)
|
167
|
+
static_call_backs[name] = block
|
168
|
+
end
|
169
|
+
|
170
|
+
def static_call_backs
|
171
|
+
@static_call_backs ||= {}
|
172
|
+
end
|
173
|
+
|
174
|
+
def export_component(opts = {})
|
175
|
+
export_name = (opts[:as] || name).split("::")
|
176
|
+
first_name = export_name.first
|
177
|
+
Native(`window`)[first_name] = add_item_to_tree(Native(`window`)[first_name], [React::API.create_native_react_class(self)] + export_name[1..-1].reverse).to_n
|
178
|
+
end
|
179
|
+
|
180
|
+
def add_item_to_tree(current_tree, new_item)
|
181
|
+
if Native(current_tree).class != Native::Object || new_item.length == 1
|
182
|
+
new_item.inject { |memo, sub_name| { sub_name => memo } }
|
183
|
+
else
|
184
|
+
Native(current_tree)[new_item.last] = add_item_to_tree(Native(current_tree)[new_item.last], new_item[0..-2])
|
185
|
+
current_tree
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
class PropsWrapper
|
4
|
+
attr_reader :props
|
5
|
+
|
6
|
+
def self.define_param(name, param_type, owner)
|
7
|
+
owner.define_method("#{name}") do |*args, &block|
|
8
|
+
deprecated_params_method("#{name}", *args, &block)
|
9
|
+
end
|
10
|
+
if param_type == Observable
|
11
|
+
owner.define_method("#{name}!") do |*args|
|
12
|
+
deprecated_params_method("#{name}!", *args)
|
13
|
+
end
|
14
|
+
define_method("#{name}") do
|
15
|
+
value_for(name)
|
16
|
+
end
|
17
|
+
define_method("#{name}!") do |*args|
|
18
|
+
current_value = value_for(name)
|
19
|
+
if args.count > 0
|
20
|
+
props[name].call args[0]
|
21
|
+
current_value
|
22
|
+
else
|
23
|
+
# rescue in case we in middle of render... What happens during a
|
24
|
+
# render that causes exception?
|
25
|
+
# Where does `dont_update_state` come from?
|
26
|
+
props[name].call current_value unless @dont_update_state rescue nil
|
27
|
+
props[name]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
elsif param_type == Proc
|
31
|
+
define_method("#{name}") do |*args, &block|
|
32
|
+
props[name].call(*args, &block) if props[name]
|
33
|
+
end
|
34
|
+
else
|
35
|
+
define_method("#{name}") do
|
36
|
+
if @processed_params.has_key? name
|
37
|
+
@processed_params[name]
|
38
|
+
else
|
39
|
+
@processed_params[name] = if param_type.respond_to? :_react_param_conversion
|
40
|
+
param_type._react_param_conversion props[name]
|
41
|
+
elsif param_type.is_a?(Array) &&
|
42
|
+
param_type[0].respond_to?(:_react_param_conversion)
|
43
|
+
props[name].collect do |param|
|
44
|
+
param_type[0]._react_param_conversion param
|
45
|
+
end
|
46
|
+
else
|
47
|
+
props[name]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def unchanged_processed_params(new_props)
|
55
|
+
Hash[
|
56
|
+
*@processed_params.collect do |key, value|
|
57
|
+
[key, value] if @props[key].equal? new_props[key] # `#{@props[key]} == #{new_props[key]}`
|
58
|
+
end.compact.flatten(1)
|
59
|
+
]
|
60
|
+
end
|
61
|
+
|
62
|
+
def initialize(props, current_props_wrapper=nil)
|
63
|
+
@props = props || {}
|
64
|
+
@processed_params = if current_props_wrapper
|
65
|
+
current_props_wrapper.unchanged_processed_params(props)
|
66
|
+
else
|
67
|
+
{}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def [](prop)
|
72
|
+
props[prop]
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def value_for(name)
|
78
|
+
self[name].instance_variable_get("@value") if self[name]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'react/ext/string'
|
2
|
+
|
3
|
+
module React
|
4
|
+
class Element
|
5
|
+
include Native
|
6
|
+
|
7
|
+
alias_native :element_type, :type
|
8
|
+
alias_native :props, :props
|
9
|
+
|
10
|
+
attr_reader :type
|
11
|
+
attr_reader :properties
|
12
|
+
attr_reader :block
|
13
|
+
|
14
|
+
attr_accessor :waiting_on_resources
|
15
|
+
|
16
|
+
def initialize(native_element, type, properties, block)
|
17
|
+
@type = type
|
18
|
+
@properties = (`typeof #{properties} === 'undefined'` ? nil : properties) || {}
|
19
|
+
@block = block
|
20
|
+
@native = native_element
|
21
|
+
end
|
22
|
+
|
23
|
+
def on(event_name)
|
24
|
+
name = event_name.to_s.event_camelize
|
25
|
+
props = if React::Event::BUILT_IN_EVENTS.include?("on#{name}")
|
26
|
+
{"on#{name}" => %x{
|
27
|
+
function(event){
|
28
|
+
#{yield React::Event.new(`event`)}
|
29
|
+
}
|
30
|
+
}}
|
31
|
+
else
|
32
|
+
{"_on#{name}" => %x{
|
33
|
+
function(){
|
34
|
+
#{yield *Array(`arguments`)}
|
35
|
+
}
|
36
|
+
}}
|
37
|
+
end
|
38
|
+
@native = `React.cloneElement(#{self.to_n}, #{props.to_n})`
|
39
|
+
@properties.merge! props
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def render(props = {}) # for rendering children
|
44
|
+
if props.empty?
|
45
|
+
React::RenderingContext.render(self)
|
46
|
+
else
|
47
|
+
React::RenderingContext.render(
|
48
|
+
Element.new(
|
49
|
+
`React.cloneElement(#{self.to_n}, #{API.convert_props(props)})`,
|
50
|
+
type,
|
51
|
+
properties.merge(props),
|
52
|
+
block
|
53
|
+
)
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def method_missing(class_name, args = {}, &new_block)
|
59
|
+
class_name = class_name.split("__").collect { |s| s.gsub("_", "-") }.join("_")
|
60
|
+
new_props = properties.dup
|
61
|
+
new_props["class"] = "#{new_props['class']} #{class_name} #{args.delete("class")} #{args.delete('className')}".split(" ").uniq.join(" ")
|
62
|
+
new_props.merge! args
|
63
|
+
React::RenderingContext.replace(
|
64
|
+
self,
|
65
|
+
React::RenderingContext.build { React::RenderingContext.render(type, new_props, &new_block) }
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
def as_node
|
70
|
+
React::RenderingContext.as_node(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
def delete
|
74
|
+
React::RenderingContext.delete(self)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/react/event.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module React
|
2
|
+
class Event
|
3
|
+
include Native
|
4
|
+
alias_native :bubbles, :bubbles
|
5
|
+
alias_native :cancelable, :cancelable
|
6
|
+
alias_native :current_target, :currentTarget
|
7
|
+
alias_native :default_prevented, :defaultPrevented
|
8
|
+
alias_native :event_phase, :eventPhase
|
9
|
+
alias_native :is_trusted?, :isTrusted
|
10
|
+
alias_native :native_event, :nativeEvent
|
11
|
+
alias_native :target, :target
|
12
|
+
alias_native :timestamp, :timeStamp
|
13
|
+
alias_native :event_type, :type
|
14
|
+
alias_native :prevent_default, :preventDefault
|
15
|
+
alias_native :stop_propagation, :stopPropagation
|
16
|
+
# Clipboard
|
17
|
+
alias_native :clipboard_data, :clipboardData
|
18
|
+
# Keyboard
|
19
|
+
alias_native :alt_key, :altKey
|
20
|
+
alias_native :char_code, :charCode
|
21
|
+
alias_native :ctrl_key, :ctrlKey
|
22
|
+
alias_native :get_modifier_state, :getModifierState
|
23
|
+
alias_native :key, :key
|
24
|
+
alias_native :key_code, :keyCode
|
25
|
+
alias_native :locale, :locale
|
26
|
+
alias_native :location, :location
|
27
|
+
alias_native :meta_key, :metaKey
|
28
|
+
alias_native :repeat, :repeat
|
29
|
+
alias_native :shift_key, :shiftKey
|
30
|
+
alias_native :which, :which
|
31
|
+
# Focus
|
32
|
+
alias_native :related_target, :relatedTarget
|
33
|
+
# Mouse
|
34
|
+
alias_native :alt_key, :altKey
|
35
|
+
alias_native :button, :button
|
36
|
+
alias_native :buttons, :buttons
|
37
|
+
alias_native :client_x, :clientX
|
38
|
+
alias_native :client_y, :clientY
|
39
|
+
alias_native :ctrl_key, :ctrlKey
|
40
|
+
alias_native :get_modifier_state, :getModifierState
|
41
|
+
alias_native :meta_key, :metaKey
|
42
|
+
alias_native :page_x, :pageX
|
43
|
+
alias_native :page_y, :pageY
|
44
|
+
alias_native :related_target, :relatedTarget
|
45
|
+
alias_native :screen_x, :screen_x
|
46
|
+
alias_native :screen_y, :screen_y
|
47
|
+
alias_native :shift_key, :shift_key
|
48
|
+
# Touch
|
49
|
+
alias_native :alt_key, :altKey
|
50
|
+
alias_native :changed_touches, :changedTouches
|
51
|
+
alias_native :ctrl_key, :ctrlKey
|
52
|
+
alias_native :get_modifier_state, :getModifierState
|
53
|
+
alias_native :meta_key, :metaKey
|
54
|
+
alias_native :shift_key, :shiftKey
|
55
|
+
alias_native :target_touches, :targetTouches
|
56
|
+
alias_native :touches, :touches
|
57
|
+
# UI
|
58
|
+
alias_native :detail, :detail
|
59
|
+
alias_native :view, :view
|
60
|
+
# Wheel
|
61
|
+
alias_native :delta_mode, :deltaMode
|
62
|
+
alias_native :delta_x, :deltaX
|
63
|
+
alias_native :delta_y, :deltaY
|
64
|
+
alias_native :delta_z, :deltaZ
|
65
|
+
|
66
|
+
BUILT_IN_EVENTS = %w{onCopy onCut onPaste onKeyDown onKeyPress onKeyUp
|
67
|
+
onFocus onBlur onChange onInput onSubmit onClick onDoubleClick onDrag
|
68
|
+
onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop
|
69
|
+
onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver
|
70
|
+
onMouseUp onTouchCancel onTouchEnd onTouchMove onTouchStart onScroll}
|
71
|
+
|
72
|
+
def initialize(native_element)
|
73
|
+
@native = native_element
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|