-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
111 lines (99 loc) · 2.25 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
106
107
108
109
110
111
var inWindow = require('in-window')
var queryString = require('query-string')
var routerParams = require('router-params')
var location = inWindow
? window.location
: { pathname: '/', search: '' }
module.exports = function thataway (paths) {
paths = paths || {}
var routes = {}
var listeners = []
var patterns = []
if (inWindow) {
window.onpopstate = back
}
function register (path, data) {
path = trim(path)
if (path) {
var matcher = routerParams(path)
matcher
? patterns.push({
matcher: matcher,
data: data
})
: routes[path] = data
}
return Object.keys(routes).length
}
function subscribe (listener) {
if (typeof listener === 'function') {
listeners.push(listener)
}
return listeners.length
}
function unsubscribe (l) {
var i = listeners.indexOf(l)
if (l && i !== -1) {
listeners.splice(i, 1)
return true
}
}
function should (path) {
return path && path !== trim(location.pathname)
}
function back () {
var data = router(location.pathname)
data.back = true
update(data)
}
function update (data) {
data = data || router(location.pathname)
data && listeners.forEach(
function (l) {
l(data)
}
)
}
function navigate (path, data, title) {
path = trim(path)
if (inWindow && should(path)) {
window.history.pushState(data, title, path)
update()
}
}
function trim (path) {
return path === '/'
? path
: path && path.replace(/\/*$/, '')
}
function match (path) {
var pattern
var params
var data
var i = 0
var l = patterns.length
for (i; i < l; i++) {
pattern = patterns[i]
params = pattern.matcher(path)
if (params) {
data = pattern.data
data.params = params
break
}
}
return data
}
function router (path) {
path = trim(path)
var data = routes[path] || match(path) || {}
data.query = queryString.parse(location.search)
data.hash = queryString.parse(location.hash)
data.path = path
return data
}
router.subscribe = subscribe
router.unsubscribe = unsubscribe
router.register = register
router.navigate = navigate
return router
}