-
Notifications
You must be signed in to change notification settings - Fork 92
/
router.cljs
76 lines (54 loc) · 2.29 KB
/
router.cljs
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
(ns bidi.router
(:require [bidi.bidi :as bidi]
[goog.History :as h]
[goog.events :as e]
[clojure.string :as s])
(:import [goog History]))
(defprotocol Router
(set-location! [_ location])
(replace-location! [_ location]))
(defn start-router!
"Starts up a Bidi router based on Google Closure's 'History'
Types:
Location :- {:handler ...
:route-params {...}}
Parameters:
routes :- a Bidi route structure
on-navigate :- 0-arg function, accepting a Location
default-location :- Location to default to if the current token doesn't match a route
Returns :- Router
Example usage:
(require '[bidi.router :as br])
(let [!location (atom nil)
router (br/start-router! [\"\" {\"/\" ::home-page
\"/page2\" ::page2}]
{:on-navigate (fn [location]
(reset! !location location))
:default-location {:handler ::home-page}})]
...
(br/set-location! router {:handler ::page2}))"
[routes {:keys [on-navigate default-location]
:or {on-navigate (constantly nil)}}]
(let [history (History.)]
(.setEnabled history true)
(letfn [(token->location [token]
(or (bidi/match-route routes token)
default-location))
(location->token [{:keys [handler route-params]}]
(bidi/unmatch-pair routes {:handler handler
:params route-params}))]
(e/listen history h/EventType.NAVIGATE
(fn [e]
(on-navigate (token->location (.-token e)))))
(let [initial-token (let [token (.getToken history)]
(if-not (s/blank? token)
token
(or (location->token default-location) "/")))
initial-location (token->location initial-token)]
(.replaceToken history initial-token)
(on-navigate initial-location))
(reify Router
(set-location! [_ location]
(.setToken history (location->token location)))
(replace-location! [_ location]
(.replaceToken history (location->token location)))))))