hyper-router 1.0.alpha1.8 → 2.4.0
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 +5 -5
- data/LICENSE +22 -0
- data/README.md +393 -0
- data/Rakefile +27 -6
- data/lib/hyper-router.rb +13 -22
- data/lib/patches/react.rb +9 -0
- data/lib/promise_extras.rb +7 -0
- data/lib/react/router.rb +117 -2
- data/lib/react/router/dsl.rb +31 -0
- data/lib/react/router/dsl/index.rb +11 -0
- data/lib/react/router/dsl/route.rb +89 -0
- data/lib/react/router/dsl/route/hooks.rb +21 -0
- data/lib/react/router/dsl/route/wrappers.rb +104 -0
- data/lib/react/router/dsl/transition_context.rb +27 -0
- data/lib/react/router/react-router.js +2 -0
- data/lib/react/router/version.rb +3 -0
- metadata +172 -92
- data/lib/hyperstack/internal/router/class_methods.rb +0 -33
- data/lib/hyperstack/internal/router/helpers.rb +0 -74
- data/lib/hyperstack/internal/router/instance_methods.rb +0 -15
- data/lib/hyperstack/internal/router/isomorphic_methods.rb +0 -26
- data/lib/hyperstack/router.rb +0 -76
- data/lib/hyperstack/router/helpers.rb +0 -27
- data/lib/hyperstack/router/history.rb +0 -48
- data/lib/hyperstack/router/location.rb +0 -31
- data/lib/hyperstack/router/match.rb +0 -20
- data/lib/hyperstack/router/react-router-source.rb +0 -4
- data/lib/hyperstack/router/version.rb +0 -3
- data/lib/react/router/dom.rb +0 -7
- data/lib/react/router/history.rb +0 -25
- data/lib/src/history.min.js +0 -1
- data/lib/src/react-router-dom.min.js +0 -1
- data/lib/src/react-router.min.js +0 -1
data/lib/hyper-router.rb
CHANGED
@@ -1,29 +1,20 @@
|
|
1
|
-
# rubocop:disable Style/FileName
|
2
|
-
|
3
|
-
require 'hyper-component'
|
4
|
-
|
5
|
-
Hyperstack.js_import 'hyperstack/router/react-router-source', defines: ['ReactRouter', 'ReactRouterDOM', 'History']
|
6
|
-
Hyperstack.import 'hyper-router'
|
7
|
-
|
8
1
|
if RUBY_ENGINE == 'opal'
|
2
|
+
# require 'reactrb' # how to require this conditionally????
|
3
|
+
require 'hyper-react'
|
4
|
+
require 'promise'
|
5
|
+
require 'promise_extras'
|
6
|
+
require 'react/router/react-router'
|
9
7
|
require 'react/router'
|
10
|
-
require 'react/router/
|
11
|
-
require 'react/router/
|
12
|
-
|
13
|
-
require '
|
14
|
-
require '
|
15
|
-
require 'hyperstack/router/location'
|
16
|
-
require 'hyperstack/router/match'
|
17
|
-
require 'hyperstack/internal/router/class_methods'
|
18
|
-
require 'hyperstack/internal/router/helpers'
|
19
|
-
require 'hyperstack/internal/router/instance_methods'
|
20
|
-
|
21
|
-
require 'hyperstack/router/helpers'
|
22
|
-
require 'hyperstack/router'
|
8
|
+
require 'react/router/dsl'
|
9
|
+
require 'react/router/dsl/route'
|
10
|
+
require 'react/router/dsl/index'
|
11
|
+
require 'react/router/dsl/transition_context'
|
12
|
+
require 'patches/react'
|
23
13
|
else
|
24
14
|
require 'opal'
|
25
|
-
require '
|
26
|
-
require '
|
15
|
+
require 'hyper-react'
|
16
|
+
require 'react/router/version'
|
27
17
|
|
28
18
|
Opal.append_path File.expand_path('../', __FILE__).untaint
|
19
|
+
Opal.append_path File.expand_path('../../vendor', __FILE__).untaint
|
29
20
|
end
|
data/lib/react/router.rb
CHANGED
@@ -1,5 +1,120 @@
|
|
1
1
|
module React
|
2
|
-
class Router
|
3
|
-
|
2
|
+
class Router
|
3
|
+
include React::Component
|
4
|
+
|
5
|
+
def self.Link(to, opts = {}, &children)
|
6
|
+
opts[:activeClassName] = opts.delete(:active_class).to_n if opts[:active_class]
|
7
|
+
opts[:activeStyle] = opts.delete(:active_style).to_n if opts[:active_style]
|
8
|
+
if opts[:only_active_on_index]
|
9
|
+
opts[:onlyActiveOnIndex] = opts.delete(:only_active_on_index).to_n
|
10
|
+
end
|
11
|
+
opts[:to] = to.to_n
|
12
|
+
Native::Link(opts, &children)
|
13
|
+
end
|
14
|
+
|
15
|
+
def route(*args, &children)
|
16
|
+
DSL::Route.new(*args, &children)
|
17
|
+
end
|
18
|
+
|
19
|
+
def index(opts = {})
|
20
|
+
DSL::Index.new(opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
def redirect(from, opts = {})
|
24
|
+
DSL::Route.new(opts.merge(path: from)).on(:enter) { |c| c.replace(opts[:to]) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def index_redirect(opts = {})
|
28
|
+
DSL::Index.new(opts).on(:enter) { |c| c.replace(opts[:to]) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_routes(&block)
|
32
|
+
React::Router::DSL.build_routes(&block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def hash_history
|
36
|
+
`window.ReactRouter.hashHistory`
|
37
|
+
end
|
38
|
+
|
39
|
+
def browser_history
|
40
|
+
`window.ReactRouter.browserHistory`
|
41
|
+
end
|
42
|
+
|
43
|
+
def gather_params
|
44
|
+
params = { routes: React::Router::DSL.children_to_n(build_routes { routes }) }
|
45
|
+
params[:history] = history if respond_to? :history
|
46
|
+
%w(create_element stringify_query parse_query_string on_error on_update).each do |method|
|
47
|
+
params[method.camelcase(false)] = send("#{method}_wrapper") if respond_to? method
|
48
|
+
end
|
49
|
+
params
|
50
|
+
end
|
51
|
+
|
52
|
+
def render
|
53
|
+
Native::Router(gather_params)
|
54
|
+
end
|
55
|
+
|
56
|
+
# private
|
57
|
+
|
58
|
+
class Native < React::NativeLibrary
|
59
|
+
imports "ReactRouter"
|
60
|
+
end
|
61
|
+
|
62
|
+
def stringify_query_wrapper
|
63
|
+
->(query) { stringify_query(query) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_query_string_wrapper
|
67
|
+
->(query_string) { parse_query_string(query_string) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def on_update_wrapper
|
71
|
+
-> { on_update(Hash.new(`this.props`), Hash.new(`this.state`)) }
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_element_wrapper
|
75
|
+
lambda do |component, props|
|
76
|
+
comp_classes = React::API.class_eval { @@component_classes }
|
77
|
+
rb_component = comp_classes.detect { |_key, value| value == component }.first
|
78
|
+
# Not sure if this could ever happen,
|
79
|
+
# could not figure out a way to test it so commented it out.
|
80
|
+
# unless rb_component
|
81
|
+
# rb_component = Class.new(React::Component::Base)
|
82
|
+
# comp_classes[rb_component] = component
|
83
|
+
# end
|
84
|
+
rb_props = convert_props(props)
|
85
|
+
result = create_element(rb_component, rb_props)
|
86
|
+
convert_or_create_element(result, component, props, rb_component, rb_props)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def on_error_wrapper
|
91
|
+
-> (message) { on_error(message) }
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def convert_props(props)
|
97
|
+
children_are_null = `props.children == undefined || props.children == null`
|
98
|
+
{ children: children_are_null ? [] : [`props.children`].flatten,
|
99
|
+
history: `props.history`,
|
100
|
+
location: `props.location`,
|
101
|
+
params: `props.params`,
|
102
|
+
route: `props.route`,
|
103
|
+
route_params: `props.route_params`,
|
104
|
+
routes: `props.routes` }
|
105
|
+
end
|
106
|
+
|
107
|
+
def convert_or_create_element(result, component, props, rb_component, rb_props)
|
108
|
+
is_result_native_react_element = `!!result._isReactElement`
|
109
|
+
if is_result_native_react_element
|
110
|
+
result
|
111
|
+
elsif !result
|
112
|
+
`React.createElement(component, props)`
|
113
|
+
elsif result.is_a? React::Element
|
114
|
+
result.to_n
|
115
|
+
else
|
116
|
+
React.create_element(rb_component, rb_props).to_n
|
117
|
+
end
|
118
|
+
end
|
4
119
|
end
|
5
120
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module React
|
2
|
+
class Router
|
3
|
+
class DSL
|
4
|
+
def self.build_routes(*args, &block)
|
5
|
+
evaluate_children(*args, &block)[0]
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.evaluate_children(*args, &children)
|
9
|
+
[[], nil].tap do |new_routes|
|
10
|
+
if children
|
11
|
+
saved_routes, @routes = [@routes, new_routes]
|
12
|
+
@routes << children.call(*args)
|
13
|
+
@routes = saved_routes
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.add_element(element)
|
19
|
+
@routes[0] << element
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.set_index(index)
|
23
|
+
@routes[1] = index
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.children_to_n(children)
|
27
|
+
children.collect { |e| e.to_json.to_n }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'react/router/dsl/route/hooks'
|
2
|
+
require 'react/router/dsl/route/wrappers'
|
3
|
+
|
4
|
+
module React
|
5
|
+
class Router
|
6
|
+
class DSL
|
7
|
+
class Route
|
8
|
+
def initialize(*args, &children)
|
9
|
+
path =
|
10
|
+
if args[0].is_a? Hash
|
11
|
+
nil
|
12
|
+
else
|
13
|
+
args[0]
|
14
|
+
end
|
15
|
+
opts =
|
16
|
+
if args[0].is_a? Hash
|
17
|
+
args[0]
|
18
|
+
else
|
19
|
+
args[1] || {}
|
20
|
+
end
|
21
|
+
unless opts.is_a? Hash
|
22
|
+
raise 'Route expects an optional path followed by an options hash, '\
|
23
|
+
"instead we got route(#{'"' + path + '", ' if path} #{opts})"
|
24
|
+
end
|
25
|
+
@children, @index = DSL.evaluate_children do
|
26
|
+
yield if children && children.arity == 0
|
27
|
+
Index.new(mounts: opts[:index]) if opts[:index]
|
28
|
+
end
|
29
|
+
opts.delete(:index)
|
30
|
+
@get_children = children if children && children.arity > 0
|
31
|
+
@path = path
|
32
|
+
if opts[:mounts].is_a? Hash
|
33
|
+
@components = opts[:mounts]
|
34
|
+
else
|
35
|
+
@component = opts[:mounts]
|
36
|
+
end
|
37
|
+
opts.delete(:mounts)
|
38
|
+
@opts = opts
|
39
|
+
save_element
|
40
|
+
end
|
41
|
+
|
42
|
+
def save_element
|
43
|
+
DSL.add_element(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_json
|
47
|
+
hash = {}
|
48
|
+
hash[:path] = @path if @path
|
49
|
+
|
50
|
+
if @get_children
|
51
|
+
hash[:getChildRoutes] = get_child_routes_wrapper
|
52
|
+
else
|
53
|
+
hash[:childRoutes] = @children.map(&:to_json)
|
54
|
+
end
|
55
|
+
|
56
|
+
if @components
|
57
|
+
if @components.detect { |_k, v| v.respond_to? :call }
|
58
|
+
hash[:getComponents] = get_components_wrapper
|
59
|
+
else
|
60
|
+
hash[:components] = @components
|
61
|
+
end
|
62
|
+
elsif @component.respond_to? :call
|
63
|
+
hash[:getComponent] = get_component_wrapper
|
64
|
+
elsif @component
|
65
|
+
hash[:component] = React::API.create_native_react_class(@component)
|
66
|
+
else
|
67
|
+
hash[:component] = DSL.router.lookup_component(@path)
|
68
|
+
end
|
69
|
+
|
70
|
+
%w(enter change leave).each do |hook|
|
71
|
+
hash["on#{hook.camelcase}"] = send("on_#{hook}_wrapper") if @opts["on_#{hook}"]
|
72
|
+
end
|
73
|
+
|
74
|
+
if @index.respond_to? :call
|
75
|
+
hash[:getIndexRoute] = get_index_route_wrapper
|
76
|
+
elsif @index
|
77
|
+
hash[:indexRoute] = @index.to_json
|
78
|
+
end
|
79
|
+
|
80
|
+
@opts.each do |key, value|
|
81
|
+
hash[key] = value unless %w(on_enter on_change on_leave).include?(key)
|
82
|
+
end
|
83
|
+
|
84
|
+
hash
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module React
|
2
|
+
class Router
|
3
|
+
class DSL
|
4
|
+
class Route
|
5
|
+
def on(hook, &block)
|
6
|
+
@opts["on_#{hook}"] = block
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def mounts(name = nil, &block)
|
11
|
+
if name
|
12
|
+
@components ||= {}
|
13
|
+
@components[name] = block
|
14
|
+
else
|
15
|
+
@component = block
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module React
|
2
|
+
class Router
|
3
|
+
class DSL
|
4
|
+
class Route
|
5
|
+
def get_child_routes_wrapper
|
6
|
+
lambda do |location, callBack|
|
7
|
+
children, index, promise =
|
8
|
+
React::Router::DSL.evaluate_children(TransitionContext.new(location: location),
|
9
|
+
&@get_children)
|
10
|
+
if promise.class < Promise || promise.is_a?(Promise)
|
11
|
+
|
12
|
+
promise.then do |children|
|
13
|
+
callBack.call(nil.to_n, React::Router::DSL.children_to_n(children))
|
14
|
+
end.fail { |err_object| callBack.call(err_object, nil.to_n) }
|
15
|
+
else
|
16
|
+
callBack.call(nil.to_n, DSL.children_to_n(children))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
def get_components_wrapper
|
21
|
+
lambda do |nextState, callBack|
|
22
|
+
result_hash = {}
|
23
|
+
promises = []
|
24
|
+
@components.each do |name, proc_or_comp|
|
25
|
+
if proc_or_comp.respond_to? :call
|
26
|
+
comp = proc.call(TransitionContext.new(next_state: nextState))
|
27
|
+
if comp.class < Promise || comp.is_a?(Promise)
|
28
|
+
promises << comp
|
29
|
+
comp.then do |component|
|
30
|
+
result_hash[name] = React::API.create_native_react_class(component)
|
31
|
+
end.fail { |err_object| `callBack(#{err_object}, null)` }
|
32
|
+
else
|
33
|
+
result_hash[name] = React::API.create_native_react_class(comp)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
result_hash[name] = React::API.create_native_react_class(proc_or_comp)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
Promise.when(*promises).then { `callBack(null, #{result_hash.to_n})` }
|
40
|
+
end.to_n
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_component_wrapper
|
44
|
+
lambda do |nextState, callBack|
|
45
|
+
comp = @component.call(TransitionContext.new(next_state: nextState))
|
46
|
+
if comp.class < Promise || comp.is_a?(Promise)
|
47
|
+
comp.then do |component|
|
48
|
+
component = React::API.create_native_react_class(component)
|
49
|
+
`callBack(null, component)`
|
50
|
+
end.fail { |err_object| `callBack(#{err_object}, null)` }
|
51
|
+
else
|
52
|
+
comp = React::API.create_native_react_class(comp)
|
53
|
+
`callBack(null, comp)`
|
54
|
+
end
|
55
|
+
end.to_n
|
56
|
+
end
|
57
|
+
|
58
|
+
def on_enter_wrapper
|
59
|
+
lambda do |nextState, replace, callBack|
|
60
|
+
comp =
|
61
|
+
@opts[:on_enter].call(TransitionContext.new(next_state: nextState,
|
62
|
+
replace: replace))
|
63
|
+
if comp.class < Promise || comp.is_a?(Promise)
|
64
|
+
comp.then { `callBack()` }
|
65
|
+
else
|
66
|
+
`callBack()`
|
67
|
+
end
|
68
|
+
end.to_n
|
69
|
+
end
|
70
|
+
|
71
|
+
def on_change_wrapper(proc)
|
72
|
+
lambda do |prevState, nextState, replace, callBack|
|
73
|
+
comp = @opts[:on_change].call(TransitionContext.new(prev_state: prevState,
|
74
|
+
next_state: nextState,
|
75
|
+
replace: replace))
|
76
|
+
if comp.class < Promise || comp.is_a?(Promise)
|
77
|
+
comp.then { `callBack()` }
|
78
|
+
else
|
79
|
+
`callBack()`
|
80
|
+
end
|
81
|
+
end.to_n
|
82
|
+
end
|
83
|
+
|
84
|
+
def on_leave_wrapper(proc)
|
85
|
+
lambda do
|
86
|
+
@opts[:on_leave].call(TransitionContext.new)
|
87
|
+
end.to_n
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_index_route_wrapper
|
91
|
+
lambda do |location, callBack|
|
92
|
+
comp = @opts[:index].call(TransitionContext.new(location: location))
|
93
|
+
if comp.class < Promise || comp.is_a?(Promise)
|
94
|
+
comp.then { |component| `callBack(null, {component: #{component}})` }
|
95
|
+
.fail { |err_object| `callBack(#{err_object}, null)` }
|
96
|
+
else
|
97
|
+
`callBack(null, {component: #{comp}})`
|
98
|
+
end
|
99
|
+
end.to_n
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|