hyper-router 1.0.alpha1.8 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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/dom'
11
- require 'react/router/history'
12
-
13
- require 'hyperstack/internal/router/isomorphic_methods'
14
- require 'hyperstack/router/history'
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 'hyperstack/internal/router/isomorphic_methods'
26
- require 'hyperstack/router/version'
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
@@ -0,0 +1,9 @@
1
+ module React
2
+ class RenderingContext
3
+ def self.remove_nodes_from_args(args)
4
+ args[0].each do |key, value|
5
+ value.as_node if `value['$is_a?']` && value.is_a?(Element)
6
+ end if args[0] && args[0].is_a?(Hash)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ class Promise
2
+ def then_build_routes(&block)
3
+ self.then do |*args|
4
+ React::Router::DSL.build_routes(*args, &block)
5
+ end
6
+ end
7
+ end
data/lib/react/router.rb CHANGED
@@ -1,5 +1,120 @@
1
1
  module React
2
- class Router < Hyperstack::Component::NativeLibrary
3
- imports 'ReactRouter'
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,11 @@
1
+ module React
2
+ class Router
3
+ class DSL
4
+ class Index < React::Router::DSL::Route
5
+ def save_element
6
+ DSL.set_index self
7
+ end
8
+ end
9
+ end
10
+ end
11
+ 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