-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathRouter.svelte
90 lines (77 loc) · 2.3 KB
/
Router.svelte
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
<script>
import { getContext, setContext, onDestroy } from 'svelte';
import navaid from 'navaid';
import writableSet from './writable-set';
import { writable } from 'svelte/store';
export let base = '/';
export let middleware = null;
export let hash = null;
export let library = null;
export function navigate(uri, replace) {
if (router) {
router.route(uri, replace);
} else {
pendingNavigate = { uri, replace };
}
}
const baseStore = writable(base);
const libraryStore = writable(library);
const routes = writableSet();
const active = writable();
const params = writable({});
let pendingNavigate = null;
let router;
const context = getContext('navaid');
const contextActive = context && context.active || writable({ path: '' });
const contextLibrary = context && context.library || writable(null);
setContext('navaid', { routes, active, params, base: baseStore, library: libraryStore });
setContext('navigate', navigate);
$: {
const path = $contextActive.path;
if (path && path.slice(-1) === '*') {
base = path.slice(0, -1);
baseStore.set(base);
}
}
$: baseStore.set(base);
$: libraryStore.set(library != null ? library : $contextLibrary);
$: updateRoutes(base, $routes, $libraryStore || navaid);
function updateRoutes(base, routes, navaid) {
if (router) {
router.unlisten();
router = null;
}
if (!routes.size) return;
let notFound;
router = navaid(base, () => $active = notFound);
routes.forEach(route => {
if (!route.path) {
notFound = route;
} else {
router.on(route.path, routeParams => {
$active = route;
$params = routeParams;
if (typeof middleware === 'function') {
middleware(route.path, routeParams);
}
});
if (route.path.slice(-2) === '/*') {
// Allow /url/* to match /url as well
router.on(route.path.slice(0, -2), routeParams => {
$params = routeParams;
$active = route;
});
}
}
});
router.listen();
if (pendingNavigate) {
router.route(pendingNavigate.uri, pendingNavigate.replace);
pendingNavigate = null;
}
}
onDestroy(() => {
if (router) router.unlisten();
});
</script>
<slot></slot>