-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathindex.js
105 lines (88 loc) · 2.98 KB
/
index.js
1
2
3
4
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
var pathname = require('./_pathname')
var wayfarer = require('wayfarer')
var assert = require('assert')
var isLocalFile = (/file:\/\//.test(typeof window === 'object' &&
window.location && window.location.origin)) // electron support
module.exports = sheetRouter
// Fast, modular client router
// fn(str, any[..]) -> fn(str, any[..])
function sheetRouter (opts, tree) {
if (!tree) {
tree = opts
opts = {}
}
assert.equal(typeof opts, 'object', 'sheet-router: opts must be a object')
assert.ok(Array.isArray(tree), 'sheet-router: tree must be an array')
var dft = opts.default || '/404'
assert.equal(typeof dft, 'string', 'sheet-router: dft must be a string')
var router = wayfarer(dft)
var prevCallback = null
var prevRoute = null
match._router = router
// register tree in router
// tree[0] is a string, thus a route
// tree[0] is an array, thus not a route
// tree[1] is a function
// tree[2] is an array
// tree[2] is not an array
// tree[1] is an array
;(function walk (tree, fullRoute) {
if (typeof tree[0] === 'string') {
var route = tree[0].replace(/^[#/]/, '')
} else {
var rootArr = tree[0]
}
var cb = (typeof tree[1] === 'function') ? tree[1] : null
var children = (Array.isArray(tree[1]))
? tree[1]
: Array.isArray(tree[2]) ? tree[2] : null
if (rootArr) {
tree.forEach(function (node) {
walk(node, fullRoute)
})
}
if (cb) {
var innerRoute = route
? fullRoute.concat(route).join('/')
: fullRoute.length ? fullRoute.join('/') : route
// if opts.thunk is false or only enabled for match, don't thunk
var handler = (opts.thunk === false || opts.thunk === 'match')
? cb
: thunkify(cb)
router.on(innerRoute, handler)
}
if (Array.isArray(children)) {
walk(children, fullRoute.concat(route))
}
})(tree, [])
return match
// match a route on the router
//
// no thunking -> call route with all arguments
// thunking only for match -> call route with all arguments
// thunking and route is same -> call prev cb with new args
// thunking and route is diff -> create cb and call with new args
//
// (str, [any..]) -> any
function match (route, arg1, arg2, arg3, arg4, arg5) {
assert.equal(typeof route, 'string', 'sheet-router: route must be a string')
if (opts.thunk === false) {
return router(pathname(route, isLocalFile), arg1, arg2, arg3, arg4, arg5)
} else if (route === prevRoute) {
return prevCallback(arg1, arg2, arg3, arg4, arg5)
} else {
prevRoute = pathname(route, isLocalFile)
prevCallback = router(prevRoute)
return prevCallback(arg1, arg2, arg3, arg4, arg5)
}
}
}
// wrap a function in a function so it can be called at a later time
// fn -> obj -> (any, any, any, any, any)
function thunkify (cb) {
return function (params) {
return function (arg1, arg2, arg3, arg4, arg5) {
return cb(params, arg1, arg2, arg3, arg4, arg5)
}
}
}