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.
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