-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvoir.js
118 lines (101 loc) · 2.4 KB
/
voir.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
112
113
114
115
116
117
118
class Router {
routes = [];
root = "/";
constructor(options) {
window.addEventListener("load", () => {
this.listen();
setTimeout(() => {
this.routeCheck();
}, 1);
});
}
add(path, cb) {
this.routes.push({ path, cb });
}
clearSlashes(path) {
return path
.toString()
.replace(/\/$/, "")
.replace(/^\//, "");
}
getCurrentPath() {
let fragment = decodeURI(window.location.pathname + window.location.search);
fragment = fragment.replace(/\?(.*)$/, "");
return fragment;
}
navigate(path) {
window.history.pushState(null, null, this.root + this.clearSlashes(path));
setTimeout(() => {
this.routeCheck();
}, 1);
}
isExternal(path) {
return path.indexOf(window.location.origin) != 0;
}
listen() {
this.interval = setInterval(this.routeCheck.bind(this), 50);
}
routeCheck() {
let curPath = this.getCurrentPath();
if (this.current === curPath) return;
this.current = curPath;
this.routes.some(route => {
const match = this.current.match(route.path);
if (match) {
match.shift();
route.cb.call(null, match);
return match;
}
return false;
});
}
}
const router = new Router();
let currentPageRoute = null;
export class PageRoute {
constructor(route) {
this.firstTime = false;
this.router = router;
this.router.add(route, match => {
currentPageRoute = this;
this.match = match;
if (this.onInit && !this.firstTime) {
spawn(this.onInit.bind(this));
this.firstTime = true;
}
if (this.onLoad) {
spawn(this.onLoad.bind(this));
}
if (this.onRender) {
spawn(this.onRender.bind(this));
}
});
}
renderCurrentPage() {
if (currentPageRoute && currentPageRoute.onRender) {
currentPageRoute.onRender();
}
}
navigate(path) {
router.navigate(path);
}
}
export function register(routes) {
for (var i in routes) {
new routes[i]();
}
}
export function spawn(f) {
f().then(() => {
//executed
});
}
document.addEventListener("click", function(e) {
var el = e.target;
while (el && "A" !== el.nodeName.toUpperCase()) el = el.parentNode;
if (!el || "A" !== el.nodeName.toUpperCase()) return;
if (el && !router.isExternal(el.href)) {
router.navigate(el.href.slice(window.location.origin.length));
e.preventDefault();
}
});