5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
# File 'lib/react/api.rb', line 5
def self.create_element(type, properties = {}, &block)
params = []
if type.kind_of?(Class)
raise "Provided class should define `render` method" if !(type.method_defined? :render)
@@component_classes[type.to_s] ||= %x{
React.createClass({
propTypes: #{type.respond_to?(:prop_types) ? type.prop_types.to_n : `{}`},
getDefaultProps: function(){
return #{type.respond_to?(:default_props) ? type.default_props.to_n : `{}`};
},
getInitialState: function(){
return #{type.respond_to?(:initial_state) ? type.initial_state.to_n : `{}`};
},
componentWillMount: function() {
var instance = this._getOpalInstance.apply(this);
return #{`instance`.component_will_mount if type.method_defined? :component_will_mount};
},
componentDidMount: function() {
var instance = this._getOpalInstance.apply(this);
return #{`instance`.component_did_mount if type.method_defined? :component_did_mount};
},
componentWillReceiveProps: function(next_props) {
var instance = this._getOpalInstance.apply(this);
return #{`instance`.component_will_receive_props(`next_props`) if type.method_defined? :component_will_receive_props};
},
shouldComponentUpdate: function(next_props, next_state) {
var instance = this._getOpalInstance.apply(this);
return #{`instance`.should_component_update?(`next_props`, `next_state`) if type.method_defined? :should_component_update?};
},
componentWillUpdate: function(next_props, next_state) {
var instance = this._getOpalInstance.apply(this);
return #{`instance`.component_will_update(`next_props`, `next_state`) if type.method_defined? :component_will_update};
},
componentDidUpdate: function(prev_props, prev_state) {
var instance = this._getOpalInstance.apply(this);
return #{`instance`.component_did_update(`prev_props`, `prev_state`) if type.method_defined? :component_did_update};
},
componentWillUnmount: function() {
var instance = this._getOpalInstance.apply(this);
return #{`instance`.component_will_unmount if type.method_defined? :component_will_unmount};
},
_getOpalInstance: function() {
if (this.__opalInstance == undefined) {
var instance = #{type.new(`this`)};
} else {
var instance = this.__opalInstance;
}
this.__opalInstance = instance;
return instance;
},
render: function() {
var instance = this._getOpalInstance.apply(this);
return #{`instance`.render.to_n};
}
})
}
params << @@component_classes[type.to_s]
else
raise "#{type} not implemented" unless HTML_TAGS.include?(type)
params << type
end
props = {}
properties.map do |key, value|
if key == "class_name" && value.is_a?(Hash)
props[lower_camelize(key)] = `React.addons.classSet(#{value.to_n})`
else
props[React::ATTRIBUTES.include?(lower_camelize(key)) ? lower_camelize(key) : key] = value
end
end
params << props.shallow_to_n
if block_given?
children = [yield].flatten.each do |ele|
params << ele.to_n
end
end
return React::Element.new(`React.createElement.apply(null, #{params})`)
end
|