Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns pantrack.tape
- (:require [clojure.string :as str]
- [goog.events :as events]
- [goog.history.EventType :as HistoryEventType])
- (:import goog.history.Html5History
- goog.history.Html5History.TokenTransformer
- goog.Uri))
- (defn- update-history! [h]
- (doto h
- (.setUseFragment false)
- (.setPathPrefix
- (str js/window.location.protocol "//"
- js/window.location.host))
- (.setEnabled true)))
- (defn- set-retrieve-token! [t]
- (set! (.. t -retrieveToken)
- (fn [path-prefix location]
- (str (.-pathname location) (.-search location)))))
- (defn- set-create-url! [t]
- (set! (.. t -createUrl)
- (fn [token path-prefix location]
- (str path-prefix token))))
- (defn new-history
- ([]
- (new-history
- (doto (TokenTransformer.)
- set-retrieve-token!
- set-create-url!)))
- ([transformer]
- (-> (Html5History. js/window transformer)
- update-history!)))
- (defn dispatch-if-client-route
- [token match-fn dispatch-fn unmatched-fn]
- (if (some? (match-fn token))
- (dispatch-fn token)
- (unmatched-fn token)))
- (defprotocol ITape
- (set-token! [this token] [this token title])
- (replace-token! [this token] [this token title])
- (get-token [this])
- (start! [this])
- (stop! [this]))
- (defrecord Tape [history dispatch-fn match-fn
- unmatched-fn identity-fn event-keys]
- ITape
- (set-token! [_ token]
- (. history (setToken token)))
- (set-token! [_ token title]
- (. history (setToken token title)))
- (replace-token! [_ token]
- (. history (replaceToken token)))
- (replace-token! [_ token title]
- (. history (replaceToken token title)))
- (get-token [_]
- (.getToken history))
- (start! [this]
- (doseq [key @event-keys]
- (events/unlistenByKey key))
- (reset! event-keys nil)
- (swap!
- event-keys conj
- (events/listen
- history
- HistoryEventType/NAVIGATE
- (fn [e]
- (dispatch-if-client-route
- (.-token e) match-fn
- dispatch-fn unmatched-fn))))
- (dispatch-if-client-route
- (get-token this) match-fn
- dispatch-fn unmatched-fn))
- (stop! [_]
- (doseq [key @event-keys]
- (events/unlistenByKey key))
- (reset! event-keys nil)
- (.setEnabled history false)))
- (defn new-tape [match-fn dispatch-fn unmatched-fn]
- (map->Tape {:history (new-history)
- :match-fn match-fn
- :dispatch-fn dispatch-fn
- :unmatched-fn unmatched-fn
- :identity-fn identity
- :event-keys (atom nil)}))
- (defn uri->query [uri]
- (let [query (.getQuery uri)]
- (when-not (empty? query)
- (str "?" query))))
- (defn uri->fragment [uri]
- (let [fragment (.getFragment uri)]
- (when-not (empty? fragment)
- (str "#" fragment))))
- (defn map->params [query]
- (let [params (map #(name %) (keys query))
- values (vals query)
- pairs (partition 2 (interleave params values))]
- (str/join "&" (map #(clojure.string/join "=" %) pairs))))
- (defn navigate!
- ([tape]
- (let [path (-> js/window .-location .-pathname)
- query (-> js/window .-location .-search)
- hash (-> js/window .-location .-hash)]
- ((:dispatch-fn tape)
- (str path query hash))))
- ([tape route] (navigate! tape route {}))
- ([tape route query]
- (let [token (get-token tape)
- old-route (first (str/split token "?"))
- query-string (map->params
- (reduce-kv
- (fn [valid k v]
- (if v
- (assoc valid k v)
- valid))
- {} query))
- with-params (if (empty? query-string)
- route
- (str route "?" query-string))]
- (if (= old-route route)
- (replace-token! tape with-params)
- (set-token! tape with-params)))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement