isomorfeus-react 16.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +1 -0
- data/README.md +620 -0
- data/isomorfeus-react.gemspec +23 -0
- data/lib/isomorfeus-react.rb +131 -0
- data/lib/isomorfeus/config.rb +84 -0
- data/lib/isomorfeus/top_level.rb +48 -0
- data/lib/isomorfeus/view_helpers.rb +38 -0
- data/lib/lucid_app/api.rb +22 -0
- data/lib/lucid_app/base.rb +7 -0
- data/lib/lucid_app/context.rb +7 -0
- data/lib/lucid_app/mixin.rb +17 -0
- data/lib/lucid_app/native_component_constructor.rb +70 -0
- data/lib/lucid_component/api.rb +97 -0
- data/lib/lucid_component/base.rb +7 -0
- data/lib/lucid_component/event_handler.rb +17 -0
- data/lib/lucid_component/initializer.rb +12 -0
- data/lib/lucid_component/mixin.rb +17 -0
- data/lib/lucid_component/native_component_constructor.rb +131 -0
- data/lib/react.rb +147 -0
- data/lib/react/active_support_support.rb +13 -0
- data/lib/react/component/api.rb +226 -0
- data/lib/react/component/base.rb +9 -0
- data/lib/react/component/elements.rb +78 -0
- data/lib/react/component/event_handler.rb +19 -0
- data/lib/react/component/features.rb +47 -0
- data/lib/react/component/history.rb +36 -0
- data/lib/react/component/initializer.rb +11 -0
- data/lib/react/component/location.rb +15 -0
- data/lib/react/component/match.rb +31 -0
- data/lib/react/component/mixin.rb +19 -0
- data/lib/react/component/native_component_constructor.rb +76 -0
- data/lib/react/component/native_component_validate_prop.rb +37 -0
- data/lib/react/component/props.rb +49 -0
- data/lib/react/component/resolution.rb +71 -0
- data/lib/react/component/should_component_update.rb +14 -0
- data/lib/react/component/state.rb +52 -0
- data/lib/react/component/unsafe_api.rb +33 -0
- data/lib/react/context_wrapper.rb +47 -0
- data/lib/react/function_component/creator.rb +47 -0
- data/lib/react/function_component/resolution.rb +61 -0
- data/lib/react/function_component/runner.rb +19 -0
- data/lib/react/native_constant_wrapper.rb +34 -0
- data/lib/react/pure_component/base.rb +9 -0
- data/lib/react/pure_component/mixin.rb +17 -0
- data/lib/react/redux_component/api.rb +132 -0
- data/lib/react/redux_component/app_store_defaults.rb +38 -0
- data/lib/react/redux_component/app_store_proxy.rb +46 -0
- data/lib/react/redux_component/base.rb +9 -0
- data/lib/react/redux_component/class_store_proxy.rb +50 -0
- data/lib/react/redux_component/component_class_store_defaults.rb +40 -0
- data/lib/react/redux_component/component_instance_store_defaults.rb +41 -0
- data/lib/react/redux_component/initializer.rb +14 -0
- data/lib/react/redux_component/instance_store_proxy.rb +50 -0
- data/lib/react/redux_component/mixin.rb +18 -0
- data/lib/react/redux_component/native_component_constructor.rb +119 -0
- data/lib/react/redux_component/reducers.rb +53 -0
- data/lib/react/ref.rb +19 -0
- data/lib/react/synthetic_event.rb +53 -0
- data/lib/react/version.rb +3 -0
- data/lib/react_dom.rb +31 -0
- data/lib/react_dom_server.rb +17 -0
- metadata +167 -0
@@ -0,0 +1,226 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module API
|
4
|
+
def self.included(base)
|
5
|
+
base.instance_exec do
|
6
|
+
base_module = base.to_s.deconstantize
|
7
|
+
if base_module != ''
|
8
|
+
base_module.constantize.define_singleton_method(base.to_s.demodulize) do |*args, &block|
|
9
|
+
%x{
|
10
|
+
var props = null;
|
11
|
+
|
12
|
+
if (args.length > 0) {
|
13
|
+
props = Opal.React.to_native_react_props(args[0]);
|
14
|
+
}
|
15
|
+
Opal.React.internal_render(#{base}.react_component, props, block);
|
16
|
+
}
|
17
|
+
end
|
18
|
+
else
|
19
|
+
Object.define_method(base.to_s) do |*args, &block|
|
20
|
+
%x{
|
21
|
+
var props = null;
|
22
|
+
|
23
|
+
if (args.length > 0) {
|
24
|
+
props = Opal.React.to_native_react_props(args[0]);
|
25
|
+
}
|
26
|
+
Opal.React.internal_render(#{base}.react_component, props, block);
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
attr_accessor :props
|
33
|
+
attr_accessor :state
|
34
|
+
|
35
|
+
def ref(ref_name, &block)
|
36
|
+
defined_refs.JS[ref_name] = if block_given?
|
37
|
+
block
|
38
|
+
else
|
39
|
+
`null`
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def defined_refs
|
44
|
+
@defined_ref ||= `{}`
|
45
|
+
end
|
46
|
+
|
47
|
+
def default_state_defined
|
48
|
+
@default_state_defined
|
49
|
+
end
|
50
|
+
|
51
|
+
def state
|
52
|
+
return @default_state if @default_state
|
53
|
+
@default_state_defined = true
|
54
|
+
%x{
|
55
|
+
var native_state = {state: {}};
|
56
|
+
native_state.setState = function(new_state, callback) {
|
57
|
+
for (var key in new_state) {
|
58
|
+
this.state[key] = new_state[key];
|
59
|
+
}
|
60
|
+
if (callback) { callback.call(); }
|
61
|
+
}
|
62
|
+
}
|
63
|
+
@default_state = React::Component::State.new(`native_state`)
|
64
|
+
end
|
65
|
+
|
66
|
+
def prop(name, options = `null`)
|
67
|
+
name = `Opal.React.lower_camelize(name)`
|
68
|
+
if options
|
69
|
+
if options.has_key?(:default)
|
70
|
+
%x{
|
71
|
+
if (typeof self.react_component.defaultProps == "undefined") {
|
72
|
+
self.react_component.defaultProps = {};
|
73
|
+
}
|
74
|
+
self.react_component.defaultProps[name] = options.$fetch("default");
|
75
|
+
}
|
76
|
+
end
|
77
|
+
if options.has_key?(:class)
|
78
|
+
%x{
|
79
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
80
|
+
self.react_component.propTypes = {};
|
81
|
+
self.react_component.propValidations = {};
|
82
|
+
self.react_component.propValidations[name] = {};
|
83
|
+
}
|
84
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
85
|
+
self.react_component.propValidations[name].ruby_class = options.$fetch("class");
|
86
|
+
}
|
87
|
+
elsif options.has_key?(:is_a)
|
88
|
+
%x{
|
89
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
90
|
+
self.react_component.propTypes = {};
|
91
|
+
self.react_component.propValidations = {};
|
92
|
+
self.react_component.propValidations[name] = {};
|
93
|
+
}
|
94
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
95
|
+
self.react_component.propValidations[name].is_a = options.$fetch("is_a");
|
96
|
+
}
|
97
|
+
end
|
98
|
+
if options.has_key?(:required)
|
99
|
+
%x{
|
100
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
101
|
+
self.react_component.propTypes = {};
|
102
|
+
self.react_component.propValidations = {};
|
103
|
+
self.react_component.propValidations[name] = {};
|
104
|
+
}
|
105
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
106
|
+
self.react_component.propValidations[name].required = options.$fetch("required");
|
107
|
+
}
|
108
|
+
elsif !options.has_key?(:default)
|
109
|
+
%x{
|
110
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
111
|
+
self.react_component.propTypes = {};
|
112
|
+
self.react_component.propValidations = {};
|
113
|
+
}
|
114
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
115
|
+
self.react_component.propValidations[name].required = true;
|
116
|
+
}
|
117
|
+
end
|
118
|
+
else
|
119
|
+
%x{
|
120
|
+
if (typeof self.react_component.propTypes == "undefined") {
|
121
|
+
self.react_component.propTypes = {};
|
122
|
+
self.react_component.propValidations = {};
|
123
|
+
self.react_component.propValidations[name] = {};
|
124
|
+
}
|
125
|
+
self.react_component.propTypes[name] = self.react_component.prototype.validateProp;
|
126
|
+
self.react_component.propValidations[name].required = options.$fetch("required");
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def default_props
|
132
|
+
return @default_props if @default_props
|
133
|
+
%x{
|
134
|
+
if (typeof self.react_component.defaultProps == "undefined") {
|
135
|
+
self.lucid_react_component.defaultProps = {};
|
136
|
+
}
|
137
|
+
}
|
138
|
+
@default_props = React::Component::Props.new(`self.react_component.defaultProps`)
|
139
|
+
end
|
140
|
+
|
141
|
+
def component_did_catch(&block)
|
142
|
+
# TODO convert error and info
|
143
|
+
%x{
|
144
|
+
self.react_component.prototype.componentDidCatch = function(error, info) {
|
145
|
+
return #{`this.__ruby_instance`.instance_exec(error, info, &block)};
|
146
|
+
}
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
def component_did_mount(&block)
|
151
|
+
%x{
|
152
|
+
self.react_component.prototype.componentDidMount = function() {
|
153
|
+
return #{`this.__ruby_instance`.instance_exec(&block)};
|
154
|
+
}
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
def component_did_update(&block)
|
159
|
+
%x{
|
160
|
+
self.react_component.prototype.componentDidUpdate = function() {
|
161
|
+
return #{`this.__ruby_instance`.instance_exec(&block)};
|
162
|
+
}
|
163
|
+
}
|
164
|
+
end
|
165
|
+
|
166
|
+
def component_will_unmount(&block)
|
167
|
+
%x{
|
168
|
+
self.react_component.prototype.componentWillUnmount = function() {
|
169
|
+
return #{`this.__ruby_instance`.instance_exec(&block)};
|
170
|
+
}
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
def get_derived_state_from_error(&block)
|
175
|
+
%x{
|
176
|
+
self.react_component.prototype.getDerivedStateFromError = function(error) {
|
177
|
+
return #{`this.__ruby_instance`.instance_exec(error, &block)};
|
178
|
+
}
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
def get_derived_state_from_props(&block)
|
183
|
+
%x{
|
184
|
+
self.react_component.prototype.getDerivedStateFromProps = function(props, state) {
|
185
|
+
return #{`this.__ruby_instance`.instance_exec(React::Component::Props.new(`props`), `Opal.Hash.$new(state)`, &block)};
|
186
|
+
}
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
def get_snapshot_before_update(&block)
|
191
|
+
%x{
|
192
|
+
self.react_component.prototype.getSnapshotBeforeUpdate = function(prev_props, prev_state) {
|
193
|
+
return #{`this.__ruby_instance`.instance_exec(React::Component::Props.new(`prev_props`), `Opal.Hash.$new(prev_state)`, &block)};
|
194
|
+
}
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
def render(&block)
|
199
|
+
%x{
|
200
|
+
self.react_component.prototype.render = function() {
|
201
|
+
Opal.React.render_buffer.push([]);
|
202
|
+
Opal.React.active_components.push(this);
|
203
|
+
#{`this.__ruby_instance`.instance_exec(&block)};
|
204
|
+
Opal.React.active_components.pop();
|
205
|
+
return Opal.React.render_buffer.pop();
|
206
|
+
}
|
207
|
+
}
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def force_update(&block)
|
213
|
+
if block_given?
|
214
|
+
# this maybe needs instance_exec too
|
215
|
+
@native.JS.forceUpdate(`function() { block.$call(); }`)
|
216
|
+
else
|
217
|
+
@native.JS.forceUpdate
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def set_state(updater, &callback)
|
222
|
+
@state.set_state(updater, &callback)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module Elements
|
4
|
+
# https://www.w3.org/TR/html52/fullindex.html#index-elements
|
5
|
+
SUPPORTED_HTML_AND_SVG_ELEMENTS = %w[
|
6
|
+
a abbr address area article aside audio
|
7
|
+
b base bdi bdo blockquote body br button
|
8
|
+
canvas caption cite code col colgroup
|
9
|
+
data datalist dd del details dfn dialog div dl dt
|
10
|
+
em embed
|
11
|
+
fieldset figcaption figure footer form
|
12
|
+
h1 h2 h3 h4 h5 h6 head header hr html
|
13
|
+
i iframe img input ins
|
14
|
+
kbd
|
15
|
+
label legend li link
|
16
|
+
main map mark meta meter
|
17
|
+
nav noscript
|
18
|
+
object ol optgroup option output
|
19
|
+
p param picture pre progress
|
20
|
+
q
|
21
|
+
rp rt rtc ruby
|
22
|
+
s samp script section select small source span strong style sub summary sup
|
23
|
+
table tbody td template textarea tfoot th thead time title tr track
|
24
|
+
u ul
|
25
|
+
var video
|
26
|
+
wbr
|
27
|
+
] +
|
28
|
+
# https://www.w3.org/TR/SVG11/eltindex.html
|
29
|
+
# elements listed above not mentioned a second time
|
30
|
+
%w[
|
31
|
+
altGlyph altGlyphDef altGlyphItem animate animateColor animateMotion animateTransform
|
32
|
+
circle clipPath color-profile cursor
|
33
|
+
defs desc
|
34
|
+
ellipse
|
35
|
+
feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting
|
36
|
+
feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur
|
37
|
+
feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting
|
38
|
+
feSpotLight feTile feTurbulence
|
39
|
+
filter font font-face font-face-format font-face-name font-face-src font-face-uri foreignObject
|
40
|
+
g glyph glyphRef
|
41
|
+
hkern
|
42
|
+
image
|
43
|
+
line linearGradient
|
44
|
+
marker mask metadata missing-glyph mpath
|
45
|
+
path pattern polygon polyline
|
46
|
+
radialGradient rect
|
47
|
+
script set stop style svg switch symbol
|
48
|
+
text textPath tref tspan
|
49
|
+
use
|
50
|
+
view vkern
|
51
|
+
]
|
52
|
+
|
53
|
+
|
54
|
+
SUPPORTED_HTML_AND_SVG_ELEMENTS.each do |element|
|
55
|
+
define_method(element) do |*args, &block|
|
56
|
+
%x{
|
57
|
+
var props = null;
|
58
|
+
|
59
|
+
if (args.length > 0) {
|
60
|
+
props = Opal.React.to_native_react_props(args[0]);
|
61
|
+
}
|
62
|
+
Opal.React.internal_render(element, props, block);
|
63
|
+
}
|
64
|
+
end
|
65
|
+
define_method(`element.toUpperCase()`) do |*args, &block|
|
66
|
+
%x{
|
67
|
+
var props = null;
|
68
|
+
|
69
|
+
if (args.length > 0) {
|
70
|
+
props = Opal.React.to_native_react_props(args[0]);
|
71
|
+
}
|
72
|
+
Opal.React.internal_render(element, props, block);
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module EventHandler
|
4
|
+
def event_handlers
|
5
|
+
@event_handlers ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
def event_handler(name, &block)
|
9
|
+
event_handlers << name
|
10
|
+
%x{
|
11
|
+
self.react_component.prototype[name] = function(event, info) {
|
12
|
+
#{ruby_event = ::React::SyntheticEvent.new(`event`)};
|
13
|
+
#{`this.__ruby_instance`.instance_exec(ruby_event, `info`, &block)};
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
module Features
|
4
|
+
def Fragment(props = `null`, &block)
|
5
|
+
%x{
|
6
|
+
var native_props = null;
|
7
|
+
|
8
|
+
if (props) {
|
9
|
+
native_props = Opal.React.to_native_react_props(args[0]);
|
10
|
+
}
|
11
|
+
Opal.React.internal_render(React.Fragment, native_props, block);
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def Portal(dom_node, &block)
|
16
|
+
%x{
|
17
|
+
var children = null;
|
18
|
+
var block_result = null;
|
19
|
+
|
20
|
+
Opal.React.render_buffer.push([]);
|
21
|
+
if (block !== nil) {
|
22
|
+
block_result = block.$call()
|
23
|
+
if (block_result && (block_result !== nil && (typeof block_result === "string" || typeof block_result.$$typeof === "symbol" ||
|
24
|
+
(typeof block_result.constructor !== "undefined" && block_result.constructor === Array && block_result[0] && typeof block_result[0].$$typeof === "symbol")
|
25
|
+
))) {
|
26
|
+
Opal.React.render_buffer[Opal.React.render_buffer.length - 1].push(block_result);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
var react_element = React.createPortal(Opal.React.render_buffer.pop(), dom_node);
|
30
|
+
Opal.React.render_buffer[Opal.React.render_buffer.length - 1].push(react_element);
|
31
|
+
return null;
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def StrictMode(props = `null`, &block)
|
36
|
+
%x{
|
37
|
+
var native_props = null;
|
38
|
+
|
39
|
+
if (props) {
|
40
|
+
native_props = Opal.React.to_native_react_props(args[0]);
|
41
|
+
}
|
42
|
+
Opal.React.internal_render(React.StrictMode, native_props, block);
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module React
|
2
|
+
module Component
|
3
|
+
class History
|
4
|
+
include ::Native::Wrapper
|
5
|
+
|
6
|
+
alias_native :block, :block
|
7
|
+
alias_native :create_href, :createHref
|
8
|
+
alias_native :go, :go
|
9
|
+
alias_native :go_back, :goBack
|
10
|
+
alias_native :go_forward, :goForward
|
11
|
+
alias_native :listen, :listen
|
12
|
+
alias_native :push, :push
|
13
|
+
alias_native :replace, :replace
|
14
|
+
|
15
|
+
alias _react_component_hitory_original_method_missing method_missing
|
16
|
+
|
17
|
+
def method_missing(prop, *args, &block)
|
18
|
+
@native.JS[:params].JS[prop]
|
19
|
+
end
|
20
|
+
|
21
|
+
def location
|
22
|
+
return @location if @location
|
23
|
+
return nil unless @native.JS[:props].JS[:location]
|
24
|
+
if @native.JS[:props].JS[:location].JS[:pathname]
|
25
|
+
@location = React::Component::Location.new(@native.JS[:props].JS[:location])
|
26
|
+
else
|
27
|
+
@native.JS[:props].JS[:location]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_n
|
32
|
+
@native
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|